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

Commit 99080505 authored by Shuzhen Wang's avatar Shuzhen Wang
Browse files

Camera: Handle physical camera metadata tracking for multi-res output

The Inflight metadata tracking needs to be modified to handle
multi-resolution output stream. Because the HAL gets to decide which
physical camera outputs the image, the physical result metadata may
originate from a different physical camera.

The status tracker is fine because the tracking starts when buffer is
dequeued from the stream.

Bug: 156254356
Test: Camera CTS
Change-Id: I9487ae4df1b4f37ab41771ce90ad8b71239eb105
parent 9b46ad1f
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -2611,6 +2611,7 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
        config.input_is_multi_resolution = mIsInputStreamMultiResolution;
    }

    mGroupIdPhysicalCameraMap.clear();
    for (size_t i = 0; i < mOutputStreams.size(); i++) {

        // Don't configure bidi streams twice, nor add them twice to the list
@@ -2644,6 +2645,12 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
                        __FUNCTION__, outputStream->data_space);
            }
        }

        if (mOutputStreams[i]->isMultiResolution()) {
            int32_t streamGroupId = mOutputStreams[i]->getHalStreamGroupId();
            const String8& physicalCameraId = mOutputStreams[i]->getPhysicalCameraId();
            mGroupIdPhysicalCameraMap[streamGroupId].insert(physicalCameraId);
        }
    }

    config.streams = streams.editArray();
@@ -2714,7 +2721,8 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
    // Request thread needs to know to avoid using repeat-last-settings protocol
    // across configure_streams() calls
    if (notifyRequestThread) {
        mRequestThread->configurationComplete(mIsConstrainedHighSpeedConfiguration, sessionParams);
        mRequestThread->configurationComplete(mIsConstrainedHighSpeedConfiguration,
                sessionParams, mGroupIdPhysicalCameraMap);
    }

    char value[PROPERTY_VALUE_MAX];
