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

Commit 07ccc7a1 authored by Shuzhen Wang's avatar Shuzhen Wang
Browse files

Camera: Add bokeh mode tags in camera metadata

Introduce new bokeh mode metadata tags for camera device to enable bokeh
effect.

Test: Build and read docs
Bug: 118258123
Change-Id: I99b85fe60ee8af008592922ae2cce64be33e88a2
parent 8ea7f3c6
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -28,10 +28,43 @@ import android.hardware.camera.metadata@3.4;

// No new metadata sections added in this revision

/**
 * Main enumeration for defining camera metadata tags added in this revision
 *
 * <p>Partial documentation is included for each tag; for complete documentation, reference
 * '/system/media/camera/docs/docs.html' in the corresponding Android source tree.</p>
 */
enum CameraMetadataTag : @3.4::CameraMetadataTag {
    /** android.control.availableBokehCapabilities [static, int32[], public]
     *
     * <p>The list of bokeh modes that are supported by this camera device, and each bokeh mode's
     * maximum streaming (non-stall) size with bokeh effect.</p>
     */
    ANDROID_CONTROL_AVAILABLE_BOKEH_CAPABILITIES = android.hardware.camera.metadata@3.3::CameraMetadataTag:ANDROID_CONTROL_END_3_3,

    /** android.control.bokehMode [dynamic, enum, public]
     *
     * <p>Whether bokeh mode is enabled for a particular capture request.</p>
     */
    ANDROID_CONTROL_BOKEH_MODE,

    ANDROID_CONTROL_END_3_5,

};

/*
 * Enumeration definitions for the various entries that need them
 */

/** android.control.bokehMode enumeration values
 * @see ANDROID_CONTROL_BOKEH_MODE
 */
enum CameraMetadataEnumAndroidControlBokehMode : uint32_t {
    ANDROID_CONTROL_BOKEH_MODE_OFF,
    ANDROID_CONTROL_BOKEH_MODE_STILL_CAPTURE,
    ANDROID_CONTROL_BOKEH_MODE_CONTINUOUS,
};

/** android.request.availableCapabilities enumeration values added since v3.4
 * @see ANDROID_REQUEST_AVAILABLE_CAPABILITIES
 */
