waylandsink: support HDR10 video playback
upstream status: imx specific
Signed-off-by: Haihua Hu <jared.hu@nxp.com>
diff --git a/ext/wayland/Makefile.am b/ext/wayland/Makefile.am
index ecdb957..9730443 100644
--- a/ext/wayland/Makefile.am
+++ b/ext/wayland/Makefile.am
@@ -6,7 +6,9 @@
linux-dmabuf-unstable-v1-protocol.c \
linux-dmabuf-unstable-v1-client-protocol.h \
alpha-compositing-unstable-v1-protocol.c \
- alpha-compositing-unstable-v1-client-protocol.h
+ alpha-compositing-unstable-v1-client-protocol.h \
+ hdr10-metadata-unstable-v1-protocol.c \
+ hdr10-metadata-unstable-v1-client-protocol.h
libgstwaylandsink_la_SOURCES = \
gstwaylandsink.c \
@@ -20,7 +22,8 @@
nodist_libgstwaylandsink_la_SOURCES = \
viewporter-protocol.c \
linux-dmabuf-unstable-v1-protocol.c \
- alpha-compositing-unstable-v1-protocol.c
+ alpha-compositing-unstable-v1-protocol.c \
+ hdr10-metadata-unstable-v1-protocol.c
libgstwaylandsink_la_CFLAGS = \
$(GST_PLUGINS_BAD_CFLAGS) \
diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
index e9be60e..90758aa 100644
--- a/ext/wayland/gstwaylandsink.c
+++ b/ext/wayland/gstwaylandsink.c
@@ -51,6 +51,7 @@
#include <gst/wayland/wayland.h>
#include <gst/video/videooverlay.h>
+#include <gst/video/gstvideohdr10meta.h>
#include <drm_fourcc.h>
#include <xf86drm.h>
@@ -105,6 +106,7 @@
gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query);
static gboolean gst_wayland_sink_show_frame (GstVideoSink * bsink,
GstBuffer * buffer);
+static void gst_wayland_sink_config_hdr10 (GstWaylandSink *sink, GstBuffer * buf);
/* VideoOverlay interface */
static void gst_wayland_sink_videooverlay_init (GstVideoOverlayInterface *
@@ -391,6 +393,7 @@
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
gst_buffer_replace (&sink->last_buffer, NULL);
+ gst_wayland_sink_config_hdr10 (sink, NULL);
if (sink->window) {
if (gst_wl_window_is_toplevel (sink->window)) {
g_clear_object (&sink->window);
@@ -489,6 +492,14 @@
g_value_set_static_string (&value, gst_wl_shm_format_to_string (fmt));
gst_value_list_append_and_take_value (&shm_list, &value);
}
+ /** FIXME:work around for 10bit format not in the none capsfeature list
+ * need vpu add memory:DMABuf capsfeature when output dmabuf
+ */
+ if (HAS_DCSS()) {
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_static_string (&value, gst_video_format_to_string(GST_VIDEO_FORMAT_NV12_10LE));
+ gst_value_list_append_and_take_value (&shm_list, &value);
+ }
gst_structure_take_value (gst_caps_get_structure (caps, 0), "format",
&shm_list);
@@ -671,6 +682,68 @@
gst_wl_window_render (sink->window, wlbuffer, info);
}
+static void
+gst_wayland_sink_config_hdr10 (GstWaylandSink *sink, GstBuffer * buf)
+{
+ GstVideoHdr10Meta *meta = NULL;
+ GstWlDisplay *display = sink->display;
+ guint32 eotf = 0;
+ guint32 type = 0;
+ guint32 display_primaries_red = 0;
+ guint32 display_primaries_green = 0;
+ guint32 display_primaries_blue = 0;
+ guint32 white_point = 0;
+ guint32 mastering_display_luminance = 0;
+ guint32 max_cll = 0;
+ guint32 max_fall = 0;
+
+ /* buf could be NULL when resize */
+ if (buf)
+ meta = gst_buffer_get_video_hdr10_meta (buf);
+
+ if (meta) {
+ GST_INFO_OBJECT (sink, "redPrimary x=%d y=%d", meta->hdr10meta.redPrimary[0], meta->hdr10meta.redPrimary[1]);
+ GST_INFO_OBJECT (sink, "greenPrimary x=%d y=%d", meta->hdr10meta.greenPrimary[0], meta->hdr10meta.greenPrimary[1]);
+ GST_INFO_OBJECT (sink, "bluePrimary x=%d y=%d", meta->hdr10meta.bluePrimary[0], meta->hdr10meta.bluePrimary[1]);
+ GST_INFO_OBJECT (sink, "whitePoint x=%d y=%d", meta->hdr10meta.whitePoint[0], meta->hdr10meta.whitePoint[1]);
+ GST_INFO_OBJECT (sink, "maxMasteringLuminance %d", meta->hdr10meta.maxMasteringLuminance);
+ GST_INFO_OBJECT (sink, "minMasteringLuminance %d", meta->hdr10meta.minMasteringLuminance);
+ GST_INFO_OBJECT (sink, "maxContentLightLevel %d", meta->hdr10meta.maxContentLightLevel);
+ GST_INFO_OBJECT (sink, "maxFrameAverageLightLevel %d", meta->hdr10meta.maxFrameAverageLightLevel);
+ GST_INFO_OBJECT (sink, "transferCharacteristics %d", meta->hdr10meta.transferCharacteristics);
+ GST_INFO_OBJECT (sink, "colourPrimaries %d", meta->hdr10meta.colourPrimaries);
+ GST_INFO_OBJECT (sink, "matrixCoeffs %d", meta->hdr10meta.matrixCoeffs);
+ GST_INFO_OBJECT (sink, "fullRange %d", meta->hdr10meta.fullRange);
+ GST_INFO_OBJECT (sink, "chromaSampleLocTypeTopField %d", meta->hdr10meta.chromaSampleLocTypeTopField);
+ GST_INFO_OBJECT (sink, "chromaSampleLocTypeBottomField %d", meta->hdr10meta.chromaSampleLocTypeBottomField);
+
+ eotf = SMPTE_ST2084;
+ type = 0;
+ display_primaries_red = (guint)(meta->hdr10meta.redPrimary[0] << 16 | meta->hdr10meta.redPrimary[1]);
+ display_primaries_green = (guint)(meta->hdr10meta.greenPrimary[0] << 16 | meta->hdr10meta.greenPrimary[1]);
+ display_primaries_blue = (guint)(meta->hdr10meta.bluePrimary[0] << 16 | meta->hdr10meta.bluePrimary[1]);
+ white_point = (guint)(meta->hdr10meta.whitePoint[0] << 16 | meta->hdr10meta.whitePoint[1]);
+ mastering_display_luminance = (guint)(((meta->hdr10meta.maxMasteringLuminance / 10000) & 0xffff) << 16
+ | (meta->hdr10meta.minMasteringLuminance & 0xffff));
+ max_cll = meta->hdr10meta.maxContentLightLevel;
+ max_fall = meta->hdr10meta.maxFrameAverageLightLevel;
+ }
+
+ if (display->hdr10_metadata) {
+ zwp_hdr10_metadata_v1_set_metadata (display->hdr10_metadata,
+ eotf,
+ type,
+ display_primaries_red,
+ display_primaries_green,
+ display_primaries_blue,
+ white_point,
+ mastering_display_luminance,
+ max_cll,
+ max_fall);
+ wl_display_roundtrip (display->display);
+ }
+}
+
static GstFlowReturn
gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
{
@@ -713,6 +786,9 @@
gst_wl_window_set_source_crop (sink->window, buffer);
+ if (sink->frame_showed == 0)
+ gst_wayland_sink_config_hdr10 (sink, buffer);
+
wlbuffer = gst_buffer_get_wl_buffer (buffer);
if (G_LIKELY (wlbuffer && wlbuffer->display == sink->display)) {
diff --git a/ext/wayland/wldisplay.c b/ext/wayland/wldisplay.c
index 7ce632d..7a773f9 100644
--- a/ext/wayland/wldisplay.c
+++ b/ext/wayland/wldisplay.c
@@ -90,6 +90,9 @@
if (self->alpha_compositing)
zwp_alpha_compositing_v1_destroy(self->alpha_compositing);
+ if (self->hdr10_metadata)
+ zwp_hdr10_metadata_v1_destroy (self->hdr10_metadata);
+
if (self->shell)
wl_shell_destroy (self->shell);
diff --git a/ext/wayland/wldisplay.h b/ext/wayland/wldisplay.h
index 2a815a7..d34caed 100644
--- a/ext/wayland/wldisplay.h
+++ b/ext/wayland/wldisplay.h
@@ -27,6 +27,7 @@
#include "viewporter-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
#include "alpha-compositing-unstable-v1-client-protocol.h"
+#include "hdr10-metadata-unstable-v1-client-protocol.h"
G_BEGIN_DECLS
@@ -57,6 +58,7 @@
struct wp_viewporter *viewporter;
struct zwp_linux_dmabuf_v1 *dmabuf;
struct zwp_alpha_compositing_v1 *alpha_compositing;
+ struct zwp_hdr10_metadata_v1 *hdr10_metadata;
GArray *shm_formats;
GArray *dmabuf_formats;
diff --git a/ext/wayland/wlvideoformat.c b/ext/wayland/wlvideoformat.c
index 77cfac8..d2138ad 100644
--- a/ext/wayland/wlvideoformat.c
+++ b/ext/wayland/wlvideoformat.c
@@ -110,6 +110,7 @@
{DRM_FORMAT_RGB565, GST_VIDEO_FORMAT_RGB16},
{DRM_FORMAT_YUYV, GST_VIDEO_FORMAT_YUY2},
{DRM_FORMAT_NV12, GST_VIDEO_FORMAT_NV12},
+ {DRM_FORMAT_P010, GST_VIDEO_FORMAT_NV12_10LE},
};
enum wl_shm_format