From: Emilian Peev Date: Wed, 8 Feb 2017 17:15:16 +0000 (+0000) Subject: Camera: Extend Camera VTS testing X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=378f8aaec6d36dcd959718f85729e46ab0841015;p=android-x86%2Fhardware-interfaces.git Camera: Extend Camera VTS testing Further tests concerning camera configurations. The additional tests corver: - The available stream configurations. - Invalid stream parameters. - Constrained mode if available. - ZSL mode if available. - Stream combinations including preview and still capture. - Stream combinations including video and snapshot. BUG: 32022758 Test: compile and run the gtest binary on device Change-Id: I5111ac96b4aaa7ad9f163f990f6b0d0c229993f9 --- diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index 01863710..3423b265 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -21,6 +21,8 @@ #include #include #include "system/camera_metadata.h" +#include +#include using ::android::hardware::Return; using ::android::hardware::Void; @@ -28,6 +30,7 @@ using ::android::hardware::hidl_handle; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::sp; +using ::android::hardware::graphics::common::V1_0::PixelFormat; using ::android::hardware::camera::common::V1_0::Status; using ::android::hardware::camera::common::V1_0::CameraDeviceStatus; using ::android::hardware::camera::common::V1_0::TorchMode; @@ -40,8 +43,30 @@ using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback; using ::android::hardware::camera::device::V3_2::ICameraDeviceSession; using ::android::hardware::camera::device::V3_2::NotifyMsg; using ::android::hardware::camera::device::V3_2::RequestTemplate; +using ::android::hardware::camera::device::V3_2::Stream; +using ::android::hardware::camera::device::V3_2::StreamType; +using ::android::hardware::camera::device::V3_2::StreamRotation; +using ::android::hardware::camera::device::V3_2::StreamConfiguration; +using ::android::hardware::camera::device::V3_2::StreamConfigurationMode; +using ::android::hardware::camera::device::V3_2::CameraMetadata; +using ::android::hardware::camera::device::V3_2::HalStreamConfiguration; #define CAMERA_PASSTHROUGH_SERVICE_NAME "legacy/0" +#define MAX_PREVIEW_WIDTH 1920 +#define MAX_PREVIEW_HEIGHT 1080 +#define MAX_VIDEO_WIDTH 4096 +#define MAX_VIDEO_HEIGHT 2160 + +struct AvailableStream { + int32_t width; + int32_t height; + int32_t format; +}; + +struct AvailableZSLInputOutput { + int32_t inputFormat; + int32_t outputFormat; +}; namespace { // "device@/legacy/" @@ -126,6 +151,19 @@ public: return Void(); } }; + + static Status getAvailableOutputStreams(camera_metadata_t *staticMeta, + std::vector &outputStreams, + AvailableStream *threshold = nullptr); + static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta); + static Status pickConstrainedModeSize(camera_metadata_t *staticMeta, + AvailableStream &hfrStream); + static Status isZSLModeAvailable(camera_metadata_t *staticMeta); + static Status getZSLInputOutputMap(camera_metadata_t *staticMeta, + std::vector &inputOutputMap); + static Status findLargestSize( + const std::vector &streamSizes, + int32_t format, AvailableStream &result); }; hidl_vec CameraHidlTest::getCameraDeviceNames() { @@ -234,6 +272,8 @@ TEST_F(CameraHidlTest, getCameraDeviceInterface_V3_x) { } } +// Verify that the device resource cost can be retrieved and the values are +// sane. TEST_F(CameraHidlTest, getResourceCost) { CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); hidl_vec cameraDeviceNames = getCameraDeviceNames(); @@ -265,6 +305,8 @@ TEST_F(CameraHidlTest, getResourceCost) { } } +// Verify that the static camera characteristics can be retrieved +// successfully. TEST_F(CameraHidlTest, getCameraCharacteristics) { CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); hidl_vec cameraDeviceNames = getCameraDeviceNames(); @@ -299,6 +341,7 @@ TEST_F(CameraHidlTest, getCameraCharacteristics) { } } +//In case it is supported verify that torch can be enabled. TEST_F(CameraHidlTest, setTorchMode) { CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); hidl_vec cameraDeviceNames = getCameraDeviceNames(); @@ -340,6 +383,7 @@ TEST_F(CameraHidlTest, setTorchMode) { } } +// Check dump functionality. TEST_F(CameraHidlTest, dumpState) { CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); hidl_vec cameraDeviceNames = getCameraDeviceNames(); @@ -408,6 +452,8 @@ TEST_F(CameraHidlTest, openClose) { } } +// Check whether all common default request settings can be sucessfully +// constructed. TEST_F(CameraHidlTest, constructDefaultRequestSettings) { CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); hidl_vec cameraDeviceNames = getCameraDeviceNames(); @@ -472,9 +518,481 @@ TEST_F(CameraHidlTest, constructDefaultRequestSettings) { } } -TEST_F(CameraHidlTest, configureStreams) { +// Verify that all supported stream formats and sizes can be configured +// successfully. +TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) { + CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); + hidl_vec cameraDeviceNames = getCameraDeviceNames(); + std::vector outputStreams; + + for (const auto& name : cameraDeviceNames) { + if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) { + ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; + ALOGI("configureStreams: Testing camera device %s", name.c_str()); + env->mProvider->getCameraDeviceInterface_V3_x( + name, + [&](auto status, const auto& device) { + ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(device, nullptr); + device3_2 = device; + }); + + sp cb = new EmptyDeviceCb; + sp session; + device3_2->open( + cb, + [&](auto status, const auto& newSession) { + ALOGI("device::open returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(newSession, nullptr); + session = newSession; + }); + + camera_metadata_t *staticMeta; + device3_2->getCameraCharacteristics([&] (Status s, + CameraMetadata metadata) { + ASSERT_EQ(Status::OK, s); + staticMeta = + reinterpret_cast(metadata.data()); + }); + outputStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, + outputStreams)); + ASSERT_NE(0u, outputStreams.size()); + + int32_t streamId = 0; + for (auto &it : outputStreams) { + Stream stream = {streamId, StreamType::OUTPUT, + static_cast (it.width), + static_cast (it.height), + static_cast (it.format), 0, 0, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec streams = {stream}; + StreamConfiguration config = {streams, + StreamConfigurationMode::NORMAL_MODE}; + session->configureStreams(config, [streamId] (Status s, + HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].id, streamId); + }); + streamId++; + } + + session->close(); + } + } +} + +// Check for correct handling of invalid/incorrect configuration parameters. +TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { + CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); + hidl_vec cameraDeviceNames = getCameraDeviceNames(); + std::vector outputStreams; + + for (const auto& name : cameraDeviceNames) { + if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) { + ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; + ALOGI("configureStreams: Testing camera device %s", name.c_str()); + env->mProvider->getCameraDeviceInterface_V3_x( + name, + [&](auto status, const auto& device) { + ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(device, nullptr); + device3_2 = device; + }); + + sp cb = new EmptyDeviceCb; + sp session; + device3_2->open( + cb, + [&](auto status, const auto& newSession) { + ALOGI("device::open returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(newSession, nullptr); + session = newSession; + }); + + camera_metadata_t *staticMeta; + device3_2->getCameraCharacteristics([&] (Status s, + CameraMetadata metadata) { + ASSERT_EQ(Status::OK, s); + staticMeta = + reinterpret_cast(metadata.data()); + }); + outputStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, + outputStreams)); + ASSERT_NE(0u, outputStreams.size()); + + int32_t streamId = 0; + Stream stream = {streamId++, StreamType::OUTPUT, + static_cast (0), + static_cast (0), + static_cast (outputStreams[0].format), + 0, 0, StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec streams = {stream}; + StreamConfiguration config = {streams, + StreamConfigurationMode::NORMAL_MODE}; + session->configureStreams(config, [] (Status s, + HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + + stream = {streamId++, StreamType::OUTPUT, + static_cast (UINT32_MAX), + static_cast (UINT32_MAX), + static_cast (outputStreams[0].format), + 0, 0, StreamRotation::ROTATION_0}; + streams[0] = stream; + config = {streams, + StreamConfigurationMode::NORMAL_MODE}; + session->configureStreams(config, [] (Status s, + HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + + for (auto &it : outputStreams) { + stream = {streamId++, StreamType::OUTPUT, + static_cast (it.width), + static_cast (it.height), + static_cast (UINT32_MAX), + 0, 0, StreamRotation::ROTATION_0}; + streams[0] = stream; + config = {streams, + StreamConfigurationMode::NORMAL_MODE}; + session->configureStreams(config, [] (Status s, + HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + + stream = {streamId++, StreamType::OUTPUT, + static_cast (it.width), + static_cast (it.height), + static_cast (it.format), + 0, 0, static_cast (UINT32_MAX)}; + streams[0] = stream; + config = {streams, + StreamConfigurationMode::NORMAL_MODE}; + session->configureStreams(config, [] (Status s, + HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } + + session->close(); + } + } +} + +// Check whether all supported ZSL output stream combinations can be +// configured successfully. +TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) { + CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); + hidl_vec cameraDeviceNames = getCameraDeviceNames(); + std::vector inputStreams; + std::vector inputOutputMap; + + for (const auto& name : cameraDeviceNames) { + if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) { + ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; + ALOGI("configureStreams: Testing camera device %s", name.c_str()); + env->mProvider->getCameraDeviceInterface_V3_x( + name, + [&](auto status, const auto& device) { + ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(device, nullptr); + device3_2 = device; + }); + + sp cb = new EmptyDeviceCb; + sp session; + device3_2->open( + cb, + [&](auto status, const auto& newSession) { + ALOGI("device::open returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(newSession, nullptr); + session = newSession; + }); + + camera_metadata_t *staticMeta; + device3_2->getCameraCharacteristics([&] (Status s, + CameraMetadata metadata) { + ASSERT_EQ(Status::OK, s); + staticMeta = + reinterpret_cast(metadata.data()); + }); + Status ret = isZSLModeAvailable(staticMeta); + if (Status::METHOD_NOT_SUPPORTED == ret) { + session->close(); + continue; + } + ASSERT_EQ(Status::OK, ret); + + inputStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, + inputStreams)); + ASSERT_NE(0u, inputStreams.size()); + + inputOutputMap.clear(); + ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, + inputOutputMap)); + ASSERT_NE(0u, inputOutputMap.size()); + + int32_t streamId = 0; + for (auto &inputIter : inputOutputMap) { + AvailableStream input, output; + ASSERT_EQ(Status::OK, + findLargestSize(inputStreams, inputIter.inputFormat, input)); + ASSERT_NE(0u, inputStreams.size()); + + AvailableStream outputThreshold = {INT32_MAX, INT32_MAX, + inputIter.outputFormat}; + std::vector outputStreams; + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, + outputStreams, &outputThreshold)); + for (auto &outputIter : outputStreams) { + Stream zslStream = {streamId++, StreamType::OUTPUT, + static_cast (input.width), + static_cast (input.height), + static_cast (input.format), + GRALLOC_USAGE_HW_CAMERA_ZSL, 0, + StreamRotation::ROTATION_0}; + Stream inputStream = {streamId++, StreamType::INPUT, + static_cast (input.width), + static_cast (input.height), + static_cast (input.format), 0, 0, + StreamRotation::ROTATION_0}; + Stream outputStream = {streamId++, StreamType::OUTPUT, + static_cast (outputIter.width), + static_cast (outputIter.height), + static_cast (outputIter.format), 0, 0, + StreamRotation::ROTATION_0}; + + ::android::hardware::hidl_vec streams = { + inputStream, zslStream, outputStream}; + StreamConfiguration config = {streams, + StreamConfigurationMode::NORMAL_MODE}; + session->configureStreams(config, [streamId] (Status s, + HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(3u, halConfig.streams.size()); + }); + } + } + + session->close(); + } + } +} + +// Verify that all supported preview + still capture stream combinations +// can be configured successfully. +TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) { + CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); + hidl_vec cameraDeviceNames = getCameraDeviceNames(); + std::vector outputBlobStreams; + std::vector outputPreviewStreams; + AvailableStream previewThreshold = {MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT, + static_cast(PixelFormat::IMPLEMENTATION_DEFINED)}; + AvailableStream blobThreshold = {INT32_MAX, INT32_MAX, + static_cast(PixelFormat::BLOB)}; + + for (const auto& name : cameraDeviceNames) { + if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) { + ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; + ALOGI("configureStreams: Testing camera device %s", name.c_str()); + env->mProvider->getCameraDeviceInterface_V3_x( + name, + [&](auto status, const auto& device) { + ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(device, nullptr); + device3_2 = device; + }); + + sp cb = new EmptyDeviceCb; + sp session; + device3_2->open( + cb, + [&](auto status, const auto& newSession) { + ALOGI("device::open returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(newSession, nullptr); + session = newSession; + }); + + camera_metadata_t *staticMeta; + device3_2->getCameraCharacteristics([&] (Status s, + CameraMetadata metadata) { + ASSERT_EQ(Status::OK, s); + staticMeta = + reinterpret_cast(metadata.data()); + }); + outputBlobStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, + outputBlobStreams, &blobThreshold)); + ASSERT_NE(0u, outputBlobStreams.size()); + + outputPreviewStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, + outputPreviewStreams, &previewThreshold)); + ASSERT_NE(0u, outputPreviewStreams.size()); + + int32_t streamId = 0; + for (auto &blobIter : outputBlobStreams) { + for (auto &previewIter : outputPreviewStreams) { + Stream previewStream = {streamId++, StreamType::OUTPUT, + static_cast (previewIter.width), + static_cast (previewIter.height), + static_cast (previewIter.format), 0, 0, + StreamRotation::ROTATION_0}; + Stream blobStream = {streamId++, StreamType::OUTPUT, + static_cast (blobIter.width), + static_cast (blobIter.height), + static_cast (blobIter.format), 0, 0, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec streams = { + previewStream, blobStream}; + StreamConfiguration config = {streams, + StreamConfigurationMode::NORMAL_MODE}; + session->configureStreams(config, [streamId] (Status s, + HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } + } + + session->close(); + } + } +} + +// In case constrained mode is supported, test whether it can be +// configured. Additionally check for common invalid inputs when +// using this mode. +TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { + CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); + hidl_vec cameraDeviceNames = getCameraDeviceNames(); + + for (const auto& name : cameraDeviceNames) { + if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) { + ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; + ALOGI("configureStreams: Testing camera device %s", name.c_str()); + env->mProvider->getCameraDeviceInterface_V3_x( + name, + [&](auto status, const auto& device) { + ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(device, nullptr); + device3_2 = device; + }); + + sp cb = new EmptyDeviceCb; + sp session; + device3_2->open( + cb, + [&](auto status, const auto& newSession) { + ALOGI("device::open returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(newSession, nullptr); + session = newSession; + }); + + camera_metadata_t *staticMeta; + device3_2->getCameraCharacteristics([&] (Status s, + CameraMetadata metadata) { + ASSERT_EQ(Status::OK, s); + staticMeta = + reinterpret_cast(metadata.data()); + }); + Status rc = isConstrainedModeAvailable(staticMeta); + if (Status::METHOD_NOT_SUPPORTED == rc) { + session->close(); + continue; + } + ASSERT_EQ(Status::OK, rc); + + AvailableStream hfrStream; + rc = pickConstrainedModeSize(staticMeta, hfrStream); + ASSERT_EQ(Status::OK, rc); + + int32_t streamId = 0; + Stream stream = {streamId, StreamType::OUTPUT, + static_cast (hfrStream.width), + static_cast (hfrStream.height), + static_cast (hfrStream.format), 0, 0, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec streams = {stream}; + StreamConfiguration config = {streams, + StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; + session->configureStreams(config, [streamId] (Status s, + HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].id, streamId); + }); + + stream = {streamId++, StreamType::OUTPUT, + static_cast (0), + static_cast (0), + static_cast (hfrStream.format), 0, 0, + StreamRotation::ROTATION_0}; + streams[0] = stream; + config = {streams, + StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; + session->configureStreams(config, [streamId] (Status s, + HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + + stream = {streamId++, StreamType::OUTPUT, + static_cast (UINT32_MAX), + static_cast (UINT32_MAX), + static_cast (hfrStream.format), 0, 0, + StreamRotation::ROTATION_0}; + streams[0] = stream; + config = {streams, + StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; + session->configureStreams(config, [streamId] (Status s, + HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + + stream = {streamId++, StreamType::OUTPUT, + static_cast (hfrStream.width), + static_cast (hfrStream.height), + static_cast (UINT32_MAX), 0, 0, + StreamRotation::ROTATION_0}; + streams[0] = stream; + config = {streams, + StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; + session->configureStreams(config, [streamId] (Status s, + HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + + session->close(); + } + } +} + +// Verify that all supported video + snapshot stream combinations can +// be configured successfully. +TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) { CameraHidlEnvironment* env = CameraHidlEnvironment::Instance(); hidl_vec cameraDeviceNames = getCameraDeviceNames(); + std::vector outputBlobStreams; + std::vector outputVideoStreams; + AvailableStream videoThreshold = {MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT, + static_cast(PixelFormat::IMPLEMENTATION_DEFINED)}; + AvailableStream blobThreshold = {MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT, + static_cast(PixelFormat::BLOB)}; for (const auto& name : cameraDeviceNames) { if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) { @@ -500,12 +1018,224 @@ TEST_F(CameraHidlTest, configureStreams) { session = newSession; }); + camera_metadata_t *staticMeta; + device3_2->getCameraCharacteristics([&] (Status s, + CameraMetadata metadata) { + ASSERT_EQ(Status::OK, s); + staticMeta = + reinterpret_cast(metadata.data()); + }); + outputBlobStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, + outputBlobStreams, &blobThreshold)); + ASSERT_NE(0u, outputBlobStreams.size()); + + outputVideoStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, + outputVideoStreams, &videoThreshold)); + ASSERT_NE(0u, outputVideoStreams.size()); + + int32_t streamId = 0; + for (auto &blobIter : outputBlobStreams) { + for (auto &videoIter : outputVideoStreams) { + Stream videoStream = {streamId++, StreamType::OUTPUT, + static_cast (videoIter.width), + static_cast (videoIter.height), + static_cast (videoIter.format), 0, 0, + StreamRotation::ROTATION_0}; + Stream blobStream = {streamId++, StreamType::OUTPUT, + static_cast (blobIter.width), + static_cast (blobIter.height), + static_cast (blobIter.format), + GRALLOC_USAGE_HW_VIDEO_ENCODER, 0, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec streams = { + videoStream, blobStream}; + StreamConfiguration config = {streams, + StreamConfigurationMode::NORMAL_MODE}; + session->configureStreams(config, [streamId] (Status s, + HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } + } session->close(); } } } +// Retrieve all valid output stream resolutions from the camera +// static characteristics. +Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta, + std::vector &outputStreams, + AvailableStream *threshold) { + if (nullptr == staticMeta) { + return Status::ILLEGAL_ARGUMENT; + } + + camera_metadata_ro_entry entry; + int rc = find_camera_metadata_ro_entry(staticMeta, + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry); + if ((0 != rc) || (0 != (entry.count % 4))) { + return Status::ILLEGAL_ARGUMENT; + } + + for (size_t i = 0; i < entry.count; i+=4) { + if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT == + entry.data.i32[i + 3]) { + if(nullptr == threshold) { + AvailableStream s = {entry.data.i32[i+1], + entry.data.i32[i+2], entry.data.i32[i]}; + outputStreams.push_back(s); + } else { + if ((threshold->format == entry.data.i32[i]) && + (threshold->width >= entry.data.i32[i+1]) && + (threshold->height >= entry.data.i32[i+2])) { + AvailableStream s = {entry.data.i32[i+1], + entry.data.i32[i+2], threshold->format}; + outputStreams.push_back(s); + } + } + } + + } + + return Status::OK; +} + +// Check if constrained mode is supported by using the static +// camera characteristics. +Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) { + Status ret = Status::METHOD_NOT_SUPPORTED; + if (nullptr == staticMeta) { + return Status::ILLEGAL_ARGUMENT; + } + + camera_metadata_ro_entry entry; + int rc = find_camera_metadata_ro_entry(staticMeta, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); + if (0 != rc) { + return Status::ILLEGAL_ARGUMENT; + } + + for (size_t i = 0; i < entry.count; i++) { + if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO == + entry.data.u8[i]) { + ret = Status::OK; + break; + } + } + + return ret; +} + +// Pick the largest supported HFR mode from the static camera +// characteristics. +Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta, + AvailableStream &hfrStream) { + if (nullptr == staticMeta) { + return Status::ILLEGAL_ARGUMENT; + } + + camera_metadata_ro_entry entry; + int rc = find_camera_metadata_ro_entry(staticMeta, + ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry); + if (0 != rc) { + return Status::METHOD_NOT_SUPPORTED; + } else if (0 != (entry.count % 5)) { + return Status::ILLEGAL_ARGUMENT; + } + + hfrStream = {0, 0, + static_cast(PixelFormat::IMPLEMENTATION_DEFINED)}; + for (size_t i = 0; i < entry.count; i+=5) { + int32_t w = entry.data.i32[i]; + int32_t h = entry.data.i32[i+1]; + if ((hfrStream.width * hfrStream.height) < (w *h)) { + hfrStream.width = w; + hfrStream.height = h; + } + } + + return Status::OK; +} + +// Check whether ZSL is available using the static camera +// characteristics. +Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) { + Status ret = Status::METHOD_NOT_SUPPORTED; + if (nullptr == staticMeta) { + return Status::ILLEGAL_ARGUMENT; + } + + camera_metadata_ro_entry entry; + int rc = find_camera_metadata_ro_entry(staticMeta, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); + if (0 != rc) { + return Status::ILLEGAL_ARGUMENT; + } + + for (size_t i = 0; i < entry.count; i++) { + if ((ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING == + entry.data.u8[i]) || + (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING == + entry.data.u8[i]) ){ + ret = Status::OK; + break; + } + } + + return ret; +} + +// Retrieve the reprocess input-output format map from the static +// camera characteristics. +Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta, + std::vector &inputOutputMap) { + if (nullptr == staticMeta) { + return Status::ILLEGAL_ARGUMENT; + } + + camera_metadata_ro_entry entry; + int rc = find_camera_metadata_ro_entry(staticMeta, + ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry); + if ((0 != rc) || (0 >= entry.count)) { + return Status::ILLEGAL_ARGUMENT; + } + + const int32_t* contents = &entry.data.i32[0]; + for (size_t i = 0; i < entry.count; ) { + int32_t inputFormat = contents[i++]; + int32_t length = contents[i++]; + for (int32_t j = 0; j < length; j++) { + int32_t outputFormat = contents[i+j]; + AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat}; + inputOutputMap.push_back(zslEntry); + } + i += length; + } + + return Status::OK; +} + +// Search for the largest stream size for a given format. +Status CameraHidlTest::findLargestSize( + const std::vector &streamSizes, int32_t format, + AvailableStream &result) { + result = {0, 0, 0}; + for (auto &iter : streamSizes) { + if (format == iter.format) { + if ((result.width * result.height) < (iter.width * iter.height)) { + result = iter; + } + } + } + + return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT; +} + int main(int argc, char **argv) { ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance()); ::testing::InitGoogleTest(&argc, argv);