diff options
-rw-r--r-- | gst/playback/gstdecodebin2.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 85a2ed188..6e5f362e2 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -186,6 +186,8 @@ struct _GstDecodeBin GList *filtered_errors; /* filtered error messages */ GList *buffering_status; /* element currently buffering messages */ + + gboolean extra_buffer_required; /* whether to controll queue size or not */ }; struct _GstDecodeBinClass @@ -253,6 +255,7 @@ enum #define DEFAULT_POST_STREAM_TOPOLOGY FALSE #define DEFAULT_EXPOSE_ALL_STREAMS TRUE #define DEFAULT_CONNECTION_SPEED 0 +#define DEFAULT_EXTRA_SIZE_BUFFERS_BYTES 8 * 1024 * 1024 /* 8 MB */ /* Properties */ enum @@ -1099,6 +1102,8 @@ gst_decode_bin_init (GstDecodeBin * decode_bin) decode_bin->expose_allstreams = DEFAULT_EXPOSE_ALL_STREAMS; decode_bin->connection_speed = DEFAULT_CONNECTION_SPEED; + + decode_bin->extra_buffer_required = FALSE; } static void @@ -3046,6 +3051,7 @@ no_more_pads_cb (GstElement * element, GstDecodeChain * chain) GST_DEBUG_OBJECT (element, "Setting group %p to complete", group); group->no_more_pads = TRUE; + group->dbin->extra_buffer_required = FALSE; /* this group has prerolled enough to not need more pads, * we can probably set its buffering state to playing now */ GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to " @@ -3481,13 +3487,20 @@ multi_queue_overrun_cb (GstElement * queue, GstDecodeGroup * group) GST_LOG_OBJECT (dbin, "multiqueue '%s' (%p) is full", GST_OBJECT_NAME (queue), queue); - group->overrun = TRUE; /* this group has prerolled enough to not need more pads, * we can probably set its buffering state to playing now */ - GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to " - "'playing' buffering mode", group); - decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE, - (group->parent ? group->parent->seekable : TRUE)); + if (!group->no_more_pads && group->parent->demuxer + && !dbin->extra_buffer_required) { + group->overrun = FALSE; + dbin->extra_buffer_required = TRUE; + } else { + GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to " + "'playing' buffering mode", group); + group->overrun = TRUE; + dbin->extra_buffer_required = FALSE; + decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE, + (group->parent ? group->parent->seekable : TRUE)); + } /* FIXME: We should make sure that everything gets exposed now * even if child chains are not complete because the will never @@ -3500,9 +3513,19 @@ multi_queue_overrun_cb (GstElement * queue, GstDecodeGroup * group) if (gst_decode_chain_is_complete (dbin->decode_chain)) { if (!gst_decode_bin_expose (dbin)) GST_WARNING_OBJECT (dbin, "Couldn't expose group"); + } else { + dbin->extra_buffer_required = TRUE; } } EXPOSE_UNLOCK (dbin); + + if (dbin->extra_buffer_required) { + GST_DEBUG_OBJECT (group->dbin, + "Setting group %p multiqueue to " "'extra_buffer_required' mode", + group); + decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE, + (group->parent ? group->parent->seekable : TRUE)); + } } static void @@ -3664,7 +3687,9 @@ decodebin_set_queue_size_full (GstDecodeBin * dbin, GstElement * multiqueue, guint max_bytes, max_buffers; guint64 max_time; - GST_DEBUG_OBJECT (multiqueue, "use buffering %d", use_buffering); + GST_DEBUG_OBJECT (multiqueue, + "use buffering %d, add extra buffer size mode %d", use_buffering, + dbin->extra_buffer_required); if (preroll || use_buffering) { /* takes queue limits, initially we only queue up up to the max bytes limit, @@ -3680,6 +3705,12 @@ decodebin_set_queue_size_full (GstDecodeBin * dbin, GstElement * multiqueue, max_time = seekable ? AUTO_PREROLL_SEEKABLE_SIZE_TIME : AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME; } + } else if (dbin->extra_buffer_required) { + max_bytes = AUTO_PREROLL_SIZE_BYTES + DEFAULT_EXTRA_SIZE_BUFFERS_BYTES; + max_buffers = AUTO_PREROLL_SIZE_BUFFERS; + if ((max_time = dbin->max_size_time) == 0) + max_time = seekable ? AUTO_PREROLL_SEEKABLE_SIZE_TIME : + AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME; } else { /* update runtime limits. At runtime, we try to keep the amount of buffers * in the queues as low as possible (but at least 5 buffers). */ @@ -5170,6 +5201,7 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition) g_list_free_full (dbin->buffering_status, (GDestroyNotify) gst_message_unref); dbin->buffering_status = NULL; + dbin->extra_buffer_required = FALSE; break; case GST_STATE_CHANGE_READY_TO_NULL: default: |