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

Commit b5bca3ff authored by Igor Murashkin's avatar Igor Murashkin Committed by Android (Google) Code Review
Browse files

Merge "camera2: Tell all streams to ignore global device UI rotation" into klp-dev

parents feb6d27b f8b2a6f7
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
@@ -360,6 +360,26 @@ status_t CameraDeviceClient::createStream(int width, int height, int format,

        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
              __FUNCTION__, mCameraId, streamId);

        /**
         * Set the stream transform flags to automatically
         * rotate the camera stream for preview use cases.
         */
        int32_t transform = 0;
        res = getRotationTransformLocked(&transform);

        if (res != OK) {
            // Error logged by getRotationTransformLocked.
            return res;
        }

        res = mDevice->setStreamTransform(streamId, transform);
        if (res != OK) {
            ALOGE("%s: Failed to set stream transform (stream id %d)",
                  __FUNCTION__, streamId);
            return res;
        }

        return streamId;
    }

@@ -560,4 +580,64 @@ bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
    return true;
}

status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
    ALOGV("%s: begin", __FUNCTION__);

    if (transform == NULL) {
        ALOGW("%s: null transform", __FUNCTION__);
        return BAD_VALUE;
    }

    *transform = 0;

    const CameraMetadata& staticInfo = mDevice->info();
    camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
    if (entry.count == 0) {
        ALOGE("%s: Camera %d: Can't find android.sensor.orientation in "
                "static metadata!", __FUNCTION__, mCameraId);
        return INVALID_OPERATION;
    }

    int32_t& flags = *transform;

    int orientation = entry.data.i32[0];
    switch (orientation) {
        case 0:
            flags = 0;
            break;
        case 90:
            flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
            break;
        case 180:
            flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
            break;
        case 270:
            flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
            break;
        default:
            ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
                  __FUNCTION__, orientation);
            return INVALID_OPERATION;
    }

    /**
     * This magic flag makes surfaceflinger un-rotate the buffers
     * to counter the extra global device UI rotation whenever the user
     * physically rotates the device.
     *
     * By doing this, the camera buffer always ends up aligned
     * with the physical camera for a "see through" effect.
     *
     * In essence, the buffer only gets rotated during preview use-cases.
     * The user is still responsible to re-create streams of the proper
     * aspect ratio, or the preview will end up looking non-uniformly
     * stretched.
     */
    flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;

    ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);

    return OK;
}

} // namespace android
+3 −0
Original line number Diff line number Diff line
@@ -120,6 +120,9 @@ protected:
                                           const CameraMetadata& frame);
    virtual void          detachDevice();

    // Calculate the ANativeWindow transform from android.sensor.orientation
    status_t              getRotationTransformLocked(/*out*/int32_t* transform);

private:
    /** ICameraDeviceUser interface-related private members */