summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-03-23 19:40:18 +0100
committerWim Taymans <wim.taymans@collabora.co.uk>2009-03-23 19:40:18 +0100
commit14be3f41e26255cf559169b4cc1acd21653d990e (patch)
tree4180e9e3e0752c1edb92c1b5d89d2214a0ffb54a
parent7628319688e0fc931d177114c477629bc8ff913c (diff)
playbin2: fix reuse of the video chains
When reusing playbin with visualisations, reset the async property on the video sink because some sinks might dynamically recreate their sinks. Fixes #576188
-rw-r--r--gst/playback/gstplaysink.c77
1 files changed, 66 insertions, 11 deletions
diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c
index 6f4365e47..c855fdd48 100644
--- a/gst/playback/gstplaysink.c
+++ b/gst/playback/gstplaysink.c
@@ -34,7 +34,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_play_sink_debug);
#define VOLUME_MAX_DOUBLE 10.0
-#define GST_PLAY_CHAIN(c) (GstPlayChain *)(c)
+#define GST_PLAY_CHAIN(c) ((GstPlayChain *)(c))
/* holds the common data fields for the audio and video pipelines. We keep them
* in a structure to more easily have all the info available. */
@@ -895,6 +895,39 @@ link_failed:
}
}
+static gboolean
+setup_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
+{
+ GstElement *elem;
+ GstPlayVideoChain *chain;
+ GstStateChangeReturn ret;
+
+ chain = playsink->videochain;
+
+ /* if the chain was active we don't do anything */
+ if (GST_PLAY_CHAIN (chain)->activated == TRUE)
+ return TRUE;
+
+ /* try to set the sink element to READY again */
+ ret = gst_element_set_state (chain->sink, GST_STATE_READY);
+ if (ret == GST_STATE_CHANGE_FAILURE)
+ return FALSE;
+
+ /* if we can disable async behaviour of the sink, we can avoid adding a
+ * queue for the audio chain. */
+ elem = gst_play_sink_find_property_sinks (playsink, chain->sink, "async");
+ if (elem) {
+ GST_DEBUG_OBJECT (playsink, "setting async property to %d on element %s",
+ async, GST_ELEMENT_NAME (elem));
+ g_object_set (elem, "async", async, NULL);
+ chain->async = async;
+ } else {
+ GST_DEBUG_OBJECT (playsink, "no async property on the sink");
+ chain->async = TRUE;
+ }
+ return TRUE;
+}
+
/* make an element for playback of video with subtitles embedded.
*
* +----------------------------------------------+
@@ -1121,9 +1154,10 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw, gboolean queue)
/* check if the sink, or something within the sink, has the volume property.
* If it does we don't need to add a volume element. */
- chain->volume =
- gst_play_sink_find_property_sinks (playsink, chain->sink, "volume");
- if (chain->volume) {
+ elem = gst_play_sink_find_property_sinks (playsink, chain->sink, "volume");
+ if (elem) {
+ chain->volume = elem;
+
GST_DEBUG_OBJECT (playsink, "the sink has a volume property");
have_volume = TRUE;
/* use the sink to control the volume */
@@ -1416,17 +1450,28 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
/* set up video pipeline */
if (need_video) {
+ gboolean raw, async;
+
+ /* we need a raw sink when we do vis or when we have a raw pad */
+ raw = need_vis ? TRUE : playsink->video_pad_raw;
+ /* we try to set the sink async=FALSE when we need vis, this way we can
+ * avoid a queue in the audio chain. */
+ async = !need_vis;
+
GST_DEBUG_OBJECT (playsink, "adding video, raw %d",
playsink->video_pad_raw);
- if (!playsink->videochain) {
- gboolean raw, async;
- /* we need a raw sink when we do vis or when we have a raw pad */
- raw = need_vis ? TRUE : playsink->video_pad_raw;
- /* we try to set the sink async=FALSE when we need vis, this way we can
- * avoid a queue in the audio chain. */
- async = !need_vis;
+ if (playsink->videochain) {
+ /* try to reactivate the chain */
+ if (!setup_video_chain (playsink, raw, async)) {
+ add_chain (GST_PLAY_CHAIN (playsink->videochain), FALSE);
+ activate_chain (GST_PLAY_CHAIN (playsink->videochain), FALSE);
+ free_chain ((GstPlayChain *) playsink->videochain);
+ playsink->videochain = NULL;
+ }
+ }
+ if (!playsink->videochain) {
playsink->videochain = gen_video_chain (playsink, raw, async);
}
if (playsink->videochain) {
@@ -1544,6 +1589,8 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
}
add_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
activate_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
+ free_chain ((GstPlayChain *) playsink->audiochain);
+ playsink->audiochain = NULL;
create_chain = TRUE;
}
}
@@ -1969,6 +2016,14 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
activate_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
add_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
}
+ if (playsink->vischain) {
+ activate_chain (GST_PLAY_CHAIN (playsink->vischain), FALSE);
+ add_chain (GST_PLAY_CHAIN (playsink->vischain), FALSE);
+ }
+ if (playsink->textchain) {
+ activate_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE);
+ add_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE);
+ }
break;
default:
break;