1. status_t Camera3Device::waitForNextFrame(nsecs_t timeout) { 2. status_t res; 3. Mutex::Autolock l(mOutputLock); 4. 5. while (mResultQueue.empty()) {//capture result 结果非空则继续执行 6. res = mResultSignal.waitRelative(mOutputLock, timeout); 7. if (res == TIMED_OUT) { 8. return res; 9. } else if (res != OK) { 10. ALOGW(\ PRId64 \, 11. __FUNCTION__, mId, timeout, strerror(-res), res); 12. return res; 13. } 14. } 15. return OK; 16. } 在这里一是看到了mResultQueue,二是看到了mResultSignal。对应于Camera3Device::sendCaptureResult()中的mOutputLock以及signal。 线程被唤醒后调用processNewFrames来处理当前帧
[cpp] view plaincopy
1. void FrameProcessorBase::processNewFrames(const sp &device) { 2. status_t res; 3. ATRACE_CALL(); 4. CaptureResult result; 5. 6. ALOGV(\, __FUNCTION__, device->getId()); 7. 8. while ( (res = device->getNextResult(&result)) == OK) { 9. 10. // TODO: instead of getting frame number from metadata, we should read 11. // this from result.mResultExtras when CameraDeviceBase interface is fixed. 21
12. camera_metadata_entry_t entry; 13. 14. entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT); 15. if (entry.count == 0) { 16. ALOGE(\number\, 17. __FUNCTION__, device->getId()); 18. break; 19. } 20. ATRACE_INT(\, entry.data.i32[0]); 21. 22. if (!processSingleFrame(result, device)) {//单独处理一帧 23. break; 24. } 25. 26. if (!result.mMetadata.isEmpty()) { 27. Mutex::Autolock al(mLastFrameMutex); 28. mLastFrame.acquire(result.mMetadata); 29. } 30. } 31. if (res != NOT_ENOUGH_DATA) { 32. ALOGE(\: %s (%d)\, 33. __FUNCTION__, device->getId(), strerror(-res), res); 34. return; 35. } 36. 37. return; 38. } device->getNextResult(&result)是从mResultQueue提取一个可用的
CaptureResult,提取完成后作erase的处理。再检验这个Result是否属于一个固定的framenum,然后由processSingleFrame来完成一件事: [cpp] view plaincopy
1. bool FrameProcessor::processSingleFrame(CaptureResult &frame, 2. const sp &device) {//处理帧 3. 4. 22
5. sp client = mClient.promote(); 6. if (!client.get()) { 7. return false; 8. } 9. 10. 11. bool isPartialResult = false; 12. if (mUsePartialResult) { 13. if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_2) { 14. isPartialResult = frame.mResultExtras.partialResultCount < mNumPartialResults; 15. } else { 16. camera_metadata_entry_t entry; 17. entry = frame.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT); 18. if (entry.count > 0 && 19. entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { 20. isPartialResult = true; 21. } 22. } 23. } 24. 25. 26. if (!isPartialResult && processFaceDetect(frame.mMetadata, client) != OK) { 27. return false; 28. } 29. 30. 31. if (mSynthesize3ANotify) { 32. process3aState(frame, client); 33. } 34. 35. 36. return FrameProcessorBase::processSingleFrame(frame, device); 37. } [cpp] view plaincopy
1. bool FrameProcessorBase::processSingleFrame(CaptureResult &result, 23
2. const sp &device) { 3. ALOGV(\)\, 4. __FUNCTION__, device->getId(), result.mMetadata.isEmpty()); 5. return processListeners(result, device) == OK;//处理所有的listener 6. } [cpp] view plaincopy
1. status_t FrameProcessorBase::processListeners(const CaptureResult &result, 2. const sp &device) { 3. ATRACE_CALL(); 4. 5. camera_metadata_ro_entry_t entry; 6. 7. // Check if this result is partial. 8. bool isPartialResult = false; 9. if (device->getDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_2) { 10. isPartialResult = result.mResultExtras.partialResultCount < mNumPartialResults; 11. } else { 12. entry = result.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT); 13. if (entry.count != 0 && 14. entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { 15. ALOGV(\sult\, 16. __FUNCTION__, device->getId()); 17. isPartialResult = true; 18. } 19. } 20. 21. // TODO: instead of getting requestID from CameraMetadata, we should get it 22. // from CaptureResultExtras. This will require changing Camera2Device. 23. // Currently Camera2Device uses MetadataQueue to store results, which does not 24
24. // include CaptureResultExtras. 25. entry = result.mMetadata.find(ANDROID_REQUEST_ID); 26. if (entry.count == 0) { 27. ALOGE(\, __FUNCTION__, device->getId()); 28. return BAD_VALUE; 29. } 30. int32_t requestId = entry.data.i32[0]; 31. 32. List > listeners; 33. { 34. Mutex::Autolock l(mInputMutex); 35. 36. List::iterator item = mRangeListeners.begin(); 37. // Don't deliver partial results to listeners that don't want them 38. while (item != mRangeListeners.end()) { 39. if (requestId >= item->minId && requestId < item->maxId && 40. (!isPartialResult || item->sendPartials)) { 41. sp listener = item->listener.promote(); 42. if (listener == 0) { 43. item = mRangeListeners.erase(item); 44. continue; 45. } else { 46. listeners.push_back(listener); 47. } 48. } 49. item++; 50. } 51. } 52. ALOGV(\of %zu\, __FUNCTION__, 53. device->getId(), listeners.size(), mRangeListeners.size()); 54. 55. List >::iterator item = listeners.begin(); 56. for (; item != listeners.end(); item++) { 25
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库Android Camera HAL3中拍照Capture模式下多模块间的交互与帧Resu(5)在线全文阅读。