summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2014-03-28 13:02:54 +0100
committerSebastian Dröge <sebastian@centricular.com>2014-09-11 17:09:59 +0300
commita38d2567d2a0623ba4631bea0117cfcad6daa403 (patch)
treed1af6f3e6f86024bb3104b440b55e92f5849cc9d
parent0bf81236c2f1e4661106020fd0b5e2c7f6e7f160 (diff)
downloadgstreamer-plugins-base-a38d2567d2a0623ba4631bea0117cfcad6daa403.tar.gz
playbin: filter out buffering messages when switching uri
When switching URI from about-to-finish, playbin starts decoding the new URI and the queue2 inside uridecodebin starts emitting buffering messages immediately. However, the queue(s) inside playsink still have buffers to play and the pipeline doesn't need to pause for buffering, so we should not send those buffering messages up to the application, otherwise there is an audible glitch caused by pausing the pipeline for a very short time. https://bugzilla.gnome.org/show_bug.cgi?id=727255
-rw-r--r--gst/playback/gstplaybin2.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c
index 08283436c..ab5879863 100644
--- a/gst/playback/gstplaybin2.c
+++ b/gst/playback/gstplaybin2.c
@@ -367,6 +367,9 @@ struct _GstSourceGroup
GMutex suburi_flushes_to_drop_lock;
GSList *suburi_flushes_to_drop;
+ /* buffering message stored for after switching */
+ GstMessage *pending_buffering_msg;
+
/* combiners for different streams */
GstSourceCombine combiner[PLAYBIN_STREAM_LAST];
};
@@ -1336,6 +1339,10 @@ free_group (GstPlayBin * playbin, GstSourceGroup * group)
if (group->suburi_flushes_to_drop_lock.p)
g_mutex_clear (&group->suburi_flushes_to_drop_lock);
group->suburi_flushes_to_drop_lock.p = NULL;
+
+ if (group->pending_buffering_msg)
+ gst_message_unref (group->pending_buffering_msg);
+ group->pending_buffering_msg = NULL;
}
static void
@@ -2741,8 +2748,43 @@ gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
}
} else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAM_START) {
GstSourceGroup *new_group = playbin->curr_group;
+ GstMessage *buffering_msg = NULL;
+ GST_SOURCE_GROUP_LOCK (new_group);
new_group->stream_changed_pending = FALSE;
+ if (new_group->pending_buffering_msg) {
+ buffering_msg = new_group->pending_buffering_msg;
+ new_group->pending_buffering_msg = NULL;
+ }
+ GST_SOURCE_GROUP_UNLOCK (new_group);
+
+ GST_DEBUG_OBJECT (playbin, "Stream start from new group %p", new_group);
+
+ if (buffering_msg) {
+ GST_DEBUG_OBJECT (playbin, "Posting pending buffering message: %"
+ GST_PTR_FORMAT, buffering_msg);
+ GST_BIN_CLASS (parent_class)->handle_message (bin, buffering_msg);
+ }
+
+ } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_BUFFERING) {
+ GstSourceGroup *group = playbin->curr_group;
+ gboolean pending;
+
+ /* drop buffering messages from child queues while we are switching
+ * groups (because the application set a new uri in about-to-finish)
+ * if the playsink queue still has buffers to play */
+
+ GST_SOURCE_GROUP_LOCK (group);
+ pending = group->stream_changed_pending;
+
+ if (pending) {
+ GST_DEBUG_OBJECT (playbin, "Storing buffering message from pending group "
+ "%p %" GST_PTR_FORMAT, group, msg);
+ gst_message_replace (&group->pending_buffering_msg, msg);
+ gst_message_unref (msg);
+ msg = NULL;
+ }
+ GST_SOURCE_GROUP_UNLOCK (group);
} else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
/* If we get an error of the subtitle uridecodebin transform
* them into warnings and disable the subtitles */
@@ -5343,11 +5385,11 @@ setup_next_source (GstPlayBin * playbin, GstState target)
if (!new_group || !new_group->valid)
goto no_next_group;
- new_group->stream_changed_pending = TRUE;
-
/* first unlink the current source, if any */
old_group = playbin->curr_group;
if (old_group && old_group->valid && old_group->active) {
+ new_group->stream_changed_pending = TRUE;
+
gst_play_bin_update_cached_duration (playbin);
/* unlink our pads with the sink */
deactivate_group (playbin, old_group);