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

Commit b75aa350 authored by Emilian Peev's avatar Emilian Peev
Browse files

camera: Add support for individual physical camera requests

Multi-camera devices should be able to accept and process
individual settings for all physical sensors backing the
logical camera. 'CaptureRequest' must be extended to hold
these additional physical camera settings.

Test: Manual using camera application,
camera_client_test,
run vts --skip-all-system-status-check --skip-preconditions
--primary-abi-only --module VtsHalCameraProviderV2_4Target -l INFO
Bug: 64691172
Change-Id: Ia38d1e7681a9385be7578c11e40f4e35e9101d75
parent 82e36b3f
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -333,11 +333,10 @@ void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(
    mResultMetadataQueue = q;
}

void CameraDeviceSession::ResultBatcher::registerBatch(
        const hidl_vec<CaptureRequest>& requests) {
void CameraDeviceSession::ResultBatcher::registerBatch(uint32_t frameNumber, uint32_t batchSize) {
    auto batch = std::make_shared<InflightBatch>();
    batch->mFirstFrame = requests[0].frameNumber;
    batch->mBatchSize = requests.size();
    batch->mFirstFrame = frameNumber;
    batch->mBatchSize = batchSize;
    batch->mLastFrame = batch->mFirstFrame + batch->mBatchSize - 1;
    batch->mNumPartialResults = mNumPartialResults;
    for (int id : mStreamsToBatch) {
@@ -1010,7 +1009,7 @@ Return<void> CameraDeviceSession::processCaptureRequest(
    }

    if (s == Status::OK && requests.size() > 1) {
        mResultBatcher.registerBatch(requests);
        mResultBatcher.registerBatch(requests[0].frameNumber, requests.size());
    }

    _hidl_cb(s, numRequestProcessed);
@@ -1111,6 +1110,7 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque
            halRequest.settings = settingsOverride.getAndLock();
        }
    }
    halRequest.num_physcam_settings = 0;

    ATRACE_ASYNC_BEGIN("frame capture", request.frameNumber);
    ATRACE_BEGIN("camera3->process_capture_request");
+1 −1
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ protected:
        void setBatchedStreams(const std::vector<int>& streamsToBatch);
        void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q);

        void registerBatch(const hidl_vec<CaptureRequest>& requests);
        void registerBatch(uint32_t frameNumber, uint32_t batchSize);
        void notify(NotifyMsg& msg);
        void processCaptureResult(CaptureResult& result);

+34 −1
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.hardware.camera.common@1.0::Status;
import @3.3::ICameraDeviceSession;
import @3.3::HalStreamConfiguration;
import @3.2::BufferCache;
import @3.2::CaptureRequest;

/**
 * Camera device active session interface.
@@ -72,4 +71,38 @@ interface ICameraDeviceSession extends @3.3::ICameraDeviceSession {
    configureStreams_3_4(@3.4::StreamConfiguration requestedConfiguration)
            generates (Status status,
                       @3.4::HalStreamConfiguration halConfiguration);

    /**
     * processCaptureRequest_3_4:
     *
     * Identical to @3.2::ICameraDeviceSession.processCaptureRequest, except that:
     *
     * - The capture request can include individual settings for physical camera devices
     *   backing a logical multi-camera.
     *
     * @return status Status code for the operation, one of:
     *     OK:
     *         On a successful start to processing the capture request
     *     ILLEGAL_ARGUMENT:
     *         If the input is malformed (the settings are empty when not
     *         allowed, the physical camera settings are invalid, there are 0
     *         output buffers, etc) and capture processing
     *         cannot start. Failures during request processing must be
     *         handled by calling ICameraDeviceCallback::notify(). In case of
     *         this error, the framework retains responsibility for the
     *         stream buffers' fences and the buffer handles; the HAL must not
     *         close the fences or return these buffers with
     *         ICameraDeviceCallback::processCaptureResult().
     *     INTERNAL_ERROR:
     *         If the camera device has encountered a serious error. After this
     *         error is returned, only the close() method can be successfully
     *         called by the framework.
     * @return numRequestProcessed Number of requests successfully processed by
     *     camera HAL. When status is OK, this must be equal to the size of
     *     requests. When the call fails, this number is the number of requests
     *     that HAL processed successfully before HAL runs into an error.
     *
     */
    processCaptureRequest_3_4(vec<CaptureRequest> requests, vec<BufferCache> cachesToRemove)
            generates (Status status, uint32_t numRequestProcessed);
};
+72 −25
Original line number Diff line number Diff line
@@ -201,9 +201,9 @@ void CameraDeviceSession::postProcessConfigurationLocked_3_4(
}

