h264parse: parse unregistered SEI without user data
authorGuillaume Desmottes <guillaume.desmottes@onestream.live>
Wed, 20 Nov 2024 13:16:23 +0000 (14:16 +0100)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 4 Dec 2024 13:56:13 +0000 (13:56 +0000)
We get loads of warnings when parsing videos from users:

gsth264parser.c:1115:gst_h264_parser_parse_user_data_unregistered: No more remaining payload data to store
gsth264parse.c:646:gst_h264_parse_process_sei:<h264parse0> failed to parse one or more SEI message

Those are raised because of unregistered SEI without user data.

The spec does not explicitly state that unregistered SEI needs to have
data and I suppose the UUID by itself can carry valuable information.
FFmpeg also parses and exposes such SEI so there is no reason for us no
too as well.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7931>

girs/GstVideo-1.0.gir
subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gsth264parser.c
subprojects/gst-plugins-bad/gst/videoparsers/gsth264parse.c
subprojects/gst-plugins-bad/tests/check/elements/h264parse.c
subprojects/gst-plugins-base/gst-libs/gst/video/video-sei.c

index dc70a707f7503b64f1222c573dbb5c12784ea9db..0d36971888d4543d976513f124f46b7e31e52449 100644 (file)
@@ -16746,7 +16746,7 @@ parameters.</doc>
           <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-sei.c">User Data Unregistered UUID</doc>
           <type name="guint8" c:type="guint8*"/>
         </parameter>
-        <parameter name="data" transfer-ownership="none">
+        <parameter name="data" transfer-ownership="none" nullable="1" allow-none="1">
           <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-sei.c">SEI User Data Unregistered buffer</doc>
           <type name="guint8" c:type="guint8*"/>
         </parameter>
index 82ba8185f301028ed78cd5fd857fd47d1d1d80b9..b9bd6c3ee548528c07eb40c487e2aa3e63ea36af 100644 (file)
@@ -1111,12 +1111,6 @@ gst_h264_parser_parse_user_data_unregistered (GstH264NalParser * nalparser,
     READ_UINT8 (nr, data[i], 8);
   }
 
-  if (payload_size < 1) {
-    GST_WARNING ("No more remaining payload data to store");
-    g_clear_pointer (&data, g_free);
-    return GST_H264_PARSER_BROKEN_DATA;
-  }
-
   urud->data = data;
   GST_MEMDUMP ("SEI user data unregistered", data, payload_size);
   return GST_H264_PARSER_OK;
index 89e235ae1268ef7d5724c37ddc166abb42254c00..0fb24b82cb11a2980d9856ae527851ce3361f805 100644 (file)
@@ -623,9 +623,6 @@ gst_h264_parse_process_sei_user_data_unregistered (GstH264Parse * h264parse,
 {
   GstByteReader br;
 
-  if (urud->data == NULL || urud->size < 1)
-    return;
-
   gst_byte_reader_init (&br, urud->data, urud->size);
 
   gst_video_parse_user_data_unregistered ((GstElement *) h264parse,
index 97cc06341473e3fca41596db89e85db0425d3646..a5bffd9a092741931b721c0151da775dba380954 100644 (file)
@@ -1488,6 +1488,16 @@ GST_START_TEST (test_parse_sei_userdefinedunregistered)
     0x1f, 0x00, 0x05, 0xff, 0x21, 0x7e, 0xff, 0x29,
     0xb5, 0xff, 0xdc, 0x13
   };
+  // Same SEI as above but without data
+  const guint8 no_data_sei[] = {
+    0x00, 0x00, 0x00, 0x20, 0x06, 0x05, 0x10, 0x4d,
+    0x49, 0x53, 0x50, 0x6d, 0x69, 0x63, 0x72, 0x6f,
+    0x73, 0x65, 0x63, 0x74, 0x69, 0x6d, 0x65,
+    /* IDR frame (doesn't match caps) */
+    0x00, 0x00, 0x00, 0x14, 0x65, 0x88, 0x84, 0x00,
+    0x10, 0xff, 0xfe, 0xf6, 0xf0, 0xfe, 0x05, 0x36,
+    0x56, 0x04, 0x50, 0x96, 0x7b, 0x3f, 0x53, 0xe1
+  };
 
   h = gst_harness_new ("h264parse");
 
@@ -1511,6 +1521,21 @@ GST_START_TEST (test_parse_sei_userdefinedunregistered)
 
   gst_buffer_unref (buf);
 
+  // Now try parsing an unregistered SEI without data
+  buf = gst_buffer_new_and_alloc (misb_sei_size);
+  gst_buffer_fill (buf, 0, no_data_sei, sizeof (no_data_sei));
+  fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
+
+  buf = gst_harness_pull (h);
+  meta = gst_buffer_get_video_sei_user_data_unregistered_meta (buf);
+  fail_unless (meta != NULL);
+
+  fail_unless (memcmp (meta->uuid, H264_MISP_MICROSECTIME, 16) == 0);
+  fail_unless (meta->data == NULL);
+  fail_unless (meta->size == 0);
+
+  gst_buffer_unref (buf);
+
   gst_harness_teardown (h);
 }
 
index 0b981c40764721507954966e9fe7efbd6338db98..908daf0c1ee83829474bb82303502f8153e593a1 100644 (file)
@@ -156,7 +156,7 @@ gst_video_sei_user_data_unregistered_meta_get_info (void)
  * gst_buffer_add_video_sei_user_data_unregistered_meta:
  * @buffer: a #GstBuffer
  * @uuid: User Data Unregistered UUID
- * @data: (transfer none): SEI User Data Unregistered buffer
+ * @data: (transfer none) (allow-none): SEI User Data Unregistered buffer
  * @size: size of the data buffer
  *
  * Attaches #GstVideoSEIUserDataUnregisteredMeta metadata to @buffer with the given
@@ -172,7 +172,6 @@ gst_buffer_add_video_sei_user_data_unregistered_meta (GstBuffer * buffer,
 {
   GstVideoSEIUserDataUnregisteredMeta *meta;
   g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
-  g_return_val_if_fail (data != NULL, NULL);
 
   meta = (GstVideoSEIUserDataUnregisteredMeta *) gst_buffer_add_meta (buffer,
       GST_VIDEO_SEI_USER_DATA_UNREGISTERED_META_INFO, NULL);