Camera: Add 10-bit dynamic range support
Check for supported 10-bit dynamic range profiles during
stream configuration.
When needed, verify incoming process requests for unsupported
dynamic range profile combinations.
Propagate HDR metadata to corresponding registered native windows.
Bug: 195946346
Test: Camera CTS
Change-Id: I3d47418e8186959d7d1772d037755c20f8f37e74
diff --git a/camera/CameraSessionStats.cpp b/camera/CameraSessionStats.cpp
index 28e037f..bc83ec1 100644
--- a/camera/CameraSessionStats.cpp
+++ b/camera/CameraSessionStats.cpp
@@ -112,6 +112,12 @@
return err;
}
+ int dynamicRangeProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
+ if ((err = parcel->readInt32(&dynamicRangeProfile)) != OK) {
+ ALOGE("%s: Failed to read dynamic range profile type from parcel", __FUNCTION__);
+ return err;
+ }
+
mWidth = width;
mHeight = height;
mFormat = format;
@@ -125,6 +131,7 @@
mHistogramType = histogramType;
mHistogramBins = std::move(histogramBins);
mHistogramCounts = std::move(histogramCounts);
+ mDynamicRangeProfile = dynamicRangeProfile;
return OK;
}
@@ -202,6 +209,11 @@
return err;
}
+ if ((err = parcel->writeInt32(mDynamicRangeProfile)) != OK) {
+ ALOGE("%s: Failed to write dynamic range profile type", __FUNCTION__);
+ return err;
+ }
+
return OK;
}
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index 2bccd87..15c9dc9 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -23,6 +23,7 @@
#include <camera/camera2/OutputConfiguration.h>
#include <binder/Parcel.h>
#include <gui/view/Surface.h>
+#include <system/camera_metadata.h>
#include <utils/String8.h>
namespace android {
@@ -76,6 +77,10 @@
return mSensorPixelModesUsed;
}
+int OutputConfiguration::getDynamicRangeProfile() const {
+ return mDynamicRangeProfile;
+}
+
OutputConfiguration::OutputConfiguration() :
mRotation(INVALID_ROTATION),
mSurfaceSetID(INVALID_SET_ID),
@@ -84,7 +89,8 @@
mHeight(0),
mIsDeferred(false),
mIsShared(false),
- mIsMultiResolution(false) {
+ mIsMultiResolution(false),
+ mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
}
OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) :
@@ -165,6 +171,12 @@
ALOGE("%s: Failed to read sensor pixel mode(s) from parcel", __FUNCTION__);
return err;
}
+ int dynamicProfile;
+ if ((err = parcel->readInt32(&dynamicProfile)) != OK) {
+ ALOGE("%s: Failed to read surface dynamic range profile flag from parcel", __FUNCTION__);
+ return err;
+ }
+
mRotation = rotation;
mSurfaceSetID = setID;
mSurfaceType = surfaceType;
@@ -181,6 +193,7 @@
}
mSensorPixelModesUsed = std::move(sensorPixelModesUsed);
+ mDynamicRangeProfile = dynamicProfile;
ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d,"
" physicalCameraId = %s, isMultiResolution = %d", __FUNCTION__, mRotation,
@@ -199,6 +212,7 @@
mIsShared = isShared;
mPhysicalCameraId = physicalId;
mIsMultiResolution = false;
+ mDynamicRangeProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
}
OutputConfiguration::OutputConfiguration(
@@ -207,7 +221,8 @@
int width, int height, bool isShared)
: mGbps(gbps), mRotation(rotation), mSurfaceSetID(surfaceSetID), mSurfaceType(surfaceType),
mWidth(width), mHeight(height), mIsDeferred(false), mIsShared(isShared),
- mPhysicalCameraId(physicalCameraId), mIsMultiResolution(false) { }
+ mPhysicalCameraId(physicalCameraId), mIsMultiResolution(false),
+ mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) { }
status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
@@ -254,6 +269,9 @@
err = parcel->writeParcelableVector(mSensorPixelModesUsed);
if (err != OK) return err;
+ err = parcel->writeInt32(mDynamicRangeProfile ? 1 : 0);
+ if (err != OK) return err;
+
return OK;
}
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index 8ca8920..6d884cb 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -46,6 +46,7 @@
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.4",
+ "android.hardware.camera.device@3.8",
],
compile_multilib: "first",
cflags: [
diff --git a/camera/include/camera/CameraSessionStats.h b/camera/include/camera/CameraSessionStats.h
index c398aca..1209a20 100644
--- a/camera/include/camera/CameraSessionStats.h
+++ b/camera/include/camera/CameraSessionStats.h
@@ -19,6 +19,8 @@
#include <binder/Parcelable.h>
+#include <camera/CameraMetadata.h>
+
namespace android {
namespace hardware {
@@ -60,16 +62,21 @@
// size(mHistogramBins) + 1 = size(mHistogramCounts)
std::vector<int64_t> mHistogramCounts;
+ // Dynamic range profile
+ int mDynamicRangeProfile;
+
CameraStreamStats() :
mWidth(0), mHeight(0), mFormat(0), mDataSpace(0), mUsage(0),
mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
- mMaxHalBuffers(0), mMaxAppBuffers(0), mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {}
+ mMaxHalBuffers(0), mMaxAppBuffers(0), mHistogramType(HISTOGRAM_TYPE_UNKNOWN),
+ mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {}
CameraStreamStats(int width, int height, int format, int dataSpace, int64_t usage,
- int maxHalBuffers, int maxAppBuffers)
+ int maxHalBuffers, int maxAppBuffers, int dynamicRangeProfile)
: mWidth(width), mHeight(height), mFormat(format), mDataSpace(dataSpace),
mUsage(usage), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers),
- mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {}
+ mHistogramType(HISTOGRAM_TYPE_UNKNOWN),
+ mDynamicRangeProfile(dynamicRangeProfile) {}
virtual status_t readFromParcel(const android::Parcel* parcel) override;
virtual status_t writeToParcel(android::Parcel* parcel) const override;
diff --git a/camera/include/camera/camera2/OutputConfiguration.h b/camera/include/camera/camera2/OutputConfiguration.h
index f80ed3a..1631903 100644
--- a/camera/include/camera/camera2/OutputConfiguration.h
+++ b/camera/include/camera/camera2/OutputConfiguration.h
@@ -44,6 +44,7 @@
int getSurfaceType() const;
int getWidth() const;
int getHeight() const;
+ int getDynamicRangeProfile() const;
bool isDeferred() const;
bool isShared() const;
String16 getPhysicalCameraId() const;
@@ -89,7 +90,8 @@
gbpsEqual(other) &&
mPhysicalCameraId == other.mPhysicalCameraId &&
mIsMultiResolution == other.mIsMultiResolution &&
- sensorPixelModesUsedEqual(other));
+ sensorPixelModesUsedEqual(other) &&
+ mDynamicRangeProfile == other.mDynamicRangeProfile);
}
bool operator != (const OutputConfiguration& other) const {
return !(*this == other);
@@ -126,6 +128,9 @@
if (!sensorPixelModesUsedEqual(other)) {
return sensorPixelModesUsedLessThan(other);
}
+ if (mDynamicRangeProfile != other.mDynamicRangeProfile) {
+ return mDynamicRangeProfile < other.mDynamicRangeProfile;
+ }
return gbpsLessThan(other);
}
@@ -150,6 +155,7 @@
String16 mPhysicalCameraId;
bool mIsMultiResolution;
std::vector<int32_t> mSensorPixelModesUsed;
+ int mDynamicRangeProfile;
};
} // namespace params
} // namespace camera2
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 4015417..bd281c8 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -3463,6 +3463,25 @@
*/
ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS = // int32[n]
ACAMERA_REQUEST_START + 17,
+ /**
+ * <p>A map of all available 10-bit dynamic range profiles along with their
+ * capture request constraints.</p>
+ *
+ * <p>Type: int32[n*2] (acamera_metadata_enum_android_request_available_dynamic_range_profiles_map_t)</p>
+ *
+ * <p>This tag may appear in:
+ * <ul>
+ * <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+ * </ul></p>
+ *
+ * <p>Devices supporting the 10-bit output capability
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT">CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT</a>
+ * must list their supported dynamic range profiles. In case the camera is not able to
+ * support every possible profile combination within a single capture request, then the
+ * constraints must be listed here as well.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP = // int32[n*2] (acamera_metadata_enum_android_request_available_dynamic_range_profiles_map_t)
+ ACAMERA_REQUEST_START + 19,
ACAMERA_REQUEST_END,
/**
@@ -9125,6 +9144,97 @@
} acamera_metadata_enum_android_request_available_capabilities_t;
+// ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP
+typedef enum acamera_metadata_enum_acamera_request_available_dynamic_range_profiles_map {
+ /**
+ * <p>8-bit SDR profile which is the default for all non 10-bit output capable devices.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD = 0x1,
+
+ /**
+ * <p>10-bit pixel samples encoded using the Hybrid log-gamma transfer function.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 0x2,
+
+ /**
+ * <p>10-bit pixel samples encoded using the SMPTE ST 2084 transfer function.
+ * This profile utilizes internal static metadata to increase the quality
+ * of the capture.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 0x4,
+
+ /**
+ * <p>10-bit pixel samples encoded using the SMPTE ST 2084 transfer function.
+ * In contrast to HDR10, this profile uses internal per-frame metadata
+ * to further enhance the quality of the capture.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS = 0x8,
+
+ /**
+ * <p>This is a camera mode for Dolby Vision capture optimized for a more scene
+ * accurate capture. This would typically differ from what a specific device
+ * might want to tune for a consumer optimized Dolby Vision general capture.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF
+ = 0x10,
+
+ /**
+ * <p>This is the power optimized mode for 10-bit Dolby Vision HDR Reference Mode.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO
+ = 0x20,
+
+ /**
+ * <p>This is the camera mode for the default Dolby Vision capture mode for the
+ * specific device. This would be tuned by each specific device for consumer
+ * pleasing results that resonate with their particular audience. We expect
+ * that each specific device would have a different look for their default
+ * Dolby Vision capture.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM
+ = 0x40,
+
+ /**
+ * <p>This is the power optimized mode for 10-bit Dolby Vision HDR device specific
+ * capture Mode.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO
+ = 0x80,
+
+ /**
+ * <p>This is the 8-bit version of the Dolby Vision reference capture mode optimized
+ * for scene accuracy.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF
+ = 0x100,
+
+ /**
+ * <p>This is the power optimized mode for 8-bit Dolby Vision HDR Reference Mode.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO
+ = 0x200,
+
+ /**
+ * <p>This is the 8-bit version of device specific tuned and optimized Dolby Vision
+ * capture mode.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM
+ = 0x400,
+
+ /**
+ * <p>This is the power optimized mode for 8-bit Dolby Vision HDR device specific
+ * capture Mode.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO
+ = 0x800,
+
+ /**
+ *
+ */
+ ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000,
+
+} acamera_metadata_enum_android_request_available_dynamic_range_profiles_map_t;
+
// ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
typedef enum acamera_metadata_enum_acamera_scaler_available_stream_configurations {
@@ -9216,6 +9326,20 @@
= 0x7,
/**
+ * <p>If supported, the recommended 10-bit output stream configurations must include
+ * a subset of the advertised <a href="https://developer.android.com/reference/android/graphics/ImageFormat.html#YCBCR_P010">ImageFormat#YCBCR_P010</a> and
+ * <a href="https://developer.android.com/reference/android/graphics/ImageFormat.html#PRIVATE">ImageFormat#PRIVATE</a> outputs that are optimized for power
+ * and performance when registered along with a supported 10-bit dynamic range profile.
+ * see android.hardware.camera2.params.OutputConfiguration#setDynamicRangeProfile for
+ * details.</p>
+ */
+ ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT
+ = 0x8,
+
+ ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8
+ = 0x9,
+
+ /**
* <p>Vendor defined use cases. These depend on the vendor implementation.</p>
*/
ACAMERA_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 8c52a6a..a7ebcf4 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -140,6 +140,40 @@
physicalKeysEntry.data.i32 + physicalKeysEntry.count);
}
+ auto entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ mDynamicProfileMap.emplace(
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+ if (entry.count > 0) {
+ const auto it = std::find(entry.data.i32, entry.data.i32 + entry.count,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT);
+ if (it != entry.data.i32 + entry.count) {
+ entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
+ if (entry.count > 0 || ((entry.count % 2) != 0)) {
+ int standardBitmap = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
+ for (size_t i = 0; i < entry.count; i += 2) {
+ if (entry.data.i32[i] !=
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
+ mDynamicProfileMap.emplace(entry.data.i32[i], entry.data.i32[i+1]);
+ if ((entry.data.i32[i+1] == 0) || (entry.data.i32[i+1] &
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD)) {
+ standardBitmap |= entry.data.i32[i];
+ }
+ } else {
+ ALOGE("%s: Device %s includes unexpected profile entry: 0x%x!",
+ __FUNCTION__, mCameraIdStr.c_str(), entry.data.i32[i]);
+ }
+ }
+ mDynamicProfileMap.emplace(
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ standardBitmap);
+ } else {
+ ALOGE("%s: Device %s supports 10-bit output but doesn't include a dynamic range"
+ " profile map!", __FUNCTION__, mCameraIdStr.c_str());
+ }
+ }
+ }
+
mProviderManager = providerPtr;
// Cache physical camera ids corresponding to this device and also the high
// resolution sensors in this device + physical camera ids
@@ -297,6 +331,7 @@
SurfaceMap surfaceMap;
Vector<int32_t> outputStreamIds;
std::vector<std::string> requestedPhysicalIds;
+ int dynamicProfileBitmap = 0;
if (request.mSurfaceList.size() > 0) {
for (const sp<Surface>& surface : request.mSurfaceList) {
if (surface == 0) continue;
@@ -313,6 +348,8 @@
String8 requestedPhysicalId(
mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
requestedPhysicalIds.push_back(requestedPhysicalId.string());
+ dynamicProfileBitmap |=
+ mConfiguredOutputs.valueAt(index).getDynamicRangeProfile();
} else {
ALOGW("%s: Output stream Id not found among configured outputs!", __FUNCTION__);
}
@@ -348,6 +385,41 @@
String8 requestedPhysicalId(
mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
requestedPhysicalIds.push_back(requestedPhysicalId.string());
+ dynamicProfileBitmap |=
+ mConfiguredOutputs.valueAt(index).getDynamicRangeProfile();
+ }
+ }
+
+ if (dynamicProfileBitmap !=
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
+ for (int i = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
+ i < ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX; i <<= 1) {
+ if ((dynamicProfileBitmap & i) == 0) {
+ continue;
+ }
+
+ const auto& it = mDynamicProfileMap.find(i);
+ if (it != mDynamicProfileMap.end()) {
+ if ((it->second == 0) ||
+ ((it->second & dynamicProfileBitmap) == dynamicProfileBitmap)) {
+ continue;
+ } else {
+ ALOGE("%s: Camera %s: Tried to submit a request with a surfaces that"
+ " reference an unsupported dynamic range profile combination"
+ " 0x%x!", __FUNCTION__, mCameraIdStr.string(),
+ dynamicProfileBitmap);
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ "Request targets an unsupported dynamic range profile"
+ " combination");
+ }
+ } else {
+ ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
+ " references unsupported dynamic range profile 0x%x!",
+ __FUNCTION__, mCameraIdStr.string(), i);
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ "Request targets 10-bit Surface with unsupported dynamic range"
+ " profile");
+ }
}
}
@@ -638,7 +710,7 @@
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
}
- hardware::camera::device::V3_7::StreamConfiguration streamConfiguration;
+ hardware::camera::device::V3_8::StreamConfiguration streamConfiguration;
bool earlyExit = false;
camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
return mDevice->infoPhysical(id);};
@@ -801,6 +873,7 @@
String8 physicalCameraId = String8(outputConfiguration.getPhysicalCameraId());
bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
bool isMultiResolution = outputConfiguration.isMultiResolution();
+ int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
res = SessionConfigurationUtils::checkSurfaceType(numBufferProducers, deferredConsumer,
outputConfiguration.getSurfaceType());
@@ -844,7 +917,7 @@
sp<Surface> surface;
res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
- mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed);
+ mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile);
if (!res.isOk())
return res;
@@ -888,7 +961,8 @@
streamInfo.height, streamInfo.format, streamInfo.dataSpace,
static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
&streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
- outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution);
+ outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution,
+ streamInfo.dynamicRangeProfile);
}
if (err != OK) {
@@ -982,7 +1056,8 @@
overriddenSensorPixelModesUsed,
&surfaceIds,
outputConfiguration.getSurfaceSetID(), isShared,
- outputConfiguration.isMultiResolution(), consumerUsage);
+ outputConfiguration.isMultiResolution(), consumerUsage,
+ outputConfiguration.getDynamicRangeProfile());
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
@@ -995,7 +1070,8 @@
mDeferredStreams.push_back(streamId);
mStreamInfoMap.emplace(std::piecewise_construct, std::forward_as_tuple(streamId),
std::forward_as_tuple(width, height, format, dataSpace, consumerUsage,
- overriddenSensorPixelModesUsed));
+ overriddenSensorPixelModesUsed,
+ outputConfiguration.getDynamicRangeProfile()));
ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
" (%d x %d) stream with format 0x%x.",
@@ -1184,12 +1260,14 @@
const std::vector<int32_t> &sensorPixelModesUsed =
outputConfiguration.getSensorPixelModesUsed();
+ int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
+
for (size_t i = 0; i < newOutputsMap.size(); i++) {
OutputStreamInfo outInfo;
sp<Surface> surface;
res = SessionConfigurationUtils::createSurfaceFromGbp(outInfo,
/*isStreamInfoValid*/ false, surface, newOutputsMap.valueAt(i), mCameraIdStr,
- mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed);
+ mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile);
if (!res.isOk())
return res;
@@ -1546,6 +1624,7 @@
std::vector<sp<Surface>> consumerSurfaces;
const std::vector<int32_t> &sensorPixelModesUsed =
outputConfiguration.getSensorPixelModesUsed();
+ int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
for (auto& bufferProducer : bufferProducers) {
// Don't create multiple streams for the same target surface
ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
@@ -1558,7 +1637,7 @@
sp<Surface> surface;
res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
- mDevice->infoPhysical(physicalId), sensorPixelModesUsed);
+ mDevice->infoPhysical(physicalId), sensorPixelModesUsed, dynamicRangeProfile);
if (!res.isOk())
return res;
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 288f2d7..77cdf9c 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -22,6 +22,7 @@
#include <camera/camera2/OutputConfiguration.h>
#include <camera/camera2/SessionConfiguration.h>
#include <camera/camera2/SubmitInfo.h>
+#include <unordered_map>
#include "CameraOfflineSessionClient.h"
#include "CameraService.h"
@@ -303,6 +304,10 @@
// Stream ID -> OutputConfiguration. Used for looking up Surface by stream/surface index
KeyedVector<int32_t, hardware::camera2::params::OutputConfiguration> mConfiguredOutputs;
+ // Dynamic range profile id -> Supported dynamic profiles bitmap within an single capture
+ // request
+ std::unordered_map<int, int> mDynamicProfileMap;
+
struct InputStreamConfiguration {
bool configured;
int32_t width;
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index c454716..e936cb6 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -182,7 +182,8 @@
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
bool isShared = false, bool isMultiResolution = false,
- uint64_t consumerUsage = 0) = 0;
+ uint64_t consumerUsage = 0,
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) = 0;
/**
* Create an output stream of the requested size, format, rotation and
@@ -199,7 +200,8 @@
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
bool isShared = false, bool isMultiResolution = false,
- uint64_t consumerUsage = 0) = 0;
+ uint64_t consumerUsage = 0,
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) = 0;
/**
* Create an input stream of width, height, and format.
@@ -220,10 +222,12 @@
android_dataspace dataSpace;
bool dataSpaceOverridden;
android_dataspace originalDataSpace;
+ uint32_t dynamicRangeProfile;
StreamInfo() : width(0), height(0), format(0), formatOverridden(false), originalFormat(0),
dataSpace(HAL_DATASPACE_UNKNOWN), dataSpaceOverridden(false),
- originalDataSpace(HAL_DATASPACE_UNKNOWN) {}
+ originalDataSpace(HAL_DATASPACE_UNKNOWN),
+ dynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD){}
/**
* Check whether the format matches the current or the original one in case
* it got overridden.
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 2cdf696..5e8d188 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -267,7 +267,7 @@
}
status_t CameraProviderManager::isSessionConfigurationSupported(const std::string& id,
- const hardware::camera::device::V3_7::StreamConfiguration &configuration,
+ const hardware::camera::device::V3_8::StreamConfiguration &configuration,
bool *status /*out*/) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id);
@@ -2698,7 +2698,7 @@
}
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::isSessionConfigurationSupported(
- const hardware::camera::device::V3_7::StreamConfiguration &configuration,
+ const hardware::camera::device::V3_8::StreamConfiguration &configuration,
bool *status /*out*/) {
const sp<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT> interface =
@@ -2710,6 +2710,8 @@
sp<hardware::camera::device::V3_5::ICameraDevice> interface_3_5 = castResult_3_5;
auto castResult_3_7 = device::V3_7::ICameraDevice::castFrom(interface);
sp<hardware::camera::device::V3_7::ICameraDevice> interface_3_7 = castResult_3_7;
+ auto castResult_3_8 = device::V3_8::ICameraDevice::castFrom(interface);
+ sp<hardware::camera::device::V3_8::ICameraDevice> interface_3_8 = castResult_3_8;
status_t res;
Status callStatus;
@@ -2719,12 +2721,28 @@
callStatus = s;
*status = combStatus;
};
- if (interface_3_7 != nullptr) {
- ret = interface_3_7->isStreamCombinationSupported_3_7(configuration, halCb);
+ if (interface_3_8 != nullptr) {
+ ret = interface_3_8->isStreamCombinationSupported_3_8(configuration, halCb);
+ } else if (interface_3_7 != nullptr) {
+ hardware::camera::device::V3_7::StreamConfiguration configuration_3_7;
+ bool success = SessionConfigurationUtils::convertHALStreamCombinationFromV38ToV37(
+ configuration_3_7, configuration);
+ if (!success) {
+ *status = false;
+ return OK;
+ }
+ ret = interface_3_7->isStreamCombinationSupported_3_7(configuration_3_7, halCb);
} else if (interface_3_5 != nullptr) {
+ hardware::camera::device::V3_7::StreamConfiguration configuration_3_7;
+ bool success = SessionConfigurationUtils::convertHALStreamCombinationFromV38ToV37(
+ configuration_3_7, configuration);
+ if (!success) {
+ *status = false;
+ return OK;
+ }
hardware::camera::device::V3_4::StreamConfiguration configuration_3_4;
- bool success = SessionConfigurationUtils::convertHALStreamCombinationFromV37ToV34(
- configuration_3_4, configuration);
+ success = SessionConfigurationUtils::convertHALStreamCombinationFromV37ToV34(
+ configuration_3_4, configuration_3_7);
if (!success) {
*status = false;
return OK;
@@ -3201,7 +3219,7 @@
status_t res = OK;
for (auto &cameraIdAndSessionConfig : cameraIdsAndSessionConfigs) {
const std::string& cameraId = cameraIdAndSessionConfig.mCameraId;
- hardware::camera::device::V3_7::StreamConfiguration streamConfiguration;
+ hardware::camera::device::V3_8::StreamConfiguration streamConfiguration;
CameraMetadata deviceInfo;
bool overrideForPerfClass =
SessionConfigurationUtils::targetPerfClassPrimaryCamera(
@@ -3235,7 +3253,8 @@
}
CameraIdAndStreamCombination halCameraIdAndStream;
halCameraIdAndStream.cameraId = cameraId;
- halCameraIdAndStream.streamConfiguration = streamConfiguration;
+ SessionConfigurationUtils::convertHALStreamCombinationFromV38ToV37(
+ halCameraIdAndStream.streamConfiguration, streamConfiguration);
halCameraIdsAndStreamsV.push_back(halCameraIdAndStream);
}
*halCameraIdsAndStreamCombinations = halCameraIdsAndStreamsV;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index b03ca62..891c8b1 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -36,6 +36,7 @@
#include <android/hardware/camera/provider/2.6/ICameraProvider.h>
#include <android/hardware/camera/provider/2.7/ICameraProvider.h>
#include <android/hardware/camera/device/3.7/types.h>
+#include <android/hardware/camera/device/3.8/types.h>
#include <android/hidl/manager/1.0/IServiceNotification.h>
#include <camera/VendorTagDescriptor.h>
@@ -243,7 +244,7 @@
* Check for device support of specific stream combination.
*/
status_t isSessionConfigurationSupported(const std::string& id,
- const hardware::camera::device::V3_7::StreamConfiguration &configuration,
+ const hardware::camera::device::V3_8::StreamConfiguration &configuration,
bool *status /*out*/) const;
/**
@@ -532,7 +533,7 @@
}
virtual status_t isSessionConfigurationSupported(
- const hardware::camera::device::V3_7::StreamConfiguration &/*configuration*/,
+ const hardware::camera::device::V3_8::StreamConfiguration &/*configuration*/,
bool * /*status*/) {
return INVALID_OPERATION;
}
@@ -601,7 +602,7 @@
virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
CameraMetadata *characteristics) const override;
virtual status_t isSessionConfigurationSupported(
- const hardware::camera::device::V3_7::StreamConfiguration &configuration,
+ const hardware::camera::device::V3_8::StreamConfiguration &configuration,
bool *status /*out*/)
override;
virtual status_t filterSmallJpegSizes() override;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 2f571a6..4c1e7f0 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -531,6 +531,12 @@
return measured;
}
+CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap
+Camera3Device::mapToHidlDynamicProfile(int dynamicRangeProfile) {
+ return static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>(
+ dynamicRangeProfile);
+}
+
hardware::graphics::common::V1_0::PixelFormat Camera3Device::mapToPixelFormat(
int frameworkFormat) {
return (hardware::graphics::common::V1_0::PixelFormat) frameworkFormat;
@@ -1384,7 +1390,7 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
- uint64_t consumerUsage) {
+ uint64_t consumerUsage, int dynamicRangeProfile) {
ATRACE_CALL();
if (consumer == nullptr) {
@@ -1397,7 +1403,7 @@
return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
format, dataSpace, rotation, id, physicalCameraId, sensorPixelModesUsed, surfaceIds,
- streamSetId, isShared, isMultiResolution, consumerUsage);
+ streamSetId, isShared, isMultiResolution, consumerUsage, dynamicRangeProfile);
}
static bool isRawFormat(int format) {
@@ -1417,7 +1423,7 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const String8& physicalCameraId, const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
- uint64_t consumerUsage) {
+ uint64_t consumerUsage, int dynamicRangeProfile) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
@@ -1495,7 +1501,7 @@
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, blobBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution);
+ isMultiResolution, dynamicRangeProfile);
} else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
bool maxResolution =
sensorPixelModesUsed.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
@@ -1509,22 +1515,22 @@
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution);
+ isMultiResolution, dynamicRangeProfile);
} else if (isShared) {
newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- mUseHalBufManager);
+ mUseHalBufManager, dynamicRangeProfile);
} else if (consumers.size() == 0 && hasDeferredConsumer) {
newStream = new Camera3OutputStream(mNextStreamId,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution);
+ isMultiResolution, dynamicRangeProfile);
} else {
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution);
+ isMultiResolution, dynamicRangeProfile);
}
size_t consumerCount = consumers.size();
@@ -1611,6 +1617,7 @@
streamInfo->originalFormat = stream->getOriginalFormat();
streamInfo->dataSpaceOverridden = stream->isDataSpaceOverridden();
streamInfo->originalDataSpace = stream->getOriginalDataSpace();
+ streamInfo->dynamicRangeProfile = stream->getDynamicRangeProfile();
return OK;
}
@@ -2223,7 +2230,8 @@
streamStats.emplace_back(stream->getWidth(), stream->getHeight(),
stream->getFormat(), stream->getDataSpace(), usage,
stream->getMaxHalBuffers(),
- stream->getMaxTotalBuffers() - stream->getMaxHalBuffers());
+ stream->getMaxTotalBuffers() - stream->getMaxHalBuffers(),
+ stream->getDynamicRangeProfile());
}
}
}
@@ -3144,6 +3152,10 @@
mSupportOfflineProcessing(supportOfflineProcessing) {
// Check with hardware service manager if we can downcast these interfaces
// Somewhat expensive, so cache the results at startup
+ auto castResult_3_8 = device::V3_8::ICameraDeviceSession::castFrom(mHidlSession);
+ if (castResult_3_8.isOk()) {
+ mHidlSession_3_8 = castResult_3_8;
+ }
auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
if (castResult_3_7.isOk()) {
mHidlSession_3_7 = castResult_3_7;
@@ -3181,6 +3193,7 @@
}
void Camera3Device::HalInterface::clear() {
+ mHidlSession_3_8.clear();
mHidlSession_3_7.clear();
mHidlSession_3_6.clear();
mHidlSession_3_5.clear();
@@ -3318,13 +3331,16 @@
device::V3_2::StreamConfiguration requestedConfiguration3_2;
device::V3_4::StreamConfiguration requestedConfiguration3_4;
device::V3_7::StreamConfiguration requestedConfiguration3_7;
+ device::V3_8::StreamConfiguration requestedConfiguration3_8;
requestedConfiguration3_2.streams.resize(config->num_streams);
requestedConfiguration3_4.streams.resize(config->num_streams);
requestedConfiguration3_7.streams.resize(config->num_streams);
+ requestedConfiguration3_8.streams.resize(config->num_streams);
for (size_t i = 0; i < config->num_streams; i++) {
device::V3_2::Stream &dst3_2 = requestedConfiguration3_2.streams[i];
device::V3_4::Stream &dst3_4 = requestedConfiguration3_4.streams[i];
device::V3_7::Stream &dst3_7 = requestedConfiguration3_7.streams[i];
+ device::V3_8::Stream &dst3_8 = requestedConfiguration3_8.streams[i];
camera3::camera_stream_t *src = config->streams[i];
Camera3Stream* cam3stream = Camera3Stream::cast(src);
@@ -3373,6 +3389,15 @@
dst3_7.sensorPixelModesUsed[j++] =
static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
}
+ if ((src->dynamic_range_profile !=
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) &&
+ (mHidlSession_3_8 == nullptr)) {
+ ALOGE("%s: Camera device doesn't support non-standard dynamic range profiles: %d",
+ __FUNCTION__, src->dynamic_range_profile);
+ return BAD_VALUE;
+ }
+ dst3_8.v3_7 = dst3_7;
+ dst3_8.dynamicRangeProfile = mapToHidlDynamicProfile(src->dynamic_range_profile);
activeStreams.insert(streamId);
// Create Buffer ID map if necessary
mBufferRecords.tryCreateBufferCache(streamId);
@@ -3398,6 +3423,10 @@
requestedConfiguration3_7.sessionParams.setToExternal(
reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
sessionParamSize);
+ requestedConfiguration3_8.operationMode = operationMode;
+ requestedConfiguration3_8.sessionParams.setToExternal(
+ reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
+ sessionParamSize);
// Invoke configureStreams
device::V3_3::HalStreamConfiguration finalConfiguration;
@@ -3444,7 +3473,17 @@
};
// See which version of HAL we have
- if (mHidlSession_3_7 != nullptr) {
+ if (mHidlSession_3_8 != nullptr) {
+ ALOGV("%s: v3.8 device found", __FUNCTION__);
+ requestedConfiguration3_8.streamConfigCounter = mNextStreamConfigCounter++;
+ requestedConfiguration3_8.multiResolutionInputImage = config->input_is_multi_resolution;
+ auto err = mHidlSession_3_8->configureStreams_3_8(requestedConfiguration3_8,
+ configStream36Cb);
+ res = postprocConfigStream36(err);
+ if (res != OK) {
+ return res;
+ }
+ } else if (mHidlSession_3_7 != nullptr) {
ALOGV("%s: v3.7 device found", __FUNCTION__);
requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
requestedConfiguration3_7.multiResolutionInputImage = config->input_is_multi_resolution;
@@ -4052,6 +4091,18 @@
return OK;
}
+status_t Camera3Device::HalInterface::repeatingRequestEnd(uint32_t frameNumber,
+ hardware::hidl_vec<int32_t> streamIds) {
+ ATRACE_NAME("CameraHal::repeatingRequestEnd");
+ if (!valid()) return INVALID_OPERATION;
+
+ if (mHidlSession_3_8.get() != nullptr) {
+ mHidlSession_3_8->repeatingRequestEnd(frameNumber, streamIds);
+ }
+
+ return OK;
+}
+
status_t Camera3Device::HalInterface::close() {
ATRACE_NAME("CameraHal::close()");
if (!valid()) return INVALID_OPERATION;
@@ -4386,10 +4437,20 @@
}
status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
+ std::vector<int32_t> streamIds;
+ for (const auto& request : mRepeatingRequests) {
+ for (const auto& stream : request->mOutputStreams) {
+ streamIds.push_back(stream->getId());
+ }
+ }
+
mRepeatingRequests.clear();
if (lastFrameNumber != NULL) {
*lastFrameNumber = mRepeatingLastFrameNumber;
}
+
+ mInterface->repeatingRequestEnd(mRepeatingLastFrameNumber, streamIds);
+
mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
return OK;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 3f069f9..3ce17f9 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -36,6 +36,7 @@
#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.6/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.8/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.2/ICameraDeviceCallback.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
@@ -44,6 +45,7 @@
#include <camera/CaptureResult.h>
+#include "android/hardware/camera/metadata/3.8/types.h"
#include "common/CameraDeviceBase.h"
#include "device3/BufferUtils.h"
#include "device3/StatusTracker.h"
@@ -68,6 +70,7 @@
using android::camera3::camera_stream_configuration_mode_t;
using android::camera3::CAMERA_TEMPLATE_COUNT;
using android::camera3::OutputStreamInfo;
+using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
namespace android {
@@ -141,7 +144,9 @@
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
bool isShared = false, bool isMultiResolution = false,
- uint64_t consumerUsage = 0) override;
+ uint64_t consumerUsage = 0,
+ int dynamicRangeProfile =
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) override;
status_t createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
@@ -151,7 +156,9 @@
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
bool isShared = false, bool isMultiResolution = false,
- uint64_t consumerUsage = 0) override;
+ uint64_t consumerUsage = 0,
+ int dynamicRangeProfile =
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) override;
status_t createInputStream(
uint32_t width, uint32_t height, int format, bool isMultiResolution,
@@ -287,6 +294,8 @@
static hardware::graphics::common::V1_0::PixelFormat mapToPixelFormat(int frameworkFormat);
static hardware::camera::device::V3_2::DataspaceFlags mapToHidlDataspace(
android_dataspace dataSpace);
+ static CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap mapToHidlDynamicProfile(
+ int dynamicRangeProfile);
static hardware::camera::device::V3_2::BufferUsageFlags mapToConsumerUsage(uint64_t usage);
static hardware::camera::device::V3_2::StreamRotation mapToStreamRotation(
camera_stream_rotation_t rotation);
@@ -416,6 +425,8 @@
/*out*/sp<hardware::camera::device::V3_6::ICameraOfflineSession>* offlineSession,
/*out*/camera3::BufferRecords* bufferRecords);
+ status_t repeatingRequestEnd(uint32_t frameNumber, hardware::hidl_vec<int32_t> streamIds);
+
/////////////////////////////////////////////////////////////////////
// Implements BufferRecordsInterface
@@ -458,6 +469,8 @@
sp<hardware::camera::device::V3_6::ICameraDeviceSession> mHidlSession_3_6;
// Valid if ICameraDeviceSession is @3.7 or newer
sp<hardware::camera::device::V3_7::ICameraDeviceSession> mHidlSession_3_7;
+ // Valid if ICameraDeviceSession is @3.8 or newer
+ sp<hardware::camera::device::V3_8::ICameraDeviceSession> mHidlSession_3_8;
std::shared_ptr<RequestMetadataQueue> mRequestMetadataQueue;
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index f4b3197..ba97367 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -34,10 +34,11 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile) :
Camera3Stream(id, type,
width, height, maxSize, format, dataSpace, rotation,
- physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution),
+ physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
+ dynamicRangeProfile),
mTotalBufferCount(0),
mHandoutTotalBufferCount(0),
mHandoutOutputBufferCount(0),
@@ -87,6 +88,7 @@
if (strlen(camera_stream::physical_camera_id) > 0) {
lines.appendFormat(" Physical camera id: %s\n", camera_stream::physical_camera_id);
}
+ lines.appendFormat(" Dynamic Range Profile: 0x%x", camera_stream::dynamic_range_profile);
lines.appendFormat(" Frames produced: %d, last timestamp: %" PRId64 " ns\n",
mFrameCount, mLastTimestamp);
lines.appendFormat(" Total buffers: %zu, currently dequeued: %zu\n",
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index fb73c97..518ee42 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -37,7 +37,8 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
public:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 0dfeac3..69723b6 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -46,10 +46,11 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
- physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution),
+ physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
+ dynamicRangeProfile),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
@@ -74,10 +75,10 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height, maxSize,
format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
- setId, isMultiResolution),
+ setId, isMultiResolution, dynamicRangeProfile),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
@@ -109,10 +110,11 @@
camera_stream_rotation_t rotation, nsecs_t timestampOffset,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
- physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution),
+ physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
+ dynamicRangeProfile),
mConsumer(nullptr),
mTransform(0),
mTraceFirstBuffer(true),
@@ -149,11 +151,13 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
uint64_t consumerUsage, nsecs_t timestampOffset,
- int setId, bool isMultiResolution) :
+ int setId, bool isMultiResolution,
+ int dynamicRangeProfile) :
Camera3IOStreamBase(id, type, width, height,
/*maxSize*/0,
format, dataSpace, rotation,
- physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution),
+ physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
+ dynamicRangeProfile),
mTransform(0),
mTraceFirstBuffer(true),
mUseMonoTimestamp(false),
@@ -379,6 +383,9 @@
__FUNCTION__, mId, strerror(-res), res);
return res;
}
+
+ queueHDRMetadata(anwBuffer->handle, currentConsumer, dynamic_range_profile);
+
res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence, surface_ids);
if (shouldLogError(res, state)) {
ALOGE("%s: Stream %d: Error queueing buffer to native window:"
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index a70b883..d9bf62a 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -89,7 +89,8 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
/**
* Set up a stream for formats that have a variable buffer size for the same
* dimensions, such as compressed JPEG.
@@ -101,7 +102,8 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
/**
* Set up a stream with deferred consumer for formats that have 2 dimensions, such as
* RAW and YUV. The consumer must be set before using this stream for output. A valid
@@ -112,7 +114,8 @@
camera_stream_rotation_t rotation, nsecs_t timestampOffset,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
virtual ~Camera3OutputStream();
@@ -239,7 +242,8 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
uint64_t consumerUsage = 0, nsecs_t timestampOffset = 0,
- int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
/**
* Note that we release the lock briefly in this function
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index 9e0c8f3..0e2671a 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -33,10 +33,10 @@
camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool useHalBufManager) :
+ int setId, bool useHalBufManager, int dynamicProfile) :
Camera3OutputStream(id, CAMERA_STREAM_OUTPUT, width, height,
format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
- consumerUsage, timestampOffset, setId),
+ consumerUsage, timestampOffset, setId, dynamicProfile),
mUseHalBufManager(useHalBufManager) {
size_t consumerCount = std::min(surfaces.size(), kMaxOutputs);
if (surfaces.size() > consumerCount) {
@@ -67,7 +67,7 @@
}
res = mStreamSplitter->connect(initialSurfaces, usage, mUsage, camera_stream::max_buffers,
- getWidth(), getHeight(), getFormat(), &mConsumer);
+ getWidth(), getHeight(), getFormat(), &mConsumer, camera_stream::dynamic_range_profile);
if (res != OK) {
ALOGE("%s: Failed to connect to stream splitter: %s(%d)",
__FUNCTION__, strerror(-res), res);
@@ -388,13 +388,15 @@
bool sizeMismatch = ((static_cast<uint32_t>(infoIt.width) != getWidth()) ||
(static_cast<uint32_t> (infoIt.height) != getHeight())) ?
true : false;
- if ((imgReaderUsage && sizeMismatch) ||
+ bool dynamicRangeMismatch = dynamic_range_profile != infoIt.dynamicRangeProfile;
+ if ((imgReaderUsage && sizeMismatch) || dynamicRangeMismatch ||
(infoIt.format != getOriginalFormat() && infoIt.format != getFormat()) ||
(infoIt.dataSpace != getDataSpace() &&
infoIt.dataSpace != getOriginalDataSpace())) {
- ALOGE("%s: Shared surface parameters format: 0x%x dataSpace: 0x%x "
- " don't match source stream format: 0x%x dataSpace: 0x%x", __FUNCTION__,
- infoIt.format, infoIt.dataSpace, getFormat(), getDataSpace());
+ ALOGE("%s: Shared surface parameters format: 0x%x dataSpace: 0x%x dynamic range 0x%x "
+ " don't match source stream format: 0x%x dataSpace: 0x%x dynamic range 0x%x"
+ , __FUNCTION__, infoIt.format, infoIt.dataSpace, infoIt.dynamicRangeProfile,
+ getFormat(), getDataSpace(), dynamic_range_profile);
return BAD_VALUE;
}
}
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 4b6341b..fafa26f 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -40,7 +40,8 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID,
- bool useHalBufManager = false);
+ bool useHalBufManager = false,
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
virtual ~Camera3SharedOutputStream();
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 1405fa1..83f9a98 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <vector>
+#include "system/window.h"
#define LOG_TAG "Camera3-Stream"
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
@@ -23,6 +25,7 @@
#include "device3/Camera3Stream.h"
#include "device3/StatusTracker.h"
#include "utils/TraceHFR.h"
+#include "ui/GraphicBufferMapper.h"
#include <cutils/properties.h>
@@ -51,7 +54,7 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile) :
camera_stream(),
mId(id),
mSetId(setId),
@@ -87,6 +90,7 @@
camera_stream::max_buffers = 0;
camera_stream::physical_camera_id = mPhysicalCameraId.string();
camera_stream::sensor_pixel_modes_used = sensorPixelModesUsed;
+ camera_stream::dynamic_range_profile = dynamicRangeProfile;
if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
maxSize == 0) {
@@ -147,6 +151,10 @@
return mOriginalFormat;
}
+int Camera3Stream::getDynamicRangeProfile() const {
+ return camera_stream::dynamic_range_profile;
+}
+
void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
mDataSpaceOverridden = dataSpaceOverridden;
}
@@ -1078,6 +1086,52 @@
return res;
}
+void Camera3Stream::queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw,
+ int dynamicRangeProfile) {
+ auto& mapper = GraphicBufferMapper::get();
+ switch (dynamicRangeProfile) {
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: {
+ std::optional<ui::Smpte2086> smpte2086;
+ auto res = mapper.getSmpte2086(buffer, &smpte2086);
+ if ((res == OK) && smpte2086.has_value()) {
+ const auto& metaValue = smpte2086.value();
+ android_smpte2086_metadata meta = {
+ .displayPrimaryRed.x = metaValue.primaryRed.x,
+ .displayPrimaryRed.y = metaValue.primaryRed.y,
+ .displayPrimaryGreen.x = metaValue.primaryGreen.x,
+ .displayPrimaryGreen.y = metaValue.primaryGreen.y,
+ .displayPrimaryBlue.x = metaValue.primaryBlue.x,
+ .displayPrimaryBlue.y = metaValue.primaryBlue.y,
+ .whitePoint.x = metaValue.whitePoint.x,
+ .whitePoint.y = metaValue.whitePoint.y,
+ .maxLuminance = metaValue.maxLuminance,
+ .minLuminance = metaValue.minLuminance};
+ native_window_set_buffers_smpte2086_metadata(anw.get(), &meta);
+ } else {
+ ALOGE("%s Couldn't retrieve Smpte2086 metadata %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+ break;
+ }
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: {
+ std::optional<std::vector<uint8_t>> smpte2094_40;
+ auto res = mapper.getSmpte2094_40(buffer, &smpte2094_40);
+ if ((res == OK) && smpte2094_40.has_value()) {
+ native_window_set_buffers_hdr10_plus_metadata(anw.get(),
+ smpte2094_40.value().size(), smpte2094_40.value().data());
+ } else {
+ ALOGE("%s Couldn't retrieve Smpte2094_40 metadata %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+ break;
+ }
+ default:
+ // No-op
+ break;
+ }
+}
+
+
}; // namespace camera3
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 17041de..bbbea8d 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -138,6 +138,10 @@
static Camera3Stream* cast(camera_stream *stream);
static const Camera3Stream* cast(const camera_stream *stream);
+ // Queue corresponding HDR metadata to given native window.
+ static void queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw,
+ int dynamicRangeProfile);
+
/**
* Get the stream's ID
*/
@@ -168,6 +172,7 @@
void setFormatOverride(bool formatOverriden);
bool isFormatOverridden() const;
int getOriginalFormat() const;
+ int getDynamicRangeProfile() const;
void setDataSpaceOverride(bool dataSpaceOverriden);
bool isDataSpaceOverridden() const;
android_dataspace getOriginalDataSpace() const;
@@ -500,7 +505,7 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution);
+ int setId, bool isMultiResolution, int dynamicRangeProfile);
wp<Camera3StreamBufferFreedListener> mBufferFreedListener;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 5f20f17..ef10f0d 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -64,6 +64,7 @@
const char* physical_camera_id;
std::unordered_set<int32_t> sensor_pixel_modes_used;
+ int dynamic_range_profile;
} camera_stream_t;
typedef struct camera_stream_buffer {
@@ -107,14 +108,17 @@
bool finalized = false;
bool supportsOffline = false;
std::unordered_set<int32_t> sensorPixelModesUsed;
+ int dynamicRangeProfile;
OutputStreamInfo() :
width(-1), height(-1), format(-1), dataSpace(HAL_DATASPACE_UNKNOWN),
- consumerUsage(0) {}
+ consumerUsage(0),
+ dynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {}
OutputStreamInfo(int _width, int _height, int _format, android_dataspace _dataSpace,
- uint64_t _consumerUsage, const std::unordered_set<int32_t>& _sensorPixelModesUsed) :
+ uint64_t _consumerUsage, const std::unordered_set<int32_t>& _sensorPixelModesUsed,
+ int _dynamicRangeProfile) :
width(_width), height(_height), format(_format),
dataSpace(_dataSpace), consumerUsage(_consumerUsage),
- sensorPixelModesUsed(_sensorPixelModesUsed) {}
+ sensorPixelModesUsed(_sensorPixelModesUsed), dynamicRangeProfile(_dynamicRangeProfile){}
};
/**
@@ -154,6 +158,7 @@
virtual uint32_t getWidth() const = 0;
virtual uint32_t getHeight() const = 0;
virtual int getFormat() const = 0;
+ virtual int getDynamicRangeProfile() const = 0;
virtual android_dataspace getDataSpace() const = 0;
virtual void setFormatOverride(bool formatOverriden) = 0;
virtual bool isFormatOverridden() const = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 5c6c518..1149d13 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -34,13 +34,16 @@
#include <cutils/atomic.h>
+#include "Camera3Stream.h"
+
#include "Camera3StreamSplitter.h"
namespace android {
status_t Camera3StreamSplitter::connect(const std::unordered_map<size_t, sp<Surface>> &surfaces,
uint64_t consumerUsage, uint64_t producerUsage, size_t halMaxBuffers, uint32_t width,
- uint32_t height, android::PixelFormat format, sp<Surface>* consumer) {
+ uint32_t height, android::PixelFormat format, sp<Surface>* consumer,
+ int dynamicRangeProfile) {
ATRACE_CALL();
if (consumer == nullptr) {
SP_LOGE("%s: consumer pointer is NULL", __FUNCTION__);
@@ -61,6 +64,7 @@
mMaxHalBuffers = halMaxBuffers;
mConsumerName = getUniqueConsumerName();
+ mDynamicRangeProfile = dynamicRangeProfile;
// Add output surfaces. This has to be before creating internal buffer queue
// in order to get max consumer side buffers.
for (auto &it : surfaces) {
@@ -136,6 +140,7 @@
}
}
mOutputs.clear();
+ mOutputSurfaces.clear();
mOutputSlots.clear();
mConsumerBufferCount.clear();
@@ -258,6 +263,7 @@
// Add new entry into mOutputs
mOutputs[surfaceId] = gbp;
+ mOutputSurfaces[surfaceId] = outputQueue;
mConsumerBufferCount[surfaceId] = maxConsumerBuffers;
if (mConsumerBufferCount[surfaceId] > mMaxHalBuffers) {
SP_LOGW("%s: Consumer buffer count %zu larger than max. Hal buffers: %zu", __FUNCTION__,
@@ -316,6 +322,7 @@
}
}
mOutputs[surfaceId] = nullptr;
+ mOutputSurfaces[surfaceId] = nullptr;
mOutputSlots[gbp] = nullptr;
for (const auto &id : pendingBufferIds) {
decrementBufRefCountLocked(id, surfaceId);
@@ -356,6 +363,14 @@
const BufferTracker& tracker = *(mBuffers[bufferId]);
int slot = getSlotForOutputLocked(output, tracker.getBuffer());
+ if (mOutputSurfaces[surfaceId] != nullptr) {
+ sp<ANativeWindow> anw = mOutputSurfaces[surfaceId];
+ camera3::Camera3Stream::queueHDRMetadata(
+ bufferItem.mGraphicBuffer->getNativeBuffer()->handle, anw, mDynamicRangeProfile);
+ } else {
+ SP_LOGE("%s: Invalid surface id: %zu!", __FUNCTION__, surfaceId);
+ }
+
// In case the output BufferQueue has its own lock, if we hold splitter lock while calling
// queueBuffer (which will try to acquire the output lock), the output could be holding its
// own lock calling releaseBuffer (which will try to acquire the splitter lock), running into
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 4eb455a..827865c 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -19,6 +19,8 @@
#include <unordered_set>
+#include <camera/CameraMetadata.h>
+
#include <gui/IConsumerListener.h>
#include <gui/IProducerListener.h>
#include <gui/BufferItemConsumer.h>
@@ -55,7 +57,8 @@
// with output surfaces.
status_t connect(const std::unordered_map<size_t, sp<Surface>> &surfaces,
uint64_t consumerUsage, uint64_t producerUsage, size_t halMaxBuffers, uint32_t width,
- uint32_t height, android::PixelFormat format, sp<Surface>* consumer);
+ uint32_t height, android::PixelFormat format, sp<Surface>* consumer,
+ int dynamicRangeProfile);
// addOutput adds an output BufferQueue to the splitter. The splitter
// connects to outputQueue as a CPU producer, and any buffers queued
@@ -232,6 +235,7 @@
uint32_t mHeight = 0;
android::PixelFormat mFormat = android::PIXEL_FORMAT_NONE;
uint64_t mProducerUsage = 0;
+ int mDynamicRangeProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
// The attachBuffer call will happen on different thread according to mUseHalBufManager and have
// different timing constraint.
@@ -251,6 +255,9 @@
//Map surface ids -> gbp outputs
std::unordered_map<int, sp<IGraphicBufferProducer> > mOutputs;
+ //Map surface ids -> gbp outputs
+ std::unordered_map<int, sp<Surface>> mOutputSurfaces;
+
//Map surface ids -> consumer buffer count
std::unordered_map<int, size_t > mConsumerBufferCount;
diff --git a/services/camera/libcameraservice/device3/PreviewFrameScheduler.cpp b/services/camera/libcameraservice/device3/PreviewFrameScheduler.cpp
index b64ec0d..6135f9e 100644
--- a/services/camera/libcameraservice/device3/PreviewFrameScheduler.cpp
+++ b/services/camera/libcameraservice/device3/PreviewFrameScheduler.cpp
@@ -196,6 +196,9 @@
return res;
}
+ Camera3Stream::queueHDRMetadata(bufferHolder.anwBuffer.get()->handle, mConsumer,
+ mParent.getDynamicRangeProfile());
+
res = mConsumer->queueBuffer(mConsumer.get(), bufferHolder.anwBuffer.get(),
bufferHolder.releaseFence);
if (res != OK) {
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
index 4f080fe..ca73e4c 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
@@ -59,6 +59,7 @@
"android.hardware.camera.device@3.5",
"android.hardware.camera.device@3.6",
"android.hardware.camera.device@3.7",
+ "android.hardware.camera.device@3.8",
],
fuzz_config: {
cc: [
diff --git a/services/camera/libcameraservice/tests/Android.bp b/services/camera/libcameraservice/tests/Android.bp
index 8757afa..c3f0620 100644
--- a/services/camera/libcameraservice/tests/Android.bp
+++ b/services/camera/libcameraservice/tests/Android.bp
@@ -48,6 +48,7 @@
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.4",
"android.hardware.camera.device@3.7",
+ "android.hardware.camera.device@3.8",
"android.hidl.token@1.0-utils",
],
@@ -121,4 +122,4 @@
test_suites: ["device-tests"],
-}
\ No newline at end of file
+}
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index f6f0539..a35e6f3 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -19,15 +19,18 @@
#include "SessionConfigurationUtils.h"
#include "../api2/DepthCompositeStream.h"
#include "../api2/HeicCompositeStream.h"
+#include "android/hardware/camera/metadata/3.8/types.h"
#include "common/CameraDeviceBase.h"
#include "../CameraService.h"
#include "device3/Camera3Device.h"
#include "device3/Camera3OutputStream.h"
+#include "system/graphics-base-v1.1.h"
using android::camera3::OutputStreamInfo;
using android::camera3::OutputStreamInfo;
using android::hardware::camera2::ICameraDeviceUser;
using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
+using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
namespace android {
namespace camera3 {
@@ -206,6 +209,80 @@
return true;
}
+//check if format is 10-bit compatible
+bool is10bitCompatibleFormat(int32_t format) {
+ switch(format) {
+ case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+ case HAL_PIXEL_FORMAT_YCBCR_P010:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool isDynamicRangeProfileSupported(int dynamicRangeProfile, const CameraMetadata& staticInfo) {
+ if (dynamicRangeProfile == ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
+ // Supported by default
+ return true;
+ }
+
+ camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ bool is10bitDynamicRangeSupported = false;
+ for (size_t i = 0; i < entry.count; ++i) {
+ uint8_t capability = entry.data.u8[i];
+ if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) {
+ is10bitDynamicRangeSupported = true;
+ break;
+ }
+ }
+
+ if (!is10bitDynamicRangeSupported) {
+ return false;
+ }
+
+ switch (dynamicRangeProfile) {
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
+ 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_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_8B_HDR_OEM:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_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:
+ entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
+ for (size_t i = 0; i < entry.count; i += 2) {
+ if (dynamicRangeProfile == entry.data.i32[i]) {
+ return true;
+ }
+ }
+
+ return false;
+ default:
+ return false;
+ }
+
+ return false;
+}
+
+//check if format is 10-bit compatible
+bool is10bitDynamicRangeProfile(int32_t dynamicRangeProfile) {
+ switch (dynamicRangeProfile) {
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
+ 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_10B_HDR_REF:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool isPublicFormat(int32_t format)
{
switch(format) {
@@ -237,7 +314,7 @@
OutputStreamInfo& streamInfo, bool isStreamInfoValid,
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
- const std::vector<int32_t> &sensorPixelModesUsed){
+ const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile){
// bufferProducer must be non-null
if (gbp == nullptr) {
String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
@@ -335,6 +412,21 @@
ALOGE("%s: %s", __FUNCTION__, msg.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
}
+ if (!SessionConfigurationUtils::isDynamicRangeProfileSupported(dynamicRangeProfile,
+ physicalCameraMetadata)) {
+ String8 msg = String8::format("Camera %s: Dynamic range profile 0x%x not supported,"
+ " failed to create output stream", logicalCameraId.string(), dynamicRangeProfile);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ if (SessionConfigurationUtils::is10bitDynamicRangeProfile(dynamicRangeProfile) &&
+ !SessionConfigurationUtils::is10bitCompatibleFormat(format)) {
+ String8 msg = String8::format("Camera %s: No 10-bit supported stream configurations with "
+ "format %#x defined and profile %#x, failed to create output stream",
+ logicalCameraId.string(), format, dynamicRangeProfile);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
if (!isStreamInfoValid) {
streamInfo.width = width;
@@ -343,6 +435,7 @@
streamInfo.dataSpace = dataSpace;
streamInfo.consumerUsage = consumerUsage;
streamInfo.sensorPixelModesUsed = overriddenSensorPixelModes;
+ streamInfo.dynamicRangeProfile = dynamicRangeProfile;
return binder::Status::ok();
}
if (width != streamInfo.width) {
@@ -385,30 +478,33 @@
void mapStreamInfo(const OutputStreamInfo &streamInfo,
camera3::camera_stream_rotation_t rotation, String8 physicalId,
- int32_t groupId, hardware::camera::device::V3_7::Stream *stream /*out*/) {
+ int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
if (stream == nullptr) {
return;
}
- stream->v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
- stream->v3_4.v3_2.width = streamInfo.width;
- stream->v3_4.v3_2.height = streamInfo.height;
- stream->v3_4.v3_2.format = Camera3Device::mapToPixelFormat(streamInfo.format);
+ stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
+ stream->v3_7.v3_4.v3_2.width = streamInfo.width;
+ stream->v3_7.v3_4.v3_2.height = streamInfo.height;
+ stream->v3_7.v3_4.v3_2.format = Camera3Device::mapToPixelFormat(streamInfo.format);
auto u = streamInfo.consumerUsage;
camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
- stream->v3_4.v3_2.usage = Camera3Device::mapToConsumerUsage(u);
- stream->v3_4.v3_2.dataSpace = Camera3Device::mapToHidlDataspace(streamInfo.dataSpace);
- stream->v3_4.v3_2.rotation = Camera3Device::mapToStreamRotation(rotation);
- stream->v3_4.v3_2.id = -1; // Invalid stream id
- stream->v3_4.physicalCameraId = std::string(physicalId.string());
- stream->v3_4.bufferSize = 0;
- stream->groupId = groupId;
- stream->sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
+ stream->v3_7.v3_4.v3_2.usage = Camera3Device::mapToConsumerUsage(u);
+ stream->v3_7.v3_4.v3_2.dataSpace = Camera3Device::mapToHidlDataspace(streamInfo.dataSpace);
+ stream->v3_7.v3_4.v3_2.rotation = Camera3Device::mapToStreamRotation(rotation);
+ stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
+ stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
+ stream->v3_7.v3_4.bufferSize = 0;
+ stream->v3_7.groupId = groupId;
+ stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
size_t idx = 0;
for (auto mode : streamInfo.sensorPixelModesUsed) {
- stream->sensorPixelModesUsed[idx++] =
+ stream->v3_7.sensorPixelModesUsed[idx++] =
static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
}
+ stream->dynamicRangeProfile =
+ static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
+ streamInfo.dynamicRangeProfile);
}
binder::Status checkPhysicalCameraId(
@@ -488,7 +584,7 @@
const SessionConfiguration& sessionConfiguration,
const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
- hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
+ hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit) {
auto operatingMode = sessionConfiguration.getOperatingMode();
@@ -529,7 +625,7 @@
defaultSensorPixelModes[0] =
static_cast<CameraMetadataEnumAndroidSensorPixelMode>(
ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
- streamConfiguration.streams[streamIdx++] = {{{/*streamId*/0,
+ streamConfiguration.streams[streamIdx++].v3_7 = {{{/*streamId*/0,
hardware::camera::device::V3_2::StreamType::INPUT,
static_cast<uint32_t> (sessionConfiguration.getInputWidth()),
static_cast<uint32_t> (sessionConfiguration.getInputHeight()),
@@ -547,6 +643,7 @@
bool deferredConsumer = it.isDeferred();
String8 physicalCameraId = String8(it.getPhysicalCameraId());
+ int dynamicRangeProfile = it.getDynamicRangeProfile();
std::vector<int32_t> sensorPixelModesUsed = it.getSensorPixelModesUsed();
const CameraMetadata &physicalDeviceInfo = getMetadata(physicalCameraId,
overrideForPerfClass);
@@ -578,6 +675,7 @@
if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
streamInfo.consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
}
+ streamInfo.dynamicRangeProfile = it.getDynamicRangeProfile();
if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed,
streamInfo.format, streamInfo.width,
streamInfo.height, metadataChosen, false /*flexibleConsumer*/,
@@ -599,7 +697,7 @@
for (auto& bufferProducer : bufferProducers) {
sp<Surface> surface;
res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
- logicalCameraId, metadataChosen, sensorPixelModesUsed);
+ logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile);
if (!res.isOk())
return res;
@@ -741,6 +839,25 @@
return OK;
}
+bool convertHALStreamCombinationFromV38ToV37(
+ hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37,
+ const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV38) {
+ streamConfigV37.streams.resize(streamConfigV38.streams.size());
+ for (size_t i = 0; i < streamConfigV38.streams.size(); i++) {
+ if (static_cast<int32_t>(streamConfigV38.streams[i].dynamicRangeProfile) !=
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
+ // ICameraDevice older than 3.8 doesn't support 10-bit dynamic range profiles
+ // image
+ return false;
+ }
+ streamConfigV37.streams[i] = streamConfigV38.streams[i].v3_7;
+ }
+ streamConfigV37.operationMode = streamConfigV38.operationMode;
+ streamConfigV37.sessionParams = streamConfigV38.sessionParams;
+
+ return true;
+}
+
bool convertHALStreamCombinationFromV37ToV34(
hardware::camera::device::V3_4::StreamConfiguration &streamConfigV34,
const hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37) {
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index efba9c9..c05b59b 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -24,6 +24,7 @@
#include <android/hardware/camera/device/3.8/types.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.8/ICameraDeviceSession.h>
#include <device3/Camera3StreamInterface.h>
@@ -96,12 +97,20 @@
camera3::OutputStreamInfo& streamInfo, bool isStreamInfoValid,
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
-const std::vector<int32_t> &sensorPixelModesUsed);
-
+const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile);
void mapStreamInfo(const camera3::OutputStreamInfo &streamInfo,
camera3::camera_stream_rotation_t rotation, String8 physicalId, int32_t groupId,
hardware::camera::device::V3_7::Stream *stream /*out*/);
+//check if format is 10-bit output compatible
+bool is10bitCompatibleFormat(int32_t format);
+
+// check if the dynamic range requires 10-bit output
+bool is10bitDynamicRangeProfile(int32_t dynamicRangeProfile);
+
+// Check if the device supports a given dynamicRangeProfile
+bool isDynamicRangeProfileSupported(int dynamicRangeProfile, const CameraMetadata& staticMeta);
+
// Check that the physicalCameraId passed in is spported by the camera
// device.
binder::Status checkPhysicalCameraId(
@@ -122,9 +131,16 @@
convertToHALStreamCombination(const SessionConfiguration& sessionConfiguration,
const String8 &cameraId, const CameraMetadata &deviceInfo,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
- hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
+ hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit);
+// Utility function to convert a V3_8::StreamConfiguration to
+// V3_7::StreamConfiguration. Return false if the original V3_8 configuration cannot
+// be used by older version HAL.
+bool convertHALStreamCombinationFromV38ToV37(
+ hardware::camera::device::V3_7::StreamConfiguration &streamConfigV34,
+ const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV37);
+
// Utility function to convert a V3_7::StreamConfiguration to
// V3_4::StreamConfiguration. Return false if the original V3_7 configuration cannot
// be used by older version HAL.