mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
gst/playback/gstplaysink.c: Move tee in front of the audio and vis pipelines.
Original commit message from CVS: * gst/playback/gstplaysink.c: (gst_play_sink_set_mute), (gst_play_sink_get_mute), (gen_video_chain), (gen_audio_chain), (gen_vis_chain), (gst_play_sink_reconfigure), (gst_play_sink_request_pad): Move tee in front of the audio and vis pipelines. Add queue for audio for now. Add visualisation support. * tests/examples/seek/seek.c: (main): Visualisation is by default disabled.
This commit is contained in:
parent
a8a8d689c9
commit
5659831526
3 changed files with 123 additions and 47 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2008-02-15 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
|
* gst/playback/gstplaysink.c: (gst_play_sink_set_mute),
|
||||||
|
(gst_play_sink_get_mute), (gen_video_chain), (gen_audio_chain),
|
||||||
|
(gen_vis_chain), (gst_play_sink_reconfigure),
|
||||||
|
(gst_play_sink_request_pad):
|
||||||
|
Move tee in front of the audio and vis pipelines.
|
||||||
|
Add queue for audio for now.
|
||||||
|
Add visualisation support.
|
||||||
|
|
||||||
|
* tests/examples/seek/seek.c: (main):
|
||||||
|
Visualisation is by default disabled.
|
||||||
|
|
||||||
2008-02-15 Sebastian Dröge <slomo@circular-chaos.org>
|
2008-02-15 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
* ext/gio/gstgiobasesink.c: (close_stream_cb):
|
* ext/gio/gstgiobasesink.c: (close_stream_cb):
|
||||||
|
|
|
@ -48,8 +48,7 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GstPlayChain chain;
|
GstPlayChain chain;
|
||||||
GstElement *tee;
|
GstElement *queue;
|
||||||
GstPad *teesrc;
|
|
||||||
GstElement *conv;
|
GstElement *conv;
|
||||||
GstElement *resample;
|
GstElement *resample;
|
||||||
GstElement *volume; /* element with the volume property */
|
GstElement *volume; /* element with the volume property */
|
||||||
|
@ -69,7 +68,6 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GstPlayChain chain;
|
GstPlayChain chain;
|
||||||
GstPad *teesrc;
|
|
||||||
GstElement *queue;
|
GstElement *queue;
|
||||||
GstElement *conv;
|
GstElement *conv;
|
||||||
GstElement *resample;
|
GstElement *resample;
|
||||||
|
@ -95,8 +93,14 @@ struct _GstPlaySink
|
||||||
|
|
||||||
GstPad *audio_pad;
|
GstPad *audio_pad;
|
||||||
gboolean audio_pad_raw;
|
gboolean audio_pad_raw;
|
||||||
|
GstElement *audio_tee;
|
||||||
|
GstPad *audio_tee_sink;
|
||||||
|
GstPad *audio_tee_asrc;
|
||||||
|
GstPad *audio_tee_vissrc;
|
||||||
|
|
||||||
GstPad *video_pad;
|
GstPad *video_pad;
|
||||||
gboolean video_pad_raw;
|
gboolean video_pad_raw;
|
||||||
|
|
||||||
GstPad *text_pad;
|
GstPad *text_pad;
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
|
@ -724,7 +728,7 @@ activate_chain (GstPlayChain * chain, gboolean activate)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static GstPlayChain *
|
static GstPlayChain *
|
||||||
gen_video_chain (GstPlaySink * playsink, gboolean raw)
|
gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
|
||||||
{
|
{
|
||||||
GstPlayVideoChain *chain;
|
GstPlayVideoChain *chain;
|
||||||
GstBin *bin;
|
GstBin *bin;
|
||||||
|
@ -744,6 +748,9 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw)
|
||||||
goto no_sinks;
|
goto no_sinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME, proxy property in sinks */
|
||||||
|
/* g_object_set (chain->sink, "async", async, NULL); */
|
||||||
|
|
||||||
/* create a bin to hold objects, as we create them we add them to this bin so
|
/* create a bin to hold objects, as we create them we add them to this bin so
|
||||||
* that when something goes wrong we only need to unref the bin */
|
* that when something goes wrong we only need to unref the bin */
|
||||||
chain->chain.bin = gst_bin_new ("vbin");
|
chain->chain.bin = gst_bin_new ("vbin");
|
||||||
|
@ -774,14 +781,14 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw)
|
||||||
gst_bin_add (bin, chain->queue);
|
gst_bin_add (bin, chain->queue);
|
||||||
|
|
||||||
if (raw) {
|
if (raw) {
|
||||||
gst_element_link_pads (chain->conv, "src", chain->queue, "sink");
|
gst_element_link_pads (chain->queue, "src", chain->conv, "sink");
|
||||||
gst_element_link_pads (chain->queue, "src", chain->scale, "sink");
|
gst_element_link_pads (chain->conv, "src", chain->scale, "sink");
|
||||||
/* be more careful with the pad from the custom sink element, it might not
|
/* be more careful with the pad from the custom sink element, it might not
|
||||||
* be named 'sink' */
|
* be named 'sink' */
|
||||||
if (!gst_element_link_pads (chain->scale, "src", chain->sink, NULL))
|
if (!gst_element_link_pads (chain->scale, "src", chain->sink, NULL))
|
||||||
goto link_failed;
|
goto link_failed;
|
||||||
|
|
||||||
pad = gst_element_get_pad (chain->conv, "sink");
|
pad = gst_element_get_pad (chain->queue, "sink");
|
||||||
} else {
|
} else {
|
||||||
if (!gst_element_link_pads (chain->queue, "src", chain->sink, NULL))
|
if (!gst_element_link_pads (chain->queue, "src", chain->sink, NULL))
|
||||||
goto link_failed;
|
goto link_failed;
|
||||||
|
@ -957,8 +964,8 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw)
|
||||||
gst_bin_add (bin, chain->sink);
|
gst_bin_add (bin, chain->sink);
|
||||||
|
|
||||||
if (raw) {
|
if (raw) {
|
||||||
chain->tee = gst_element_factory_make ("tee", "atee");
|
chain->queue = gst_element_factory_make ("queue", "aqueue");
|
||||||
gst_bin_add (bin, chain->tee);
|
gst_bin_add (bin, chain->queue);
|
||||||
|
|
||||||
chain->conv = gst_element_factory_make ("audioconvert", "aconv");
|
chain->conv = gst_element_factory_make ("audioconvert", "aconv");
|
||||||
if (chain->conv == NULL)
|
if (chain->conv == NULL)
|
||||||
|
@ -970,12 +977,9 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw)
|
||||||
goto no_audioresample;
|
goto no_audioresample;
|
||||||
gst_bin_add (bin, chain->resample);
|
gst_bin_add (bin, chain->resample);
|
||||||
|
|
||||||
chain->teesrc = gst_element_get_request_pad (chain->tee, "src%d");
|
/* FIXME, remove queue */
|
||||||
pad = gst_element_get_pad (chain->conv, "sink");
|
res = gst_element_link_pads (chain->queue, "src", chain->conv, "sink");
|
||||||
gst_pad_link (chain->teesrc, pad);
|
res &= gst_element_link_pads (chain->conv, "src", chain->resample, "sink");
|
||||||
gst_object_unref (pad);
|
|
||||||
|
|
||||||
res = gst_element_link_pads (chain->conv, "src", chain->resample, "sink");
|
|
||||||
|
|
||||||
/* FIXME check if the sink has the volume property */
|
/* FIXME check if the sink has the volume property */
|
||||||
|
|
||||||
|
@ -1000,7 +1004,7 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw)
|
||||||
if (!res)
|
if (!res)
|
||||||
goto link_failed;
|
goto link_failed;
|
||||||
|
|
||||||
pad = gst_element_get_pad (chain->tee, "sink");
|
pad = gst_element_get_pad (chain->queue, "sink");
|
||||||
} else {
|
} else {
|
||||||
pad = gst_element_get_pad (chain->sink, "sink");
|
pad = gst_element_get_pad (chain->sink, "sink");
|
||||||
}
|
}
|
||||||
|
@ -1056,17 +1060,16 @@ link_failed:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +--------------------------------------------------+
|
* +----------------------------------------------------+
|
||||||
* | visbin |
|
* | visbin |
|
||||||
* | +--------+ +------------+ +-------+ |
|
* | +----------+ +------------+ +-------+ |
|
||||||
* | | vqueue | | audioconv | | vis | |
|
* | | visqueue | | audioconv | | vis | |
|
||||||
* | +-sink src-sink + samp src-sink src-+ |
|
* | +-sink src-sink + samp src-sink src-+ |
|
||||||
* | | +--------+ +------------+ +-------+ | |
|
* | | +----------+ +------------+ +-------+ | |
|
||||||
* sink-+ +-src
|
* sink-+ +-src
|
||||||
* +--------------------------------------------------+
|
* +----------------------------------------------------+
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#if 0
|
|
||||||
static GstPlayChain *
|
static GstPlayChain *
|
||||||
gen_vis_chain (GstPlaySink * playsink)
|
gen_vis_chain (GstPlaySink * playsink)
|
||||||
{
|
{
|
||||||
|
@ -1078,7 +1081,7 @@ gen_vis_chain (GstPlaySink * playsink)
|
||||||
chain = g_new0 (GstPlayVisChain, 1);
|
chain = g_new0 (GstPlayVisChain, 1);
|
||||||
chain->chain.playsink = gst_object_ref (playsink);
|
chain->chain.playsink = gst_object_ref (playsink);
|
||||||
|
|
||||||
chain->chain.bin = gst_bin_new ("abin");
|
chain->chain.bin = gst_bin_new ("visbin");
|
||||||
bin = GST_BIN_CAST (chain->chain.bin);
|
bin = GST_BIN_CAST (chain->chain.bin);
|
||||||
gst_object_ref (bin);
|
gst_object_ref (bin);
|
||||||
gst_object_sink (bin);
|
gst_object_sink (bin);
|
||||||
|
@ -1159,7 +1162,6 @@ link_failed:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1193,39 +1195,47 @@ gboolean
|
||||||
gst_play_sink_reconfigure (GstPlaySink * playsink)
|
gst_play_sink_reconfigure (GstPlaySink * playsink)
|
||||||
{
|
{
|
||||||
GstPlayFlags flags;
|
GstPlayFlags flags;
|
||||||
|
gboolean need_audio, need_video, need_vis;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playsink, "reconfiguring");
|
GST_DEBUG_OBJECT (playsink, "reconfiguring");
|
||||||
|
|
||||||
|
/* assume we need nothing */
|
||||||
|
need_audio = need_video = need_vis = FALSE;
|
||||||
|
|
||||||
GST_PLAY_SINK_LOCK (playsink);
|
GST_PLAY_SINK_LOCK (playsink);
|
||||||
GST_OBJECT_LOCK (playsink);
|
GST_OBJECT_LOCK (playsink);
|
||||||
|
/* get flags, there are protected with the object lock */
|
||||||
flags = playsink->flags;
|
flags = playsink->flags;
|
||||||
GST_OBJECT_UNLOCK (playsink);
|
GST_OBJECT_UNLOCK (playsink);
|
||||||
|
|
||||||
if (flags & GST_PLAY_FLAG_AUDIO && playsink->audio_pad) {
|
/* figure out which components we need */
|
||||||
if (!playsink->audiochain)
|
if (flags & GST_PLAY_FLAG_VIDEO && playsink->video_pad) {
|
||||||
playsink->audiochain =
|
/* we have video and we are requested to show it */
|
||||||
gen_audio_chain (playsink, playsink->audio_pad_raw);
|
need_video = TRUE;
|
||||||
add_chain (playsink->audiochain, TRUE);
|
}
|
||||||
activate_chain (playsink->audiochain, TRUE);
|
if (playsink->audio_pad) {
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->audio_pad),
|
if (flags & GST_PLAY_FLAG_AUDIO) {
|
||||||
playsink->audiochain->sinkpad);
|
need_audio = TRUE;
|
||||||
} else {
|
}
|
||||||
if (playsink->audiochain) {
|
if (flags & GST_PLAY_FLAG_VIS && !need_video) {
|
||||||
add_chain (playsink->audiochain, FALSE);
|
/* also add video when we add visualisation */
|
||||||
activate_chain (playsink->audiochain, FALSE);
|
need_video = TRUE;
|
||||||
|
need_vis = TRUE;
|
||||||
}
|
}
|
||||||
if (playsink->audio_pad)
|
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->audio_pad), NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & GST_PLAY_FLAG_VIDEO && playsink->video_pad) {
|
if (need_video) {
|
||||||
|
GST_DEBUG_OBJECT (playsink, "adding video, raw %d",
|
||||||
|
playsink->video_pad_raw);
|
||||||
if (!playsink->videochain)
|
if (!playsink->videochain)
|
||||||
playsink->videochain =
|
playsink->videochain =
|
||||||
gen_video_chain (playsink, playsink->video_pad_raw);
|
gen_video_chain (playsink, need_vis ? TRUE : playsink->video_pad_raw,
|
||||||
|
!need_vis);
|
||||||
add_chain (playsink->videochain, TRUE);
|
add_chain (playsink->videochain, TRUE);
|
||||||
activate_chain (playsink->videochain, TRUE);
|
activate_chain (playsink->videochain, TRUE);
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad),
|
if (!need_vis)
|
||||||
playsink->videochain->sinkpad);
|
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad),
|
||||||
|
playsink->videochain->sinkpad);
|
||||||
} else {
|
} else {
|
||||||
if (playsink->videochain) {
|
if (playsink->videochain) {
|
||||||
add_chain (playsink->videochain, FALSE);
|
add_chain (playsink->videochain, FALSE);
|
||||||
|
@ -1234,6 +1244,45 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
|
||||||
if (playsink->video_pad)
|
if (playsink->video_pad)
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad), NULL);
|
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (need_audio) {
|
||||||
|
GST_DEBUG_OBJECT (playsink, "adding audio");
|
||||||
|
if (!playsink->audiochain)
|
||||||
|
playsink->audiochain =
|
||||||
|
gen_audio_chain (playsink, playsink->audio_pad_raw);
|
||||||
|
add_chain (playsink->audiochain, TRUE);
|
||||||
|
gst_pad_link (playsink->audio_tee_asrc, playsink->audiochain->sinkpad);
|
||||||
|
activate_chain (playsink->audiochain, TRUE);
|
||||||
|
} else {
|
||||||
|
/* we have no audio or we are requested to not play audio */
|
||||||
|
if (playsink->audiochain) {
|
||||||
|
gst_pad_unlink (playsink->audio_tee_asrc, playsink->audiochain->sinkpad);
|
||||||
|
add_chain (playsink->audiochain, FALSE);
|
||||||
|
activate_chain (playsink->audiochain, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_vis) {
|
||||||
|
GstPad *srcpad;
|
||||||
|
|
||||||
|
if (!playsink->vischain)
|
||||||
|
playsink->vischain = gen_vis_chain (playsink);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (playsink, "adding visualisation");
|
||||||
|
|
||||||
|
srcpad =
|
||||||
|
gst_element_get_pad (GST_ELEMENT_CAST (playsink->vischain->bin), "src");
|
||||||
|
add_chain (playsink->vischain, TRUE);
|
||||||
|
gst_pad_link (playsink->audio_tee_vissrc, playsink->vischain->sinkpad);
|
||||||
|
gst_pad_link (srcpad, playsink->videochain->sinkpad);
|
||||||
|
gst_object_unref (srcpad);
|
||||||
|
activate_chain (playsink->vischain, TRUE);
|
||||||
|
} else {
|
||||||
|
if (playsink->vischain) {
|
||||||
|
add_chain (playsink->vischain, FALSE);
|
||||||
|
activate_chain (playsink->vischain, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
GST_PLAY_SINK_UNLOCK (playsink);
|
GST_PLAY_SINK_UNLOCK (playsink);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1278,9 +1327,23 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
|
||||||
case GST_PLAY_SINK_TYPE_AUDIO_RAW:
|
case GST_PLAY_SINK_TYPE_AUDIO_RAW:
|
||||||
raw = TRUE;
|
raw = TRUE;
|
||||||
case GST_PLAY_SINK_TYPE_AUDIO:
|
case GST_PLAY_SINK_TYPE_AUDIO:
|
||||||
|
if (!playsink->audio_tee) {
|
||||||
|
/* create tee when needed. This element will feed the audio sink chain
|
||||||
|
* and the vis chain. */
|
||||||
|
playsink->audio_tee = gst_element_factory_make ("tee", "audiotee");
|
||||||
|
playsink->audio_tee_sink =
|
||||||
|
gst_element_get_pad (playsink->audio_tee, "sink");
|
||||||
|
/* get two request pads */
|
||||||
|
playsink->audio_tee_asrc =
|
||||||
|
gst_element_get_request_pad (playsink->audio_tee, "src%d");
|
||||||
|
playsink->audio_tee_vissrc =
|
||||||
|
gst_element_get_request_pad (playsink->audio_tee, "src%d");
|
||||||
|
gst_bin_add (GST_BIN_CAST (playsink), playsink->audio_tee);
|
||||||
|
gst_element_set_state (playsink->audio_tee, GST_STATE_PAUSED);
|
||||||
|
}
|
||||||
if (!playsink->audio_pad) {
|
if (!playsink->audio_pad) {
|
||||||
playsink->audio_pad =
|
playsink->audio_pad =
|
||||||
gst_ghost_pad_new_no_target ("audio_sink", GST_PAD_SINK);
|
gst_ghost_pad_new ("audio_sink", playsink->audio_tee_sink);
|
||||||
created = TRUE;
|
created = TRUE;
|
||||||
}
|
}
|
||||||
playsink->audio_pad_raw = raw;
|
playsink->audio_pad_raw = raw;
|
||||||
|
|
|
@ -1898,7 +1898,7 @@ main (int argc, char **argv)
|
||||||
gtk_box_pack_start (GTK_BOX (boxes), text_checkbox, TRUE, TRUE, 2);
|
gtk_box_pack_start (GTK_BOX (boxes), text_checkbox, TRUE, TRUE, 2);
|
||||||
gtk_box_pack_start (GTK_BOX (boxes), mute_checkbox, TRUE, TRUE, 2);
|
gtk_box_pack_start (GTK_BOX (boxes), mute_checkbox, TRUE, TRUE, 2);
|
||||||
gtk_box_pack_start (GTK_BOX (boxes), volume_spinbutton, TRUE, TRUE, 2);
|
gtk_box_pack_start (GTK_BOX (boxes), volume_spinbutton, TRUE, TRUE, 2);
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (vis_checkbox), TRUE);
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (vis_checkbox), FALSE);
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (audio_checkbox), TRUE);
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (audio_checkbox), TRUE);
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (video_checkbox), TRUE);
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (video_checkbox), TRUE);
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (text_checkbox), TRUE);
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (text_checkbox), TRUE);
|
||||||
|
|
Loading…
Reference in a new issue