Loading camera/device/3.2/ICameraDeviceCallback.hal +3 −1 Original line number Diff line number Diff line Loading @@ -42,7 +42,9 @@ interface ICameraDeviceCallback { * metadata and low-resolution buffers to be returned in one call, and * post-processed JPEG buffers in a later call, once it is available. Each * call must include the frame number of the request it is returning * metadata or buffers for. * metadata or buffers for. Only one call to processCaptureResult * may be made at a time by the HAL although the calls may come from * different threads in the HAL. * * A component (buffer or metadata) of the complete result may only be * included in one process_capture_result call. A buffer for each stream, Loading camera/device/3.2/ICameraDeviceSession.hal +18 −0 Original line number Diff line number Diff line Loading @@ -262,6 +262,24 @@ interface ICameraDeviceSession { */ getCaptureRequestMetadataQueue() generates (fmq_sync<uint8_t> queue); /** * getCaptureResultMetadataQueue: * * Retrieves the queue used along with * ICameraDeviceCallback.processCaptureResult. * * Clients to ICameraDeviceSession must: * - Call getCaptureRequestMetadataQueue to retrieve the fast message queue; * - In implementation of ICameraDeviceCallback, test whether * .fmqResultSize field is zero. * - If .fmqResultSize != 0, read result metadata from the fast message * queue; * - otherwise, read result metadata in CaptureResult.result. * * @return queue the queue that implementation writes result metadata to. */ getCaptureResultMetadataQueue() generates (fmq_sync<uint8_t> queue); /** * flush: * Loading camera/device/3.2/default/CameraDeviceSession.cpp +58 −4 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ namespace implementation { // Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer. static constexpr size_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */; // Size of result metadata fast message queue. Change to 0 to always use hwbinder buffer. static constexpr size_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */; HandleImporter& CameraDeviceSession::sHandleImporter = HandleImporter::getInstance(); const int CameraDeviceSession::ResultBatcher::NOT_BATCHED; Loading Loading @@ -73,9 +75,16 @@ bool CameraDeviceSession::initialize() { mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>( CAMERA_REQUEST_METADATA_QUEUE_SIZE, false /* non blocking */); if (!mRequestMetadataQueue->isValid()) { ALOGE("%s: invalid fmq", __FUNCTION__); ALOGE("%s: invalid request fmq", __FUNCTION__); return true; } mResultMetadataQueue = std::make_shared<RequestMetadataQueue>( CAMERA_RESULT_METADATA_QUEUE_SIZE, false /* non blocking */); if (!mResultMetadataQueue->isValid()) { ALOGE("%s: invalid result fmq", __FUNCTION__); return true; } mResultBatcher.setResultMetadataQueue(mResultMetadataQueue); return false; } Loading Loading @@ -231,6 +240,11 @@ void CameraDeviceSession::ResultBatcher::setBatchedStreams( mStreamsToBatch = streamsToBatch; } void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q) { Mutex::Autolock _l(mLock); mResultMetadataQueue = q; } void CameraDeviceSession::ResultBatcher::registerBatch( const hidl_vec<CaptureRequest>& requests) { auto batch = std::make_shared<InflightBatch>(); Loading Loading @@ -350,6 +364,7 @@ void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked( results.resize(batchSize); for (size_t i = 0; i < batchSize; i++) { results[i].frameNumber = batch->mFirstFrame + i; results[i].fmqResultSize = 0; results[i].partialResult = 0; // 0 for buffer only results results[i].inputBuffer.streamId = -1; results[i].inputBuffer.bufferId = 0; Loading @@ -366,7 +381,7 @@ void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked( } results[i].outputBuffers = outBufs; } mCallback->processCaptureResult(results); invokeProcessCaptureResultCallback(results, /* tryWriteFmq */false); freeReleaseFences(results); for (int streamId : streams) { InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId]; Loading Loading @@ -396,6 +411,7 @@ void CameraDeviceSession::ResultBatcher::sendBatchMetadataLocked( CaptureResult result; result.frameNumber = p.first; result.result = std::move(p.second); result.fmqResultSize = 0; result.inputBuffer.streamId = -1; result.inputBuffer.bufferId = 0; result.inputBuffer.buffer = nullptr; Loading @@ -404,7 +420,9 @@ void CameraDeviceSession::ResultBatcher::sendBatchMetadataLocked( } mb.mMds.clear(); } mCallback->processCaptureResult(results); hidl_vec<CaptureResult> hResults; hResults.setToExternal(results.data(), results.size()); invokeProcessCaptureResultCallback(hResults, /* tryWriteFmq */true); batch->mPartialResultProgress = lastPartialResultIdx; for (uint32_t partialIdx : toBeRemovedIdxes) { batch->mResultMds.erase(partialIdx); Loading Loading @@ -477,9 +495,37 @@ void CameraDeviceSession::ResultBatcher::notify(NotifyMsg& msg) { } } void CameraDeviceSession::ResultBatcher::invokeProcessCaptureResultCallback( hidl_vec<CaptureResult> &results, bool tryWriteFmq) { if (mProcessCaptureResultLock.tryLock() != OK) { ALOGW("%s: previous call is not finished! waiting 1s...", __FUNCTION__); if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) { ALOGE("%s: cannot acquire lock in 1s, cannot proceed", __FUNCTION__); return; } } if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) { for (CaptureResult &result : results) { if (result.result.size() > 0) { if (mResultMetadataQueue->write(result.result.data(), result.result.size())) { result.fmqResultSize = result.result.size(); result.result.resize(0); } else { ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__); result.fmqResultSize = 0; } } } } mCallback->processCaptureResult(results); mProcessCaptureResultLock.unlock(); } void CameraDeviceSession::ResultBatcher::processOneCaptureResult(CaptureResult& result) { hidl_vec<CaptureResult> results = {result}; mCallback->processCaptureResult(results); invokeProcessCaptureResultCallback(results, /* tryWriteFmq */true); freeReleaseFences(results); return; } Loading Loading @@ -526,6 +572,7 @@ void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& res if (nonBatchedBuffers.size() > 0 || result.inputBuffer.streamId != -1) { CaptureResult nonBatchedResult; nonBatchedResult.frameNumber = result.frameNumber; nonBatchedResult.fmqResultSize = 0; nonBatchedResult.outputBuffers = nonBatchedBuffers; nonBatchedResult.inputBuffer = result.inputBuffer; nonBatchedResult.partialResult = 0; // 0 for buffer only results Loading Loading @@ -716,6 +763,12 @@ Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue( return Void(); } Return<void> CameraDeviceSession::getCaptureResultMetadataQueue( getCaptureResultMetadataQueue_cb _hidl_cb) { _hidl_cb(*mResultMetadataQueue->getDesc()); return Void(); } Return<void> CameraDeviceSession::processCaptureRequest( const hidl_vec<CaptureRequest>& requests, const hidl_vec<BufferCache>& cachesToRemove, Loading Loading @@ -915,6 +968,7 @@ void CameraDeviceSession::sProcessCaptureResult( // within the scope of this function CaptureResult result; result.frameNumber = frameNumber; result.fmqResultSize = 0; result.partialResult = hal_result->partial_result; convertToHidl(hal_result->result, &result.result); if (hasInputBuf) { Loading camera/device/3.2/default/CameraDeviceSession.h +11 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,8 @@ struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callba const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override; Return<void> getCaptureRequestMetadataQueue( getCaptureRequestMetadataQueue_cb _hidl_cb) override; Return<void> getCaptureResultMetadataQueue( getCaptureResultMetadataQueue_cb _hidl_cb) override; Return<void> processCaptureRequest( const hidl_vec<CaptureRequest>& requests, const hidl_vec<BufferCache>& cachesToRemove, Loading Loading @@ -134,12 +136,15 @@ private: using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue; using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue; class ResultBatcher { public: ResultBatcher(const sp<ICameraDeviceCallback>& callback); void setNumPartialResults(uint32_t n); void setBatchedStreams(const std::vector<int>& streamsToBatch); void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q); void registerBatch(const hidl_vec<CaptureRequest>& requests); void notify(NotifyMsg& msg); Loading Loading @@ -217,6 +222,7 @@ private: void freeReleaseFences(hidl_vec<CaptureResult>&); void notifySingleMsg(NotifyMsg& msg); void processOneCaptureResult(CaptureResult& result); void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq); // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch // processCaptureRequest, processCaptureResult, notify will compete for this lock Loading @@ -226,6 +232,11 @@ private: uint32_t mNumPartialResults; std::vector<int> mStreamsToBatch; const sp<ICameraDeviceCallback> mCallback; std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue; // Protect against invokeProcessCaptureResultCallback() Mutex mProcessCaptureResultLock; } mResultBatcher; std::vector<int> mVideoStreamIds; Loading camera/device/3.2/types.hal +7 −0 Original line number Diff line number Diff line Loading @@ -852,6 +852,13 @@ struct CaptureResult { */ uint32_t frameNumber; /** * If non-zero, read result from result queue instead * (see ICameraDeviceSession.getCaptureResultMetadataQueue). * If zero, read result from .result field. */ uint64_t fmqResultSize; /** * The result metadata for this capture. This contains information about the * final capture parameters, the state of the capture and post-processing Loading Loading
camera/device/3.2/ICameraDeviceCallback.hal +3 −1 Original line number Diff line number Diff line Loading @@ -42,7 +42,9 @@ interface ICameraDeviceCallback { * metadata and low-resolution buffers to be returned in one call, and * post-processed JPEG buffers in a later call, once it is available. Each * call must include the frame number of the request it is returning * metadata or buffers for. * metadata or buffers for. Only one call to processCaptureResult * may be made at a time by the HAL although the calls may come from * different threads in the HAL. * * A component (buffer or metadata) of the complete result may only be * included in one process_capture_result call. A buffer for each stream, Loading
camera/device/3.2/ICameraDeviceSession.hal +18 −0 Original line number Diff line number Diff line Loading @@ -262,6 +262,24 @@ interface ICameraDeviceSession { */ getCaptureRequestMetadataQueue() generates (fmq_sync<uint8_t> queue); /** * getCaptureResultMetadataQueue: * * Retrieves the queue used along with * ICameraDeviceCallback.processCaptureResult. * * Clients to ICameraDeviceSession must: * - Call getCaptureRequestMetadataQueue to retrieve the fast message queue; * - In implementation of ICameraDeviceCallback, test whether * .fmqResultSize field is zero. * - If .fmqResultSize != 0, read result metadata from the fast message * queue; * - otherwise, read result metadata in CaptureResult.result. * * @return queue the queue that implementation writes result metadata to. */ getCaptureResultMetadataQueue() generates (fmq_sync<uint8_t> queue); /** * flush: * Loading
camera/device/3.2/default/CameraDeviceSession.cpp +58 −4 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ namespace implementation { // Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer. static constexpr size_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */; // Size of result metadata fast message queue. Change to 0 to always use hwbinder buffer. static constexpr size_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */; HandleImporter& CameraDeviceSession::sHandleImporter = HandleImporter::getInstance(); const int CameraDeviceSession::ResultBatcher::NOT_BATCHED; Loading Loading @@ -73,9 +75,16 @@ bool CameraDeviceSession::initialize() { mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>( CAMERA_REQUEST_METADATA_QUEUE_SIZE, false /* non blocking */); if (!mRequestMetadataQueue->isValid()) { ALOGE("%s: invalid fmq", __FUNCTION__); ALOGE("%s: invalid request fmq", __FUNCTION__); return true; } mResultMetadataQueue = std::make_shared<RequestMetadataQueue>( CAMERA_RESULT_METADATA_QUEUE_SIZE, false /* non blocking */); if (!mResultMetadataQueue->isValid()) { ALOGE("%s: invalid result fmq", __FUNCTION__); return true; } mResultBatcher.setResultMetadataQueue(mResultMetadataQueue); return false; } Loading Loading @@ -231,6 +240,11 @@ void CameraDeviceSession::ResultBatcher::setBatchedStreams( mStreamsToBatch = streamsToBatch; } void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q) { Mutex::Autolock _l(mLock); mResultMetadataQueue = q; } void CameraDeviceSession::ResultBatcher::registerBatch( const hidl_vec<CaptureRequest>& requests) { auto batch = std::make_shared<InflightBatch>(); Loading Loading @@ -350,6 +364,7 @@ void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked( results.resize(batchSize); for (size_t i = 0; i < batchSize; i++) { results[i].frameNumber = batch->mFirstFrame + i; results[i].fmqResultSize = 0; results[i].partialResult = 0; // 0 for buffer only results results[i].inputBuffer.streamId = -1; results[i].inputBuffer.bufferId = 0; Loading @@ -366,7 +381,7 @@ void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked( } results[i].outputBuffers = outBufs; } mCallback->processCaptureResult(results); invokeProcessCaptureResultCallback(results, /* tryWriteFmq */false); freeReleaseFences(results); for (int streamId : streams) { InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId]; Loading Loading @@ -396,6 +411,7 @@ void CameraDeviceSession::ResultBatcher::sendBatchMetadataLocked( CaptureResult result; result.frameNumber = p.first; result.result = std::move(p.second); result.fmqResultSize = 0; result.inputBuffer.streamId = -1; result.inputBuffer.bufferId = 0; result.inputBuffer.buffer = nullptr; Loading @@ -404,7 +420,9 @@ void CameraDeviceSession::ResultBatcher::sendBatchMetadataLocked( } mb.mMds.clear(); } mCallback->processCaptureResult(results); hidl_vec<CaptureResult> hResults; hResults.setToExternal(results.data(), results.size()); invokeProcessCaptureResultCallback(hResults, /* tryWriteFmq */true); batch->mPartialResultProgress = lastPartialResultIdx; for (uint32_t partialIdx : toBeRemovedIdxes) { batch->mResultMds.erase(partialIdx); Loading Loading @@ -477,9 +495,37 @@ void CameraDeviceSession::ResultBatcher::notify(NotifyMsg& msg) { } } void CameraDeviceSession::ResultBatcher::invokeProcessCaptureResultCallback( hidl_vec<CaptureResult> &results, bool tryWriteFmq) { if (mProcessCaptureResultLock.tryLock() != OK) { ALOGW("%s: previous call is not finished! waiting 1s...", __FUNCTION__); if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) { ALOGE("%s: cannot acquire lock in 1s, cannot proceed", __FUNCTION__); return; } } if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) { for (CaptureResult &result : results) { if (result.result.size() > 0) { if (mResultMetadataQueue->write(result.result.data(), result.result.size())) { result.fmqResultSize = result.result.size(); result.result.resize(0); } else { ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__); result.fmqResultSize = 0; } } } } mCallback->processCaptureResult(results); mProcessCaptureResultLock.unlock(); } void CameraDeviceSession::ResultBatcher::processOneCaptureResult(CaptureResult& result) { hidl_vec<CaptureResult> results = {result}; mCallback->processCaptureResult(results); invokeProcessCaptureResultCallback(results, /* tryWriteFmq */true); freeReleaseFences(results); return; } Loading Loading @@ -526,6 +572,7 @@ void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& res if (nonBatchedBuffers.size() > 0 || result.inputBuffer.streamId != -1) { CaptureResult nonBatchedResult; nonBatchedResult.frameNumber = result.frameNumber; nonBatchedResult.fmqResultSize = 0; nonBatchedResult.outputBuffers = nonBatchedBuffers; nonBatchedResult.inputBuffer = result.inputBuffer; nonBatchedResult.partialResult = 0; // 0 for buffer only results Loading Loading @@ -716,6 +763,12 @@ Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue( return Void(); } Return<void> CameraDeviceSession::getCaptureResultMetadataQueue( getCaptureResultMetadataQueue_cb _hidl_cb) { _hidl_cb(*mResultMetadataQueue->getDesc()); return Void(); } Return<void> CameraDeviceSession::processCaptureRequest( const hidl_vec<CaptureRequest>& requests, const hidl_vec<BufferCache>& cachesToRemove, Loading Loading @@ -915,6 +968,7 @@ void CameraDeviceSession::sProcessCaptureResult( // within the scope of this function CaptureResult result; result.frameNumber = frameNumber; result.fmqResultSize = 0; result.partialResult = hal_result->partial_result; convertToHidl(hal_result->result, &result.result); if (hasInputBuf) { Loading
camera/device/3.2/default/CameraDeviceSession.h +11 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,8 @@ struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callba const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override; Return<void> getCaptureRequestMetadataQueue( getCaptureRequestMetadataQueue_cb _hidl_cb) override; Return<void> getCaptureResultMetadataQueue( getCaptureResultMetadataQueue_cb _hidl_cb) override; Return<void> processCaptureRequest( const hidl_vec<CaptureRequest>& requests, const hidl_vec<BufferCache>& cachesToRemove, Loading Loading @@ -134,12 +136,15 @@ private: using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue; using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue; class ResultBatcher { public: ResultBatcher(const sp<ICameraDeviceCallback>& callback); void setNumPartialResults(uint32_t n); void setBatchedStreams(const std::vector<int>& streamsToBatch); void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q); void registerBatch(const hidl_vec<CaptureRequest>& requests); void notify(NotifyMsg& msg); Loading Loading @@ -217,6 +222,7 @@ private: void freeReleaseFences(hidl_vec<CaptureResult>&); void notifySingleMsg(NotifyMsg& msg); void processOneCaptureResult(CaptureResult& result); void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq); // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch // processCaptureRequest, processCaptureResult, notify will compete for this lock Loading @@ -226,6 +232,11 @@ private: uint32_t mNumPartialResults; std::vector<int> mStreamsToBatch; const sp<ICameraDeviceCallback> mCallback; std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue; // Protect against invokeProcessCaptureResultCallback() Mutex mProcessCaptureResultLock; } mResultBatcher; std::vector<int> mVideoStreamIds; Loading
camera/device/3.2/types.hal +7 −0 Original line number Diff line number Diff line Loading @@ -852,6 +852,13 @@ struct CaptureResult { */ uint32_t frameNumber; /** * If non-zero, read result from result queue instead * (see ICameraDeviceSession.getCaptureResultMetadataQueue). * If zero, read result from .result field. */ uint64_t fmqResultSize; /** * The result metadata for this capture. This contains information about the * final capture parameters, the state of the capture and post-processing Loading