全国服务热线:0551-64931480

27
17-04

Camera源码解析之数据传递

云库科技 722615 0

MTK Camera HAL 层数据传递主要三模块:

一:预览(StartPreview)

二:拍照(TakePicture)

三:回传(PreviewCallBack)

一:预览(StartPreview)

AP层下达预览指令后如何获取数据,数据是什么格式的,最后拿到数据后
是如何去预览,以下分为四部分解析预览数据流程

1 :AP 层到HAL 层流程及获取数据参数
AP层下达startPreview后调到JNI层
android_hardware_Camera_startPreview,在CameraClient中去设
setPreviewWindow和mHardware->startPreview,通过
Cam1DeviceBase:: startPreview去初始化DisplayClient,获取
getPreviewFormat,getPreviewSize及initBuffers初始化预览数据的Buf.

2 :预览线程的创建及数据处理
HAL层PreviewClient下达eID_WAKEUP创建
onClientThreadLoop线程,在线程 waitAndHandleReturnBuffers中
通过dequeProcessor获取实时预览数据.

3: 数据是如何显示出来的
AP层setPreviewSurface后调用JNI层setPreviewTarget,此函数
这里写图片描述
即window就是Surface变量,然后通过setPreviewWindow函数
这里写图片描述
中的initDisplayClient去初始化显示
这里写图片描述
直到set_preview_stream_ops
通过mpStreamOps把拿到的buffer数据显示出来,至此完成了显示的初始化

4 : mpStreamOps 是如何拿到数据的
在上面setPreviewWindow中通过enableDisplayClient向
DisplayClient发送eID_WAKEUP指令创建显示线程
DisplayThread::threadLoop,在handleReturnBuffers通过
enquePrvOps(pStreamImgBuf)接收数据
可以看出这个mpStramOps变量,即window变量是一个Surface

二:拍照(TakePicture )

相机拍照是Camera最重要最复杂的步骤,从点击拍照按钮到成像保
存为图片takePicture贯穿整个流程,如下分四步剖析拍照整个过程(单击
拍照,模式区分,压缩图片,图片回传)

1 :单击拍照
当用户触发拍照时,AP层下达takePicture指令调到JNI层
android_hardware_Camera_takePicture,在CameraClient和
CameraHardwareInterface中转换后直到HAL层再到关键CamAdapter
下的takePicture,在此函数处理中四个关键函数( getShotMode ,
onPreCapture , onStopPreview , onCapture ).

2 :模式区分
onCapture下发eID_CAPTURE Command创建拍照线程
onCaptureThreadLoop, updateShotInstance去更新状态区分不同
拍照模式:NormalShot,ContinuousShot,ZsdShot…
这里写图片描述

这里写图片描述

3 :压缩图片
在onCaptureThreadLoop中下达eCmd_capture指令触发拍照关
键部分,创建pSingleShot调用startOne获取data, 得到data后通过
createJpegImg中的MTK默认的JpegCodec:: encode来压缩图片,
此过程中注意32位数据对齐,还有申请内存时VirAddr和PhyAddr
区别.

4 :图片回传
得到数据后可对数据做第三方处理或者postView,在上传图片前通过
createJpegImgWithThumbnail和createJpegImg得到两张数据
JPEG和Thumbnail两张图片,然后通过onCB_CompressedImage回
传给到AP层

takePicture 数据流程处理:
这里写图片描述

三: 回传(PreviewCallBack)

在实际Android Camera开发过程中,摄像头模块不仅预览,拍照这么
简单,还需要做一些复杂的数据处理功能(如:人脸检测,微信画中画视频通
话等),这些在AP层要获得Camera实时预览帧数据,就需要用到
PreviewCallBack Function.
PreviewCallBack 的使用及数据回传分四步:

1 :Ap 层通过JNI 层向HAL 层传递message
a: 在AP层注册preview Callback setPreviewCallback(Camera.PreviewCallback)
b :在JNI层调用android_hardware_Camera_setHasPreviewCallback中的
setCallbackMode()直到CameraClient中去
enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
说明AP层注册callback就是为了向HAL层发送一个使能message.

2 : 创建线程处理数据及回传数据
在HAL层PreviewClient中比较新旧消息状态来updateMsg.
状态发生改变后创建prevewClient的threadLoop来TodoBuffers,为
实时传递预览数据回传给AP层做准备(关键函数:
waitAndHandleReturnBuffers , mDataCb )

3 : handleMessage 接收数据
在Framework层拿到frame buffer通过通过CameraListener传
递数据到JNI层,然后通过postEventFromNative注册的post_event
来响应handleMessage接收preview cb的YUV数据
data onPreviewFrame(byte[] data, Camera camera) ,Ap层拿
到实时数据做处理及显示.

4:数据回传流程图
这里写图片描述

评论列表(0)
暂无评论