h265parser: Various update of vps parsing
authorSeungha Yang <seungha.yang@navercorp.com>
Sun, 14 Oct 2018 07:36:33 +0000 (16:36 +0900)
committerSeungha Yang <seungha.yang@navercorp.com>
Wed, 7 Nov 2018 09:24:59 +0000 (18:24 +0900)
* Add FIXME for future correction of HRDParames parsing.
Spec. defines that the number of HRDParames could be up to
"vps_num_layer_sets_minus1 + 1" (i.e., 1024).

* Add parsing vps_base_layer_{internal,available}_flag.

* Fix possible invalid vps_extension parsing.

Fixes #798

gst-libs/gst/codecparsers/gsth265parser.c
gst-libs/gst/codecparsers/gsth265parser.h

index 8b38c45..a6baa49 100644 (file)
@@ -1400,9 +1400,8 @@ gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
 
   READ_UINT8 (&nr, vps->id, 4);
 
-  /* skip reserved_three_2bits */
-  if (!nal_reader_skip (&nr, 2))
-    goto error;
+  READ_UINT8 (&nr, vps->base_layer_internal_flag, 1);
+  READ_UINT8 (&nr, vps->base_layer_available_flag, 1);
 
   READ_UINT8 (&nr, vps->max_layers_minus1, 6);
   READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
@@ -1446,9 +1445,13 @@ gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
   /* allowd range is 0 to 1023 */
   CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 1023);
 
-  for (i = 1; i <= vps->num_layer_sets_minus1; i++)
-    for (j = 0; j <= vps->max_layer_id; j++)
+  for (i = 1; i <= vps->num_layer_sets_minus1; i++) {
+    for (j = 0; j <= vps->max_layer_id; j++) {
+      /* layer_id_included_flag[i][j] */
+      /* FIXME: need to parse this when we can support parsing multi-layer info. */
       nal_reader_skip (&nr, 1);
+    }
+  }
 
   READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
 
@@ -1476,6 +1479,31 @@ gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
               vps->cprms_present_flag, vps->max_sub_layers_minus1))
         goto error;
     }
+
+    /* FIXME: VPS can have multiple hrd parameters, and therefore hrd_params
+     * should be an array (like Garray). But it also requires new _clear()
+     * method for free the array in GstH265VPS whenever gst_h265_parse_vps()
+     * is called. Need to work for multi-layer related parsing supporting
+     *
+     * FIXME: Following code is just work around to find correct
+     * vps_extension position */
+
+    /* skip the first parsed one above */
+    for (i = 1; i < vps->num_hrd_parameters; i++) {
+      guint16 hrd_layer_set_idx;
+      guint8 cprms_present_flag;
+      GstH265HRDParams hrd_params;
+
+      READ_UE_MAX (&nr, hrd_layer_set_idx, 1023);
+      CHECK_ALLOWED_MAX (hrd_layer_set_idx, vps->num_layer_sets_minus1);
+
+      /* need parsing if (i > 1) */
+      READ_UINT8 (&nr, cprms_present_flag, 1);
+
+      if (!gst_h265_parse_hrd_parameters (&hrd_params, &nr,
+              cprms_present_flag, vps->max_sub_layers_minus1))
+        goto error;
+    }
   }
   READ_UINT8 (&nr, vps->vps_extension, 1);
   vps->valid = TRUE;
index 1a9440f..c8c0a98 100644 (file)
@@ -517,6 +517,8 @@ struct _GstH265HRDParams
 /**
  * GstH265VPS:
  * @id: vps id
+ * @base_layer_internal_flag and @base_layer_available_flag:
+ *   specify availability of base layer
  * @max_layers_minus1: should be zero, but can be other values in future
  * @max_sub_layers_minus1:specifies the maximum number of temporal sub-layers
  * @temporal_id_nesting_flag: specifies whether inter prediction is
@@ -555,6 +557,9 @@ struct _GstH265HRDParams
 struct _GstH265VPS {
   guint8 id;
 
+  guint8 base_layer_internal_flag;
+  guint8 base_layer_available_flag;
+
   guint8 max_layers_minus1;
   guint8 max_sub_layers_minus1;
   guint8 temporal_id_nesting_flag;
@@ -576,9 +581,10 @@ struct _GstH265VPS {
   guint32 num_ticks_poc_diff_one_minus1;
 
   guint16 num_hrd_parameters;
+
+  /* FIXME: following HRD related info should be an array */
   guint16 hrd_layer_set_idx;
   guint8 cprms_present_flag;
-
   GstH265HRDParams hrd_params;
 
   guint8 vps_extension;