From 1e28cba08883129cfcdb619b94858bbeb026fcb3 Mon Sep 17 00:00:00 2001 From: "hoonhee.lee" Date: Tue, 25 Apr 2017 16:35:45 +0900 Subject: [PATCH] decodebin3: Re-order all streams and add to collection Sort all streams from parsebins by stream type and SELECT flag and stream-id. First video, then audio, then others. https://bugzilla.gnome.org/show_bug.cgi?id=775615 --- gst/playback/gstdecodebin3.c | 82 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/gst/playback/gstdecodebin3.c b/gst/playback/gstdecodebin3.c index 3a61645..09828e2 100644 --- a/gst/playback/gstdecodebin3.c +++ b/gst/playback/gstdecodebin3.c @@ -1139,6 +1139,70 @@ beach: SELECTION_UNLOCK (dbin); } +/* sort_streams: + * GCompareFunc to use with lists of GstStream. + * Sorts GstStreams by stream type and SELECT flag and stream-id + * First video, then audio, then others. + * + * Return: negative if ab + */ +static gint +sort_streams (GstStream * sa, GstStream * sb) +{ + GstStreamType typea, typeb; + GstStreamFlags flaga, flagb; + const gchar *ida, *idb; + gint ret = 0; + + typea = gst_stream_get_stream_type (sa); + typeb = gst_stream_get_stream_type (sb); + + GST_LOG ("sa(%s), sb(%s)", gst_stream_get_stream_id (sa), + gst_stream_get_stream_id (sb)); + + /* Sort by stream type. First video, then audio, then others(text, container, unknown) */ + if (typea != typeb) { + if (typea & GST_STREAM_TYPE_VIDEO) + ret = -1; + else if (typea & GST_STREAM_TYPE_AUDIO) + ret = (!(typeb & GST_STREAM_TYPE_VIDEO)) ? -1 : 1; + else if (typea & GST_STREAM_TYPE_TEXT) + ret = (!(typeb & GST_STREAM_TYPE_VIDEO) + && !(typeb & GST_STREAM_TYPE_AUDIO)) ? -1 : 1; + else if (typea & GST_STREAM_TYPE_CONTAINER) + ret = (typeb & GST_STREAM_TYPE_UNKNOWN) ? -1 : 1; + else + ret = 1; + + if (ret != 0) { + GST_LOG ("Sort by stream-type: %d", ret); + return ret; + } + } + + /* Sort by SELECT flag, if stream type is same. */ + flaga = gst_stream_get_stream_flags (sa); + flagb = gst_stream_get_stream_flags (sb); + + ret = + (flaga & GST_STREAM_FLAG_SELECT) ? ((flagb & GST_STREAM_FLAG_SELECT) ? 0 : + -1) : ((flagb & GST_STREAM_FLAG_SELECT) ? 1 : 0); + + if (ret != 0) { + GST_LOG ("Sort by SELECT flag: %d", ret); + return ret; + } + + /* Sort by stream-id, if otherwise the same. */ + ida = gst_stream_get_stream_id (sa); + idb = gst_stream_get_stream_id (sb); + ret = g_strcmp0 (ida, idb); + + GST_LOG ("Sort by stream-id: %d", ret); + + return ret; +} + /* Call with INPUT_LOCK taken */ static GstStreamCollection * get_merged_collection (GstDecodebin3 * dbin) @@ -1146,6 +1210,7 @@ get_merged_collection (GstDecodebin3 * dbin) gboolean needs_merge = FALSE; GstStreamCollection *res = NULL; GList *tmp; + GList *unsorted_streams = NULL; guint i, nb_stream; /* First check if we need to do a merge or just return the only collection */ @@ -1176,7 +1241,7 @@ get_merged_collection (GstDecodebin3 * dbin) for (i = 0; i < nb_stream; i++) { GstStream *stream = gst_stream_collection_get_stream (dbin->main_input->collection, i); - gst_stream_collection_add_stream (res, gst_object_ref (stream)); + unsorted_streams = g_list_append (unsorted_streams, stream); } } @@ -1190,11 +1255,24 @@ get_merged_collection (GstDecodebin3 * dbin) for (i = 0; i < nb_stream; i++) { GstStream *stream = gst_stream_collection_get_stream (input->collection, i); - gst_stream_collection_add_stream (res, gst_object_ref (stream)); + unsorted_streams = g_list_append (unsorted_streams, stream); } } } + /* re-order streams : video, then audio, then others */ + unsorted_streams = + g_list_sort (unsorted_streams, (GCompareFunc) sort_streams); + for (tmp = unsorted_streams; tmp; tmp = tmp->next) { + GstStream *stream = (GstStream *) tmp->data; + GST_DEBUG_OBJECT (dbin, "Adding #stream(%s) to collection", + gst_stream_get_stream_id (stream)); + gst_stream_collection_add_stream (res, gst_object_ref (stream)); + } + + if (unsorted_streams) + g_list_free (unsorted_streams); + return res; } -- 2.7.4