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

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

Camera: Enable session parameter handling for Rotate&Crop and

Autoframing

Service managed settings like Rotate&Crop and Autoframing are
overridden just before they are sent to camera provider. The
session update logic runs prior to that so it cannot detect any
modifications for keys advertised as session parameters by CameraHal.
Refactor the parameter override logic so it can be triggered
before the request thread starts processing the requests.
Additionally consolidate the specific override logic so it
can be re-used by the parameter session filter during
stream configuration.
Incoming AUTO session values will be overridden accordingly.
In case 'mOverrideToPortrait' is enabled, the Rotate&Crop
session parameter value will always include the configured
override.

Bug: 272528553
Bug: 274929202
Test: Camera CTS,
Manual using Camera2Basic on CF with R&C set
to AUTO. The overridden filtered R&C session value is
NONE.

Change-Id: I685f32e15510d69b15dc2f4749068645a4d172a0
parent 49ae1e4a
Loading
Loading
Loading
Loading
+111 −44
Original line number Diff line number Diff line
@@ -98,6 +98,9 @@ Camera3Device::Camera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraS
        mNeedFixupMonochromeTags(false),
        mOverrideForPerfClass(overrideForPerfClass),
        mOverrideToPortrait(overrideToPortrait),
        mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
        mComposerOutput(false),
        mAutoframingOverride(ANDROID_CONTROL_AUTOFRAMING_OFF),
        mActivePhysicalId("")
{
    ATRACE_CALL();
@@ -1363,12 +1366,54 @@ status_t Camera3Device::filterParamsAndConfigureLocked(const CameraMetadata& ses
    set_camera_metadata_vendor_id(meta, mVendorTagId);
    filteredParams.unlock(meta);
    if (availableSessionKeys.count > 0) {
        bool rotateAndCropSessionKey = false;
        bool autoframingSessionKey = false;
        for (size_t i = 0; i < availableSessionKeys.count; i++) {
            camera_metadata_ro_entry entry = params.find(
                    availableSessionKeys.data.i32[i]);
            if (entry.count > 0) {
                filteredParams.update(entry);
            }
            if (ANDROID_SCALER_ROTATE_AND_CROP == availableSessionKeys.data.i32[i]) {
                rotateAndCropSessionKey = true;
            }
            if (ANDROID_CONTROL_AUTOFRAMING == availableSessionKeys.data.i32[i]) {
                autoframingSessionKey = true;
            }
        }

        if (rotateAndCropSessionKey || autoframingSessionKey) {
            sp<CaptureRequest> request = new CaptureRequest();
            PhysicalCameraSettings settingsList;
            settingsList.metadata = filteredParams;
            request->mSettingsList.push_back(settingsList);

            if (rotateAndCropSessionKey) {
                sp<CaptureRequest> request = new CaptureRequest();
                PhysicalCameraSettings settingsList;
                settingsList.metadata = filteredParams;
                request->mSettingsList.push_back(settingsList);

                auto rotateAndCropEntry = filteredParams.find(ANDROID_SCALER_ROTATE_AND_CROP);
                if (rotateAndCropEntry.count > 0 &&
                        rotateAndCropEntry.data.u8[0] == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
                    request->mRotateAndCropAuto = true;
                } else {
                    request->mRotateAndCropAuto = false;
                }

                overrideAutoRotateAndCrop(request, mOverrideToPortrait, mRotateAndCropOverride);
            }

            if (autoframingSessionKey) {
                auto autoframingEntry = filteredParams.find(ANDROID_CONTROL_AUTOFRAMING);
                if (autoframingEntry.count > 0 &&
                        autoframingEntry.data.u8[0] == ANDROID_CONTROL_AUTOFRAMING_AUTO) {
                    overrideAutoframing(request, mAutoframingOverride);
                }
            }

            filteredParams = request->mSettingsList.begin()->metadata;
        }
    }

@@ -2397,7 +2442,7 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
    }

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

        // Don't configure bidi streams twice, nor add them twice to the list
@@ -2440,7 +2485,7 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
        }

        if (outputStream->usage & GraphicBuffer::USAGE_HW_COMPOSER) {
            composerSurfacePresent = true;
            mComposerOutput = true;
        }
    }

@@ -2510,7 +2555,7 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
        }
    }

    mRequestThread->setComposerSurface(composerSurfacePresent);
    mRequestThread->setComposerSurface(mComposerOutput);

    // Request thread needs to know to avoid using repeat-last-settings protocol
    // across configure_streams() calls
@@ -3465,6 +3510,17 @@ bool Camera3Device::RequestThread::threadLoop() {
        latestRequestId = NAME_NOT_FOUND;
    }

    for (size_t i = 0; i < mNextRequests.size(); i++) {
        auto& nextRequest = mNextRequests.editItemAt(i);
        sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
        // Do not override rotate&crop for stream configurations that include
        // SurfaceViews(HW_COMPOSER) output, unless mOverrideToPortrait is set.
        // The display rotation there will be compensated by NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY
        captureRequest->mRotateAndCropChanged = (mComposerOutput && !mOverrideToPortrait) ? false :
            overrideAutoRotateAndCrop(captureRequest);
        captureRequest->mAutoframingChanged = overrideAutoframing(captureRequest);
    }

    // 'mNextRequests' will at this point contain either a set of HFR batched requests
    //  or a single request from streaming or burst. In either case the first element
    //  should contain the latest camera settings that we need to check for any session
@@ -3614,19 +3670,15 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
        bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
        mPrevTriggers = triggerCount;

        // Do not override rotate&crop for stream configurations that include
        // SurfaceViews(HW_COMPOSER) output, unless mOverrideToPortrait is set.
        // The display rotation there will be compensated by NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY
        bool rotateAndCropChanged = (mComposerOutput && !mOverrideToPortrait) ? false :
            overrideAutoRotateAndCrop(captureRequest);
        bool autoframingChanged = overrideAutoframing(captureRequest);
        bool testPatternChanged = overrideTestPattern(captureRequest);

        // If the request is the same as last, or we had triggers now or last time or
        // changing overrides this time
        bool newRequest =
                (mPrevRequest != captureRequest || triggersMixedIn || rotateAndCropChanged ||
                         autoframingChanged || testPatternChanged) &&
                (mPrevRequest != captureRequest || triggersMixedIn ||
                         captureRequest->mRotateAndCropChanged ||
                         captureRequest->mAutoframingChanged ||
                         testPatternChanged) &&
                // Request settings are all the same within one batch, so only treat the first
                // request in a batch as new
                !(batchedRequest && i > 0);
@@ -4101,9 +4153,6 @@ status_t Camera3Device::RequestThread::setRotateAndCropAutoBehavior(
        camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) {
    ATRACE_CALL();
    Mutex::Autolock l(mTriggerMutex);
    if (rotateAndCropValue == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
        return BAD_VALUE;
    }
    mRotateAndCropOverride = rotateAndCropValue;
    return OK;
}
@@ -4112,9 +4161,6 @@ status_t Camera3Device::RequestThread::setAutoframingAutoBehaviour(
        camera_metadata_enum_android_control_autoframing_t autoframingValue) {
    ATRACE_CALL();
    Mutex::Autolock l(mTriggerMutex);
    if (autoframingValue == ANDROID_CONTROL_AUTOFRAMING_AUTO) {
        return BAD_VALUE;
    }
    mAutoframingOverride = autoframingValue;
    return OK;
}
@@ -4702,13 +4748,20 @@ status_t Camera3Device::RequestThread::addFakeTriggerIds(
    return OK;
}

bool Camera3Device::RequestThread::overrideAutoRotateAndCrop(
        const sp<CaptureRequest> &request) {
bool Camera3Device::RequestThread::overrideAutoRotateAndCrop(const sp<CaptureRequest> &request) {
    ATRACE_CALL();

    if (mOverrideToPortrait) {
    Mutex::Autolock l(mTriggerMutex);
        uint8_t rotateAndCrop_u8 = mRotateAndCropOverride;
    return Camera3Device::overrideAutoRotateAndCrop(request, this->mOverrideToPortrait,
            this->mRotateAndCropOverride);
}

bool Camera3Device::overrideAutoRotateAndCrop(const sp<CaptureRequest> &request,
        bool overrideToPortrait,
        camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropOverride) {
    ATRACE_CALL();

    if (overrideToPortrait) {
        uint8_t rotateAndCrop_u8 = rotateAndCropOverride;
        CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
        metadata.update(ANDROID_SCALER_ROTATE_AND_CROP,
                &rotateAndCrop_u8, 1);
@@ -4716,49 +4769,55 @@ bool Camera3Device::RequestThread::overrideAutoRotateAndCrop(
    }

    if (request->mRotateAndCropAuto) {
        Mutex::Autolock l(mTriggerMutex);
        CameraMetadata &metadata = request->mSettingsList.begin()->metadata;

        auto rotateAndCropEntry = metadata.find(ANDROID_SCALER_ROTATE_AND_CROP);
        if (rotateAndCropEntry.count > 0) {
            if (rotateAndCropEntry.data.u8[0] == mRotateAndCropOverride) {
            if (rotateAndCropEntry.data.u8[0] == rotateAndCropOverride) {
                return false;
            } else {
                rotateAndCropEntry.data.u8[0] = mRotateAndCropOverride;
                rotateAndCropEntry.data.u8[0] = rotateAndCropOverride;
                return true;
            }
        } else {
            uint8_t rotateAndCrop_u8 = mRotateAndCropOverride;
            metadata.update(ANDROID_SCALER_ROTATE_AND_CROP,
                    &rotateAndCrop_u8, 1);
            uint8_t rotateAndCrop_u8 = rotateAndCropOverride;
            metadata.update(ANDROID_SCALER_ROTATE_AND_CROP, &rotateAndCrop_u8, 1);
            return true;
        }
    }

    return false;
}

bool Camera3Device::RequestThread::overrideAutoframing(const sp<CaptureRequest> &request) {
    ATRACE_CALL();

    if (request->mAutoframingAuto) {
        Mutex::Autolock l(mTriggerMutex);
bool Camera3Device::overrideAutoframing(const sp<CaptureRequest> &request /*out*/,
        camera_metadata_enum_android_control_autoframing_t autoframingOverride) {
    CameraMetadata &metadata = request->mSettingsList.begin()->metadata;

    auto autoframingEntry = metadata.find(ANDROID_CONTROL_AUTOFRAMING);
    if (autoframingEntry.count > 0) {
            if (autoframingEntry.data.u8[0] == mAutoframingOverride) {
        if (autoframingEntry.data.u8[0] == autoframingOverride) {
            return false;
        } else {
                autoframingEntry.data.u8[0] = mAutoframingOverride;
            autoframingEntry.data.u8[0] = autoframingOverride;
            return true;
        }
    } else {
            uint8_t autoframing_u8 = mAutoframingOverride;
        uint8_t autoframing_u8 = autoframingOverride;
        metadata.update(ANDROID_CONTROL_AUTOFRAMING,
                &autoframing_u8, 1);
        return true;
    }

    return false;
}

bool Camera3Device::RequestThread::overrideAutoframing(const sp<CaptureRequest> &request) {
    ATRACE_CALL();

    if (request->mAutoframingAuto) {
        Mutex::Autolock l(mTriggerMutex);
        return Camera3Device::overrideAutoframing(request, mAutoframingOverride);
    }

    return false;
}

@@ -5246,6 +5305,10 @@ status_t Camera3Device::setRotateAndCropAutoBehavior(
    if (mRequestThread == nullptr) {
        return INVALID_OPERATION;
    }
    if (rotateAndCropValue == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
        return BAD_VALUE;
    }
    mRotateAndCropOverride = rotateAndCropValue;
    return mRequestThread->setRotateAndCropAutoBehavior(rotateAndCropValue);
}

@@ -5257,6 +5320,10 @@ status_t Camera3Device::setAutoframingAutoBehavior(
    if (mRequestThread == nullptr) {
        return INVALID_OPERATION;
    }
    if (autoframingValue == ANDROID_CONTROL_AUTOFRAMING_AUTO) {
        return BAD_VALUE;
    }
    mAutoframingOverride = autoframingValue;
    return mRequestThread->setAutoframingAutoBehaviour(autoframingValue);
}

+20 −1
Original line number Diff line number Diff line
@@ -625,9 +625,14 @@ class Camera3Device :
        // overriding of ROTATE_AND_CROP value and adjustment of coordinates
        // in several other controls in both the request and the result
        bool                                mRotateAndCropAuto;
        // Indicates that the ROTATE_AND_CROP value within 'mSettingsList' was modified
        // irrespective of the original value.
        bool                                mRotateAndCropChanged = false;
        // Whether this request has AUTOFRAMING_AUTO set, so need to override the AUTOFRAMING value
        // in the capture request.
        bool                                mAutoframingAuto;
        // Indicates that the auto framing value within 'mSettingsList' was modified
        bool                                mAutoframingChanged = false;

        // Whether this capture request has its zoom ratio set to 1.0x before
        // the framework overrides it for camera HAL consumption.
@@ -816,6 +821,15 @@ class Camera3Device :
     */
    static nsecs_t getMonoToBoottimeOffset();

    // Override rotate_and_crop control if needed
    static bool    overrideAutoRotateAndCrop(const sp<CaptureRequest> &request /*out*/,
            bool overrideToPortrait,
            camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropOverride);

    // Override auto framing control if needed
    static bool    overrideAutoframing(const sp<CaptureRequest> &request /*out*/,
            camera_metadata_enum_android_control_autoframing_t autoframingOverride);

    struct RequestTrigger {
        // Metadata tag number, e.g. android.control.aePrecaptureTrigger
        uint32_t metadataTag;
@@ -973,7 +987,7 @@ class Camera3Device :
        status_t           addFakeTriggerIds(const sp<CaptureRequest> &request);

        // Override rotate_and_crop control if needed; returns true if the current value was changed
        bool               overrideAutoRotateAndCrop(const sp<CaptureRequest> &request);
        bool               overrideAutoRotateAndCrop(const sp<CaptureRequest> &request /*out*/);

        // Override autoframing control if needed; returns true if the current value was changed
        bool               overrideAutoframing(const sp<CaptureRequest> &request);
@@ -1417,6 +1431,11 @@ class Camera3Device :
    // Whether the camera framework overrides the device characteristics for
    // app compatibility reasons.
    bool mOverrideToPortrait;
    camera_metadata_enum_android_scaler_rotate_and_crop_t mRotateAndCropOverride;
    bool mComposerOutput;

    // Auto framing override value
    camera_metadata_enum_android_control_autoframing mAutoframingOverride;

    // Current active physical id of the logical multi-camera, if any
    std::string mActivePhysicalId;