+98 −2
Original line number Diff line number Diff line
@@ -778,6 +778,7 @@ public:
            const CameraMetadata& chars, int deviceVersion,
            const hidl_vec<hidl_string>& deviceNames);
    void verifyCameraCharacteristics(Status status, const CameraMetadata& chars);
    void verifyBokehCharacteristics(const camera_metadata_t* metadata);
    void verifyRecommendedConfigs(const CameraMetadata& metadata);
    void verifyMonochromeCharacteristics(const CameraMetadata& chars, int deviceVersion);
    void verifyMonochromeCameraResult(
@@ -801,7 +802,7 @@ public:

    bool isDepthOnly(camera_metadata_t* staticMeta);

    static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
    static Status getAvailableOutputStreams(const camera_metadata_t *staticMeta,
            std::vector<AvailableStream> &outputStreams,
            const AvailableStream *threshold = nullptr);
    static Status getJpegBufferSize(camera_metadata_t *staticMeta,
@@ -4856,7 +4857,7 @@ TEST_F(CameraHidlTest, providerDeviceStateNotification) {

// Retrieve all valid output stream resolutions from the camera
// static characteristics.
Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
Status CameraHidlTest::getAvailableOutputStreams(const camera_metadata_t *staticMeta,
        std::vector<AvailableStream> &outputStreams,
        const AvailableStream *threshold) {
    AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
@@ -5839,6 +5840,101 @@ void CameraHidlTest::verifyCameraCharacteristics(Status status, const CameraMeta
            ADD_FAILURE() << "Get Heic maxJpegAppSegmentsCount failed!";
        }
    }

    verifyBokehCharacteristics(metadata);
}

void CameraHidlTest::verifyBokehCharacteristics(const camera_metadata_t* metadata) {
    camera_metadata_ro_entry entry;
    int retcode = 0;

    // Check key availability in capabilities, request and result.

    retcode = find_camera_metadata_ro_entry(metadata,
            ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry);
    bool hasBokehRequestKey = false;
    if ((0 == retcode) && (entry.count > 0)) {
        hasBokehRequestKey = std::find(entry.data.i32, entry.data.i32+entry.count,
                ANDROID_CONTROL_BOKEH_MODE) != entry.data.i32+entry.count;
    } else {
        ADD_FAILURE() << "Get camera availableRequestKeys failed!";
    }

    retcode = find_camera_metadata_ro_entry(metadata,
            ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
    bool hasBokehResultKey = false;
    if ((0 == retcode) && (entry.count > 0)) {
        hasBokehResultKey = std::find(entry.data.i32, entry.data.i32+entry.count,
                ANDROID_CONTROL_BOKEH_MODE) != entry.data.i32+entry.count;
    } else {
        ADD_FAILURE() << "Get camera availableResultKeys failed!";
    }

    retcode = find_camera_metadata_ro_entry(metadata,
            ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry);
    bool hasBokehCharacteristicsKey = false;
    if ((0 == retcode) && (entry.count > 0)) {
        hasBokehCharacteristicsKey = std::find(entry.data.i32, entry.data.i32+entry.count,
                ANDROID_CONTROL_AVAILABLE_BOKEH_CAPABILITIES) != entry.data.i32+entry.count;
    } else {
        ADD_FAILURE() << "Get camera availableCharacteristicsKeys failed!";
    }
    retcode = find_camera_metadata_ro_entry(metadata,
            ANDROID_CONTROL_AVAILABLE_BOKEH_CAPABILITIES, &entry);
    bool hasAvailableBokehCaps = (0 == retcode && entry.count > 0);

    // Bokeh keys must all be available, or all be unavailable.
    bool noBokeh = !hasBokehRequestKey && !hasBokehResultKey && !hasBokehCharacteristicsKey &&
            !hasAvailableBokehCaps;
    if (noBokeh) {
        return;
    }
    bool hasBokeh = hasBokehRequestKey && hasBokehResultKey && hasBokehCharacteristicsKey &&
            hasAvailableBokehCaps;
    ASSERT_TRUE(hasBokeh);

    // Must have OFF, and must have one of STILL_CAPTURE and CONTINUOUS.
    ASSERT_TRUE(entry.count == 6 || entry.count == 9);
    bool hasOffMode = false;
    bool hasStillCaptureMode = false;
    bool hasContinuousMode = false;
    std::vector<AvailableStream> outputStreams;
    ASSERT_EQ(Status::OK, getAvailableOutputStreams(metadata, outputStreams));
    for (int i = 0; i < entry.count; i += 3) {
        int32_t mode = entry.data.i32[i];
        int32_t maxWidth = entry.data.i32[i+1];
        int32_t maxHeight = entry.data.i32[i+2];
        switch (mode) {
            case ANDROID_CONTROL_BOKEH_MODE_OFF:
                hasOffMode = true;
                ASSERT_TRUE(maxWidth == 0 && maxHeight == 0);
                break;
            case ANDROID_CONTROL_BOKEH_MODE_STILL_CAPTURE:
                hasStillCaptureMode = true;
                break;
            case ANDROID_CONTROL_BOKEH_MODE_CONTINUOUS:
                hasContinuousMode = true;
                break;
            default:
                ADD_FAILURE() << "Invalid bokehMode advertised: " << mode;
                break;
        }

        if (mode != ANDROID_CONTROL_BOKEH_MODE_OFF) {
            bool sizeSupported = false;
            for (const auto& stream : outputStreams) {
                if ((stream.format == static_cast<int32_t>(PixelFormat::YCBCR_420_888) ||
                        stream.format == static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED))
                        && stream.width == maxWidth && stream.height == maxHeight) {
                    sizeSupported = true;
                    break;
                }
            }
            ASSERT_TRUE(sizeSupported);
        }
    }
    ASSERT_TRUE(hasOffMode);
    ASSERT_TRUE(hasStillCaptureMode || hasContinuousMode);
}

void CameraHidlTest::verifyMonochromeCharacteristics(const CameraMetadata& chars,