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
This commit is contained in:
Emilian Peev
2021-12-13 15:13:46 -08:00
parent ffd7f9ce43
commit b5f634fc37
9 changed files with 858 additions and 34 deletions

View File

@@ -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

View File

@@ -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();

View File

@@ -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",
],

View File

@@ -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);
};

View File

@@ -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);
};

View File

@@ -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;
};

View File

@@ -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,
};

View File

@@ -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",

View File

@@ -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;