c. 对于STILL_CAPTURE类型的picture
client->stopStream(),实现的本质是res = device->clearStreamingRequest(),mRequestThread->clearRepeatingRequests(lastFrameNumber);
该函数是将之前Preview模式下的建立的captureRequest作delete处理,之前在预览模式下是将最终生产的capturelist加入到了一个mRepeatingRequests当中,这里通过clear使之为empty,即不会再发送Request和HAL3进行数据的交互。
d.Camera3Device capture函数
首先关注capture函数传入的参数为captureCopy,即CameraMetadata mCaptureRequest的一个copy值。 [cpp] view plaincopy
1. status_t Camera3Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) { 2. ATRACE_CALL(); 3. 4. List
1. status_t Camera3Device::captureList(const List
这也表明了最终CameraMetadata类型的Request都是由submitRequestsHelper来完成的,所以convertMetadataListToRequestListLocked这个将
CameraMetadata转换为List
11
两者来说都是一致的。但在后续处理时,对picture模式下的Request,其不再是repeating的处理,mRequestThread->queueRequestList(): [cpp] view plaincopy
1. status_t Camera3Device::RequestThread::queueRequestList( 2. List
最简单的理解是picture模式下是拍去几帧的数据流即可,Preview模式下是实时的获取帧,前者是几次one snop,后者是连续continuous。
到这里为止,可以说CaptureSequence已经完成了START状态机的处理。
e. 从START到STANDARD_CAPTURE_WAIT
该状态下对应的状态机处理函数为manageStandardCaptureWait: [cpp] view plaincopy
1. CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait( 2. sp
12. break; 13. } 14. } 15. 16. // Approximation of the shutter being closed 17. // - TODO: use the hal3 exposure callback in Camera3Device instead 18. if (mNewFrameReceived && !mShutterNotified) { 19. SharedParameters::Lock l(client->getParameters()); 20. /* warning: this also locks a SharedCameraCallbacks */ 21. shutterNotifyLocked(l.mParameters, client, mMsgType); 22. mShutterNotified = true; 23. } 24. 25. // Wait until jpeg was captured by JpegProcessor 26. while (mNewFrameReceived && !mNewCaptureReceived) { 27. res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);//等待JPEG数据 28. if (res == TIMED_OUT) { 29. mTimeoutCount--; 30. break; 31. } 32. } 33. if (mTimeoutCount <= 0) { 34. ALOGW(\te\); 35. return DONE; 36. } 37. if (mNewFrameReceived && mNewCaptureReceived) {//满足mNewFrameReceived 38. if (mNewFrameId != mCaptureId) { 39. ALOGW(\ted %d, got %d\, 40. mCaptureId, mNewFrameId); 41. } 42. camera_metadata_entry_t entry; 43. entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP); 44. if (entry.count == 0) { 13
45. ALOGE(\!\); 46. } else if (entry.count == 1) { 47. if (entry.data.i64[0] != mCaptureTimestamp) { 48. ALOGW(\Metadata frame %\ PRId64 \ 49. \ PRId64, 50. entry.data.i64[0], 51. mCaptureTimestamp); 52. } 53. } else { 54. ALOGE(\); 55. } 56. client->removeFrameListener(mCaptureId, mCaptureId + 1, this); 57. 58. mNewFrameReceived = false; 59. mNewCaptureReceived = false; 60. return DONE; 61. } 62. return STANDARD_CAPTURE_WAIT; 63. } 具体分析该函数可以知道其处于两次wait休眠状态,主要响应两个条件等待信号mNewFrameSignal与mNewCaptureSignal,两者者的等待周期为100ms。只有当mNewFrameReceived && mNewCaptureReceived同事满足条件时,才算是Capture到一帧picture。
f . Done State状态
这里先假设已经完成了wait这个状态,就会进入Done状态的执行函数manageDone(),最重要的部分如下: [cpp] view plaincopy
1. if (mCaptureBuffer != 0 && res == OK) { 2. ATRACE_ASYNC_END(Camera2Client::kTakepictureLabel, takePictureCounter); 3. 4. Camera2Client::SharedCameraCallbacks::Lock 5. l(client->mSharedCameraCallbacks); 6. ALOGV(\, __FUNCTION__); 7. if (l.mRemoteCallback != 0) { 14
8. l.mRemoteCallback->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, 9. mCaptureBuffer, NULL);//回传压缩好的jpeg数据到上层 10. } else { 11. ALOGV(\, __FUNCTION__); 12. } 13. } 14. mCaptureBuffer.clear(); 他将采集到的一帧jpeg压缩格式的图像,回传到APP层,便于后期写入到文件等。在以往Camera HAL1.0中这部分的数据回传玩玩都是由HAL层来完成的,这也给编码带来复杂度以及效率低下等问题。Google在Camera3.0中很好的封装了dataCallback以及notifyCallback的回调处理,将其转到Camera2Client下不同模块来做响应回调。
其中mCaptureBuffer是回传回来的真实的jpeg格式的图像数据,其本质是从stream中提取的一个buffer然后被copy到一个heap中,等待APP Callback完成后,就会释放。
完成了Done状态后,CaptureSequence又会再次进入到IDLE模式,等待下一次的take picture的处理。
3 picture模式下Camera3Device处理Request与result
对于picture模式下的Request处理,可以参考Preview模式下的
RequestThread::threadLoop下的处理过程。这里主要分析result的响应过程: 在前面已经提到CaptureSequence需要wait两个signal,一般都是有其他模块来触发回调这个signal,我们先来定位这两个signal发出的位置: [cpp] view plaincopy
1. void CaptureSequencer::onResultAvailable(const CaptureResult &result) { 2. ATRACE_CALL(); 3. ALOGV(\, __FUNCTION__); 4. Mutex::Autolock l(mInputMutex); 5. mNewFrameId = result.mResultExtras.requestId;//返回帧所属的request id 6. mNewFrame = result.mMetadata; 7. if (!mNewFrameReceived) { 8. mNewFrameReceived = true; 9. mNewFrameSignal.signal();//buffer相应的result 信息,由FrameProcessor模块来触发listener 10. } 11. } 15
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库Android Camera HAL3中拍照Capture模式下多模块间的交互与帧Resu(3)在线全文阅读。
相关推荐: