From 5659831526eead04da187a2f18599607bcd54da4 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 15 Feb 2008 18:38:52 +0000 Subject: [PATCH] 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. --- ChangeLog | 13 ++++ gst/playback/gstplaysink.c | 155 ++++++++++++++++++++++++++----------- tests/examples/seek/seek.c | 2 +- 3 files changed, 123 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index df2eb2b5fe..49c06cd598 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-02-15 Wim Taymans + + * 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 * ext/gio/gstgiobasesink.c: (close_stream_cb): diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index d39253b8c7..2ec20e2303 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -48,8 +48,7 @@ typedef struct typedef struct { GstPlayChain chain; - GstElement *tee; - GstPad *teesrc; + GstElement *queue; GstElement *conv; GstElement *resample; GstElement *volume; /* element with the volume property */ @@ -69,7 +68,6 @@ typedef struct typedef struct { GstPlayChain chain; - GstPad *teesrc; GstElement *queue; GstElement *conv; GstElement *resample; @@ -95,8 +93,14 @@ struct _GstPlaySink GstPad *audio_pad; gboolean audio_pad_raw; + GstElement *audio_tee; + GstPad *audio_tee_sink; + GstPad *audio_tee_asrc; + GstPad *audio_tee_vissrc; + GstPad *video_pad; gboolean video_pad_raw; + GstPad *text_pad; /* properties */ @@ -724,7 +728,7 @@ activate_chain (GstPlayChain * chain, gboolean activate) * */ static GstPlayChain * -gen_video_chain (GstPlaySink * playsink, gboolean raw) +gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async) { GstPlayVideoChain *chain; GstBin *bin; @@ -744,6 +748,9 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw) 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 * that when something goes wrong we only need to unref the bin */ chain->chain.bin = gst_bin_new ("vbin"); @@ -774,14 +781,14 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw) gst_bin_add (bin, chain->queue); if (raw) { - gst_element_link_pads (chain->conv, "src", chain->queue, "sink"); - gst_element_link_pads (chain->queue, "src", chain->scale, "sink"); + gst_element_link_pads (chain->queue, "src", chain->conv, "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 named 'sink' */ if (!gst_element_link_pads (chain->scale, "src", chain->sink, NULL)) goto link_failed; - pad = gst_element_get_pad (chain->conv, "sink"); + pad = gst_element_get_pad (chain->queue, "sink"); } else { if (!gst_element_link_pads (chain->queue, "src", chain->sink, NULL)) goto link_failed; @@ -957,8 +964,8 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw) gst_bin_add (bin, chain->sink); if (raw) { - chain->tee = gst_element_factory_make ("tee", "atee"); - gst_bin_add (bin, chain->tee); + chain->queue = gst_element_factory_make ("queue", "aqueue"); + gst_bin_add (bin, chain->queue); chain->conv = gst_element_factory_make ("audioconvert", "aconv"); if (chain->conv == NULL) @@ -970,12 +977,9 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw) goto no_audioresample; gst_bin_add (bin, chain->resample); - chain->teesrc = gst_element_get_request_pad (chain->tee, "src%d"); - pad = gst_element_get_pad (chain->conv, "sink"); - gst_pad_link (chain->teesrc, pad); - gst_object_unref (pad); - - res = gst_element_link_pads (chain->conv, "src", chain->resample, "sink"); + /* FIXME, remove queue */ + res = gst_element_link_pads (chain->queue, "src", chain->conv, "sink"); + res &= gst_element_link_pads (chain->conv, "src", chain->resample, "sink"); /* FIXME check if the sink has the volume property */ @@ -1000,7 +1004,7 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw) if (!res) goto link_failed; - pad = gst_element_get_pad (chain->tee, "sink"); + pad = gst_element_get_pad (chain->queue, "sink"); } else { pad = gst_element_get_pad (chain->sink, "sink"); } @@ -1056,17 +1060,16 @@ link_failed: } /* - * +--------------------------------------------------+ - * | visbin | - * | +--------+ +------------+ +-------+ | - * | | vqueue | | audioconv | | vis | | - * | +-sink src-sink + samp src-sink src-+ | - * | | +--------+ +------------+ +-------+ | | - * sink-+ +-src - * +--------------------------------------------------+ + * +----------------------------------------------------+ + * | visbin | + * | +----------+ +------------+ +-------+ | + * | | visqueue | | audioconv | | vis | | + * | +-sink src-sink + samp src-sink src-+ | + * | | +----------+ +------------+ +-------+ | | + * sink-+ +-src + * +----------------------------------------------------+ * */ -#if 0 static GstPlayChain * gen_vis_chain (GstPlaySink * playsink) { @@ -1078,7 +1081,7 @@ gen_vis_chain (GstPlaySink * playsink) chain = g_new0 (GstPlayVisChain, 1); 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); gst_object_ref (bin); gst_object_sink (bin); @@ -1159,7 +1162,6 @@ link_failed: return NULL; } } -#endif #if 0 static gboolean @@ -1193,39 +1195,47 @@ gboolean gst_play_sink_reconfigure (GstPlaySink * playsink) { GstPlayFlags flags; + gboolean need_audio, need_video, need_vis; GST_DEBUG_OBJECT (playsink, "reconfiguring"); + /* assume we need nothing */ + need_audio = need_video = need_vis = FALSE; + GST_PLAY_SINK_LOCK (playsink); GST_OBJECT_LOCK (playsink); + /* get flags, there are protected with the object lock */ flags = playsink->flags; GST_OBJECT_UNLOCK (playsink); - if (flags & GST_PLAY_FLAG_AUDIO && playsink->audio_pad) { - if (!playsink->audiochain) - playsink->audiochain = - gen_audio_chain (playsink, playsink->audio_pad_raw); - add_chain (playsink->audiochain, TRUE); - activate_chain (playsink->audiochain, TRUE); - gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->audio_pad), - playsink->audiochain->sinkpad); - } else { - if (playsink->audiochain) { - add_chain (playsink->audiochain, FALSE); - activate_chain (playsink->audiochain, FALSE); + /* figure out which components we need */ + if (flags & GST_PLAY_FLAG_VIDEO && playsink->video_pad) { + /* we have video and we are requested to show it */ + need_video = TRUE; + } + if (playsink->audio_pad) { + if (flags & GST_PLAY_FLAG_AUDIO) { + need_audio = TRUE; + } + if (flags & GST_PLAY_FLAG_VIS && !need_video) { + /* also add video when we add visualisation */ + 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) 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); activate_chain (playsink->videochain, TRUE); - gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad), - playsink->videochain->sinkpad); + if (!need_vis) + gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad), + playsink->videochain->sinkpad); } else { if (playsink->videochain) { add_chain (playsink->videochain, FALSE); @@ -1234,6 +1244,45 @@ gst_play_sink_reconfigure (GstPlaySink * playsink) if (playsink->video_pad) 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); return TRUE; @@ -1278,9 +1327,23 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type) case GST_PLAY_SINK_TYPE_AUDIO_RAW: raw = TRUE; 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) { 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; } playsink->audio_pad_raw = raw; diff --git a/tests/examples/seek/seek.c b/tests/examples/seek/seek.c index 460f3feb02..af88e2c935 100644 --- a/tests/examples/seek/seek.c +++ b/tests/examples/seek/seek.c @@ -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), mute_checkbox, 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 (video_checkbox), TRUE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (text_checkbox), TRUE);