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