@@ -2887,8 +2895,9 @@ void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
status_t Camera3Device::registerInFlight(uint32_t frameNumber,
        int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
        bool hasAppCallback, nsecs_t maxExpectedDuration,
        std::set<String8>& physicalCameraIds, bool isStillCapture,
        bool isZslCapture, bool rotateAndCropAuto, const std::set<std::string>& cameraIdsWithZoom,
        const std::set<std::set<String8>>& physicalCameraIds,
        bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto,
        const std::set<std::string>& cameraIdsWithZoom,
        const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs) {
    ATRACE_CALL();
    std::lock_guard<std::mutex> l(mInFlightLock);
@@ -3962,11 +3971,13 @@ void Camera3Device::RequestThread::setNotificationListener(
}

void Camera3Device::RequestThread::configurationComplete(bool isConstrainedHighSpeed,
        const CameraMetadata& sessionParams) {
        const CameraMetadata& sessionParams,
        const std::map<int32_t, std::set<String8>>& groupIdPhysicalCameraMap) {
    ATRACE_CALL();
    Mutex::Autolock l(mRequestLock);
    mReconfigured = true;
    mLatestSessionParams = sessionParams;
    mGroupIdPhysicalCameraMap = groupIdPhysicalCameraMap;
    // Prepare video stream for high speed recording.
    mPrepareVideoStream = isConstrainedHighSpeed;
    mConstrainedMode = isConstrainedHighSpeed;
@@ -4725,7 +4736,7 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
        outputBuffers->insertAt(camera_stream_buffer_t(), 0,
                captureRequest->mOutputStreams.size());
        halRequest->output_buffers = outputBuffers->array();
        std::set<String8> requestedPhysicalCameras;
        std::set<std::set<String8>> requestedPhysicalCameras;

        sp<Camera3Device> parent = mParent.promote();
        if (parent == NULL) {
@@ -4820,8 +4831,11 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
            }

            String8 physicalCameraId = outputStream->getPhysicalCameraId();
            if (!physicalCameraId.isEmpty()) {
                requestedPhysicalCameras.insert(physicalCameraId);
            int32_t streamGroupId = outputStream->getHalStreamGroupId();
            if (streamGroupId != -1 && mGroupIdPhysicalCameraMap.count(streamGroupId) == 1) {
                requestedPhysicalCameras.insert(mGroupIdPhysicalCameraMap[streamGroupId]);
            } else if (!physicalCameraId.isEmpty()) {
                requestedPhysicalCameras.insert(std::set<String8>({physicalCameraId}));
            }
            halRequest->num_output_buffers++;
        }
+8 −2
Original line number Diff line number Diff line
@@ -497,6 +497,8 @@ class Camera3Device :
    sp<camera3::Camera3Stream> mInputStream;
    bool                       mIsInputStreamMultiResolution;
    SessionStatsBuilder        mSessionStatsBuilder;
    // Map from stream group ID to physical cameras backing the stream group
    std::map<int32_t, std::set<String8>> mGroupIdPhysicalCameraMap;

    int                        mNextStreamId;
    bool                       mNeedConfig;
@@ -800,7 +802,8 @@ class Camera3Device :
         * Call after stream (re)-configuration is completed.
         */
        void     configurationComplete(bool isConstrainedHighSpeed,
                const CameraMetadata& sessionParams);
                const CameraMetadata& sessionParams,
                const std::map<int32_t, std::set<String8>>& groupIdPhysicalCameraMap);

        /**
         * Set or clear the list of repeating requests. Does not block
@@ -1057,6 +1060,8 @@ class Camera3Device :
        Vector<int32_t>    mSessionParamKeys;
        CameraMetadata     mLatestSessionParams;

        std::map<int32_t, std::set<String8>> mGroupIdPhysicalCameraMap;

        const bool         mUseHalBufManager;
    };
    sp<RequestThread> mRequestThread;
@@ -1076,7 +1081,8 @@ class Camera3Device :

    status_t registerInFlight(uint32_t frameNumber,
            int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
            bool callback, nsecs_t maxExpectedDuration, std::set<String8>& physicalCameraIds,
            bool callback, nsecs_t maxExpectedDuration,
            const std::set<std::set<String8>>& physicalCameraIds,
            bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto,
            const std::set<std::string>& cameraIdsWithZoom, const SurfaceMap& outputSurfaces,
            nsecs_t requestTimeNs);
+21 −9
Original line number Diff line number Diff line
@@ -484,6 +484,20 @@ void removeInFlightRequestIfReadyLocked(CaptureOutputStates& states, int idx) {
    states.inflightIntf.checkInflightMapLengthLocked();
}

// Erase the subset of physicalCameraIds that contains id
bool erasePhysicalCameraIdSet(
        std::set<std::set<String8>>& physicalCameraIds, const String8& id) {
    bool found = false;
    for (auto iter = physicalCameraIds.begin(); iter != physicalCameraIds.end(); iter++) {
        if (iter->count(id) == 1) {
            physicalCameraIds.erase(iter);
            found = true;
            break;
        }
    }
    return found;
}

void processCaptureResult(CaptureOutputStates& states, const camera_capture_result *result) {
    ATRACE_CALL();

@@ -583,12 +597,10 @@ void processCaptureResult(CaptureOutputStates& states, const camera_capture_resu
            }
            for (uint32_t i = 0; i < result->num_physcam_metadata; i++) {
                String8 physicalId(result->physcam_ids[i]);
                std::set<String8>::iterator cameraIdIter =
                        request.physicalCameraIds.find(physicalId);
                if (cameraIdIter != request.physicalCameraIds.end()) {
                    request.physicalCameraIds.erase(cameraIdIter);
                } else {
                    SET_ERR("Total result for frame %d has already returned for camera %s",
                bool validPhysicalCameraMetadata =
                        erasePhysicalCameraIdSet(request.physicalCameraIds, physicalId);
                if (!validPhysicalCameraMetadata) {
                    SET_ERR("Unexpected total result for frame %d camera %s",
                            frameNumber, physicalId.c_str());
                    return;
                }
@@ -1083,14 +1095,14 @@ void notifyError(CaptureOutputStates& states, const camera_error_msg_t &msg) {
                            errorCode) {
                        if (physicalCameraId.size() > 0) {
                            String8 cameraId(physicalCameraId);
                            auto iter = r.physicalCameraIds.find(cameraId);
                            if (iter == r.physicalCameraIds.end()) {
                            bool validPhysicalCameraId =
                                    erasePhysicalCameraIdSet(r.physicalCameraIds, cameraId);
                            if (!validPhysicalCameraId) {
                                ALOGE("%s: Reported result failure for physical camera device: %s "
                                        " which is not part of the respective request!",
                                        __FUNCTION__, cameraId.string());
                                break;
                            }
                            r.physicalCameraIds.erase(iter);
                            resultExtras.errorPhysicalCameraId = physicalCameraId;
                            physicalDeviceResultError = true;
                        }
+10 −0
Original line number Diff line number Diff line
@@ -134,6 +134,16 @@ class Camera3StreamInterface : public virtual RefBase {
     */
    virtual int      getStreamSetId() const = 0;

    /**
     * Is this stream part of a multi-resolution stream set
     */
    virtual bool     isMultiResolution() const = 0;

    /**
     * Get the HAL stream group id for a multi-resolution stream set
     */
    virtual int      getHalStreamGroupId() const = 0;

    /**
     * Get the stream's dimensions and format
     */
+5 −2
Original line number Diff line number Diff line
@@ -96,7 +96,10 @@ struct InFlightRequest {
    ERROR_BUF_STRATEGY errorBufStrategy;

    // The physical camera ids being requested.
    std::set<String8> physicalCameraIds;
    // For request on a physical camera stream, the inside set contains one Id
    // For request on a stream group containing physical camera streams, the
    // inside set contains all stream Ids in the group.
    std::set<std::set<String8>> physicalCameraIds;

    // Map of physicalCameraId <-> Metadata
    std::vector<PhysicalCaptureResultInfo> physicalMetadatas;
@@ -142,7 +145,7 @@ struct InFlightRequest {

    InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
            bool hasAppCallback, nsecs_t maxDuration,
            const std::set<String8>& physicalCameraIdSet, bool isStillCapture,
            const std::set<std::set<String8>>& physicalCameraIdSet, bool isStillCapture,
            bool isZslCapture, bool rotateAndCropAuto, const std::set<std::string>& idsWithZoom,
            nsecs_t requestNs, const SurfaceMap& outSurfaces = SurfaceMap{}) :
            shutterTimestamp(0),