Adding HDR10+ metadata support for media API
Bug: 118343714
Test: build, boot, run libgui_test
Change-Id: Ifa5ccb31083d920f1162ea892de0be047f5b88a1
diff --git a/libs/gui/HdrMetadata.cpp b/libs/gui/HdrMetadata.cpp
index b715e43..add3ef0 100644
--- a/libs/gui/HdrMetadata.cpp
+++ b/libs/gui/HdrMetadata.cpp
@@ -15,6 +15,7 @@
*/
#include <gui/HdrMetadata.h>
+#include <limits>
namespace android {
@@ -26,6 +27,10 @@
if (validTypes & CTA861_3) {
size += sizeof(cta8613);
}
+ if (validTypes & HDR10PLUS) {
+ size += sizeof(size_t);
+ size += hdr10plus.size();
+ }
return size;
}
@@ -41,6 +46,12 @@
if (validTypes & CTA861_3) {
FlattenableUtils::write(buffer, size, cta8613);
}
+ if (validTypes & HDR10PLUS) {
+ size_t metadataSize = hdr10plus.size();
+ FlattenableUtils::write(buffer, size, metadataSize);
+ memcpy(buffer, hdr10plus.data(), metadataSize);
+ FlattenableUtils::advance(buffer, size, metadataSize);
+ }
return NO_ERROR;
}
@@ -62,6 +73,22 @@
}
FlattenableUtils::read(buffer, size, cta8613);
}
+ if (validTypes & HDR10PLUS) {
+ if (size < sizeof(size_t)) {
+ return NO_MEMORY;
+ }
+
+ size_t metadataSize;
+ FlattenableUtils::read(buffer, size, metadataSize);
+
+ if (size < metadataSize) {
+ return NO_MEMORY;
+ }
+
+ hdr10plus.resize(metadataSize);
+ memcpy(hdr10plus.data(), buffer, metadataSize);
+ FlattenableUtils::advance(buffer, size, metadataSize);
+ }
return NO_ERROR;
}
@@ -91,6 +118,10 @@
}
}
+ if ((validTypes & HDR10PLUS) == HDR10PLUS) {
+ if (hdr10plus != rhs.hdr10plus) return false;
+ }
+
return true;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index b505c6f..00e23f0 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -965,6 +965,9 @@
case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA:
res = dispatchSetBuffersCta8613Metadata(args);
break;
+ case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA:
+ res = dispatchSetBuffersHdr10PlusMetadata(args);
+ break;
case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
res = dispatchSetSurfaceDamage(args);
break;
@@ -1120,6 +1123,12 @@
return setBuffersCta8613Metadata(metadata);
}
+int Surface::dispatchSetBuffersHdr10PlusMetadata(va_list args) {
+ const size_t size = va_arg(args, size_t);
+ const uint8_t* metadata = va_arg(args, const uint8_t*);
+ return setBuffersHdr10PlusMetadata(size, metadata);
+}
+
int Surface::dispatchSetSurfaceDamage(va_list args) {
android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
size_t numRects = va_arg(args, size_t);
@@ -1568,6 +1577,19 @@
return NO_ERROR;
}
+int Surface::setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata) {
+ ALOGV("Surface::setBuffersBlobMetadata");
+ Mutex::Autolock lock(mMutex);
+ if (size > 0) {
+ mHdrMetadata.hdr10plus.assign(metadata, metadata + size);
+ mHdrMetadata.validTypes |= HdrMetadata::HDR10PLUS;
+ } else {
+ mHdrMetadata.validTypes &= ~HdrMetadata::HDR10PLUS;
+ mHdrMetadata.hdr10plus.clear();
+ }
+ return NO_ERROR;
+}
+
Dataspace Surface::getBuffersDataSpace() {
ALOGV("Surface::getBuffersDataSpace");
Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/include/gui/HdrMetadata.h b/libs/gui/include/gui/HdrMetadata.h
index 9800602..1e9c3e7 100644
--- a/libs/gui/include/gui/HdrMetadata.h
+++ b/libs/gui/include/gui/HdrMetadata.h
@@ -17,6 +17,7 @@
#pragma once
#include <stdint.h>
+#include <vector>
#include <system/graphics.h>
#include <utils/Flattenable.h>
@@ -26,12 +27,15 @@
struct HdrMetadata : public LightFlattenable<HdrMetadata> {
enum Type : uint32_t {
SMPTE2086 = 1 << 0,
- CTA861_3 = 1 << 1,
+ CTA861_3 = 1 << 1,
+ HDR10PLUS = 1 << 2,
};
+
uint32_t validTypes{0};
android_smpte2086_metadata smpte2086{};
android_cta861_3_metadata cta8613{};
+ std::vector<uint8_t> hdr10plus{};
// LightFlattenable
bool isFixedSize() const { return false; }
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 32ee595..248e105 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -218,6 +218,7 @@
int dispatchSetBuffersDataSpace(va_list args);
int dispatchSetBuffersSmpte2086Metadata(va_list args);
int dispatchSetBuffersCta8613Metadata(va_list args);
+ int dispatchSetBuffersHdr10PlusMetadata(va_list args);
int dispatchSetSurfaceDamage(va_list args);
int dispatchSetSharedBufferMode(va_list args);
int dispatchSetAutoRefresh(va_list args);
@@ -249,6 +250,7 @@
virtual int setBuffersDataSpace(ui::Dataspace dataSpace);
virtual int setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata);
virtual int setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata);
+ virtual int setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata);
virtual int setCrop(Rect const* rect);
virtual int setUsage(uint64_t reqUsage);
virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index d0600da..4ba7da3 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -366,10 +366,17 @@
78.0,
62.0,
};
+
+ std::vector<uint8_t> hdr10plus;
+ hdr10plus.push_back(0xff);
+
int error = native_window_set_buffers_smpte2086_metadata(window.get(), &smpte2086);
ASSERT_EQ(error, NO_ERROR);
error = native_window_set_buffers_cta861_3_metadata(window.get(), &cta861_3);
ASSERT_EQ(error, NO_ERROR);
+ error = native_window_set_buffers_hdr10_plus_metadata(window.get(), hdr10plus.size(),
+ hdr10plus.data());
+ ASSERT_EQ(error, NO_ERROR);
}
TEST_F(SurfaceTest, DynamicSetBufferCount) {
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index 197f73f..61590e0 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -202,7 +202,7 @@
* ANativeWindow.
*/
enum {
-// clang-format off
+ // clang-format off
NATIVE_WINDOW_SET_USAGE = 0, /* deprecated */
NATIVE_WINDOW_CONNECT = 1, /* deprecated */
NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */
@@ -237,7 +237,8 @@
NATIVE_WINDOW_GET_CONSUMER_USAGE64 = 31,
NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA = 32,
NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33,
-// clang-format on
+ NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA = 34,
+ // clang-format on
};
/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */
@@ -748,6 +749,27 @@
}
/*
+ * native_window_set_buffers_hdr10_plus_metadata(..., metadata)
+ * All buffers queued after this call will be associated with the
+ * HDR10+ dynamic metadata specified.
+ *
+ * metadata specifies additional dynamic information about the
+ * contents of the buffer that may affect how it is displayed. When
+ * it is nullptr, it means no such information is available. No
+ * HDR10+ dynamic emtadata is associated with the buffers by default.
+ *
+ * Parameter "size" refers to the length of the metadata blob pointed to
+ * by parameter "data". The metadata blob will adhere to the HDR10+ SEI
+ * message standard.
+ */
+static inline int native_window_set_buffers_hdr10_plus_metadata(struct ANativeWindow* window,
+ const size_t size,
+ const uint8_t* metadata) {
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA, size,
+ metadata);
+}
+
+/*
* native_window_set_buffers_transform(..., int transform)
* All buffers queued after this call will be displayed transformed according
* to the transform parameter specified.