12. 13. void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp, 14. sp
3.1.明确picture模式下,一次处理需要的stream数目
需要明确的是一次take picture需要的stream分别有JpegProcessor、
CallbackProcessor、StreamingProcessor三种,第一个主要接收的是jpeg格式的帧图像,第二个主要接收的是一帧的preview模式下回调到APP的视频帧,而最后一个是直接获取一帧视频图像后直接进行显示用的视频帧。
3.2.帧数据回调响应的由来processCaptureResult函数: 无论是哪一个模块,数据回调响应最初的入口是HAL3的
process_capture_result函数即processCaptureResult()函数,该函数的处理之所以复杂是因为HAL3.0中允许一次result回来的数据可以是不完整的,其中以3A相关的cameraMetadata的数据为主,这里需要说明每一帧的result回来时
camera3_capture_result都是含有一个camera_metadata_t的,包含着一帧图像的各种信息tag字段,其中以3A信息为主。在processCaptureResult函数中由三个核心函数:
processPartial3AResult():处理回传回来的部分cameraMetadata result数据; returnOutputBuffers():返回这次result中各个stream对应的buffer数据; sendCaptureResult():处理的是一次完整的cameraMetadata result数据;
3.3. FrameProcessor模块的帧Result响应,以3A回调处理为主
processPartial3AResult()函数与sendCaptureResult()函数都是将3A的result结果发送给FrameProcessor去作处理的,因为无论是Request还是result都是必然带有一个类似stream的cameraMetadata的,所以在这个模块有别于其他模块,故不需要单独的stream流来交互数据的。 [cpp] view plaincopy
16
1. if (isPartialResult) { 2. // Fire off a 3A-only result if possible 3. if (!request.partialResult.haveSent3A) {//返回的只是3A的数据 4. request.partialResult.haveSent3A = 5. processPartial3AResult(frameNumber, 6. request.partialResult.collectedResult, 7. request.resultExtras);// frame含有3A则notify 处理 8. } 9. } processPartial3AResult是将当前帧收集到的partialResult进行处理,需要明确的是partialResult是指定帧framenum下返回的result最新组成的result:
其内部需要确保目前收集到的result需要至少含有如下的tag的值,才算一次3A数据可True:
[cpp] view plaincopy
1. gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE, 2. &afMode, frameNumber); 3. 4. gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE, 5. &awbMode, frameNumber); 6. 7. gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE, 8. &aeState, frameNumber); 9. 10. gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE, 11. &afState, frameNumber); 12. 13. gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE, 14. &awbState, frameNumber); if (!gotAllStates) return false; 17
只有这样才满足构建一个CaptureResult minResult的要求,上述过程表明对已有的Result需要AE、AF、AWB同时OK时才会构建一个CaptureResult。 接着对比着来看sendCaptureResult: [cpp] view plaincopy
1. void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, 2. CaptureResultExtras &resultExtras, 3. CameraMetadata &collectedPartialResult, 4. uint32_t frameNumber) { 5. if (pendingMetadata.isEmpty()) 6. return; 7. 8. Mutex::Autolock l(mOutputLock); 9. 10. // TODO: need to track errors for tighter bounds on expected frame number 11. if (frameNumber < mNextResultFrameNumber) { 12. SET_ERR(\order capture result metadata submitted! \ 13. \, 14. frameNumber, mNextResultFrameNumber); 15. return; 16. } 17. mNextResultFrameNumber = frameNumber + 1;//下一帧 18. 19. CaptureResult captureResult; 20. captureResult.mResultExtras = resultExtras; 21. captureResult.mMetadata = pendingMetadata; 22. 23. if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT, 24. (int32_t*)&frameNumber, 1) != OK) { 25. SET_ERR(\\, 26. frameNumber); 27. return; 28. } else { 29. ALOGVV(\(%d)\, 30. __FUNCTION__, mId, frameNumber); 31. } 18
32. 33. // Append any previous partials to form a complete result 34. if (mUsePartialResult && !collectedPartialResult.isEmpty()) { 35. captureResult.mMetadata.append(collectedPartialResult);// 36. } 37. 38. captureResult.mMetadata.sort(); 39. 40. // Check that there's a timestamp in the result metadata 41. camera_metadata_entry entry = 42. captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); 43. if (entry.count == 0) { 44. SET_ERR(\e %d!\, 45. frameNumber); 46. return; 47. } 48. 49. // Valid result, insert into queue 50. List
19
个人理解这个partialResult的处理机制是每次返回的Result并不一定包含了当前frameNumber帧号所需要的tag信息,而且这个每次回传的mNumPartialResults值是由HAL3.0层来决定的。在每次一的Result中,会收集
其中 isPartialResult = (result->partial_result < mNumPartialResults)决定了当前的Result是否还是一个处于partial Result的模式,是的话每次都进行collectResult,此外对于此模式下会收集3A的tag信息,调用
processPartial3AResult来处理3A的值,而这个过程也是单列的处理。而一旦当前的Result返回处于非partial模式时,直接提取之前collect的Result并和当前的Result共同组成一个新的Capture Result。生成的CaptureResult会加入到mResultQueue队列。
至此分析完了HAL3返回的Captrue Result的处理过程,最终
mResultSignal.signal()唤醒相应的等待线程,而这个过程就是由FrameProcessor模块来响应的。
FrameProcessorBase是一个FrameProcessor的基类,会启动一个Threadloop:
[cpp] view plaincopy
1. bool FrameProcessorBase::threadLoop() { 2. status_t res; 3. 4. sp
20
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库Android Camera HAL3中拍照Capture模式下多模块间的交互与帧Resu(4)在线全文阅读。
相关推荐: