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

Commit eed6f6b1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Camera: Plumb through stream mirroring mode"

parents 7223ba44 610d7b80
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0

#include <camera/CameraUtils.h>
#include <camera/camera2/OutputConfiguration.h>
#include <media/hardware/HardwareAPI.h>

#include <android-base/properties.h>
@@ -31,7 +32,7 @@ namespace android {
const char *kCameraServiceDisabledProperty = "config.disable_cameraservice";

status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
                /*out*/int32_t* transform) {
        int mirrorMode, /*out*/int32_t* transform) {
    ALOGV("%s", __FUNCTION__);

    if (transform == NULL) {
@@ -55,9 +56,18 @@ status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,

    int32_t& flags = *transform;

    bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT);
    int32_t mirror = 0;
    if (mirrorMode == OutputConfiguration::MIRROR_MODE_AUTO &&
            entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT) {
        mirror = NATIVE_WINDOW_TRANSFORM_FLIP_H;
    } else if (mirrorMode == OutputConfiguration::MIRROR_MODE_H) {
        mirror = NATIVE_WINDOW_TRANSFORM_FLIP_H;
    } else if (mirrorMode == OutputConfiguration::MIRROR_MODE_V) {
        mirror = NATIVE_WINDOW_TRANSFORM_FLIP_V;
    }

    int orientation = entry.data.i32[0];
    if (!mirror) {
    if (mirror == 0) {
        switch (orientation) {
            case 0:
                flags = 0;
@@ -77,25 +87,25 @@ status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
                return INVALID_OPERATION;
        }
    } else {
        // Front camera needs to be horizontally flipped for mirror-like behavior.
        // - Front camera needs to be horizontally flipped for mirror-like behavior.
        // - Application-specified mirroring needs to be applied.
        // Note: Flips are applied before rotates; using XOR here as some of these flags are
        // composed in terms of other flip/rotation flags, and are not bitwise-ORable.
        switch (orientation) {
            case 0:
                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H;
                flags = mirror;
                break;
            case 90:
                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
                flags = mirror ^
                        NATIVE_WINDOW_TRANSFORM_ROT_270;
                break;
            case 180:
                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
                flags = mirror ^
                        NATIVE_WINDOW_TRANSFORM_ROT_180;
                break;
            case 270:
                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
                flags = mirror ^
                        NATIVE_WINDOW_TRANSFORM_ROT_90;

                break;
            default:
                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
+23 −4
Original line number Diff line number Diff line
@@ -89,6 +89,10 @@ int OutputConfiguration::getTimestampBase() const {
    return mTimestampBase;
}

int OutputConfiguration::getMirrorMode() const {
    return mMirrorMode;
}

OutputConfiguration::OutputConfiguration() :
        mRotation(INVALID_ROTATION),
        mSurfaceSetID(INVALID_SET_ID),
@@ -100,7 +104,8 @@ OutputConfiguration::OutputConfiguration() :
        mIsMultiResolution(false),
        mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
        mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT),
        mTimestampBase(TIMESTAMP_BASE_DEFAULT) {
        mTimestampBase(TIMESTAMP_BASE_DEFAULT),
        mMirrorMode(MIRROR_MODE_AUTO) {
}

OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) :
@@ -199,6 +204,12 @@ status_t OutputConfiguration::readFromParcel(const android::Parcel* parcel) {
        return err;
    }

    int mirrorMode = MIRROR_MODE_AUTO;
    if ((err = parcel->readInt32(&mirrorMode)) != OK) {
        ALOGE("%s: Failed to read mirroring mode from parcel", __FUNCTION__);
        return err;
    }

    mRotation = rotation;
    mSurfaceSetID = setID;
    mSurfaceType = surfaceType;
@@ -209,6 +220,7 @@ status_t OutputConfiguration::readFromParcel(const android::Parcel* parcel) {
    mIsMultiResolution = isMultiResolution != 0;
    mStreamUseCase = streamUseCase;
    mTimestampBase = timestampBase;
    mMirrorMode = mirrorMode;
    for (auto& surface : surfaceShims) {
        ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
                surface.graphicBufferProducer.get(),
@@ -220,9 +232,11 @@ status_t OutputConfiguration::readFromParcel(const android::Parcel* parcel) {
    mDynamicRangeProfile = dynamicProfile;

    ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d,"
          " physicalCameraId = %s, isMultiResolution = %d, streamUseCase = %d, timestampBase = %d",
          " physicalCameraId = %s, isMultiResolution = %d, streamUseCase = %d, timestampBase = %d,"
          " mirrorMode = %d",
          __FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType,
          String8(mPhysicalCameraId).string(), mIsMultiResolution, mStreamUseCase, timestampBase);
          String8(mPhysicalCameraId).string(), mIsMultiResolution, mStreamUseCase, timestampBase,
          mMirrorMode);

    return err;
}
@@ -240,6 +254,7 @@ OutputConfiguration::OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int ro
    mDynamicRangeProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
    mStreamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
    mTimestampBase = TIMESTAMP_BASE_DEFAULT;
    mMirrorMode = MIRROR_MODE_AUTO;
}

OutputConfiguration::OutputConfiguration(
@@ -251,7 +266,8 @@ OutputConfiguration::OutputConfiguration(
    mPhysicalCameraId(physicalCameraId), mIsMultiResolution(false),
    mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
    mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT),
    mTimestampBase(TIMESTAMP_BASE_DEFAULT) { }
    mTimestampBase(TIMESTAMP_BASE_DEFAULT),
    mMirrorMode(MIRROR_MODE_AUTO) { }

status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {

@@ -307,6 +323,9 @@ status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
    err = parcel->writeInt32(mTimestampBase);
    if (err != OK) return err;

    err = parcel->writeInt32(mMirrorMode);
    if (err != OK) return err;

    return OK;
}

+4 −1
Original line number Diff line number Diff line
@@ -37,10 +37,13 @@ class CameraUtils {
         * metadata.  This is based on the sensor orientation and lens facing
         * attributes of the camera device.
         *
         * If mirrorMode is not AUTO, it will be used to override the lens
         * facing based mirror.
         *
         * Returns OK on success, or a negative error code.
         */
        static status_t getRotationTransform(const CameraMetadata& staticInfo,
                /*out*/int32_t* transform);
                int mirrorMode, /*out*/int32_t* transform);

        /**
         * Check if the image data is VideoNativeHandleMetadata, that contains a native handle.
+14 −2
Original line number Diff line number Diff line
@@ -38,13 +38,19 @@ public:
        SURFACE_TYPE_SURFACE_VIEW = 0,
        SURFACE_TYPE_SURFACE_TEXTURE = 1
    };
    enum TimestampBaseByte {
    enum TimestampBaseType {
        TIMESTAMP_BASE_DEFAULT = 0,
        TIMESTAMP_BASE_SENSOR = 1,
        TIMESTAMP_BASE_MONOTONIC = 2,
        TIMESTAMP_BASE_REALTIME = 3,
        TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED = 4
    };
    enum MirrorModeType {
        MIRROR_MODE_AUTO = 0,
        MIRROR_MODE_NONE = 1,
        MIRROR_MODE_H = 2,
        MIRROR_MODE_V = 3,
    };

    const std::vector<sp<IGraphicBufferProducer>>& getGraphicBufferProducers() const;
    int                        getRotation() const;
@@ -59,6 +65,7 @@ public:
    bool                       isMultiResolution() const;
    int                        getStreamUseCase() const;
    int                        getTimestampBase() const;
    int                        getMirrorMode() const;

    // set of sensor pixel mode resolutions allowed {MAX_RESOLUTION, DEFAULT_MODE};
    const std::vector<int32_t>&            getSensorPixelModesUsed() const;
@@ -103,7 +110,8 @@ public:
                sensorPixelModesUsedEqual(other) &&
                mDynamicRangeProfile == other.mDynamicRangeProfile &&
                mStreamUseCase == other.mStreamUseCase &&
                mTimestampBase == other.mTimestampBase);
                mTimestampBase == other.mTimestampBase &&
                mMirrorMode == other.mMirrorMode);
    }
    bool operator != (const OutputConfiguration& other) const {
        return !(*this == other);
@@ -149,6 +157,9 @@ public:
        if (mTimestampBase != other.mTimestampBase) {
            return mTimestampBase < other.mTimestampBase;
        }
        if (mMirrorMode != other.mMirrorMode) {
            return mMirrorMode < other.mMirrorMode;
        }
        return gbpsLessThan(other);
    }

@@ -176,6 +187,7 @@ private:
    int                        mDynamicRangeProfile;
    int                        mStreamUseCase;
    int                        mTimestampBase;
    int                        mMirrorMode;
};
} // namespace params
} // namespace camera2
+18 −12
Original line number Diff line number Diff line
@@ -865,6 +865,7 @@ binder::Status CameraDeviceClient::createStream(
    int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
    int streamUseCase = outputConfiguration.getStreamUseCase();
    int timestampBase = outputConfiguration.getTimestampBase();
    int mirrorMode = outputConfiguration.getMirrorMode();

    res = SessionConfigurationUtils::checkSurfaceType(numBufferProducers, deferredConsumer,
            outputConfiguration.getSurfaceType());
@@ -909,7 +910,7 @@ binder::Status CameraDeviceClient::createStream(
        res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
                isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
                mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
                streamUseCase, timestampBase);
                streamUseCase, timestampBase, mirrorMode);

        if (!res.isOk())
            return res;
@@ -956,7 +957,7 @@ binder::Status CameraDeviceClient::createStream(
                &streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
                outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution,
                /*consumerUsage*/0, streamInfo.dynamicRangeProfile, streamInfo.streamUseCase,
                streamInfo.timestampBase);
                streamInfo.timestampBase, streamInfo.mirrorMode);
    }

    if (err != OK) {
@@ -982,7 +983,7 @@ binder::Status CameraDeviceClient::createStream(
                  streamInfo.height, streamInfo.format);

        // Set transform flags to ensure preview to be rotated correctly.
        res = setStreamTransformLocked(streamId);
        res = setStreamTransformLocked(streamId, streamInfo.mirrorMode);

        // Fill in mHighResolutionCameraIdToStreamIdSet map
        const String8 &cameraIdUsed =
@@ -1052,7 +1053,8 @@ binder::Status CameraDeviceClient::createDeferredSurfaceStreamLocked(
            outputConfiguration.getSurfaceSetID(), isShared,
            outputConfiguration.isMultiResolution(), consumerUsage,
            outputConfiguration.getDynamicRangeProfile(),
            outputConfiguration.getStreamUseCase());
            outputConfiguration.getStreamUseCase(),
            outputConfiguration.getMirrorMode());

    if (err != OK) {
        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
@@ -1068,14 +1070,15 @@ binder::Status CameraDeviceClient::createDeferredSurfaceStreamLocked(
                        overriddenSensorPixelModesUsed,
                        outputConfiguration.getDynamicRangeProfile(),
                        outputConfiguration.getStreamUseCase(),
                        outputConfiguration.getTimestampBase()));
                        outputConfiguration.getTimestampBase(),
                        outputConfiguration.getMirrorMode()));

        ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
                " (%d x %d) stream with format 0x%x.",
              __FUNCTION__, mCameraIdStr.string(), streamId, width, height, format);

        // Set transform flags to ensure preview to be rotated correctly.
        res = setStreamTransformLocked(streamId);
        res = setStreamTransformLocked(streamId, outputConfiguration.getMirrorMode());

        *newStreamId = streamId;
        // Fill in mHighResolutionCameraIdToStreamIdSet
@@ -1089,7 +1092,7 @@ binder::Status CameraDeviceClient::createDeferredSurfaceStreamLocked(
    return res;
}

binder::Status CameraDeviceClient::setStreamTransformLocked(int streamId) {
binder::Status CameraDeviceClient::setStreamTransformLocked(int streamId, int mirrorMode) {
    int32_t transform = 0;
    status_t err;
    binder::Status res;
@@ -1098,7 +1101,7 @@ binder::Status CameraDeviceClient::setStreamTransformLocked(int streamId) {
        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
    }

    err = getRotationTransformLocked(&transform);
    err = getRotationTransformLocked(mirrorMode, &transform);
    if (err != OK) {
        // Error logged by getRotationTransformLocked.
        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
@@ -1259,6 +1262,7 @@ binder::Status CameraDeviceClient::updateOutputConfiguration(int streamId,
    int streamUseCase = outputConfiguration.getStreamUseCase();
    int timestampBase = outputConfiguration.getTimestampBase();
    int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
    int mirrorMode = outputConfiguration.getMirrorMode();

    for (size_t i = 0; i < newOutputsMap.size(); i++) {
        OutputStreamInfo outInfo;
@@ -1266,7 +1270,7 @@ binder::Status CameraDeviceClient::updateOutputConfiguration(int streamId,
        res = SessionConfigurationUtils::createSurfaceFromGbp(outInfo,
                /*isStreamInfoValid*/ false, surface, newOutputsMap.valueAt(i), mCameraIdStr,
                mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
                streamUseCase, timestampBase);
                streamUseCase, timestampBase, mirrorMode);
        if (!res.isOk())
            return res;

@@ -1626,6 +1630,7 @@ binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId
    int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
    int streamUseCase= outputConfiguration.getStreamUseCase();
    int timestampBase = outputConfiguration.getTimestampBase();
    int mirrorMode = outputConfiguration.getMirrorMode();
    for (auto& bufferProducer : bufferProducers) {
        // Don't create multiple streams for the same target surface
        ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
@@ -1639,7 +1644,7 @@ binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId
        res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
                true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
                mDevice->infoPhysical(physicalId), sensorPixelModesUsed, dynamicRangeProfile,
                streamUseCase, timestampBase);
                streamUseCase, timestampBase, mirrorMode);

        if (!res.isOk())
            return res;
@@ -2121,11 +2126,12 @@ bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
    return true;
}

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

    const CameraMetadata& staticInfo = mDevice->info();
    return CameraUtils::getRotationTransform(staticInfo, transform);
    return CameraUtils::getRotationTransform(staticInfo, mirrorMode, transform);
}

binder::Status CameraDeviceClient::mapRequestTemplate(int templateId,
Loading