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

Commit 0918fc86 authored by Austin Borger's avatar Austin Borger
Browse files

Camera VTS: Add test validating stream configuration metadata

Vendor static metadata entries related to the stream configuration tags
like min frame duration, stall duration could include duplicate or
invalid data. Check that this is not the case.

Initially, this test only has impact for 10-bit HDR devices. More checks
will be added in the future.

Bug: 269165407
Test: Ran test on Pixel 7.
Change-Id: I2ad820c1ba4753508fa1f61b31b51739358099ea
parent 2da97768
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -3051,6 +3051,47 @@ TEST_P(CameraAidlTest, configureStreamsUseCases) {
    configureStreamUseCaseInternal(previewStreamThreshold);
}

// Validate the integrity of stream configuration metadata
TEST_P(CameraAidlTest, validateStreamConfigurations) {
    std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
    std::vector<AvailableStream> outputStreams;

    const int32_t scalerSizesTag = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
    const int32_t scalerMinFrameDurationsTag = ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
    const int32_t scalerStallDurationsTag = ANDROID_SCALER_AVAILABLE_STALL_DURATIONS;

    for (const auto& name : cameraDeviceNames) {
        CameraMetadata meta;
        std::shared_ptr<ICameraDevice> cameraDevice;

        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
                               &cameraDevice /*out*/);
        camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());

        if (is10BitDynamicRangeCapable(staticMeta)) {
            std::vector<std::tuple<size_t, size_t>> supportedP010Sizes, supportedBlobSizes;

            getSupportedSizes(staticMeta, scalerSizesTag, HAL_PIXEL_FORMAT_BLOB,
                              &supportedBlobSizes);
            getSupportedSizes(staticMeta, scalerSizesTag, HAL_PIXEL_FORMAT_YCBCR_P010,
                              &supportedP010Sizes);
            ASSERT_FALSE(supportedP010Sizes.empty());

            std::vector<int64_t> blobMinDurations, blobStallDurations;
            getSupportedDurations(staticMeta, scalerMinFrameDurationsTag, HAL_PIXEL_FORMAT_BLOB,
                                  supportedP010Sizes, &blobMinDurations);
            getSupportedDurations(staticMeta, scalerStallDurationsTag, HAL_PIXEL_FORMAT_BLOB,
                                  supportedP010Sizes, &blobStallDurations);
            ASSERT_FALSE(blobStallDurations.empty());
            ASSERT_FALSE(blobMinDurations.empty());
            ASSERT_EQ(supportedP010Sizes.size(), blobMinDurations.size());
            ASSERT_EQ(blobMinDurations.size(), blobStallDurations.size());
        }

        // Validate other aspects of stream configuration metadata...
    }
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CameraAidlTest);
INSTANTIATE_TEST_SUITE_P(
        PerInstance, CameraAidlTest,
+45 −0
Original line number Diff line number Diff line
@@ -3703,3 +3703,48 @@ void CameraAidlTest::processZoomSettingsOverrideRequests(
        ASSERT_TRUE(ret.isOk());
    }
}

void CameraAidlTest::getSupportedSizes(const camera_metadata_t* ch, uint32_t tag, int32_t format,
                                       std::vector<std::tuple<size_t, size_t>>* sizes /*out*/) {
    if (sizes == nullptr) {
        return;
    }

    camera_metadata_ro_entry entry;
    int retcode = find_camera_metadata_ro_entry(ch, tag, &entry);
    if ((0 == retcode) && (entry.count > 0)) {
        // Scaler entry contains 4 elements (format, width, height, type)
        for (size_t i = 0; i < entry.count; i += 4) {
            if ((entry.data.i32[i] == format) &&
                (entry.data.i32[i + 3] == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
                sizes->push_back(std::make_tuple(entry.data.i32[i + 1], entry.data.i32[i + 2]));
            }
        }
    }
}

void CameraAidlTest::getSupportedDurations(const camera_metadata_t* ch, uint32_t tag,
                                           int32_t format,
                                           const std::vector<std::tuple<size_t, size_t>>& sizes,
                                           std::vector<int64_t>* durations /*out*/) {
    if (durations == nullptr) {
        return;
    }

    camera_metadata_ro_entry entry;
    int retcode = find_camera_metadata_ro_entry(ch, tag, &entry);
    if ((0 == retcode) && (entry.count > 0)) {
        // Duration entry contains 4 elements (format, width, height, duration)
        for (const auto& size : sizes) {
            int64_t width = std::get<0>(size);
            int64_t height = std::get<1>(size);
            for (size_t i = 0; i < entry.count; i += 4) {
                if ((entry.data.i64[i] == format) && (entry.data.i64[i + 1] == width) &&
                    (entry.data.i64[i + 2] == height)) {
                    durations->push_back(entry.data.i64[i + 3]);
                    break;
                }
            }
        }
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -418,6 +418,13 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> {
    bool supportsCroppedRawUseCase(const camera_metadata_t *staticMeta);
    bool isPerFrameControl(const camera_metadata_t* staticMeta);

    void getSupportedSizes(const camera_metadata_t* ch, uint32_t tag, int32_t format,
                           std::vector<std::tuple<size_t, size_t>>* sizes /*out*/);

    void getSupportedDurations(const camera_metadata_t* ch, uint32_t tag, int32_t format,
                               const std::vector<std::tuple<size_t, size_t>>& sizes,
                               std::vector<int64_t>* durations /*out*/);

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