在Android中,当Camera原生服务有数据上传给客户端时,在ICameraClient的数据回调函数中会收到数据,具体如下:
        代码:客户端的数据回调处理
void CameraService::Client::dataCallback(int32_t msgType, const sp< IMemory>& dataPtr, void* user)
    {
        LOGV("dataCallback(%d)", msgType);
        sp< Client> client=getClientFromCookie(user);    //获取客户端
        if (client==0) {
              return;
        }
        sp< ICameraClient> c=client->mCameraClient;    //获取ICameraClient
        if (dataPtr==NULL) {	    //如果没有数据
            LOGE("Null data returned in data callback");
            if (c != NULL) {
                  c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
                  c->dataCallback(msgType, NULL); 
 
              }
            return;
        }
        switch (msgType) {
            case CAMERA_MSG_PREVIEW_FRAME:    //预览数据帧
                  client->handlePreviewData(dataPtr);
                  break;
            case CAMERA_MSG_POSTVIEW_FRAME:    //准备预览
                  client->handlePostview(dataPtr);
                  break;
            case CAMERA_MSG_RAW_IMAGE:    //原始图像
                  client->handleRawPicture(dataPtr);
                  break;
            case CAMERA_MSG_COMPRESSED_IMAGE:    //压缩图像
                  client->handleCompressedPicture(dataPtr);
                  break;
            default:
                if (c !=NULL) {
                      c->dataCallback(msgType, dataPtr);
                  }
                break;
        }
    #if DEBUG_CLIENT_REFERENCES
          if (client->getStrongCount()==1) {
    LOGE("++++++++++++++++ (DATA CALLBACK) THIS WILL CAUSE A LOCKUP!");
              client->printRefs();
          }
    #endif
    }
当客户端的数据回调函数收到的消息类型为CAMERA_MSG_PREVIEW_FRAME时,客户端通过handlePreviewData()方法进行处理;当消息类型为CAMERA_MSG_ POSTVIEW_FRAME时,客户端通过handlePostview()方法进行处理,然后向上层应用传递CAMERA_MSG_PREVIEW_FRAME消息;当消息类型为CAMERA_MSG_RAW_IMAGE时,客户端通过handleRawPicture()方法进行处理,将拍摄的图像渲染在屏幕上;当消息类型为CAMERA_MSG_COMPRESSED_IMAGE时,客户端通过handleCompressedPicture()方法进行处理,将JPG数据传递给上层应用。
        在handlePreviewData()方法中,会将收到的数据进行屏幕渲染,下面是handlePreviewData()方法的实现:
        代码:预览数据处理
        void CameraService::Client::handlePreviewData(const sp< IMemory>& mem)
    {
        ssize_t offset;
        size_t size;
    //获取偏移地址和大小,格式为YUV
        sp< IMemoryHeap> heap=mem->getMemory(&offset, &size);  
    #if DEBUG_HEAP_LEAKS && 0 // debugging
        if (gWeakHeap==NULL) {
            if (gWeakHeap != heap) {
      LOGD("SETTING PREVIEW HEAP");
                  heap->trackMe(true, true);
                  gWeakHeap=heap;
              }
        }
    #endif
    if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
        {
            if (debug_frame_cnt++==DEBUG_DUMP_PREVIEW_FRAME_TO_FILE) {
                  dump_to_file("/data/preview.yuv",  //调试用
                  uint8_t *)heap->base() + offset, size);
              }
        }
    #endif
        if (!mUseOverlay)
        {
              Mutex::Autolock surfaceLock(mSurfaceLock);
              if (mSurface !=NULL) {
              mSurface->postBuffer(offset);  //传递给Surface
              }
        }
        int flags=mPreviewCallbackFlag;
        if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
              LOGV("frame callback is diabled");
              return;
        }
        sp< ICameraClient> c=mCameraClient;
        if ((c==NULL) || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
              LOGV("Disable preview callback");
              mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASKFRAME_CALLBACK_FLAG_COPY_OUT_MASK|
FRAME_CALLBACK_FLAG_ENABLE_MASK);
              if (mUseOverlay)
              mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
        }
        if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
              LOGV("frame is copied");
              copyFrameAndPostCopiedFrame(c, heap, offset, size);	//将数据存入预览缓冲
        } else {
              LOGV("frame is forwarded");
              c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);		//向上层传递消息
          }
    }
当上层收到数据时,执行保持数据的方法为ImageCapture:: storeImage()。