Return<void> CameraDeviceSession::processCaptureRequest_3_4(
        const hidl_vec<CaptureRequest>& requests,
        const hidl_vec<V3_4::CaptureRequest>& requests,
        const hidl_vec<V3_2::BufferCache>& cachesToRemove,
        ICameraDeviceSession::processCaptureRequest_cb _hidl_cb)  {
        ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb)  {
    updateBufferCaches(cachesToRemove);

    uint32_t numRequestProcessed = 0;
@@ -216,14 +216,14 @@ Return<void> CameraDeviceSession::processCaptureRequest_3_4(
    }

    if (s == Status::OK && requests.size() > 1) {
        mResultBatcher.registerBatch(requests);
        mResultBatcher.registerBatch(requests[0].v3_2.frameNumber, requests.size());
    }

    _hidl_cb(s, numRequestProcessed);
    return Void();
}

Status CameraDeviceSession::processOneCaptureRequest_3_4(const CaptureRequest& request)  {
Status CameraDeviceSession::processOneCaptureRequest_3_4(const V3_4::CaptureRequest& request)  {
    Status status = initStatus();
    if (status != Status::OK) {
        ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
@@ -231,15 +231,15 @@ Status CameraDeviceSession::processOneCaptureRequest_3_4(const CaptureRequest& r
    }

    camera3_capture_request_t halRequest;
    halRequest.frame_number = request.frameNumber;
    halRequest.frame_number = request.v3_2.frameNumber;

    bool converted = true;
    V3_2::CameraMetadata settingsFmq;  // settings from FMQ
    if (request.fmqSettingsSize > 0) {
    if (request.v3_2.fmqSettingsSize > 0) {
        // non-blocking read; client must write metadata before calling
        // processOneCaptureRequest
        settingsFmq.resize(request.fmqSettingsSize);
        bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.fmqSettingsSize);
        settingsFmq.resize(request.v3_2.fmqSettingsSize);
        bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.v3_2.fmqSettingsSize);
        if (read) {
            converted = V3_2::implementation::convertFromHidl(settingsFmq, &halRequest.settings);
        } else {
@@ -247,7 +247,8 @@ Status CameraDeviceSession::processOneCaptureRequest_3_4(const CaptureRequest& r
            converted = false;
        }
    } else {
        converted = V3_2::implementation::convertFromHidl(request.settings, &halRequest.settings);
        converted = V3_2::implementation::convertFromHidl(request.v3_2.settings,
                &halRequest.settings);
    }

    if (!converted) {
@@ -263,9 +264,9 @@ Status CameraDeviceSession::processOneCaptureRequest_3_4(const CaptureRequest& r

    hidl_vec<buffer_handle_t*> allBufPtrs;
    hidl_vec<int> allFences;
    bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
            request.inputBuffer.bufferId != 0);
    size_t numOutputBufs = request.outputBuffers.size();
    bool hasInputBuf = (request.v3_2.inputBuffer.streamId != -1 &&
            request.v3_2.inputBuffer.bufferId != 0);
    size_t numOutputBufs = request.v3_2.outputBuffers.size();
    size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);

    if (numOutputBufs == 0) {
@@ -273,7 +274,7 @@ Status CameraDeviceSession::processOneCaptureRequest_3_4(const CaptureRequest& r
        return Status::ILLEGAL_ARGUMENT;
    }

    status = importRequest(request, allBufPtrs, allFences);
    status = importRequest(request.v3_2, allBufPtrs, allFences);
    if (status != Status::OK) {
        return status;
    }
@@ -285,12 +286,12 @@ Status CameraDeviceSession::processOneCaptureRequest_3_4(const CaptureRequest& r
    {
        Mutex::Autolock _l(mInflightLock);
        if (hasInputBuf) {
            auto streamId = request.inputBuffer.streamId;
            auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
            auto streamId = request.v3_2.inputBuffer.streamId;
            auto key = std::make_pair(request.v3_2.inputBuffer.streamId, request.v3_2.frameNumber);
            auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
            convertFromHidl(
                    allBufPtrs[numOutputBufs], request.inputBuffer.status,
                    &mStreamMap[request.inputBuffer.streamId], allFences[numOutputBufs],
                    allBufPtrs[numOutputBufs], request.v3_2.inputBuffer.status,
                    &mStreamMap[request.v3_2.inputBuffer.streamId], allFences[numOutputBufs],
                    &bufCache);
            bufCache.stream->physical_camera_id = mPhysicalCameraIdMap[streamId].c_str();
            halRequest.input_buffer = &bufCache;
@@ -300,11 +301,11 @@ Status CameraDeviceSession::processOneCaptureRequest_3_4(const CaptureRequest& r

        halRequest.num_output_buffers = numOutputBufs;
        for (size_t i = 0; i < numOutputBufs; i++) {
            auto streamId = request.outputBuffers[i].streamId;
            auto key = std::make_pair(streamId, request.frameNumber);
            auto streamId = request.v3_2.outputBuffers[i].streamId;
            auto key = std::make_pair(streamId, request.v3_2.frameNumber);
            auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
            convertFromHidl(
                    allBufPtrs[i], request.outputBuffers[i].status,
                    allBufPtrs[i], request.v3_2.outputBuffers[i].status,
                    &mStreamMap[streamId], allFences[i],
                    &bufCache);
            bufCache.stream->physical_camera_id = mPhysicalCameraIdMap[streamId].c_str();
@@ -322,7 +323,47 @@ Status CameraDeviceSession::processOneCaptureRequest_3_4(const CaptureRequest& r
        }
    }

    ATRACE_ASYNC_BEGIN("frame capture", request.frameNumber);
    std::vector<const char *> physicalCameraIds;
    std::vector<const camera_metadata_t *> physicalCameraSettings;
    std::vector<V3_2::CameraMetadata> physicalFmq;
    size_t settingsCount = request.physicalCameraSettings.size();
    if (settingsCount > 0) {
        physicalCameraIds.reserve(settingsCount);
        physicalCameraSettings.reserve(settingsCount);
        physicalFmq.reserve(settingsCount);

        for (size_t i = 0; i < settingsCount; i++) {
            uint64_t settingsSize = request.physicalCameraSettings[i].fmqSettingsSize;
            const camera_metadata_t *settings;
            if (settingsSize > 0) {
                physicalFmq.push_back(V3_2::CameraMetadata(settingsSize));
                bool read = mRequestMetadataQueue->read(physicalFmq[i].data(), settingsSize);
                if (read) {
                    converted = V3_2::implementation::convertFromHidl(physicalFmq[i], &settings);
                    physicalCameraSettings.push_back(settings);
                } else {
                    ALOGE("%s: physical camera settings metadata couldn't be read from fmq!",
                            __FUNCTION__);
                    converted = false;
                }
            } else {
                converted = V3_2::implementation::convertFromHidl(
                        request.physicalCameraSettings[i].settings, &settings);
                physicalCameraSettings.push_back(settings);
            }

            if (!converted) {
                ALOGE("%s: physical camera settings metadata is corrupt!", __FUNCTION__);
                return Status::ILLEGAL_ARGUMENT;
            }
            physicalCameraIds.push_back(request.physicalCameraSettings[i].physicalCameraId.c_str());
        }
    }
    halRequest.num_physcam_settings = settingsCount;
    halRequest.physcam_id = physicalCameraIds.data();
    halRequest.physcam_settings = physicalCameraSettings.data();

    ATRACE_ASYNC_BEGIN("frame capture", request.v3_2.frameNumber);
    ATRACE_BEGIN("camera3->process_capture_request");
    status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
    ATRACE_END();
@@ -335,18 +376,24 @@ Status CameraDeviceSession::processOneCaptureRequest_3_4(const CaptureRequest& r

        cleanupInflightFences(allFences, numBufs);
        if (hasInputBuf) {
            auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
            auto key = std::make_pair(request.v3_2.inputBuffer.streamId, request.v3_2.frameNumber);
            mInflightBuffers.erase(key);
        }
        for (size_t i = 0; i < numOutputBufs; i++) {
            auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
            auto key = std::make_pair(request.v3_2.outputBuffers[i].streamId,
                    request.v3_2.frameNumber);
            mInflightBuffers.erase(key);
        }
        if (aeCancelTriggerNeeded) {
            mInflightAETriggerOverrides.erase(request.frameNumber);
            mInflightAETriggerOverrides.erase(request.v3_2.frameNumber);
        }

        if (ret == BAD_VALUE) {
            return Status::ILLEGAL_ARGUMENT;
        } else {
            return Status::INTERNAL_ERROR;
        }
    }

    mFirstRequest = false;
    return Status::OK;
+10 −4
Original line number Diff line number Diff line
@@ -85,10 +85,10 @@ protected:
    void postProcessConfigurationLocked_3_4(const StreamConfiguration& requestedConfiguration);

    Return<void> processCaptureRequest_3_4(
            const hidl_vec<CaptureRequest>& requests,
            const hidl_vec<V3_4::CaptureRequest>& requests,
            const hidl_vec<V3_2::BufferCache>& cachesToRemove,
            ICameraDeviceSession::processCaptureRequest_cb _hidl_cb);
    Status processOneCaptureRequest_3_4(const CaptureRequest& request);
            ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb);
    Status processOneCaptureRequest_3_4(const V3_4::CaptureRequest& request);

    std::map<int, std::string> mPhysicalCameraIdMap;
private:
@@ -109,10 +109,16 @@ private:
            return mParent->configureStreams(requestedConfiguration, _hidl_cb);
        }

        virtual Return<void> processCaptureRequest_3_4(const hidl_vec<V3_4::CaptureRequest>& requests,
                const hidl_vec<V3_2::BufferCache>& cachesToRemove,
                ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb) override {
            return mParent->processCaptureRequest_3_4(requests, cachesToRemove, _hidl_cb);
        }

        virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests,
                const hidl_vec<V3_2::BufferCache>& cachesToRemove,
                V3_3::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override {
            return mParent->processCaptureRequest_3_4(requests, cachesToRemove, _hidl_cb);
            return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb);
        }

        virtual Return<void> getCaptureRequestMetadataQueue(
Loading