对于preview部分到CameraService的控制流可以参考博文Android4.2.2的preview的数据流和控制流以及最终的预览显示,本文将直接从Camera2Client::startPreview() 作为入口来分析整个Framework层中Preview相关的数据流。
[cpp] view plaincopy
1. 2. 3. 4. 5. 6. 7. 8. 9. status_t Camera2Client::startPreview() { ATRACE_CALL(); ALOGV(\, __FUNCTION__); Mutex::Autolock icl(mBinderSerializationLock); status_t res; if ( (res = checkPid(__FUNCTION__) ) != OK) return res; SharedParameters::Lock l(mParameters); return startPreviewL(l.mParameters, false); } startPreview通过startPreviewL提取参数后真正的开始执行Preview相关的控制流。该函数看上去内容虽然较多,但基本采用了同一种处理方式:
[cpp] view plaincopy
1. 2. 3. 4. 5. 6. 7. status_t Camera2Client::startPreviewL(Parameters ?ms, bool restart) {//restart == false ATRACE_CALL(); status_t res; ...... int lastPreviewStreamId = mStreamingProcessor->getPreviewStreamId();//获取上一层Preview stream id res = mStreamingProcessor->updatePreviewStream(params);//创建camera3device stream, Camera3OutputStream 8. ..... 9. int lastJpegStreamId = mJpegProcessor->getStreamId(); 10. res = updateProcessorStream(mJpegProcessor, params);//预览启动时就建立一个jpeg的outstream 11. ..... 12. res = mCallbackProcessor->updateStream(params);//回调处理建立一个Camera3outputstream 13. 14. 15. 16. 17. 18. if (res != OK) { ALOGE(\, __FUNCTION__, mCameraId, strerror(-res), res); return res; } outputStreams.push(getCallbackStreamId()); 19. ...... 20. outputStreams.push(getPreviewStreamId());//预览stream 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. ...... if (!params.recordingHint) { if (!restart) { res = mStreamingProcessor->updatePreviewRequest(params);//request处理,更新了mPreviewrequest if (res != OK) { ALOGE(\ \, __FUNCTION__, mCameraId, strerror(-res), res); return res; } } res = mStreamingProcessor->startStream(StreamingProcessor::PREVIEW, outputStreams);//启动stream,传入outputStreams即stream 的id } else { if (!restart) { res = mStreamingProcessor->updateRecordingRequest(params); if (res != OK) { ALOGE(\ \, __FUNCTION__, mCameraId, strerror(-res), res); return res; } } res = mStreamingProcessor->startStream(StreamingProcessor::RECORD, outputStreams); 46. } 47. ...... 48. }
(1). mStreamingProcessor->updatePreviewStream() 由预览与录像处理模块更新一个预览流,其实现过程如下:
[cpp] view plaincopy
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. status_t StreamingProcessor::updatePreviewStream(const Parameters ?ms) { ATRACE_CALL(); Mutex::Autolock m(mMutex); status_t res; sp device = mDevice.promote();//Camera3Device if (device == 0) { ALOGE(\, __FUNCTION__, mId); return INVALID_OPERATION; } if (mPreviewStreamId != NO_STREAM) { // Check if stream parameters have to change uint32_t currentWidth, currentHeight; res = device->getStreamInfo(mPreviewStreamId, ¤tWidth, ¤tHeight, 0); if (res != OK) { 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. ALOGE(\ \, __FUNCTION__, mId, strerror(-res), res); return res; } if (currentWidth != (uint32_t)params.previewWidth || currentHeight != (uint32_t)params.previewHeight) { ALOGV(\, __FUNCTION__, mId, currentWidth, currentHeight, params.previewWidth, params.previewHeight); res = device->waitUntilDrained(); if (res != OK) { ALOGE(\ \, __FUNCTION__, mId, strerror(-res), res); return res; } res = device->deleteStream(mPreviewStreamId); if (res != OK) { ALOGE(\ \, __FUNCTION__, mId, strerror(-res), res); return res; } mPreviewStreamId = NO_STREAM; } } if (mPreviewStreamId == NO_STREAM) {//首次create stream 45. res = device->createStream(mPreviewWindow, 46. params.previewWidth, params.previewHeight, 47. CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, &mPreviewStreamId);//创建一个Camera3OutputStream 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. if (res != OK) { ALOGE(\, __FUNCTION__, mId, strerror(-res), res); return res; } } res = device->setStreamTransform(mPreviewStreamId, params.previewTransform); if (res != OK) { ALOGE(\ \, __FUNCTION__, mId, strerror(-res), res); return res; } return OK; } 该函数首先是查看当前StreamingProcessor模块下是否存在Stream,没有的话,则交由Camera3Device创建一个stream。显然,一个StreamingProcessor只能拥有一个PreviewStream,而一个Camera3Device显然控制着所有的Stream。
注意:在Camera2Client中,Stream大行其道,5大模块的数据交互均以stream作为基础。 下面我们来重点关注Camera3Device的接口createStream,他是5个模块创建stream的基础:
[cpp] view plaincopy
1. 2. 3. 4. 5. 6. status_t Camera3Device::createStream(sp consumer, uint32_t width, uint32_t height, int format, int *id) { ATRACE_CALL(); Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); ALOGV(\, 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. mId, mNextStreamId, width, height, format); status_t res; bool wasActive = false; switch (mStatus) { case STATUS_ERROR: CLOGE(\); return INVALID_OPERATION; case STATUS_UNINITIALIZED: CLOGE(\); return INVALID_OPERATION; case STATUS_UNCONFIGURED: case STATUS_CONFIGURED: // OK break; case STATUS_ACTIVE: ALOGV(\, __FUNCTION__); res = internalPauseAndWaitLocked(); if (res != OK) { SET_ERR_L(\); return res; } wasActive = true; break; default: SET_ERR_L(\, mStatus); return INVALID_OPERATION; } assert(mStatus != STATUS_ACTIVE); sp newStream; if (format == HAL_PIXEL_FORMAT_BLOB) {//图片 if (jpegBufferSize <= 0) { SET_ERR_L(\, jpegBufferSize); return BAD_VALUE; } newStream = new Camera3OutputStream(mNextStreamId, consumer, width, height, jpegBufferSize, format);//jpeg 缓存的大小 } else { newStream = new Camera3OutputStream(mNextStreamId, consumer, width, height, format);//Camera3OutputStream } newStream->setStatusTracker(mStatusTracker); res = mOutputStreams.add(mNextStreamId, newStream);//一个streamid与Camera3OutputStream绑定 if (res < 0) { SET_ERR_L(\, strerror(-res), res); return res; } *id = mNextStreamId++;//至少一个previewstream 一般还有CallbackStream mNeedConfig = true; // Continue captures if active at start if (wasActive) { ALOGV(\, __FUNCTION__); res = configureStreamsLocked(); if (res != OK) { CLOGE(\, 40. ssize_t jpegBufferSize = getJpegBufferSize(width, height);