您的位置:华清远见教育科技集团 >> Android资料 >> Android中Camera数据的处理  
 
Android中Camera数据的处理
分享到:

在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()。

 更多相关文章

·Android Camera拍照源码分析
·Android Camera原生服务架构
·Android Camera录像过程分析
·Android 原生层媒体播放过程
·Android 视频解码过程详解