gst-amlv4l2dec: CF1 support HDR info [1/1]

PD#SWPL-85659

Problem:
support hdr info when recv caps with colorimetry and mastering-display-metadata

Solution:
add new flow

Verify:
(detail info)

Change-Id: Ieceb7fc0815767fdb97530054cc922f39293503b
Signed-off-by: xuesong.jiang <xuesong.jiang@amlogic.com>
diff --git a/src/gstamlv4l2object.c b/src/gstamlv4l2object.c
index 40c4c72..ee00acf 100644
--- a/src/gstamlv4l2object.c
+++ b/src/gstamlv4l2object.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/ioctl.h>
+#include <stdio.h>
 
 #ifdef HAVE_GUDEV
 #include <gudev/gudev.h>
@@ -52,6 +53,11 @@
 #define ENCODED_BUFFER_SIZE (2 * 1024 * 1024)
 #define DEFAULT_EXTRA_CAPTURE_BUF_SIZE 3
 
+#define V4L2_CONFIG_PARM_DECODE_CFGINFO (1 << 0)
+#define V4L2_CONFIG_PARM_DECODE_PSINFO  (1 << 1)
+#define V4L2_CONFIG_PARM_DECODE_HDRINFO (1 << 2)
+#define V4L2_CONFIG_PARM_DECODE_CNTINFO (1 << 3)
+
 enum
 {
     PROP_0,
@@ -1937,6 +1943,8 @@
         matrix = fmt->fmt.pix.ycbcr_enc;
         transfer = fmt->fmt.pix.xfer_func;
     }
+    GST_DEBUG("colorspace:%d, range:%d, matrix:%d, transfer:%d", colorspace, range, matrix, transfer);
+    GST_DEBUG("cinfo update 1 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
 
     /* First step, set the defaults for each primaries */
     switch (colorspace)
@@ -2002,6 +2010,7 @@
         ret = FALSE;
         break;
     }
+    GST_DEBUG("cinfo update 2 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
 
     if (!ret)
         goto done;
@@ -2029,6 +2038,7 @@
         cinfo->range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
         break;
     }
