Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 993e3d02 authored by Yifan Hong's avatar Yifan Hong Committed by Yin-Chia Yeh
Browse files

Use fmq for camera capture result.

Test: camera works.

Bug: 35788245 [Treble] Pass camera metadata using shared memory

Change-Id: Ia8ba8ac4c8f7d1a89035f549c0281a30190554bb
parent e1df4992
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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,
+18 −0
Original line number Diff line number Diff line
@@ -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:
     *
+58 −4
Original line number Diff line number Diff line
@@ -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) {
+11 −0
Original line number Diff line number Diff line
@@ -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;
+7 −0
Original line number Diff line number Diff line
@@ -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