diff options
Diffstat (limited to 'camera')
-rw-r--r-- | camera/common/1.0/default/HandleImporter.cpp | 65 | ||||
-rw-r--r-- | camera/common/1.0/default/include/HandleImporter.h | 5 | ||||
-rw-r--r-- | camera/device/3.8/Android.bp | 3 | ||||
-rw-r--r-- | camera/device/3.8/ICameraDevice.hal | 15 | ||||
-rw-r--r-- | camera/device/3.8/ICameraDeviceSession.hal | 95 | ||||
-rw-r--r-- | camera/device/3.8/types.hal | 77 | ||||
-rw-r--r-- | camera/metadata/3.8/types.hal | 63 | ||||
-rw-r--r-- | camera/provider/2.4/vts/functional/Android.bp | 4 | ||||
-rw-r--r-- | camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp | 565 |
9 files changed, 858 insertions, 34 deletions
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp index 7fcf52330c..fbe8686766 100644 --- a/camera/common/1.0/default/HandleImporter.cpp +++ b/camera/common/1.0/default/HandleImporter.cpp @@ -30,6 +30,7 @@ namespace helper { using aidl::android::hardware::graphics::common::PlaneLayout; using aidl::android::hardware::graphics::common::PlaneLayoutComponent; using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; +using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType; using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error; using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error; using MapperErrorV4 = android::hardware::graphics::mapper::V4_0::Error; @@ -123,6 +124,21 @@ YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_ return layout; } +bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf, + MetadataType metadataType) { + auto buffer = const_cast<native_handle_t*>(buf); + mapper->get(buffer, metadataType, [] (const auto& tmpError, + const auto& tmpMetadata) { + if (tmpError == MapperErrorV4::NONE) { + return tmpMetadata.size() > 0; + } else { + ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError); + return false; + }}); + + return false; +} + std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) { auto buffer = const_cast<native_handle_t*>(buf); std::vector<PlaneLayout> planeLayouts; @@ -449,6 +465,55 @@ int HandleImporter::unlock(buffer_handle_t& buf) { return -1; } +bool HandleImporter::isSmpte2086Present(const buffer_handle_t& buf) { + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2086); + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + } + + return false; +} + +bool HandleImporter::isSmpte2094_10Present(const buffer_handle_t& buf) { + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_10); + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + } + + return false; +} + +bool HandleImporter::isSmpte2094_40Present(const buffer_handle_t& buf) { + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_40); + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + } + + return false; +} + + } // namespace helper } // namespace V1_0 } // namespace common diff --git a/camera/common/1.0/default/include/HandleImporter.h b/camera/common/1.0/default/include/HandleImporter.h index e404439cb6..83fa755c99 100644 --- a/camera/common/1.0/default/include/HandleImporter.h +++ b/camera/common/1.0/default/include/HandleImporter.h @@ -61,6 +61,11 @@ public: int unlock(buffer_handle_t& buf); // returns release fence + // Query Gralloc4 metadata + bool isSmpte2086Present(const buffer_handle_t& buf); + bool isSmpte2094_10Present(const buffer_handle_t& buf); + bool isSmpte2094_40Present(const buffer_handle_t& buf); + private: void initializeLocked(); void cleanup(); diff --git a/camera/device/3.8/Android.bp b/camera/device/3.8/Android.bp index 2a1f215023..c3c29416a9 100644 --- a/camera/device/3.8/Android.bp +++ b/camera/device/3.8/Android.bp @@ -9,7 +9,6 @@ package { default_applicable_licenses: ["hardware_interfaces_license"], } - hidl_interface { name: "android.hardware.camera.device@3.8", root: "android.hardware", @@ -17,6 +16,7 @@ hidl_interface { "types.hal", "ICameraDevice.hal", "ICameraDeviceCallback.hal", + "ICameraDeviceSession.hal", ], interfaces: [ "android.hardware.camera.common@1.0", @@ -31,6 +31,7 @@ hidl_interface { "android.hardware.camera.metadata@3.4", "android.hardware.camera.metadata@3.5", "android.hardware.camera.metadata@3.6", + "android.hardware.camera.metadata@3.8", "android.hardware.graphics.common@1.0", "android.hidl.base@1.0", ], diff --git a/camera/device/3.8/ICameraDevice.hal b/camera/device/3.8/ICameraDevice.hal index 1101819a4d..8832c68098 100644 --- a/camera/device/3.8/ICameraDevice.hal +++ b/camera/device/3.8/ICameraDevice.hal @@ -26,8 +26,8 @@ import @3.7::ICameraDevice; * API at LIMITED or better hardware level. * * ICameraDevice.open() must return @3.2::ICameraDeviceSession, - * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, or - * @3.7::ICameraDeviceSession. + * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, + * @3.7::ICameraDeviceSession, or @3.8::ICameraDeviceSession. */ interface ICameraDevice extends @3.7::ICameraDevice { /** @@ -107,4 +107,15 @@ interface ICameraDevice extends @3.7::ICameraDevice { * */ getTorchStrengthLevel() generates (Status status, int32_t torchStrength); + + /** + * isStreamCombinationSupported_3_8: + * + * Identical to @3.7::ICameraDevice.isStreamCombinationSupported, except + * that it takes a @3.8::StreamConfiguration parameter, which could contain + * additional information about a specific 10-bit dynamic range profile. + * + */ + isStreamCombinationSupported_3_8(StreamConfiguration streams) + generates (Status status, bool queryStatus); }; diff --git a/camera/device/3.8/ICameraDeviceSession.hal b/camera/device/3.8/ICameraDeviceSession.hal new file mode 100644 index 0000000000..88e4338209 --- /dev/null +++ b/camera/device/3.8/ICameraDeviceSession.hal @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.camera.device@3.8; + +import android.hardware.camera.common@1.0::Status; +import @3.5::StreamConfiguration; +import @3.7::ICameraDeviceSession; +import @3.6::HalStreamConfiguration; + +/** + * Camera device active session interface. + * + * Obtained via ICameraDevice::open(), this interface contains the methods to + * configure and request captures from an active camera device. + */ +interface ICameraDeviceSession extends @3.7::ICameraDeviceSession { + /** + * configureStreams_3_8: + * + * Identical to @3.7::ICameraDeviceSession.configureStreams_3_7, except that: + * + * - The requestedConfiguration allows the camera framework to configure + * 10-bit dynamic range profile. + * + * @return status Status code for the operation, one of: + * OK: + * On successful stream configuration. + * INTERNAL_ERROR: + * If there has been a fatal error and the device is no longer + * operational. Only close() can be called successfully by the + * framework after this error is returned. + * ILLEGAL_ARGUMENT: + * If the requested stream configuration is invalid. Some examples + * of invalid stream configurations include: + * - Including more than 1 INPUT stream + * - Not including any OUTPUT streams + * - Including streams with unsupported formats, or an unsupported + * size for that format. + * - Including too many output streams of a certain format. + * - Unsupported rotation configuration + * - Stream sizes/formats don't satisfy the + * StreamConfigurationMode requirements + * for non-NORMAL mode, or the requested operation_mode is not + * supported by the HAL. + * - Unsupported usage flag + * - Unsupported stream groupIds, or unsupported multi-resolution + * input stream. + * - Invalid combination between a 10-bit dynamic range profile + * and none impl. defined 8-bit format for a particular stream. + * The camera service cannot filter out all possible illegal stream + * configurations, since some devices may support more simultaneous + * streams or larger stream resolutions than the minimum required + * for a given camera device hardware level. The HAL must return an + * ILLEGAL_ARGUMENT for any unsupported stream set, and then be + * ready to accept a future valid stream configuration in a later + * configureStreams call. + * @return halConfiguration The stream parameters desired by the HAL for + * each stream, including maximum buffers, the usage flags, and the + * override format and dataspace. + */ + configureStreams_3_8(StreamConfiguration requestedConfiguration) + generates (Status status, @3.6::HalStreamConfiguration halConfiguration); + + /** + * repeatingRequestEnd: + * + * Notification about the last frame number in a repeating request along with the + * ids of all streams included in the repeating request. + * + * This can be called at any point after 'processCaptureRequest' in response + * to camera clients disabling an active repeating request. + * + * Performance requirements: + * The call must not be blocked for extensive periods and should be extremely lightweight. There + * must be no frame rate degradation or frame jitter introduced. + * + * This method must always succeed, even if the device has encountered a + * serious error. + */ + repeatingRequestEnd(uint32_t frameNumber, vec<int32_t> streamIds); +}; diff --git a/camera/device/3.8/types.hal b/camera/device/3.8/types.hal index 843d050bb2..9d1ac22f5a 100644 --- a/camera/device/3.8/types.hal +++ b/camera/device/3.8/types.hal @@ -19,6 +19,11 @@ package android.hardware.camera.device@3.8; import @3.2::ErrorMsg; import @3.2::MsgType; import @3.2::ShutterMsg; +import @3.2::CameraMetadata; +import @3.2::StreamConfigurationMode; +import @3.7::Stream; + +import android.hardware.camera.metadata@3.8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap; /** * ShutterMsg: @@ -67,3 +72,75 @@ struct NotifyMsg { ShutterMsg shutter; } msg; }; + +/** + * Stream: + * + * A descriptor for a single camera input or output stream. A stream is defined + * by the framework by its buffer resolution and format, and additionally by the + * HAL with the gralloc usage flags and the maximum in-flight buffer count. + * + * This version extends the @3.7 Stream with the dynamic range profile field. + */ +struct Stream { + /** + * The definition of Stream from the prior version. + */ + @3.7::Stream v3_7; + + /** + * The dynamic range profile for this stream. + * + * This field is valid and must only be considered for streams with format + * android.hardware.graphics.common.PixelFormat.YCBCR_P010 or + * android.hardware.graphics.common.PixelFormat.IMPLEMENTATION_DEFINED on devices supporting the + * ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_10_BIT capability. + * + */ + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap dynamicRangeProfile; +}; + +/** + * StreamConfiguration: + * + * Identical to @3.7::StreamConfiguration, except that the streams + * vector contains @3.8::Stream. + */ +struct StreamConfiguration { + /** + * An array of camera stream pointers, defining the input/output + * configuration for the camera HAL device. + */ + vec<Stream> streams; + + /** + * The definition of operation mode from prior version. + * + */ + @3.2::StreamConfigurationMode operationMode; + + /** + * The definition of session parameters from prior version. + */ + @3.2::CameraMetadata sessionParams; + + /** + * The definition of stream configuration counter from prior version. + */ + uint32_t streamConfigCounter; + + /** + * If an input stream is configured, whether the input stream is expected to + * receive variable resolution images. + * + * This flag can only be set to true if the camera device supports + * multi-resolution input streams by advertising input stream configurations in + * physicalCameraMultiResolutionStreamConfigurations in its physical cameras' + * characteristics. + * + * When this flag is set to true, the input stream's width and height can be + * any one of the supported multi-resolution input stream sizes. + */ + bool multiResolutionInputImage; +}; + diff --git a/camera/metadata/3.8/types.hal b/camera/metadata/3.8/types.hal index 11360da72b..4c70eb9528 100644 --- a/camera/metadata/3.8/types.hal +++ b/camera/metadata/3.8/types.hal @@ -53,6 +53,21 @@ enum CameraMetadataTag : @3.7::CameraMetadataTag { ANDROID_FLASH_INFO_END_3_8, + /** android.request.availableDynamicRangeProfilesMap [static, enum[], ndk_public] + * + * <p>A map of all available 10-bit dynamic range profiles along with their + * capture request constraints.</p> + */ + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP = android.hardware.camera.metadata@3.4::CameraMetadataTag:ANDROID_REQUEST_END_3_4, + + /** android.request.recommendedTenBitDynamicRangeProfile [static, int32, java_public] + * + * <p>Recommended 10-bit dynamic range profile.</p> + */ + ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE, + + ANDROID_REQUEST_END_3_8, + }; /* @@ -66,3 +81,51 @@ enum CameraMetadataEnumAndroidControlVideoStabilizationMode : @3.2::CameraMetadataEnumAndroidControlVideoStabilizationMode { ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION, }; + +/** android.request.availableCapabilities enumeration values added since v3.6 + * @see ANDROID_REQUEST_AVAILABLE_CAPABILITIES + */ +enum CameraMetadataEnumAndroidRequestAvailableCapabilities : + @3.6::CameraMetadataEnumAndroidRequestAvailableCapabilities { + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT, +}; + +/** android.request.availableDynamicRangeProfilesMap enumeration values + * @see ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP + */ +enum CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap : uint32_t { + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD + = 0x1, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 0x2, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 0x4, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS + = 0x8, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF + = 0x10, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO + = 0x20, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM + = 0x40, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO + = 0x80, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF + = 0x100, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO + = 0x200, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM + = 0x400, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO + = 0x800, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000, +}; + +/** android.scaler.availableRecommendedStreamConfigurations enumeration values added since v3.4 + * @see ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS + */ +enum CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations : + @3.4::CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations { + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT + = 0x8, + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8 + = 0x9, +}; diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp index 2c141ee1d6..0e622655df 100644 --- a/camera/provider/2.4/vts/functional/Android.bp +++ b/camera/provider/2.4/vts/functional/Android.bp @@ -51,11 +51,15 @@ cc_test { "android.hardware.camera.device@3.7", "android.hardware.camera.device@3.8", "android.hardware.camera.metadata@3.4", + "android.hardware.camera.metadata@3.8", "android.hardware.camera.provider@2.4", "android.hardware.camera.provider@2.5", "android.hardware.camera.provider@2.6", "android.hardware.camera.provider@2.7", "android.hardware.graphics.common@1.0", + "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@3.0", + "android.hardware.graphics.mapper@4.0", "android.hidl.allocator@1.0", "libgrallocusage", "libhidlmemory", diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index d39850d06d..dd45b0dca8 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -30,6 +30,7 @@ #include <CameraMetadata.h> #include <CameraParameters.h> +#include <HandleImporter.h> #include <android/hardware/camera/device/1.0/ICameraDevice.h> #include <android/hardware/camera/device/3.2/ICameraDevice.h> #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h> @@ -45,7 +46,9 @@ #include <android/hardware/camera/device/3.7/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.7/ICameraInjectionSession.h> #include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h> +#include <android/hardware/camera/device/3.8/ICameraDeviceSession.h> #include <android/hardware/camera/metadata/3.4/types.h> +#include <android/hardware/camera/metadata/3.8/types.h> #include <android/hardware/camera/provider/2.4/ICameraProvider.h> #include <android/hardware/camera/provider/2.5/ICameraProvider.h> #include <android/hardware/camera/provider/2.6/ICameraProvider.h> @@ -97,6 +100,7 @@ using ::android::hardware::camera::common::V1_0::Status; using ::android::hardware::camera::common::V1_0::TorchMode; using ::android::hardware::camera::common::V1_0::TorchModeStatus; using ::android::hardware::camera::common::V1_0::helper::CameraParameters; +using ::android::hardware::camera::common::V1_0::helper::HandleImporter; using ::android::hardware::camera::common::V1_0::helper::Size; using ::android::hardware::camera::device::V1_0::CameraFacing; using ::android::hardware::camera::device::V1_0::CameraFrameMetadata; @@ -129,6 +133,8 @@ using ::android::hardware::camera::metadata::V3_4:: CameraMetadataEnumAndroidSensorInfoColorFilterArrangement; using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag; using ::android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode; +using ::android::hardware::camera::metadata::V3_8:: + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap; using ::android::hardware::camera::provider::V2_4::ICameraProvider; using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; using ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination; @@ -136,7 +142,6 @@ using ::android::hardware::graphics::common::V1_0::BufferUsage; using ::android::hardware::graphics::common::V1_0::Dataspace; using ::android::hardware::graphics::common::V1_0::PixelFormat; using ::android::hidl::allocator::V1_0::IAllocator; -using ::android::hidl::memory::V1_0::IMapper; using ::android::hidl::memory::V1_0::IMemory; using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; using ::android::hidl::manager::V1_0::IServiceManager; @@ -781,13 +786,15 @@ public: sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/, sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/, - sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/); + sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/, + sp<device::V3_8::ICameraDeviceSession> *session3_8 /*out*/); void castInjectionSession( const sp<ICameraDeviceSession>& session, sp<device::V3_7::ICameraInjectionSession>* injectionSession3_7 /*out*/); void castDevice(const sp<device::V3_2::ICameraDevice>& device, int32_t deviceVersion, sp<device::V3_5::ICameraDevice>* device3_5 /*out*/, - sp<device::V3_7::ICameraDevice>* device3_7 /*out*/); + sp<device::V3_7::ICameraDevice>* device3_7 /*out*/, + sp<device::V3_8::ICameraDevice>* device3_8 /*out*/); void createStreamConfiguration( const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2, StreamConfigurationMode configMode, @@ -817,6 +824,16 @@ public: uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, bool maxResolution); + void configureStreams3_8(const std::string& name, int32_t deviceVersion, + sp<ICameraProvider> provider, PixelFormat format, + sp<device::V3_8::ICameraDeviceSession>* session3_8 /*out*/, + V3_2::Stream* previewStream /*out*/, + device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, + bool* supportsPartialResults /*out*/, + uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, + sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, + bool maxResolution, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap prof); void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, @@ -896,6 +913,9 @@ public: static bool isDepthOnly(const camera_metadata_t* staticMeta); static bool isUltraHighResolution(const camera_metadata_t* staticMeta); + static void get10BitDynamicRangeProfiles(const camera_metadata_t* staticMeta, + std::vector<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> *profiles); + static bool is10BitDynamicRangeCapable(const camera_metadata_t* staticMeta); static Status getAvailableOutputStreams(const camera_metadata_t* staticMeta, std::vector<AvailableStream>& outputStreams, @@ -1077,6 +1097,10 @@ protected: expectedPhysicalResults(extraPhysicalResult) {} }; + static void verify10BitMetadata(HandleImporter& importer, + const InFlightRequest& request, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap profile); + // Map from frame number to the in-flight request state typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap; @@ -1105,6 +1129,8 @@ protected: // Camera provider type. std::string mProviderType; + + HandleImporter mHandleImporter; }; Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback( @@ -3342,10 +3368,13 @@ TEST_P(CameraHidlTest, openClose) { sp<device::V3_5::ICameraDeviceSession> sessionV3_5; sp<device::V3_6::ICameraDeviceSession> sessionV3_6; sp<device::V3_7::ICameraDeviceSession> sessionV3_7; + sp<device::V3_8::ICameraDeviceSession> sessionV3_8; castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4, &sessionV3_5, &sessionV3_6, - &sessionV3_7); - if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) { + &sessionV3_7, &sessionV3_8); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_8) { + ASSERT_TRUE(sessionV3_8.get() != nullptr); + } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) { ASSERT_TRUE(sessionV3_7.get() != nullptr); } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) { ASSERT_TRUE(sessionV3_6.get() != nullptr); @@ -3513,14 +3542,17 @@ TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); @@ -3616,9 +3648,11 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; ::android::hardware::camera::device::V3_7::StreamConfiguration config3_7; ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; @@ -3655,8 +3689,9 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { openEmptyDeviceSession(name, mProvider2_6, &cti.session /*out*/, &cti.staticMeta /*out*/, &cti.cameraDevice /*out*/); castSession(cti.session, deviceVersion, &cti.session3_3, &cti.session3_4, - &cti.session3_5, &cti.session3_6, &cti.session3_7); - castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5, &cti.cameraDevice3_7); + &cti.session3_5, &cti.session3_6, &cti.session3_7, &cti.session3_8); + castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5, &cti.cameraDevice3_7, + &cti.cameraDevice3_8); outputStreams.clear(); ASSERT_EQ(Status::OK, getMandatoryConcurrentStreams(cti.staticMeta, &outputStreams)); @@ -3785,14 +3820,17 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); @@ -3998,14 +4036,17 @@ TEST_P(CameraHidlTest, configureStreamsZSLInputOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); Status rc = isZSLModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -4184,9 +4225,10 @@ TEST_P(CameraHidlTest, configureStreamsWithSessionParameters) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) { ASSERT_NE(session3_4, nullptr); } else { @@ -4325,14 +4367,17 @@ TEST_P(CameraHidlTest, configureStreamsPreviewStillOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); // Check if camera support depth only if (isDepthOnly(staticMeta)) { @@ -4459,14 +4504,17 @@ TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); Status rc = isConstrainedModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -4706,14 +4754,17 @@ TEST_P(CameraHidlTest, configureStreamsVideoStillOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); // Check if camera support depth only if (isDepthOnly(staticMeta)) { @@ -4997,6 +5048,20 @@ void CameraHidlTest::processCaptureRequestInternal(uint64_t bufferUsage, ASSERT_EQ(Status::OK, status); ASSERT_EQ(numRequestProcessed, 1u); + if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8) { + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + sp<device::V3_5::ICameraDeviceSession> session3_5; + sp<device::V3_6::ICameraDeviceSession> session3_6; + sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7, &session3_8); + ASSERT_TRUE(session3_8.get() != nullptr); + hidl_vec<int32_t> streamIds = { halStreamConfig.streams[0].id }; + session3_8->repeatingRequestEnd(request.frameNumber, streamIds); + } + { std::unique_lock<std::mutex> l(mLock); while (!inflightReq.errorCodeValid && @@ -5640,6 +5705,188 @@ TEST_P(CameraHidlTest, processUltraHighResolutionRequest) { } } +// Generate and verify 10-bit dynamic range request +TEST_P(CameraHidlTest, process10BitDynamicRangeRequest) { + hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); + uint64_t bufferId = 1; + uint32_t frameNumber = 1; + ::android::hardware::hidl_vec<uint8_t> settings; + + for (const auto& name : cameraDeviceNames) { + int deviceVersion = getCameraDeviceVersion(name, mProviderType); + if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_8) { + continue; + } + std::string version, deviceId; + ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId)); + camera_metadata_t* staticMeta; + Return<void> ret; + sp<ICameraDeviceSession> session; + openEmptyDeviceSession(name, mProvider, &session, &staticMeta); + if (!is10BitDynamicRangeCapable(staticMeta)) { + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + std::vector<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> profileList; + get10BitDynamicRangeProfiles(staticMeta, &profileList); + ASSERT_FALSE(profileList.empty()); + + android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings; + ret = session->constructDefaultRequestSettings( + RequestTemplate::STILL_CAPTURE, + [&defaultSettings](auto status, const auto& req) mutable { + ASSERT_EQ(Status::OK, status); + + const camera_metadata_t* metadata = + reinterpret_cast<const camera_metadata_t*>(req.data()); + size_t expectedSize = req.size(); + int result = validate_camera_metadata_structure(metadata, &expectedSize); + ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED)); + + size_t entryCount = get_camera_metadata_entry_count(metadata); + ASSERT_GT(entryCount, 0u); + defaultSettings = metadata; + }); + ASSERT_TRUE(ret.isOk()); + + const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock(); + settings.setToExternal( + reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(settingsBuffer)), + get_camera_metadata_size(settingsBuffer)); + overrideRotateAndCrop(&settings); + + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + V3_6::HalStreamConfiguration halStreamConfig; + bool supportsPartialResults = false; + bool useHalBufManager = false; + uint32_t partialResultCount = 0; + V3_2::Stream previewStream; + sp<device::V3_8::ICameraDeviceSession> session3_8; + sp<DeviceCb> cb; + for (const auto& profile : profileList) { + configureStreams3_8(name, deviceVersion, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, + &session3_8, &previewStream, &halStreamConfig, + &supportsPartialResults, &partialResultCount, &useHalBufManager, + &cb, 0, /*maxResolution*/ false, profile); + ASSERT_NE(session3_8, nullptr); + + std::shared_ptr<ResultMetadataQueue> resultQueue; + auto resultQueueRet = session3_8->getCaptureResultMetadataQueue( + [&resultQueue](const auto& descriptor) { + 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. + } + }); + ASSERT_TRUE(resultQueueRet.isOk()); + + std::vector<hidl_handle> graphicBuffers; + graphicBuffers.reserve(halStreamConfig.streams.size()); + ::android::hardware::hidl_vec<StreamBuffer> outputBuffers; + outputBuffers.resize(halStreamConfig.streams.size()); + InFlightRequest inflightReq = {static_cast<ssize_t>(halStreamConfig.streams.size()), + false, + supportsPartialResults, + partialResultCount, + std::unordered_set<std::string>(), + resultQueue}; + + size_t k = 0; + for (const auto& halStream : halStreamConfig.streams) { + hidl_handle buffer_handle; + if (useHalBufManager) { + outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, + 0, + buffer_handle, + BufferStatus::OK, + nullptr, + nullptr}; + } else { + allocateGraphicBuffer( + previewStream.width, previewStream.height, + android_convertGralloc1To0Usage(halStream.v3_4.v3_3.v3_2.producerUsage, + halStream.v3_4.v3_3.v3_2.consumerUsage), + halStream.v3_4.v3_3.v3_2.overrideFormat, &buffer_handle); + + graphicBuffers.push_back(buffer_handle); + outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, + bufferId, + buffer_handle, + BufferStatus::OK, + nullptr, + nullptr}; + bufferId++; + } + k++; + } + + StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; + V3_4::CaptureRequest request3_4; + request3_4.v3_2.frameNumber = frameNumber; + request3_4.v3_2.fmqSettingsSize = 0; + request3_4.v3_2.settings = settings; + request3_4.v3_2.inputBuffer = emptyInputBuffer; + request3_4.v3_2.outputBuffers = outputBuffers; + V3_7::CaptureRequest request3_7; + request3_7.v3_4 = request3_4; + request3_7.inputWidth = 0; + request3_7.inputHeight = 0; + + { + std::unique_lock<std::mutex> l(mLock); + mInflightMap.clear(); + mInflightMap.add(frameNumber, &inflightReq); + } + + Status stat = Status::INTERNAL_ERROR; + uint32_t numRequestProcessed = 0; + hidl_vec<BufferCache> cachesToRemove; + Return<void> returnStatus = session3_8->processCaptureRequest_3_7( + {request3_7}, cachesToRemove, + [&stat, &numRequestProcessed](auto s, uint32_t n) { + stat = s; + numRequestProcessed = n; + }); + ASSERT_TRUE(returnStatus.isOk()); + ASSERT_EQ(Status::OK, stat); + ASSERT_EQ(numRequestProcessed, 1u); + + { + std::unique_lock<std::mutex> l(mLock); + while (!inflightReq.errorCodeValid && + ((0 < inflightReq.numBuffersLeft) || (!inflightReq.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(inflightReq.errorCodeValid); + ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); + verify10BitMetadata(mHandleImporter, inflightReq, profile); + } + if (useHalBufManager) { + hidl_vec<int32_t> streamIds(halStreamConfig.streams.size()); + for (size_t i = 0; i < streamIds.size(); i++) { + streamIds[i] = halStreamConfig.streams[i].v3_4.v3_3.v3_2.id; + } + session3_8->signalStreamFlush(streamIds, /*streamConfigCounter*/ 0); + cb->waitForBuffersReturned(); + } + + ret = session3_8->close(); + ASSERT_TRUE(ret.isOk()); + } + } +} + // Generate and verify a burst containing alternating sensor sensitivity values TEST_P(CameraHidlTest, processCaptureRequestBurstISO) { hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); @@ -7448,8 +7695,9 @@ void CameraHidlTest::configureStreams3_7( sp<device::V3_4::ICameraDeviceSession> session3_4; sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; + sp<device::V3_8::ICameraDeviceSession> session3_8; castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6, - session3_7); + session3_7, &session3_8); ASSERT_NE(nullptr, (*session3_7).get()); *useHalBufManager = false; @@ -7497,7 +7745,8 @@ void CameraHidlTest::configureStreams3_7( ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7); sp<device::V3_5::ICameraDevice> cameraDevice3_5 = nullptr; sp<device::V3_7::ICameraDevice> cameraDevice3_7 = nullptr; - castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + sp<device::V3_8::ICameraDevice> cameraDevice3_8 = nullptr; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8); ASSERT_NE(cameraDevice3_7, nullptr); bool supported = false; ret = cameraDevice3_7->isStreamCombinationSupported_3_7( @@ -7530,6 +7779,153 @@ void CameraHidlTest::configureStreams3_7( ASSERT_TRUE(ret.isOk()); } +// Configure streams +void CameraHidlTest::configureStreams3_8( + const std::string& name, int32_t deviceVersion, sp<ICameraProvider> provider, + PixelFormat format, sp<device::V3_8::ICameraDeviceSession>* session3_8 /*out*/, + V3_2::Stream* previewStream /*out*/, + device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, + bool* supportsPartialResults /*out*/, uint32_t* partialResultCount /*out*/, + bool* useHalBufManager /*out*/, sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, + bool maxResolution, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap prof) { + ASSERT_NE(nullptr, session3_8); + ASSERT_NE(nullptr, halStreamConfig); + ASSERT_NE(nullptr, previewStream); + ASSERT_NE(nullptr, supportsPartialResults); + ASSERT_NE(nullptr, partialResultCount); + ASSERT_NE(nullptr, useHalBufManager); + ASSERT_NE(nullptr, outCb); + ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8); + + std::vector<AvailableStream> outputStreams; + ::android::sp<ICameraDevice> device3_x; + ALOGI("configureStreams: Testing camera device %s", name.c_str()); + Return<void> ret; + ret = provider->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_x = device; + }); + ASSERT_TRUE(ret.isOk()); + + camera_metadata_t* staticMeta; + ret = device3_x->getCameraCharacteristics([&](Status s, CameraMetadata metadata) { + ASSERT_EQ(Status::OK, s); + staticMeta = + clone_camera_metadata(reinterpret_cast<const camera_metadata_t*>(metadata.data())); + ASSERT_NE(nullptr, staticMeta); + }); + ASSERT_TRUE(ret.isOk()); + + camera_metadata_ro_entry entry; + auto status = + find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); + if ((0 == status) && (entry.count > 0)) { + *partialResultCount = entry.data.i32[0]; + *supportsPartialResults = (*partialResultCount > 1); + } + + sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta); + sp<ICameraDeviceSession> session; + ret = device3_x->open(cb, [&session](auto status, const auto& newSession) { + ALOGI("device::open returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(newSession, nullptr); + session = newSession; + }); + ASSERT_TRUE(ret.isOk()); + *outCb = cb; + + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + sp<device::V3_5::ICameraDeviceSession> session3_5; + sp<device::V3_6::ICameraDeviceSession> session3_6; + sp<device::V3_7::ICameraDeviceSession> session3_7; + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6, + &session3_7, session3_8); + ASSERT_NE(nullptr, (*session3_8).get()); + + *useHalBufManager = false; + status = find_camera_metadata_ro_entry( + staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry); + if ((0 == status) && (entry.count == 1)) { + *useHalBufManager = (entry.data.u8[0] == + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); + } + + outputStreams.clear(); + Size maxSize; + auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution); + ASSERT_EQ(Status::OK, rc); + free_camera_metadata(staticMeta); + + ::android::hardware::hidl_vec<V3_8::Stream> streams3_8(1); + streams3_8[0].v3_7.groupId = -1; + streams3_8[0].v3_7.sensorPixelModesUsed = { + CameraMetadataEnumAndroidSensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT}; + streams3_8[0].v3_7.v3_4.bufferSize = 0; + streams3_8[0].v3_7.v3_4.v3_2.id = 0; + streams3_8[0].v3_7.v3_4.v3_2.streamType = StreamType::OUTPUT; + streams3_8[0].v3_7.v3_4.v3_2.width = static_cast<uint32_t>(maxSize.width); + streams3_8[0].v3_7.v3_4.v3_2.height = static_cast<uint32_t>(maxSize.height); + streams3_8[0].v3_7.v3_4.v3_2.format = static_cast<PixelFormat>(format); + streams3_8[0].v3_7.v3_4.v3_2.usage = GRALLOC1_CONSUMER_USAGE_CPU_READ; + streams3_8[0].v3_7.v3_4.v3_2.dataSpace = 0; + streams3_8[0].v3_7.v3_4.v3_2.rotation = StreamRotation::ROTATION_0; + streams3_8[0].dynamicRangeProfile = prof; + + ::android::hardware::camera::device::V3_8::StreamConfiguration config3_8; + config3_8.streams = streams3_8; + config3_8.operationMode = StreamConfigurationMode::NORMAL_MODE; + config3_8.streamConfigCounter = streamConfigCounter; + config3_8.multiResolutionInputImage = false; + RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE; + ret = (*session3_8) + ->constructDefaultRequestSettings(reqTemplate, + [&config3_8](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + config3_8.sessionParams = req; + }); + ASSERT_TRUE(ret.isOk()); + + sp<device::V3_5::ICameraDevice> cameraDevice3_5 = nullptr; + sp<device::V3_7::ICameraDevice> cameraDevice3_7 = nullptr; + sp<device::V3_8::ICameraDevice> cameraDevice3_8 = nullptr; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8); + ASSERT_NE(cameraDevice3_8, nullptr); + bool supported = false; + ret = cameraDevice3_8->isStreamCombinationSupported_3_8( + config3_8, [&supported](Status s, bool combStatus) { + ASSERT_TRUE((Status::OK == s) || (Status::METHOD_NOT_SUPPORTED == s)); + if (Status::OK == s) { + supported = combStatus; + } + }); + ASSERT_TRUE(ret.isOk()); + ASSERT_EQ(supported, true); + + if (*session3_8 != nullptr) { + ret = (*session3_8) + ->configureStreams_3_8( + config3_8, + [&](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + *halStreamConfig = halConfig; + if (*useHalBufManager) { + hidl_vec<V3_4::Stream> streams(1); + hidl_vec<V3_2::HalStream> halStreams(1); + streams[0] = streams3_8[0].v3_7.v3_4; + halStreams[0] = halConfig.streams[0].v3_4.v3_3.v3_2; + cb->setCurrentStreamConfig(streams, halStreams); + } + }); + } + *previewStream = streams3_8[0].v3_7.v3_4.v3_2; + ASSERT_TRUE(ret.isOk()); +} + // Configure multiple preview streams using different physical ids. void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, @@ -7604,8 +8000,9 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t sp<device::V3_3::ICameraDeviceSession> session3_3; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; castSession(session, deviceVersion, &session3_3, session3_4, session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); ASSERT_NE(nullptr, (*session3_4).get()); *useHalBufManager = false; @@ -7650,7 +8047,8 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t if (allowUnsupport) { sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; - castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + sp<device::V3_8::ICameraDevice> cameraDevice3_8; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8); bool supported = false; ret = cameraDevice3_5->isStreamCombinationSupported(config3_4, @@ -7843,6 +8241,95 @@ bool CameraHidlTest::isUltraHighResolution(const camera_metadata_t* staticMeta) return false; } +void CameraHidlTest::get10BitDynamicRangeProfiles(const camera_metadata_t* staticMeta, + std::vector<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> *profiles) { + ASSERT_NE(nullptr, staticMeta); + ASSERT_NE(nullptr, profiles); + camera_metadata_ro_entry entry; + std::unordered_set<int32_t> entries; + int rc = find_camera_metadata_ro_entry(staticMeta, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP, &entry); + ASSERT_EQ(rc, 0); + ASSERT_TRUE(entry.count > 0); + ASSERT_EQ(entry.count % 2, 0); + + for (uint32_t i = 0; i < entry.count; i += 2) { + ASSERT_NE(entry.data.i32[i], + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD); + ASSERT_EQ(entries.find(entry.data.i32[i]), entries.end()); + entries.insert(static_cast<int32_t>(entry.data.i32[i])); + profiles->emplace_back( + static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> + (entry.data.i32[i])); + } + + if (!entries.empty()) { + ASSERT_NE(entries.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10), + entries.end()); + } +} + +bool CameraHidlTest::is10BitDynamicRangeCapable(const camera_metadata_t* staticMeta) { + camera_metadata_ro_entry scalarEntry; + int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, + &scalarEntry); + if (rc == 0) { + for (uint32_t i = 0; i < scalarEntry.count; i++) { + if (scalarEntry.data.u8[i] == + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) { + return true; + } + } + } + return false; +} + +void CameraHidlTest::verify10BitMetadata(HandleImporter& importer, + const InFlightRequest& request, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap profile) { + for (const auto& b : request.resultOutputBuffers) { + bool smpte2086Present = importer.isSmpte2086Present(b.buffer.buffer.getNativeHandle()); + bool smpte2094_10Present = importer.isSmpte2094_10Present( + b.buffer.buffer.getNativeHandle()); + bool smpte2094_40Present = importer.isSmpte2094_40Present( + b.buffer.buffer.getNativeHandle()); + + switch (static_cast<uint32_t>(profile)) { + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10: + ASSERT_FALSE(smpte2086Present); + ASSERT_FALSE(smpte2094_10Present); + ASSERT_FALSE(smpte2094_40Present); + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: + ASSERT_TRUE(smpte2086Present); + ASSERT_FALSE(smpte2094_10Present); + ASSERT_FALSE(smpte2094_40Present); + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: + ASSERT_FALSE(smpte2086Present); + ASSERT_FALSE(smpte2094_10Present); + ASSERT_TRUE(smpte2094_40Present); + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO: + ASSERT_FALSE(smpte2086Present); + ASSERT_TRUE(smpte2094_10Present); + ASSERT_FALSE(smpte2094_40Present); + break; + default: + ALOGE("%s: Unexpected 10-bit dynamic range profile: %d", + __FUNCTION__, profile); + ADD_FAILURE(); + } + } +} + bool CameraHidlTest::isDepthOnly(const camera_metadata_t* staticMeta) { camera_metadata_ro_entry scalarEntry; camera_metadata_ro_entry depthEntry; @@ -8006,8 +8493,9 @@ void CameraHidlTest::configureSingleStream( sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); *useHalBufManager = false; status = find_camera_metadata_ro_entry(staticMeta, @@ -8138,12 +8626,19 @@ void CameraHidlTest::configureSingleStream( void CameraHidlTest::castDevice(const sp<device::V3_2::ICameraDevice>& device, int32_t deviceVersion, sp<device::V3_5::ICameraDevice>* device3_5 /*out*/, - sp<device::V3_7::ICameraDevice>* device3_7 /*out*/) { + sp<device::V3_7::ICameraDevice>* device3_7 /*out*/, + sp<device::V3_8::ICameraDevice>* device3_8 /*out*/) { ASSERT_NE(nullptr, device3_5); ASSERT_NE(nullptr, device3_7); + ASSERT_NE(nullptr, device3_8); switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_8: + case CAMERA_DEVICE_API_VERSION_3_8: { + auto castResult = device::V3_8::ICameraDevice::castFrom(device); + ASSERT_TRUE(castResult.isOk()); + *device3_8 = castResult; + } + [[fallthrough]]; case CAMERA_DEVICE_API_VERSION_3_7: { auto castResult = device::V3_7::ICameraDevice::castFrom(device); ASSERT_TRUE(castResult.isOk()); @@ -8192,15 +8687,22 @@ void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_ sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/, sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/, - sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/) { + sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/, + sp<device::V3_8::ICameraDeviceSession> *session3_8 /*out*/) { ASSERT_NE(nullptr, session3_3); ASSERT_NE(nullptr, session3_4); ASSERT_NE(nullptr, session3_5); ASSERT_NE(nullptr, session3_6); ASSERT_NE(nullptr, session3_7); + ASSERT_NE(nullptr, session3_8); switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_8: + case CAMERA_DEVICE_API_VERSION_3_8: { + auto castResult = device::V3_8::ICameraDeviceSession::castFrom(session); + ASSERT_TRUE(castResult.isOk()); + *session3_8 = castResult; + } + [[fallthrough]]; case CAMERA_DEVICE_API_VERSION_3_7: { auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session); ASSERT_TRUE(castResult.isOk()); @@ -9077,8 +9579,9 @@ void CameraHidlTest::verifyBuffersReturned( sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); ASSERT_NE(nullptr, session3_5.get()); hidl_vec<int32_t> streamIds(1); @@ -9320,7 +9823,7 @@ void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) { size_t CONFIG_ENTRY_TYPE_OFFSET = 3; size_t CONFIG_ENTRY_BITFIELD_OFFSET = 4; uint32_t maxPublicUsecase = - ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END; + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8; uint32_t vendorUsecaseStart = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START; uint32_t usecaseMask = (1 << vendorUsecaseStart) - 1; |