[MMFMWK-7905] kmssink: add hdr10 support
upstream status: imx specific
diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c
index 86fa1ce..a59ea2e 100644
--- a/sys/kms/gstkmssink.c
+++ b/sys/kms/gstkmssink.c
@@ -48,9 +48,8 @@
#include <gst/allocators/gstdmabufmeta.h>
#include <gst/allocators/gstphymemmeta.h>
-#include <drm.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
+#include <stdint.h>
+
#include <drm_fourcc.h>
#include <string.h>
@@ -1452,6 +1451,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;
@@ -1484,6 +1484,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:
{
@@ -1516,6 +1517,17 @@
if (self->hold_buf[i])
gst_buffer_unref (self->hold_buf[i]);
}
+
+ if (self->old_crtc) {
+ gint err;
+ err = drmModeSetCrtc (self->ctrl_fd, self->crtc_id, self->old_crtc->buffer_id, 0, 0,
+ (uint32_t *) & self->conn_id, 1, & self->old_crtc->mode);
+ if (err) {
+ GST_ERROR_OBJECT (self, "set crtc fail");
+ }
+ drmModeFreeCrtc (self->old_crtc);
+ }
+ self->old_crtc = NULL;
break;
}
case GST_STATE_CHANGE_READY_TO_NULL:
@@ -1618,17 +1630,36 @@
}
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;
+ guint32 fb_id;
+ drmModeConnector *conn = NULL;
+ drmModeModeInfo *mode = NULL;
+ drmModeObjectPropertiesPtr props = NULL;
+ drmModePropertyPtr prop = NULL;
GstVideoHdr10Meta *meta = NULL;
+ GstKMSMemory *kmsmem = NULL;
+ GstVideoInfo vinfo;
+
+ 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) {
+ conn = drmModeGetConnector (self->fd, self->conn_id);
+ if (!conn) {
+ GST_ERROR_OBJECT (self, "no connector res");
+ return;
+ }
+
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]);
@@ -1643,7 +1674,90 @@
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 = 0x8a48;
+ 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;
+ self->hdr10meta.min_mastering_display_luminance = meta->hdr10meta.minMasteringLuminance;
+ 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");
+ goto bail;
+ }
+
+ 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");
+ goto bail;
+ }
+
+ GST_DEBUG_OBJECT (self, "set blob property success, continue to setCrtc");
+
+ /* FIXME: temporarily we can only enable HDR10 on 4k@60fps mode */
+ for (i = 0; i < conn->count_modes; i++) {
+ if (conn->modes[i].vdisplay == 2160 &&
+ conn->modes[i].hdisplay == 3840 &&
+ conn->modes[i].vrefresh == 60) {
+ mode = &conn->modes[i];
+ break;
+ }
+ }
+
+ if (!mode) {
+ GST_ERROR_OBJECT (self, "4k@60fps mode not found");
+ goto bail;
+ }
+
+ gst_video_info_init (&vinfo);
+ gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_NV12_10LE, mode->hdisplay, mode->vdisplay);
+
+ ensure_kms_allocator (self);
+
+ kmsmem = (GstKMSMemory *) gst_kms_allocator_bo_alloc (self->allocator, &vinfo);
+ if (!kmsmem)
+ goto bail;
+
+ fb_id = kmsmem->fb_id;
+
+ self->old_crtc = drmModeGetCrtc (self->fd, self->crtc_id);
+
+ err = drmModeSetCrtc (self->ctrl_fd, self->crtc_id, fb_id, 0, 0,
+ (uint32_t *) & self->conn_id, 1, mode);
+ if (err) {
+ GST_ERROR_OBJECT (self, "set crtc fail");
+ goto bail;
+ }
+ self->hdr10_mem = kmsmem;
}
+bail:
+ if (conn)
+ drmModeFreeConnector (conn);
}
static gboolean
@@ -1679,8 +1793,6 @@
gboolean can_scale = TRUE;
guint32 fmt, alignment;
- dump_hdr10meta (GST_KMS_SINK (vsink), buf);
-
self = GST_KMS_SINK (vsink);
res = GST_FLOW_ERROR;
@@ -1706,6 +1818,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;
@@ -1822,6 +1937,7 @@
if (buffer != self->last_buffer)
gst_buffer_replace (&self->last_buffer, buffer);
g_clear_pointer (&self->tmp_kmsmem, gst_memory_unref);
+ g_clear_pointer (&self->hdr10_mem, gst_memory_unref);
GST_OBJECT_UNLOCK (self);
res = GST_FLOW_OK;
@@ -1962,11 +2078,13 @@
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;
sink->downscale_ratio = 1;
sink->hantro_tile_enabled = FALSE;
+ sink->old_crtc = NULL;
gst_poll_fd_init (&sink->pollfd);
sink->poll = gst_poll_new (TRUE);
gst_video_info_init (&sink->vinfo);
diff --git a/sys/kms/gstkmssink.h b/sys/kms/gstkmssink.h
index 24222fd..3db971b 100644
--- a/sys/kms/gstkmssink.h
+++ b/sys/kms/gstkmssink.h
@@ -26,7 +26,9 @@
#ifndef __GST_KMS_SINK_H__
#define __GST_KMS_SINK_H__
-#include <stdint.h>
+#include <drm.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
#include <gst/video/gstvideosink.h>
@@ -57,6 +59,7 @@
gint conn_id;
gint crtc_id;
gint plane_id;
+ gint primary_plane_id;
guint pipe;
/* fps print support */
@@ -83,6 +86,11 @@
gboolean display_connected;
gboolean hantro_tile_enabled;
+ /* hdr10 support */
+ struct hdr_static_metadata hdr10meta;
+ drmModeCrtcPtr old_crtc;
+ GstMemory *hdr10_mem;
+
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),