kmssink: add hdr10 support

upstream status: imx specific

Conflicts:
	sys/kms/gstkmssink.h

Signed-off-by: Haihua Hu <jared.hu@nxp.com>
diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c
index b5c82a5..87023f2 100644
--- a/sys/kms/gstkmssink.c
+++ b/sys/kms/gstkmssink.c
@@ -48,7 +48,8 @@
 #include <gst/allocators/gstdmabufmeta.h>
 #include <gst/allocators/gstphymemmeta.h>
 
-#include <drm.h>
+#include <stdint.h>
+
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 #include <drm_fourcc.h>
@@ -1504,6 +1505,7 @@
       GST_DEBUG ("set global alpha %d to primary plane %d property %d",
           alpha, plane->plane_id, prop->prop_id);
       drmModeObjectSetProperty (self->ctrl_fd, plane->plane_id, DRM_MODE_OBJECT_PLANE, prop->prop_id, alpha);
+      self->primary_plane_id = plane->plane_id;
     }
     drmModeFreeProperty (prop);
     prop = NULL;
@@ -1536,6 +1538,7 @@
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
       self->is_kmsproperty_set = FALSE;
+      memset (&self->hdr10meta, 0, sizeof (self->hdr10meta));
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
     {
@@ -1568,6 +1571,7 @@
         if (self->hold_buf[i])
           gst_buffer_unref (self->hold_buf[i]);
       }
+
       break;
     }
     case GST_STATE_CHANGE_READY_TO_NULL:
@@ -1682,17 +1686,25 @@
 }
 
 void
