mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 14:36:24 +00:00
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
This commit is contained in:
parent
7628319688
commit
14be3f41e2
1 changed files with 67 additions and 12 deletions
|
@ -34,7 +34,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_play_sink_debug);
|
||||||
|
|
||||||
#define VOLUME_MAX_DOUBLE 10.0
|
#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
|
/* 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. */
|
* 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.
|
/* 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.
|
/* 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. */
|
* If it does we don't need to add a volume element. */
|
||||||
chain->volume =
|
elem = gst_play_sink_find_property_sinks (playsink, chain->sink, "volume");
|
||||||
gst_play_sink_find_property_sinks (playsink, chain->sink, "volume");
|
if (elem) {
|
||||||
if (chain->volume) {
|
chain->volume = elem;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playsink, "the sink has a volume property");
|
GST_DEBUG_OBJECT (playsink, "the sink has a volume property");
|
||||||
have_volume = TRUE;
|
have_volume = TRUE;
|
||||||
/* use the sink to control the volume */
|
/* use the sink to control the volume */
|
||||||
|
@ -1416,17 +1450,28 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
|
||||||
|
|
||||||
/* set up video pipeline */
|
/* set up video pipeline */
|
||||||
if (need_video) {
|
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",
|
GST_DEBUG_OBJECT (playsink, "adding video, raw %d",
|
||||||
playsink->video_pad_raw);
|
playsink->video_pad_raw);
|
||||||
|
|
||||||
|
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) {
|
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;
|
|
||||||
|
|
||||||
playsink->videochain = gen_video_chain (playsink, raw, async);
|
playsink->videochain = gen_video_chain (playsink, raw, async);
|
||||||
}
|
}
|
||||||
if (playsink->videochain) {
|
if (playsink->videochain) {
|
||||||
|
@ -1544,6 +1589,8 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
|
||||||
}
|
}
|
||||||
add_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
|
add_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
|
||||||
activate_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;
|
create_chain = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1969,6 +2016,14 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
activate_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
|
activate_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
|
||||||
add_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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue