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

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

DO NOT MERGE Camera: Enable session parameter handling for Rotate&Crop

Service managed settings like Rotate&Crop 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.
Specifically for Rotate&Crop 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
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 2490b2d2
Loading
Loading
Loading
Loading
+59 −23
Original line number Diff line number Diff line
@@ -97,6 +97,8 @@ Camera3Device::Camera3Device(const String8 &id, bool overrideForPerfClass, bool
        mNeedFixupMonochromeTags(false),
        mOverrideForPerfClass(overrideForPerfClass),
        mOverrideToPortrait(overrideToPortrait),
        mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
        mComposerOutput(false),
        mActivePhysicalId("")
{
    ATRACE_CALL();
@@ -1353,12 +1355,34 @@ status_t Camera3Device::filterParamsAndConfigureLocked(const CameraMetadata& ses
    set_camera_metadata_vendor_id(meta, mVendorTagId);
    filteredParams.unlock(meta);
    if (availableSessionKeys.count > 0) {
        bool rotateAndCropSessionKey = 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 (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);
            filteredParams = request->mSettingsList.begin()->metadata;
        }
    }

@@ -2370,7 +2394,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
@@ -2413,7 +2437,7 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
        }

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

@@ -2482,7 +2506,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
@@ -3439,6 +3463,16 @@ 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);
    }

    // '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
@@ -3584,18 +3618,13 @@ 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 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 || testPatternChanged) &&
                        captureRequest->mRotateAndCropChanged || testPatternChanged) &&
                // Request settings are all the same within one batch, so only treat the first
                // request in a batch as new
                !(batchedRequest && i > 0);
@@ -4058,9 +4087,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;
}
@@ -4637,13 +4663,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);
@@ -4651,24 +4684,23 @@ 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;
}

@@ -5154,6 +5186,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);
}

+11 −1
Original line number Diff line number Diff line
@@ -581,6 +581,9 @@ 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 capture request has its zoom ratio set to 1.0x before
        // the framework overrides it for camera HAL consumption.
@@ -767,6 +770,11 @@ 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);

    struct RequestTrigger {
        // Metadata tag number, e.g. android.control.aePrecaptureTrigger
        uint32_t metadataTag;
@@ -917,7 +925,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 test_pattern control if needed for camera mute; returns true
        // if the current value was changed
@@ -1356,6 +1364,8 @@ 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;

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