+    GST_DEBUG("cinfo update 3 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
 
     switch (matrix)
     {
@@ -2062,6 +2072,7 @@
         cinfo->matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
         break;
     }
+    GST_DEBUG("cinfo update 4 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
 
     /* Set identity matrix for R'G'B' formats to avoid creating
      * confusion. This though is cosmetic as it's now properly ignored by
@@ -2097,6 +2108,7 @@
         cinfo->transfer = GST_VIDEO_TRANSFER_UNKNOWN;
         break;
     }
+    GST_DEBUG("cinfo update 5 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
 
 done:
     return ret;
@@ -2202,6 +2214,7 @@
 
     g_value_init(&colorimetry, G_TYPE_STRING);
     g_value_take_string(&colorimetry, gst_video_colorimetry_to_string(cinfo));
+    GST_DEBUG("fill colorimetry:%s into list", gst_video_colorimetry_to_string(cinfo));
 
     /* only insert if no duplicate */
     size = gst_value_list_get_size(list);
@@ -2242,6 +2255,7 @@
 
     /* step 1: get device default colorspace and insert it first as
      * it should be the preferred one */
+    GST_DEBUG("try for pixl format");
     if (gst_aml_v4l2_object_try_fmt(v4l2object, &fmt) == 0)
     {
         if (gst_aml_v4l2_object_get_colorspace(&fmt, &cinfo))
@@ -2255,6 +2269,7 @@
     for (req_cspace = V4L2_COLORSPACE_SMPTE170M;
          req_cspace <= V4L2_COLORSPACE_RAW; req_cspace++)
     {
+        GST_DEBUG("try for pixl format in while loop :%d", req_cspace);
         /* V4L2_COLORSPACE_BT878 is deprecated and shall not be used, so skip */
         if (req_cspace == V4L2_COLORSPACE_BT878)
             continue;
@@ -2266,6 +2281,7 @@
 
         if (gst_aml_v4l2_object_try_fmt(v4l2object, &fmt) == 0)
         {
+            GST_DEBUG("try for pixl format in while loop :%d tried ok", req_cspace);
             enum v4l2_colorspace colorspace;
 
             if (V4L2_TYPE_IS_MULTIPLANAR(v4l2object->type))
@@ -2281,6 +2297,13 @@
         }
     }
 
+    //deal: caps with colorimetry 2,3,14,7
+    cinfo.range = 2;
+    cinfo.matrix = 3;
+    cinfo.transfer = 14;
+    cinfo.primaries = 7;
+    gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+
     if (gst_value_list_get_size(&list) > 0)
         gst_structure_take_value(s, "colorimetry", &list);
     else
@@ -3283,7 +3306,7 @@
 }
 
 static void
-set_amlogic_vdec_parm(GstAmlV4l2Object *v4l2object, struct v4l2_streamparm *streamparm)
+set_amlogic_vdec_parm(GstAmlV4l2Object *v4l2object, struct v4l2_streamparm *streamparm, GstCaps *caps)
 {
     struct aml_dec_params *decParm = (struct aml_dec_params *)streamparm->parm.raw_data;
     const char *env;
@@ -3318,6 +3341,222 @@
         {
             GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Set dwMode to %d", decParm->cfg.double_write_mode);
         }
+
+        GstStructure *structure= gst_caps_get_structure(caps, 0);
+        if (structure == NULL)
+        {
+            return;
+        }
+        if ( gst_structure_has_field(structure, "colorimetry") )
+        {
+            const char *colorimetry= gst_structure_get_string(structure,"colorimetry");
+            GstVideoColorimetry vci = {0};
+            if ( colorimetry &&  gst_video_colorimetry_from_string( &vci, colorimetry ))
+            {
+                decParm->parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
+                decParm->hdr.signal_type= (1<<29); /* present flag */
+                /*set default value, this is to keep up with driver hdr info synchronization*/
+                decParm->hdr.signal_type |= (5<<26) | (1<<24);
+
+                gint hdrColorimetry[4] = {0};
+                hdrColorimetry[0]= (int)vci.range;
+                hdrColorimetry[1]= (int)vci.matrix;
+                hdrColorimetry[2]= (int)vci.transfer;
+                hdrColorimetry[3]= (int)vci.primaries;
+                GST_DEBUG_OBJECT(v4l2object->dbg_obj, "colorimetry: [%d,%d,%d,%d]",
+                                                        hdrColorimetry[0],
+                                                        hdrColorimetry[1],
+                                                        hdrColorimetry[2],
+                                                        hdrColorimetry[3] );
+                /* range */
+                switch ( hdrColorimetry[0] )
+                {
+                    case 1:
+                    case 2:
+                    decParm->hdr.signal_type |= ((hdrColorimetry[0] % 2)<<25);
+                    break;
+                    default:
+                    break;
+                }
+                /* matrix coefficient */
+                switch ( hdrColorimetry[1] )
+                {
+                    case 1: /* RGB */
+                    decParm->hdr.signal_type |= 0;
+                    break;
+                    case 2: /* FCC */
+                    decParm->hdr.signal_type |= 4;
+                    break;
+                    case 3: /* BT709 */
+                    decParm->hdr.signal_type |= 1;
+                    break;
+                    case 4: /* BT601 */
+                    decParm->hdr.signal_type |= 3;
+                    break;
+                    case 5: /* SMPTE240M */
+                    decParm->hdr.signal_type |= 7;
+                    break;
+                    case 6: /* BT2020 */
+                    decParm->hdr.signal_type |= 9;
+                    break;
+                    default: /* unknown */
+                    decParm->hdr.signal_type |= 2;
+                    break;
+                }
+                /* transfer function */
+                switch ( hdrColorimetry[2] )
+                {
+                    case 5: /* BT709 */
+                    decParm->hdr.signal_type |= (1<<8);
+                    break;
+                    case 6: /* SMPTE240M */
+                    decParm->hdr.signal_type |= (7<<8);
+                    break;
+                    case 9: /* LOG100 */
+                    decParm->hdr.signal_type |= (9<<8);
+                    break;
+                    case 10: /* LOG316 */
+                    decParm->hdr.signal_type |= (10<<8);
+                    break;
+                    case 12: /* BT2020_12 */
+                    decParm->hdr.signal_type |= (15<<8);
+                    break;
+                    case 11: /* BT2020_10 */
+                    decParm->hdr.signal_type |= (14<<8);
+                    break;
+                    case 13: /* SMPTE2084 */
+                    decParm->hdr.signal_type |= (16<<8);
+                    break;
+                    case 14: /* ARIB_STD_B67 */
+                    decParm->hdr.signal_type |= (18<<8);
+                    break;
+                    #if ((GST_VERSION_MAJOR == 1) && (GST_VERSION_MINOR >= 18))
+                    case 16: /* BT601 */
+                    decParm->hdr.signal_type |= (3<<8);
+                    break;
+                    #endif
+                    case 1: /* GAMMA10 */
+                    case 2: /* GAMMA18 */
+                    case 3: /* GAMMA20 */
+                    case 4: /* GAMMA22 */
+                    case 7: /* SRGB */
+                    case 8: /* GAMMA28 */
+                    case 15: /* ADOBERGB */
+                    default:
+                    break;
+                }
+                /* primaries */
+                switch ( hdrColorimetry[3] )
+                {
+                    case 1: /* BT709 */
+                    decParm->hdr.signal_type |= ((1<<24)|(1<<16));
+                    break;
+                    case 2: /* BT470M */
+                    decParm->hdr.signal_type |= ((1<<24)|(4<<16));
+                    break;
+                    case 3: /* BT470BG */
+                    decParm->hdr.signal_type |= ((1<<24)|(5<<16));
+                    break;
+                    case 4: /* SMPTE170M */
+                    decParm->hdr.signal_type |= ((1<<24)|(6<<16));
+                    break;
+                    case 5: /* SMPTE240M */
+                    decParm->hdr.signal_type |= ((1<<24)|(7<<16));
+                    break;
+                    case 6: /* FILM */
+                    decParm->hdr.signal_type |= ((1<<24)|(8<<16));
+                    break;
+                    case 7: /* BT2020 */
+                    decParm->hdr.signal_type |= ((1<<24)|(9<<16));
+                    break;
+                    case 8: /* ADOBERGB */
+                    default:
+                    break;
+                }
+                GST_DEBUG_OBJECT(v4l2object->dbg_obj, "HDR signal_type %X", decParm->hdr.signal_type);
+            }
+
+            GST_DEBUG_OBJECT(v4l2object->dbg_obj, "got caps %" GST_PTR_FORMAT, caps);
+            GstStructure *st = gst_caps_get_structure(caps, 0);
+            GstCapsFeatures *features = gst_caps_get_features(caps, 0);
+
+            if (gst_structure_has_field(st, "colorimetry"))
+            {
+                GST_DEBUG_OBJECT(v4l2object->dbg_obj, "have colorimetry");
+            }
+
+            if (st && features)
+            {
+                GST_DEBUG_OBJECT(v4l2object->dbg_obj, "trace in remove colorimetry");
+                gst_structure_remove_field(st, "colorimetry");
+                gst_caps_features_remove(features, "colorimetry");
+            }
+            GST_DEBUG_OBJECT(v4l2object->dbg_obj, "caps after remove colorimetry %" GST_PTR_FORMAT, caps);
+        }
+
+        if ( gst_structure_has_field(structure, "mastering-display-metadata") )
+        {
+            const char *masteringDisplay= gst_structure_get_string(structure,"mastering-display-metadata");
+            float hdrMasteringDisplay[10];
+            if ( masteringDisplay && sscanf( masteringDisplay, "%f:%f:%f:%f:%f:%f:%f:%f:%f:%f",
+                                                                &hdrMasteringDisplay[0],
+                                                                &hdrMasteringDisplay[1],
+                                                                &hdrMasteringDisplay[2],
+                                                                &hdrMasteringDisplay[3],
+                                                                &hdrMasteringDisplay[4],
+                                                                &hdrMasteringDisplay[5],
+                                                                &hdrMasteringDisplay[6],
+                                                                &hdrMasteringDisplay[7],
+                                                                &hdrMasteringDisplay[8],
+                                                                &hdrMasteringDisplay[9] ) == 10 )
+            {
+                GST_DEBUG_OBJECT(v4l2object->dbg_obj, "mastering display [%f,%f,%f,%f,%f,%f,%f,%f,%f,%f]",
+                                                        hdrMasteringDisplay[0],
+                                                        hdrMasteringDisplay[1],
+                                                        hdrMasteringDisplay[2],
+                                                        hdrMasteringDisplay[3],
+                                                        hdrMasteringDisplay[4],
+                                                        hdrMasteringDisplay[5],
+                                                        hdrMasteringDisplay[6],
+                                                        hdrMasteringDisplay[7],
+                                                        hdrMasteringDisplay[8],
+                                                        hdrMasteringDisplay[9] );
+
+                decParm->hdr.color_parms.present_flag= 1;
+                decParm->hdr.color_parms.primaries[2][0]= (uint32_t)(hdrMasteringDisplay[0]*50000); /* R.x */
+                decParm->hdr.color_parms.primaries[2][1]= (uint32_t)(hdrMasteringDisplay[1]*50000); /* R.y */
+                decParm->hdr.color_parms.primaries[0][0]= (uint32_t)(hdrMasteringDisplay[2]*50000); /* G.x */
+                decParm->hdr.color_parms.primaries[0][1]= (uint32_t)(hdrMasteringDisplay[3]*50000); /* G.y */
+                decParm->hdr.color_parms.primaries[1][0]= (uint32_t)(hdrMasteringDisplay[4]*50000); /* B.x */
+                decParm->hdr.color_parms.primaries[1][1]= (uint32_t)(hdrMasteringDisplay[5]*50000); /* B.y */
+                decParm->hdr.color_parms.white_point[0]= (uint32_t)(hdrMasteringDisplay[6]*50000);
+                decParm->hdr.color_parms.white_point[1]= (uint32_t)(hdrMasteringDisplay[7]*50000);
+                decParm->hdr.color_parms.luminance[0]= (uint32_t)(hdrMasteringDisplay[8]);
+                decParm->hdr.color_parms.luminance[1]= (uint32_t)(hdrMasteringDisplay[9]);
+                GST_DEBUG_OBJECT(v4l2object->dbg_obj, "HDR mastering: primaries %X %X %X %X %X %X",
+                                                        decParm->hdr.color_parms.primaries[2][0],
+                                                        decParm->hdr.color_parms.primaries[2][1],
+                                                        decParm->hdr.color_parms.primaries[0][0],
+                                                        decParm->hdr.color_parms.primaries[0][1],
+                                                        decParm->hdr.color_parms.primaries[1][0],
+                                                        decParm->hdr.color_parms.primaries[1][1] );
+                GST_DEBUG_OBJECT(v4l2object->dbg_obj, "HDR mastering: white point: %X %X",
+                                                        decParm->hdr.color_parms.white_point[0],
+                                                        decParm->hdr.color_parms.white_point[1] );
+                GST_DEBUG_OBJECT(v4l2object->dbg_obj, "HDR mastering: luminance: %X %X",
+                                                        decParm->hdr.color_parms.luminance[0],
+                                                        decParm->hdr.color_parms.luminance[1] );
+            }
+
+            GstStructure *st = gst_caps_get_structure(caps, 0);
+            GstCapsFeatures * features = gst_caps_get_features(caps, 0);
+            if (st && features)
+            {
+                gst_structure_remove_fields(st, "mastering-display-metadata", NULL);
+                gst_caps_features_remove(features, "mastering-display-metadata");
+            }
+            GST_DEBUG_OBJECT(v4l2object->dbg_obj, "caps after remove mastering-display-metadata %" GST_PTR_FORMAT, caps);
+        }
     }
 }
 
@@ -3354,7 +3593,7 @@
 
     memset(&streamparm, 0x00, sizeof(struct v4l2_streamparm));
     streamparm.type = v4l2object->type;
-    set_amlogic_vdec_parm(v4l2object, &streamparm);
+    set_amlogic_vdec_parm(v4l2object, &streamparm, caps);
 
     is_mplane = V4L2_TYPE_IS_MULTIPLANAR(v4l2object->type);
 
@@ -3728,9 +3967,10 @@
     {
         if (gst_structure_has_field(s, "colorimetry"))
         {
-            if (!gst_aml_v4l2_video_colorimetry_matches(&info.colorimetry,
-                                                        gst_structure_get_string(s, "colorimetry")))
-                goto invalid_colorimetry;
+            if (!gst_aml_v4l2_video_colorimetry_matches(&info.colorimetry, gst_structure_get_string(s, "colorimetry")))
+            {
+                // goto invalid_colorimetry;
+            }
         }
     }
     else
@@ -4514,6 +4754,7 @@
             GstCaps *format_caps = gst_caps_new_empty();
 
             gst_caps_append_structure(format_caps, gst_structure_copy(template));
+            GST_INFO_OBJECT(v4l2object->dbg_obj, "format_caps: %" GST_PTR_FORMAT, format_caps);
 
             if (!gst_caps_can_intersect(format_caps, filter))
             {
@@ -4527,6 +4768,7 @@
 
         tmp = gst_aml_v4l2_object_probe_caps_for_format(v4l2object,
                                                         format->pixelformat, template);
+        GST_INFO_OBJECT(v4l2object->dbg_obj, "tmp caps: %" GST_PTR_FORMAT, tmp);
 
         if (tmp)
         {