Merge "Use fmq for camera capture result." into oc-dev
This commit is contained in:
commit
939c906a4f
5 changed files with 97 additions and 5 deletions
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>();
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
|
|
@ -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…
Reference in a new issue