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