一:預覽(StartPreview)
二:拍照(TakePicture)
三:回傳(PreviewCallBack)
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
相機拍照是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 數據流程處理: 
在實際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:數據回傳流程圖 
發表評論 取消回復