videoparseutils: Store multiple user data unregistered messages

A frame can have multiple unregistered messages attached. We need to
store them all.

For: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3008
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5450>
This commit is contained in:
Jan Alexander Steffens (heftig) 2023-10-10 08:45:06 +02:00 committed by GStreamer Marge Bot
parent 75f61cba80
commit 92017b983e
4 changed files with 65 additions and 14 deletions

View file

@ -235,7 +235,8 @@ gst_h264_parse_finalize (GObject * object)
{ {
GstH264Parse *h264parse = GST_H264_PARSE (object); GstH264Parse *h264parse = GST_H264_PARSE (object);
gst_video_clear_user_data_unregistered (&h264parse->user_data_unregistered); gst_video_clear_user_data_unregistered (&h264parse->user_data_unregistered,
TRUE);
g_object_unref (h264parse->frame_out); g_object_unref (h264parse->frame_out);
g_array_unref (h264parse->nal_backlog); g_array_unref (h264parse->nal_backlog);
@ -263,7 +264,8 @@ gst_h264_parse_reset_frame (GstH264Parse * h264parse)
h264parse->have_aud_in_frame = FALSE; h264parse->have_aud_in_frame = FALSE;
gst_adapter_clear (h264parse->frame_out); gst_adapter_clear (h264parse->frame_out);
gst_video_clear_user_data (&h264parse->user_data); gst_video_clear_user_data (&h264parse->user_data);
gst_video_clear_user_data_unregistered (&h264parse->user_data_unregistered); gst_video_clear_user_data_unregistered (&h264parse->user_data_unregistered,
FALSE);
} }
static void static void

View file

@ -182,7 +182,8 @@ gst_h265_parse_finalize (GObject * object)
{ {
GstH265Parse *h265parse = GST_H265_PARSE (object); GstH265Parse *h265parse = GST_H265_PARSE (object);
gst_video_clear_user_data_unregistered (&h265parse->user_data_unregistered); gst_video_clear_user_data_unregistered (&h265parse->user_data_unregistered,
TRUE);
g_object_unref (h265parse->frame_out); g_object_unref (h265parse->frame_out);
@ -209,7 +210,8 @@ gst_h265_parse_reset_frame (GstH265Parse * h265parse)
h265parse->have_pps_in_frame = FALSE; h265parse->have_pps_in_frame = FALSE;
gst_adapter_clear (h265parse->frame_out); gst_adapter_clear (h265parse->frame_out);
gst_video_clear_user_data (&h265parse->user_data); gst_video_clear_user_data (&h265parse->user_data);
gst_video_clear_user_data_unregistered (&h265parse->user_data_unregistered); gst_video_clear_user_data_unregistered (&h265parse->user_data_unregistered,
FALSE);
} }
static void static void

View file

@ -39,6 +39,9 @@ static gboolean gst_video_parse_utils_parse_bar (const guint8 * data,
static gboolean gst_video_parse_utils_parse_afd (const guint8 data, static gboolean gst_video_parse_utils_parse_afd (const guint8 data,
GstVideoAFDSpec spec, GstVideoParseUtilsField field, GstVideoAFD * afd); GstVideoAFDSpec spec, GstVideoParseUtilsField field, GstVideoAFD * afd);
static void gst_video_clear_unregistered_message
(GstVideoUnregisteredMessage * msg);
/* /*
* gst_video_parse_user_data: * gst_video_parse_user_data:
@ -465,14 +468,23 @@ gst_video_parse_user_data_unregistered (GstElement * elt,
GstVideoParseUserDataUnregistered * user_data, GstVideoParseUserDataUnregistered * user_data,
GstByteReader * br, guint8 uuid[16]) GstByteReader * br, guint8 uuid[16])
{ {
gst_video_clear_user_data_unregistered (user_data); GstVideoUnregisteredMessage msg;
memcpy (&user_data->uuid, uuid, 16); memcpy (&msg.uuid, uuid, 16);
user_data->size = gst_byte_reader_get_size (br); msg.size = gst_byte_reader_get_size (br);
if (!gst_byte_reader_dup_data (br, user_data->size, &user_data->data)) { if (!gst_byte_reader_dup_data (br, msg.size, &msg.data)) {
g_return_if_reached (); g_return_if_reached ();
} }
if (user_data->messages == NULL) {
user_data->messages = g_array_sized_new (FALSE, TRUE,
sizeof (GstVideoUnregisteredMessage), 3);
g_array_set_clear_func (user_data->messages,
(GDestroyNotify) gst_video_clear_unregistered_message);
}
g_array_append_val (user_data->messages, msg);
} }
/* /*
@ -481,27 +493,52 @@ gst_video_parse_user_data_unregistered (GstElement * elt,
* @user_data: #GstVideoParseUserDataUnregistered holding SEI User Data Unregistered * @user_data: #GstVideoParseUserDataUnregistered holding SEI User Data Unregistered
* @buf: (transfer none): #GstBuffer that receives the unregistered data * @buf: (transfer none): #GstBuffer that receives the unregistered data
* *
* Attach unregistered user data from @user_data to @buf as * Attach unregistered messages from @user_data to @buf as
* GstVideoSEIUserDataUnregisteredMeta * GstVideoSEIUserDataUnregisteredMeta
*/ */
void void
gst_video_push_user_data_unregistered (GstElement * elt, gst_video_push_user_data_unregistered (GstElement * elt,
GstVideoParseUserDataUnregistered * user_data, GstBuffer * buf) GstVideoParseUserDataUnregistered * user_data, GstBuffer * buf)
{ {
if (user_data->data != NULL) { GArray *messages = user_data->messages;
gst_buffer_add_video_sei_user_data_unregistered_meta (buf, user_data->uuid, guint i;
user_data->data, user_data->size);
if (messages == NULL)
return;
for (i = 0; i < messages->len; i++) {
GstVideoUnregisteredMessage *msg =
&g_array_index (messages, GstVideoUnregisteredMessage, i);
gst_buffer_add_video_sei_user_data_unregistered_meta (buf, msg->uuid,
msg->data, msg->size);
} }
} }
/* /*
* gst_video_clear_user_data_unregistered: * gst_video_clear_user_data_unregistered:
* @user_data: #GstVideoParseUserDataUnregistered holding SEI User Data Unregistered * @user_data: #GstVideoParseUserDataUnregistered holding SEI User Data Unregistered
* @free: Whether to deallocate memory resources
* *
* Clears the user data unregistered, resetting it for the next frame * Clears the user data unregistered, resetting it for the next frame
*/ */
void gst_video_clear_user_data_unregistered void gst_video_clear_user_data_unregistered
(GstVideoParseUserDataUnregistered * user_data) (GstVideoParseUserDataUnregistered * user_data, gboolean free)
{
if (free)
g_clear_pointer (&user_data->messages, g_array_unref);
else if (user_data->messages != NULL)
g_array_set_size (user_data->messages, 0);
}
/*
* gst_video_clear_unregistered_message:
* @msg: #GstVideoUnregisteredMessage holding a single SEI User Data Unregistered
*
* Clears the message, freeing the data
*/
static void
gst_video_clear_unregistered_message (GstVideoUnregisteredMessage * msg)
{ {
memset (&msg->uuid, 0, sizeof msg->uuid); memset (&msg->uuid, 0, sizeof msg->uuid);
g_clear_pointer (&msg->data, g_free); g_clear_pointer (&msg->data, g_free);

View file

@ -173,10 +173,20 @@ typedef struct
*/ */
typedef struct typedef struct
{ {
/* item type: GstVideoUnregisteredMessage */
GArray *messages;
} GstVideoParseUserDataUnregistered;
/*
* GstVideoUnregisteredMessage
*
* Item type for the unregistered user data.
*/
typedef struct {
guint8 uuid[16]; guint8 uuid[16];
guint8 *data; guint8 *data;
gsize size; gsize size;
} GstVideoParseUserDataUnregistered; } GstVideoUnregisteredMessage;
G_BEGIN_DECLS G_BEGIN_DECLS