mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
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
This commit is contained in:
parent
9dc7859184
commit
f279bc5336
1 changed files with 75 additions and 45 deletions
|
@ -592,21 +592,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");
|
||||
|
||||
|
@ -619,8 +614,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;
|
||||
|
@ -637,10 +630,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)) {
|
||||
|
@ -659,12 +651,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);
|
||||
|
@ -731,8 +717,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;
|
||||
}
|
||||
|
||||
|
@ -751,8 +735,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)) {
|
||||
|
@ -1033,8 +1015,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)) {
|
||||
|
@ -1363,11 +1343,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;
|
||||
}
|
||||
|
||||
|
@ -1378,21 +1356,16 @@ 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);
|
||||
|
||||
if (!context->intra_only)
|
||||
demux->have_nonintraonly_v_streams = TRUE;
|
||||
|
||||
if (codec) {
|
||||
gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
|
||||
GST_TAG_VIDEO_CODEC, codec, NULL);
|
||||
|
@ -1406,8 +1379,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);
|
||||
|
@ -1425,8 +1396,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;
|
||||
|
@ -1498,9 +1467,59 @@ 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");
|
||||
|
||||
if (!context->intra_only)
|
||||
demux->have_nonintraonly_v_streams = TRUE;
|
||||
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));
|
||||
|
@ -1508,7 +1527,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);
|
||||
|
||||
|
@ -1576,9 +1595,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
|
||||
|
@ -3085,9 +3101,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,
|
||||
|
|
Loading…
Reference in a new issue