h264parser: Parse all SEI payload type even if it's not handled by parser
authorSeungha Yang <seungha@centricular.com>
Wed, 8 Apr 2020 07:24:06 +0000 (16:24 +0900)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 8 Apr 2020 15:39:12 +0000 (15:39 +0000)
... so that user can handle it from outside of parser API

gst-libs/gst/codecparsers/gsth264parser.c
gst-libs/gst/codecparsers/gsth264parser.h
gst/videoparsers/gsth264parse.c

index bf454bc..ca9eb65 100644 (file)
@@ -1231,6 +1231,33 @@ error:
 }
 
 static GstH264ParserResult
+gst_h264_parser_parse_sei_unhandled_payload (GstH264NalParser * parser,
+    GstH264SEIUnhandledPayload * payload, NalReader * nr, guint payload_type,
+    guint payload_size)
+{
+  guint8 *data = NULL;
+  gint i;
+
+  payload->payloadType = payload_type;
+
+  data = g_malloc0 (payload_size);
+  for (i = 0; i < payload_size; ++i) {
+    READ_UINT8 (nr, data[i], 8);
+  }
+
+  payload->size = payload_size;
+  payload->data = data;
+
+  return GST_H264_PARSER_OK;
+
+error:
+  GST_WARNING ("error parsing \"Unhandled payload\"");
+  g_free (data);
+
+  return GST_H264_PARSER_ERROR;
+}
+
+static GstH264ParserResult
 gst_h264_parser_parse_sei_message (GstH264NalParser * nalparser,
     NalReader * nr, GstH264SEIMessage * sei)
 {
@@ -1298,11 +1325,10 @@ gst_h264_parser_parse_sei_message (GstH264NalParser * nalparser,
           &sei->payload.content_light_level, nr);
       break;
     default:
-      /* Just consume payloadSize bytes, which does not account for
-         emulation prevention bytes */
-      if (!nal_reader_skip_long (nr, payload_size))
-        goto error;
-      res = GST_H264_PARSER_OK;
+      res = gst_h264_parser_parse_sei_unhandled_payload (nalparser,
+          &sei->payload.unhandled_payload, nr, sei->payloadType,
+          payload_size >> 3);
+      sei->payloadType = GST_H264_SEI_UNHANDLED_PAYLOAD;
       break;
   }
 
@@ -2421,6 +2447,14 @@ gst_h264_sei_clear (GstH264SEIMessage * sei)
       rud->data = NULL;
       break;
     }
+    case GST_H264_SEI_UNHANDLED_PAYLOAD:{
+      GstH264SEIUnhandledPayload *payload = &sei->payload.unhandled_payload;
+
+      g_free (payload->data);
+      payload->data = NULL;
+      payload->size = 0;
+      break;
+    }
     default:
       break;
   }
index f86f21a..e72e2cf 100644 (file)
@@ -247,6 +247,8 @@ typedef enum
  *     contains the 3D arrangement for stereoscopic 3D video (Since: 1.6)
  * @GST_H264_SEI_MASTERING_DISPLAY_COLOUR_VOLUME: Mastering display colour volume information SEI message (D.2.29) (Since: 1.18)
  * @GST_H264_SEI_CONTENT_LIGHT_LEVEL: Content light level information SEI message (D.2.31) (Since: 1.18)
+ * @GST_H264_SEI_UNHANDLED_PAYLOAD: Unhandled SEI message. This may or may not
+ *     be defined by spec (Since 1.18)
  * ...
  *
  * The type of SEI message.
@@ -262,6 +264,9 @@ typedef enum
   GST_H264_SEI_MASTERING_DISPLAY_COLOUR_VOLUME = 137,
   GST_H264_SEI_CONTENT_LIGHT_LEVEL = 144,
       /* and more...  */
+
+  /* Unhandled SEI type */
+  GST_H264_SEI_UNHANDLED_PAYLOAD = -1
 } GstH264SEIPayloadType;
 
 /**
@@ -358,6 +363,7 @@ typedef struct _GstH264StereoVideoInfo        GstH264StereoVideoInfo;
 typedef struct _GstH264FramePacking           GstH264FramePacking;
 typedef struct _GstH264MasteringDisplayColourVolume GstH264MasteringDisplayColourVolume;
 typedef struct _GstH264ContentLightLevel        GstH264ContentLightLevel;
+typedef struct _GstH264SEIUnhandledPayload    GstH264SEIUnhandledPayload;
 typedef struct _GstH264SEIMessage             GstH264SEIMessage;
 
 /**
@@ -1160,6 +1166,25 @@ struct _GstH264ContentLightLevel
   guint16 max_pic_average_light_level;
 };
 
+/**
+ * GstH264SEIUnhandledPayload:
+ * @payloadType: Payload type
+ * @data: payload raw data excluding payload type and payload size byte
+ * @size: the size of @data
+ *
+ * Contains unhandled SEI payload data. This SEI may or may not
+ * be defined by spec
+ *
+ * Since: 1.18
+ */
+struct _GstH264SEIUnhandledPayload
+{
+  guint payloadType;
+
+  guint8 *data;
+  guint size;
+};
+
 struct _GstH264SEIMessage
 {
   GstH264SEIPayloadType payloadType;
@@ -1173,6 +1198,7 @@ struct _GstH264SEIMessage
     GstH264FramePacking frame_packing;
     GstH264MasteringDisplayColourVolume mastering_display_colour_volume;
     GstH264ContentLightLevel content_light_level;
+    GstH264SEIUnhandledPayload unhandled_payload;
     /* ... could implement more */
   } payload;
 };
index 885301a..f47998d 100644 (file)
@@ -866,10 +866,18 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu)
 
         break;
       }
-      default:
-        GST_LOG_OBJECT (h264parse, "Unsupported payload type %u",
-            sei.payloadType);
+      default:{
+        gint payload_type = sei.payloadType;
+
+        if (payload_type == GST_H264_SEI_UNHANDLED_PAYLOAD) {
+          GstH264SEIUnhandledPayload *unhandled =
+              &sei.payload.unhandled_payload;
+          payload_type = unhandled->payloadType;
+        }
+
+        GST_LOG_OBJECT (h264parse, "Unsupported payload type %d", payload_type);
         break;
+      }
     }
   }
   g_array_free (messages, TRUE);