Camera: Add device 3.8 and HDR10 native APIs
Initial set of native API extensions to support 10-bit
output capable device:
- Identification
- Configuration
- Data plumbing
Bug: 195946346
Test: adb shell
/data/nativetest64/VtsHalCameraProviderV2_4TargetTest/VtsHalCameraProviderV2_4TargetTest
--gtest_filter=PerInstance/CameraHidlTest.process10BitDynamicRangeRequest/0_internal_0
Change-Id: I526120944232ce211259cbd215935db7e445a6c5
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
index 7fcf523..fbe8686 100644
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ b/camera/common/1.0/default/HandleImporter.cpp
@@ -30,6 +30,7 @@
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 @@
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 @@
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 e404439..83fa755 100644
--- a/camera/common/1.0/default/include/HandleImporter.h
+++ b/camera/common/1.0/default/include/HandleImporter.h
@@ -61,6 +61,11 @@
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 2a1f215..c3c2941 100644
--- a/camera/device/3.8/Android.bp
+++ b/camera/device/3.8/Android.bp
@@ -9,7 +9,6 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-
hidl_interface {
name: "android.hardware.camera.device@3.8",
root: "android.hardware",
@@ -17,6 +16,7 @@
"types.hal",
"ICameraDevice.hal",
"ICameraDeviceCallback.hal",
+ "ICameraDeviceSession.hal",
],
interfaces: [
"android.hardware.camera.common@1.0",
@@ -31,6 +31,7 @@
"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 1101819..8832c68 100644
--- a/camera/device/3.8/ICameraDevice.hal
+++ b/camera/device/3.8/ICameraDevice.hal
@@ -26,8 +26,8 @@
* 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 @@
*
*/
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 0000000..88e4338
--- /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 843d050..9d1ac22 100644
--- a/camera/device/3.8/types.hal
+++ b/camera/device/3.8/types.hal
@@ -19,6 +19,11 @@
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 @@
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 11360da..4c70eb9 100644
--- a/camera/metadata/3.8/types.hal
+++ b/camera/metadata/3.8/types.hal
@@ -53,6 +53,21 @@
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 @@
@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 2c141ee..0e62265 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -51,11 +51,15 @@
"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 d39850d..dd45b0d 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::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 @@
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::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 @@
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 @@
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 @@
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 @@
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 @@
// Camera provider type.
std::string mProviderType;
+
+ HandleImporter mHandleImporter;
};
Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback(
@@ -3342,10 +3368,13 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
+// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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::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 @@
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 @@
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 @@
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;