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

Commit d2e68f15 authored by Shuzhen Wang's avatar Shuzhen Wang Committed by Android (Google) Code Review
Browse files

Merge "Camera: Add new camera metadata for settings override frame number"

parents a5fa2dfd 4dd6a516
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -94,9 +94,10 @@ enum CameraMetadataTag {
  ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION = 65584,
  ANDROID_CONTROL_SETTINGS_OVERRIDE = 65588,
  ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES = 65589,
  ANDROID_CONTROL_AUTOFRAMING = 65590,
  ANDROID_CONTROL_AUTOFRAMING_AVAILABLE = 65591,
  ANDROID_CONTROL_AUTOFRAMING_STATE = 65592,
  ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER = 65590,
  ANDROID_CONTROL_AUTOFRAMING = 65591,
  ANDROID_CONTROL_AUTOFRAMING_AVAILABLE = 65592,
  ANDROID_CONTROL_AUTOFRAMING_STATE = 65593,
  ANDROID_DEMOSAIC_MODE = 131072,
  ANDROID_EDGE_MODE = 196608,
  ANDROID_EDGE_STRENGTH = 196609,
+6 −0
Original line number Diff line number Diff line
@@ -463,6 +463,12 @@ enum CameraMetadataTag {
     * be used to speed up certain controls.</p>
     */
    ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
    /**
     * android.control.settingsOverridingFrameNumber [dynamic, int32, system]
     *
     * <p>The frame number of the newer request overriding this capture.</p>
     */
    ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
    /**
     * android.control.autoframing [dynamic, enum, public]
     *
+22 −0
Original line number Diff line number Diff line
@@ -2065,6 +2065,28 @@ TEST_P(CameraAidlTest, process10BitColorSpaceRequests) {
    }
}

TEST_P(CameraAidlTest, processZoomSettingsOverrideRequests) {
    const int32_t kFrameCount = 5;
    const int32_t kTestCases = 2;
    const bool kOverrideSequence[kTestCases][kFrameCount] = {
        // ZOOM, ZOOM, ZOOM, ZOOM, ZOOM;
        { true, true, true, true, true },
        // OFF, OFF, ZOOM, ZOOM, OFF;
        { false, false, true, true, false } };
    const bool kExpectedOverrideResults[kTestCases][kFrameCount] = {
        // All resuls should be overridden except the last one. The last result's
        // zoom doesn't have speed-up.
        { true, true, true, true, false },
        // Because we require at least 2 frames speed-up, request #1, #2 and #3
        // will be overridden.
        { true, true, true, false, false } };

    for (int i = 0; i < kTestCases; i++) {
        processZoomSettingsOverrideRequests(kFrameCount, kOverrideSequence[i],
                kExpectedOverrideResults[i]);
    }
}

// Generate and verify a burst containing alternating sensor sensitivity values
TEST_P(CameraAidlTest, processCaptureRequestBurstISO) {
    std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+186 −1
Original line number Diff line number Diff line
@@ -363,10 +363,15 @@ void CameraAidlTest::verifySettingsOverrideCharacteristics(const camera_metadata
    retcode = find_camera_metadata_ro_entry(metadata,
            ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
    bool hasSettingsOverrideResultKey = false;
    bool hasOverridingFrameNumberKey = false;
    if ((0 == retcode) && (entry.count > 0)) {
        hasSettingsOverrideResultKey =
                std::find(entry.data.i32, entry.data.i32 + entry.count,
                        ANDROID_CONTROL_SETTINGS_OVERRIDE) != entry.data.i32 + entry.count;
        hasOverridingFrameNumberKey =
                std::find(entry.data.i32, entry.data.i32 + entry.count,
                        ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER)
                        != entry.data.i32 + entry.count;
    } else {
        ADD_FAILURE() << "Get camera availableResultKeys failed!";
    }
@@ -385,6 +390,7 @@ void CameraAidlTest::verifySettingsOverrideCharacteristics(const camera_metadata

    ASSERT_EQ(supportSettingsOverride, hasSettingsOverrideRequestKey);
    ASSERT_EQ(supportSettingsOverride, hasSettingsOverrideResultKey);
    ASSERT_EQ(supportSettingsOverride, hasOverridingFrameNumberKey);
    ASSERT_EQ(supportSettingsOverride, hasSettingsOverrideCharacteristicsKey);
}

@@ -3019,6 +3025,30 @@ int32_t CameraAidlTest::halFormatToPublicFormat(
    }
}

bool CameraAidlTest::supportZoomSettingsOverride(const camera_metadata_t* staticMeta) {
    camera_metadata_ro_entry availableOverridesEntry;
    int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
                                           &availableOverridesEntry);
    if (rc == 0) {
        for (size_t i = 0; i < availableOverridesEntry.count; i++) {
            if (availableOverridesEntry.data.i32[i] == ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM) {
                return true;
            }
        }
    }
    return false;
}

bool CameraAidlTest::isPerFrameControl(const camera_metadata_t* staticMeta) {
    camera_metadata_ro_entry syncLatencyEntry;
    int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SYNC_MAX_LATENCY,
                                           &syncLatencyEntry);
    if (rc == 0 && syncLatencyEntry.data.i32[0] == ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL) {
        return true;
    }
    return false;
}

void CameraAidlTest::configurePreviewStream(
        const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
        const AvailableStream* previewThreshold, std::shared_ptr<ICameraDeviceSession>* session,
@@ -3385,3 +3415,158 @@ void CameraAidlTest::processColorSpaceRequest(
        ASSERT_TRUE(ret.isOk());
    }
}

void CameraAidlTest::processZoomSettingsOverrideRequests(
        int32_t frameCount, const bool *overrideSequence, const bool *expectedResults) {
    std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
    int64_t bufferId = 1;
    int32_t frameNumber = 1;
    CameraMetadata settings;
    ndk::ScopedAStatus ret;
    for (const auto& name : cameraDeviceNames) {
        CameraMetadata meta;
        std::shared_ptr<ICameraDevice> device;
        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
                               &device /*out*/);
        camera_metadata_t* staticMeta =
                clone_camera_metadata(reinterpret_cast<camera_metadata_t*>(meta.metadata.data()));

        ret = mSession->close();
        mSession = nullptr;
        ASSERT_TRUE(ret.isOk());

        // Device does not support zoom settnigs override
        if (!supportZoomSettingsOverride(staticMeta)) {
            continue;
        }

        if (!isPerFrameControl(staticMeta)) {
            continue;
        }

        bool supportsPartialResults = false;
        bool useHalBufManager = false;
        int32_t partialResultCount = 0;
        Stream previewStream;
        std::vector<HalStream> halStreams;
        std::shared_ptr<DeviceCb> cb;
        configurePreviewStream(name, mProvider, &previewThreshold, &mSession /*out*/,
                               &previewStream /*out*/, &halStreams /*out*/,
                               &supportsPartialResults /*out*/, &partialResultCount /*out*/,
                               &useHalBufManager /*out*/, &cb /*out*/);
        ASSERT_NE(mSession, nullptr);

        ::aidl::android::hardware::common::fmq::MQDescriptor<
                int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
                descriptor;
        auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
        ASSERT_TRUE(resultQueueRet.isOk());

        std::shared_ptr<ResultMetadataQueue> resultQueue =
                std::make_shared<ResultMetadataQueue>(descriptor);
        if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
            ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
            resultQueue = nullptr;
            // Don't use the queue onwards.
        }

        ret = mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &settings);
        ASSERT_TRUE(ret.isOk());

        mInflightMap.clear();
        ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
        std::vector<CaptureRequest> requests(frameCount);
        std::vector<buffer_handle_t> buffers(frameCount);
        std::vector<std::shared_ptr<InFlightRequest>> inflightReqs(frameCount);
        std::vector<CameraMetadata> requestSettings(frameCount);

        for (int32_t i = 0; i < frameCount; i++) {
            std::unique_lock<std::mutex> l(mLock);
            CaptureRequest& request = requests[i];
            std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
            outputBuffers.resize(1);
            StreamBuffer& outputBuffer = outputBuffers[0];

            if (useHalBufManager) {
                outputBuffer = {halStreams[0].id, 0,
                                NativeHandle(),   BufferStatus::OK,
                                NativeHandle(),   NativeHandle()};
            } else {
                allocateGraphicBuffer(previewStream.width, previewStream.height,
                                      android_convertGralloc1To0Usage(
                                              static_cast<uint64_t>(halStreams[0].producerUsage),
                                              static_cast<uint64_t>(halStreams[0].consumerUsage)),
                                      halStreams[0].overrideFormat, &buffers[i]);
                outputBuffer = {halStreams[0].id, bufferId + i,   ::android::makeToAidl(buffers[i]),
                                BufferStatus::OK, NativeHandle(), NativeHandle()};
            }

            // Set appropriate settings override tag
            requestMeta.append(reinterpret_cast<camera_metadata_t*>(settings.metadata.data()));
            int32_t settingsOverride = overrideSequence[i] ?
                    ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM : ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF;
            ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_SETTINGS_OVERRIDE,
                    &settingsOverride, 1));
            camera_metadata_t* metaBuffer = requestMeta.release();
            uint8_t* rawMetaBuffer = reinterpret_cast<uint8_t*>(metaBuffer);
            requestSettings[i].metadata = std::vector(
                    rawMetaBuffer, rawMetaBuffer + get_camera_metadata_size(metaBuffer));
            overrideRotateAndCrop(&(requestSettings[i]));
            request.frameNumber = frameNumber + i;
            request.fmqSettingsSize = 0;
            request.settings = requestSettings[i];
            request.inputBuffer = {
                    -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};

            inflightReqs[i] = std::make_shared<InFlightRequest>(1, false, supportsPartialResults,
                                                                partialResultCount, resultQueue);
            mInflightMap[frameNumber + i] = inflightReqs[i];
        }

        int32_t numRequestProcessed = 0;
        std::vector<BufferCache> cachesToRemove;

        ndk::ScopedAStatus returnStatus =
                mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
        ASSERT_TRUE(returnStatus.isOk());
        ASSERT_EQ(numRequestProcessed, frameCount);

        for (size_t i = 0; i < frameCount; i++) {
            std::unique_lock<std::mutex> l(mLock);
            while (!inflightReqs[i]->errorCodeValid && ((0 < inflightReqs[i]->numBuffersLeft) ||
                                                        (!inflightReqs[i]->haveResultMetadata))) {
                auto timeout = std::chrono::system_clock::now() +
                               std::chrono::seconds(kStreamBufferTimeoutSec);
                ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
            }

            ASSERT_FALSE(inflightReqs[i]->errorCodeValid);
            ASSERT_NE(inflightReqs[i]->resultOutputBuffers.size(), 0u);
            ASSERT_EQ(previewStream.id, inflightReqs[i]->resultOutputBuffers[0].buffer.streamId);
            ASSERT_FALSE(inflightReqs[i]->collectedResult.isEmpty());
            ASSERT_TRUE(inflightReqs[i]->collectedResult.exists(ANDROID_CONTROL_SETTINGS_OVERRIDE));
            camera_metadata_entry_t overrideResult =
                    inflightReqs[i]->collectedResult.find(ANDROID_CONTROL_SETTINGS_OVERRIDE);
            ASSERT_EQ(overrideResult.data.i32[0] == ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM,
                    expectedResults[i]);
            ASSERT_TRUE(inflightReqs[i]->collectedResult.exists(
                    ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER));
            camera_metadata_entry_t frameNumberEntry = inflightReqs[i]->collectedResult.find(
                    ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER);
            ALOGV("%s: i %zu, expcetedResults[i] %d, overrideResult is %d, frameNumber %d",
                  __FUNCTION__, i, expectedResults[i], overrideResult.data.i32[0],
                  frameNumberEntry.data.i32[0]);
            if (expectedResults[i]) {
                ASSERT_GT(frameNumberEntry.data.i32[0], inflightReqs[i]->frameNumber);
            } else {
                ASSERT_EQ(frameNumberEntry.data.i32[0], frameNumber + i);
            }
        }

        ret = mSession->close();
        mSession = nullptr;
        ASSERT_TRUE(ret.isOk());
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -406,6 +406,12 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> {
            aidl::android::hardware::camera::metadata::
            RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile);

    void processZoomSettingsOverrideRequests(
            int32_t frameCount, const bool *overrideSequence, const bool *expectedResults);

    bool supportZoomSettingsOverride(const camera_metadata_t* staticMeta);
    bool isPerFrameControl(const camera_metadata_t* staticMeta);

  protected:
    // In-flight queue for tracking completion of capture requests.
    struct InFlightRequest {