| From 1ef01359e5ab267ea13253cea688869697f7ff0d Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Alicia=20Boya=20Garc=C3=ADa?= <aboya@igalia.com> |
| Date: Mon, 24 Sep 2018 17:20:15 +0200 |
| Subject: [PATCH] (backport for 1.4.13) matroskademux: Refactor track parsing |
| out from adding tracks |
| |
| This splits gst_matroska_demux_add_stream() into: |
| |
| * gst_matroska_demux_parse_stream(): will read the Matroska bytestream |
| and fill a GstMatroskaTrackContext. |
| |
| * gst_matroska_demux_parse_tracks(): will check there are no repeated |
| tracks. |
| |
| * gst_matroska_demux_add_stream(): creates and sets up the pad for the |
| track. |
| |
| https://bugzilla.gnome.org/show_bug.cgi?id=793333 |
| --- |
| gst/matroska/matroska-demux.c | 114 +++++++++++++++++++++------------- |
| 1 file changed, 72 insertions(+), 42 deletions(-) |
| |
| diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c |
| index 3f329ed6e..7c8990cf4 100644 |
| --- a/gst/matroska/matroska-demux.c |
| +++ b/gst/matroska/matroska-demux.c |
| @@ -575,21 +575,16 @@ beach: |
| } |
| |
| static GstFlowReturn |
| -gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| +gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml, |
| + GstMatroskaTrackContext ** dest_context) |
| { |
| - GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux); |
| GstMatroskaTrackContext *context; |
| - GstPadTemplate *templ = NULL; |
| - GstStreamFlags stream_flags; |
| GstCaps *caps = NULL; |
| GstTagList *cached_taglist; |
| - gchar *padname = NULL; |
| GstFlowReturn ret; |
| guint32 id, riff_fourcc = 0; |
| guint16 riff_audio_fmt = 0; |
| - GstEvent *stream_start; |
| gchar *codec = NULL; |
| - gchar *stream_id; |
| |
| DEBUG_ELEMENT_START (demux, ebml, "TrackEntry"); |
| |
| @@ -602,8 +597,6 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| /* allocate generic... if we know the type, we'll g_renew() |
| * with the precise type */ |
| context = g_new0 (GstMatroskaTrackContext, 1); |
| - g_ptr_array_add (demux->common.src, context); |
| - context->index = demux->common.num_streams; |
| context->index_writer_id = -1; |
| context->type = 0; /* no type yet */ |
| context->default_duration = 0; |
| @@ -620,10 +613,9 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| context->dts_only = FALSE; |
| context->intra_only = FALSE; |
| context->tags = gst_tag_list_new_empty (); |
| - demux->common.num_streams++; |
| - g_assert (demux->common.src->len == demux->common.num_streams); |
| |
| - GST_DEBUG_OBJECT (demux, "Stream number %d", context->index); |
| + GST_DEBUG_OBJECT (demux, "Parsing a TrackEntry (%d tracks parsed so far)", |
| + demux->common.num_streams); |
| |
| /* try reading the trackentry headers */ |
| while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) { |
| @@ -642,12 +634,6 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0"); |
| ret = GST_FLOW_ERROR; |
| break; |
| - } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common, |
| - num)) { |
| - GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT |
| - " is not unique", num); |
| - ret = GST_FLOW_ERROR; |
| - break; |
| } |
| |
| GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num); |
| @@ -714,8 +700,6 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| context->type = 0; |
| break; |
| } |
| - g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) |
| - = context; |
| break; |
| } |
| |
| @@ -734,8 +718,6 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| break; |
| } |
| videocontext = (GstMatroskaTrackVideoContext *) context; |
| - g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) |
| - = context; |
| |
| while (ret == GST_FLOW_OK && |
| gst_ebml_read_has_remaining (ebml, 1, TRUE)) { |
| @@ -1011,8 +993,6 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| break; |
| |
| audiocontext = (GstMatroskaTrackAudioContext *) context; |
| - g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) |
| - = context; |
| |
| while (ret == GST_FLOW_OK && |
| gst_ebml_read_has_remaining (ebml, 1, TRUE)) { |
| @@ -1341,11 +1321,9 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS) |
| GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header"); |
| |
| - demux->common.num_streams--; |
| - g_ptr_array_remove_index (demux->common.src, demux->common.num_streams); |
| - g_assert (demux->common.src->len == demux->common.num_streams); |
| gst_matroska_track_free (context); |
| - |
| + context = NULL; |
| + *dest_context = NULL; |
| return ret; |
| } |
| |
| @@ -1356,14 +1334,12 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| if (cached_taglist) |
| gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND); |
| |
| - /* now create the GStreamer connectivity */ |
| + /* compute caps */ |
| switch (context->type) { |
| case GST_MATROSKA_TRACK_TYPE_VIDEO:{ |
| GstMatroskaTrackVideoContext *videocontext = |
| (GstMatroskaTrackVideoContext *) context; |
| |
| - padname = g_strdup_printf ("video_%u", demux->num_v_streams++); |
| - templ = gst_element_class_get_pad_template (klass, "video_%u"); |
| caps = gst_matroska_demux_video_caps (videocontext, |
| context->codec_id, context->codec_priv, |
| context->codec_priv_size, &codec, &riff_fourcc); |
| @@ -1381,8 +1357,6 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| GstMatroskaTrackAudioContext *audiocontext = |
| (GstMatroskaTrackAudioContext *) context; |
| |
| - padname = g_strdup_printf ("audio_%u", demux->num_a_streams++); |
| - templ = gst_element_class_get_pad_template (klass, "audio_%u"); |
| caps = gst_matroska_demux_audio_caps (audiocontext, |
| context->codec_id, context->codec_priv, context->codec_priv_size, |
| &codec, &riff_audio_fmt); |
| @@ -1400,8 +1374,6 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| GstMatroskaTrackSubtitleContext *subtitlecontext = |
| (GstMatroskaTrackSubtitleContext *) context; |
| |
| - padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++); |
| - templ = gst_element_class_get_pad_template (klass, "subtitle_%u"); |
| caps = gst_matroska_demux_subtitle_caps (subtitlecontext, |
| context->codec_id, context->codec_priv, context->codec_priv_size); |
| break; |
| @@ -1468,9 +1440,56 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| context->stream_headers, caps); |
| } |
| |
| + context->caps = caps; |
| + |
| + /* tadaah! */ |
| + *dest_context = context; |
| + return ret; |
| +} |
| + |
| +static void |
| +gst_matroska_demux_add_stream (GstMatroskaDemux * demux, |
| + GstMatroskaTrackContext * context) |
| +{ |
| + GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux); |
| + gchar *padname = NULL; |
| + GstPadTemplate *templ = NULL; |
| + GstStreamFlags stream_flags; |
| + |
| + GstEvent *stream_start; |
| + |
| + gchar *stream_id; |
| + |
| + g_ptr_array_add (demux->common.src, context); |
| + context->index = demux->common.num_streams++; |
| + g_assert (demux->common.src->len == demux->common.num_streams); |
| + g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) = |
| + context; |
| + |
| + /* now create the GStreamer connectivity */ |
| + switch (context->type) { |
| + case GST_MATROSKA_TRACK_TYPE_VIDEO: |
| + padname = g_strdup_printf ("video_%u", demux->num_v_streams++); |
| + templ = gst_element_class_get_pad_template (klass, "video_%u"); |
| + break; |
| + |
| + case GST_MATROSKA_TRACK_TYPE_AUDIO: |
| + padname = g_strdup_printf ("audio_%u", demux->num_a_streams++); |
| + templ = gst_element_class_get_pad_template (klass, "audio_%u"); |
| + break; |
| + |
| + case GST_MATROSKA_TRACK_TYPE_SUBTITLE: |
| + padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++); |
| + templ = gst_element_class_get_pad_template (klass, "subtitle_%u"); |
| + break; |
| + |
| + default: |
| + /* we should already have quit by now */ |
| + g_assert_not_reached (); |
| + } |
| + |
| /* the pad in here */ |
| context->pad = gst_pad_new_from_template (templ, padname); |
| - context->caps = caps; |
| |
| gst_pad_set_event_function (context->pad, |
| GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event)); |
| @@ -1478,7 +1497,7 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query)); |
| |
| GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT, |
| - padname, caps); |
| + padname, context->caps); |
| |
| gst_pad_set_element_private (context->pad, context); |
| |
| @@ -1543,9 +1562,6 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| gst_flow_combiner_add_pad (demux->flowcombiner, context->pad); |
| |
| g_free (padname); |
| - |
| - /* tadaah! */ |
| - return ret; |
| } |
| |
| static gboolean |
| @@ -2768,9 +2784,23 @@ gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml) |
| |
| switch (id) { |
| /* one track within the "all-tracks" header */ |
| - case GST_MATROSKA_ID_TRACKENTRY: |
| - ret = gst_matroska_demux_add_stream (demux, ebml); |
| + case GST_MATROSKA_ID_TRACKENTRY:{ |
| + GstMatroskaTrackContext *track; |
| + ret = gst_matroska_demux_parse_stream (demux, ebml, &track); |
| + if (track != NULL) { |
| + if (gst_matroska_read_common_tracknumber_unique (&demux->common, |
| + track->num)) { |
| + gst_matroska_demux_add_stream (demux, track); |
| + } else { |
| + GST_ERROR_OBJECT (demux, |
| + "TrackNumber %" G_GUINT64_FORMAT " is not unique", track->num); |
| + ret = GST_FLOW_ERROR; |
| + gst_matroska_track_free (track); |
| + track = NULL; |
| + } |
| + } |
| break; |
| + } |
| |
| default: |
| ret = gst_matroska_read_common_parse_skip (&demux->common, ebml, |
| -- |
| 2.17.1 |
| |