-dump_hdr10meta (GstKMSSink *self, GstBuffer * buf)
+gst_kms_sink_config_hdr10 (GstKMSSink *self, GstBuffer * buf)
 {
-
+  guint blob_id = 0, prop_id = 0;
+  int err;
+  gint i;
+  drmModeObjectPropertiesPtr props = NULL;
+  drmModePropertyPtr prop = NULL;
   GstVideoHdr10Meta *meta = NULL;
 
+  if (self->conn_id < 0) {
+    GST_ERROR_OBJECT (self, "no connector");
+    return;
+  }
+
   /* buf could be NULL when resize */
   if (buf)
     meta = gst_buffer_get_video_hdr10_meta (buf);
 
-  if (meta){
-    /* TODO: just dump temporarily, to do configure to drm driver for hdr10 in future */
+  if (meta && self->hdr10meta.eotf == 0) {
     GST_INFO_OBJECT (self, "redPrimary x=%d y=%d", meta->hdr10meta.redPrimary[0], meta->hdr10meta.redPrimary[1]);
     GST_INFO_OBJECT (self, "greenPrimary x=%d y=%d", meta->hdr10meta.greenPrimary[0], meta->hdr10meta.greenPrimary[1]);
     GST_INFO_OBJECT (self, "bluePrimary x=%d y=%d", meta->hdr10meta.bluePrimary[0], meta->hdr10meta.bluePrimary[1]);
@@ -1707,6 +1719,48 @@
     GST_INFO_OBJECT (self, "fullRange %d", meta->hdr10meta.fullRange);
     GST_INFO_OBJECT (self, "chromaSampleLocTypeTopField %d", meta->hdr10meta.chromaSampleLocTypeTopField);
     GST_INFO_OBJECT (self, "chromaSampleLocTypeBottomField %d", meta->hdr10meta.chromaSampleLocTypeBottomField);
+
+    /* FIXME: better to use marcos instead of const value */
+    self->hdr10meta.eotf = 2;
+    self->hdr10meta.type = 0;
+    self->hdr10meta.display_primaries_x [0] = meta->hdr10meta.redPrimary[0];
+    self->hdr10meta.display_primaries_x [1] = meta->hdr10meta.greenPrimary[0];
+    self->hdr10meta.display_primaries_x [2] = meta->hdr10meta.bluePrimary[0];
+    self->hdr10meta.display_primaries_y [0] = meta->hdr10meta.redPrimary[1];
+    self->hdr10meta.display_primaries_y [1] = meta->hdr10meta.greenPrimary[1];
+    self->hdr10meta.display_primaries_y [2] = meta->hdr10meta.bluePrimary[1];
+    self->hdr10meta.white_point_x = meta->hdr10meta.whitePoint[0];
+    self->hdr10meta.white_point_y = meta->hdr10meta.whitePoint[1];
+    self->hdr10meta.max_mastering_display_luminance = (meta->hdr10meta.maxMasteringLuminance / 10000) & 0xffff;;
+    self->hdr10meta.min_mastering_display_luminance = meta->hdr10meta.minMasteringLuminance & 0xffff;
+    self->hdr10meta.max_fall = meta->hdr10meta.maxFrameAverageLightLevel;
+    self->hdr10meta.max_cll =  meta->hdr10meta.maxContentLightLevel;
+  
+    props = drmModeObjectGetProperties (self->fd, self->conn_id, DRM_MODE_OBJECT_CONNECTOR);
+    for (i = 0; i < props->count_props; ++i) {
+      prop = drmModeGetProperty(self->fd, props->props[i]);
+      if (!strcmp(prop->name, "HDR_SOURCE_METADATA")) {
+        GST_DEBUG_OBJECT (self, "found HDR_SOURCE_METADATA property on connector %d property id %d",
+            self->conn_id, prop->prop_id);
+        prop_id = prop->prop_id;
+      }
+      drmModeFreeProperty (prop);
+      prop = NULL;
+    }
+
+    if (prop_id == 0) {
+      GST_WARNING_OBJECT (self, "no HDR_SOURCE_METADATA property found");
+      return;
+    }
+
+    drmModeCreatePropertyBlob (self->fd, &self->hdr10meta, sizeof (self->hdr10meta), &blob_id);
+    GST_INFO_OBJECT (self, "create blob id %d", blob_id);
+    err = drmModeObjectSetProperty (self->ctrl_fd, self->conn_id, DRM_MODE_OBJECT_CONNECTOR, prop_id, blob_id);
+    drmModeDestroyPropertyBlob (self->fd, blob_id);
+    if (err) {
+      GST_ERROR_OBJECT (self, "set blob property fail");
+      return;
+    }
   }
 }
 
@@ -1743,8 +1797,6 @@
   gboolean can_scale = TRUE;
   guint32 fmt, alignment;
   
-  dump_hdr10meta (GST_KMS_SINK (vsink), buf);
-
   self = GST_KMS_SINK (vsink);
 
   res = GST_FLOW_ERROR;
@@ -1773,6 +1825,9 @@
 
   if (!buffer)
     return GST_FLOW_ERROR;
+  
+  gst_kms_sink_config_hdr10 (self, buffer);
+
   fb_id = gst_kms_memory_get_fb_id (gst_buffer_peek_memory (buffer, 0));
   if (fb_id == 0)
     goto buffer_invalid;
@@ -2098,6 +2153,7 @@
   sink->fd = -1;
   sink->conn_id = -1;
   sink->plane_id = -1;
+  sink->primary_plane_id = -1;
   sink->can_scale = TRUE;
   sink->scale_checked = FALSE;
   sink->upscale_ratio = 1;
diff --git a/sys/kms/gstkmssink.h b/sys/kms/gstkmssink.h
index 25c6ee0..28ad9cd 100644
--- a/sys/kms/gstkmssink.h
+++ b/sys/kms/gstkmssink.h
@@ -26,6 +26,8 @@
 #ifndef __GST_KMS_SINK_H__
 #define __GST_KMS_SINK_H__
 
+#include <drm.h>
+
 #include <gst/video/gstvideosink.h>
 
 G_BEGIN_DECLS
@@ -55,6 +57,7 @@
   gint conn_id;
   gint crtc_id;
   gint plane_id;
+  gint primary_plane_id;
   guint pipe;
 
   /* fps print support */
@@ -82,6 +85,9 @@
   gboolean display_connected;
   gboolean hantro_tile_enabled;
 
+  /* hdr10 support */
+  struct hdr_static_metadata hdr10meta;
+
   GstVideoInfo vinfo;
   GstCaps *allowed_caps;
   GstBufferPool *pool;
diff --git a/sys/kms/gstkmsutils.c b/sys/kms/gstkmsutils.c
index 2816f00..90961ca 100644
--- a/sys/kms/gstkmsutils.c
+++ b/sys/kms/gstkmsutils.c
@@ -27,6 +27,8 @@
 #include "config.h"
 #endif
 
+#include <stdint.h>
+
 #include <drm_fourcc.h>
 #include <dirent.h>
 #include <string.h>
@@ -62,9 +64,7 @@
   DEF_FMT (YVU420, YV12),
   DEF_FMT (YUV422, Y42B),
   DEF_FMT (NV12, NV12),
-  /* FIXME: just hack for debug usage, need 
-   * drm driver owner add 10bit fourcc format */
-  DEF_FMT (NV12, NV12_10LE),
+  DEF_FMT (P010, NV12_10LE),
   DEF_FMT (NV21, NV21),
   DEF_FMT (NV16, NV16),