From 26e1c2d628a024da6b72e5ce6ba706f27e869a00 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Sun, 16 Oct 2011 11:32:41 +0100 Subject: [PATCH 01/21] oggdemux: do not retry seeking indefinitely https://bugzilla.gnome.org/show_bug.cgi?id=661897 --- ext/ogg/gstoggdemux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index c883d12733..3a880d48d5 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -3098,6 +3098,7 @@ gst_ogg_demux_get_duration_push (GstOggDemux * ogg, int flags) } else { GST_INFO_OBJECT (ogg, "Seek failed, duration will stay unknown"); ogg->push_state = PUSH_PLAYING; + ogg->push_disable_seeking = TRUE; return FALSE; } } From 5e9862b2ba891b066fcedc4f9c2dcabecfb3b9fc Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 7 Oct 2011 17:41:32 +0100 Subject: [PATCH 02/21] decodebin2: fire drained signal where appropriate This will allow playbin2 to send its about-to-finish signal. Taken out (apparently by mistake) by the EOS rewrite in july. https://bugzilla.gnome.org/show_bug.cgi?id=661202 --- gst/playback/gstdecodebin2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 23b4564656..826ca85992 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -3165,6 +3165,9 @@ beach: GST_DEBUG ("Chain %p (handled:%d, last_group:%d, drained:%d, switched:%d)", chain, handled, *last_group, *drained, *switched); + if (*drained) + g_signal_emit (dbin, gst_decode_bin_signals[SIGNAL_DRAINED], 0, NULL); + return handled; } From becba526d9e1136ab5c476ef34cdb3f440a374b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Tue, 18 Oct 2011 13:00:29 +0200 Subject: [PATCH 03/21] subtitleoverlay: fix event unref in (rare) error case --- gst/playback/gstsubtitleoverlay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/playback/gstsubtitleoverlay.c b/gst/playback/gstsubtitleoverlay.c index f43d945909..cd795dfd6c 100644 --- a/gst/playback/gstsubtitleoverlay.c +++ b/gst/playback/gstsubtitleoverlay.c @@ -1822,7 +1822,7 @@ gst_subtitle_overlay_video_sink_event (GstPad * pad, GstEvent * event) if (format != GST_FORMAT_TIME) { GST_ERROR_OBJECT (pad, "Newsegment event in non-time format: %s", gst_format_get_name (format)); - gst_object_unref (event); + gst_event_unref (event); gst_object_unref (self); return FALSE; } From 4e59e63ff7c3d32b2a81ec52a6825ed00471eec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 19 Oct 2011 00:32:13 +0100 Subject: [PATCH 04/21] baseaudiosink: fix unused variable compiler warning if debugging in core is disabled https://bugzilla.gnome.org/show_bug.cgi?id=660150 --- gst-libs/gst/audio/gstbaseaudiosink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index 6dafb4b322..a7477508e4 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -1367,9 +1367,11 @@ gst_base_audio_sink_get_alignment (GstBaseAudioSink * sink, "align with prev sample, ABS (%" G_GINT64_FORMAT ") < %" G_GINT64_FORMAT, align, maxdrift); } else { + gint64 diff_s G_GNUC_UNUSED; + /* calculate sample diff in seconds for error message */ - gint64 diff_s = gst_util_uint64_scale_int (diff, GST_SECOND, - ringbuf->spec.rate); + diff_s = gst_util_uint64_scale_int (diff, GST_SECOND, ringbuf->spec.rate); + /* timestamps drifted apart from previous samples too much, we need to * resync. We log this as an element warning. */ GST_WARNING_OBJECT (sink, From b4803361c6292c4f628015a2a04f2835d26cedef Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Wed, 19 Oct 2011 10:41:31 +0200 Subject: [PATCH 05/21] x(v)imagesink: make it more clean that "synchronous" props are not for avsync --- sys/ximage/ximagesink.c | 5 +++-- sys/xvimage/xvimagesink.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index d68ec68c6d..41d7df061f 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -2403,8 +2403,9 @@ gst_ximagesink_class_init (GstXImageSinkClass * klass) g_param_spec_string ("display", "Display", "X Display name", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_SYNCHRONOUS, - g_param_spec_boolean ("synchronous", "Synchronous", "When enabled, runs " - "the X display in synchronous mode. (used only for debugging)", FALSE, + g_param_spec_boolean ("synchronous", "Synchronous", + "When enabled, runs the X display in synchronous mode. " + "(unrelated to A/V sync, used only for debugging)", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO, g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio", diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c index ba10ef0717..03e4d30ad8 100644 --- a/sys/xvimage/xvimagesink.c +++ b/sys/xvimage/xvimagesink.c @@ -3575,8 +3575,8 @@ gst_xvimagesink_class_init (GstXvImageSinkClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_SYNCHRONOUS, g_param_spec_boolean ("synchronous", "Synchronous", - "When enabled, runs " - "the X display in synchronous mode. (used only for debugging)", FALSE, + "When enabled, runs the X display in synchronous mode. " + "(unrelated to A/V sync, used only for debugging)", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO, g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio", From 43928e33e6ec9817c9c8ef3e289442b646508168 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 18 Oct 2011 21:40:54 +0200 Subject: [PATCH 06/21] vorbisdec: only finish header packet frame if received in-stream ... rather than scaring audiodecoder with a frame extracted from caps. Fixes #662108 (partially). --- ext/vorbis/gstvorbisdec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/vorbis/gstvorbisdec.c b/ext/vorbis/gstvorbisdec.c index 6e6601a29c..9b0b50bd16 100644 --- a/ext/vorbis/gstvorbisdec.c +++ b/ext/vorbis/gstvorbisdec.c @@ -458,9 +458,6 @@ vorbis_handle_header_packet (GstVorbisDec * vd, ogg_packet * packet) break; } - /* consumer header packet/frame */ - gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), NULL, 1); - return res; /* ERRORS */ @@ -693,6 +690,8 @@ vorbis_dec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer) goto done; } result = vorbis_handle_header_packet (vd, packet); + /* consumer header packet/frame */ + gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), NULL, 1); } else { GstClockTime timestamp, duration; From 1f900dc20d2d74a7255f7aeab2304bbed3a7c45c Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Wed, 19 Oct 2011 15:28:44 +0100 Subject: [PATCH 07/21] vorbisdec: do not try to read past the buffer array https://bugzilla.gnome.org/show_bug.cgi?id=662108 --- ext/vorbis/gstvorbisdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/vorbis/gstvorbisdec.c b/ext/vorbis/gstvorbisdec.c index 9b0b50bd16..9a89fe7fb7 100644 --- a/ext/vorbis/gstvorbisdec.c +++ b/ext/vorbis/gstvorbisdec.c @@ -501,7 +501,7 @@ vorbis_dec_handle_header_caps (GstVorbisDec * vd) GstBuffer *buf = NULL; gint i = 0; - while (result == GST_FLOW_OK) { + while (result == GST_FLOW_OK && i < gst_value_array_get_size (array)) { value = gst_value_array_get_value (array, i); buf = gst_value_get_buffer (value); if (!buf) From 981070eb4471ee303706abd80f22d7e54fc60c60 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 18 Oct 2011 21:42:21 +0200 Subject: [PATCH 08/21] audiodecoder: having gather queue contents implies some draining is in order ... which ensures e.g. processing and sending last fragment of reverse playback downstream at EOS. --- gst-libs/gst/audio/gstaudiodecoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c index 5ed2af107a..2e3d1986b4 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.c +++ b/gst-libs/gst/audio/gstaudiodecoder.c @@ -1008,7 +1008,7 @@ gst_audio_decoder_drain (GstAudioDecoder * dec) { GstFlowReturn ret; - if (dec->priv->drained) + if (dec->priv->drained && !dec->priv->gather) return GST_FLOW_OK; else { /* dispatch reverse pending buffers */ From 56419cce771d16bdcdf173d2b11b40af0c4e80c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Wed, 19 Oct 2011 19:37:07 +0200 Subject: [PATCH 09/21] subtitleoverlay: fix leak of element reference through pad block If the pad block never happens because there is no data flow at all, the callback is never fired and the reference is never released. This causes a reference cycle between the pad and element, so valgrind is not very vocal about it (memory is still reachable). --- gst/playback/gstsubtitleoverlay.c | 85 +++++++++++-------------------- 1 file changed, 29 insertions(+), 56 deletions(-) diff --git a/gst/playback/gstsubtitleoverlay.c b/gst/playback/gstsubtitleoverlay.c index cd795dfd6c..c61cc87922 100644 --- a/gst/playback/gstsubtitleoverlay.c +++ b/gst/playback/gstsubtitleoverlay.c @@ -642,13 +642,11 @@ _setup_passthrough (GstSubtitleOverlay * self) out: /* Unblock pads */ gst_pad_set_blocked_async_full (self->video_block_pad, FALSE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); if (self->subtitle_sink_blocked) gst_pad_set_blocked_async_full (self->subtitle_block_pad, FALSE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); return TRUE; } @@ -791,13 +789,11 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data) /* Unblock pads */ gst_pad_set_blocked_async_full (self->video_block_pad, FALSE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); if (self->subtitle_sink_blocked) gst_pad_set_blocked_async_full (self->subtitle_block_pad, FALSE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); goto out; } else if (target) { gst_object_unref (target); @@ -807,8 +803,7 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data) if (self->subtitle_sink_blocked && !self->video_sink_blocked) { GST_DEBUG_OBJECT (self, "Subtitle sink blocked but video not blocked"); gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); goto out; } @@ -1347,11 +1342,9 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data) } else { GST_DEBUG_OBJECT (self, "Everything worked, unblocking pads"); gst_pad_set_blocked_async_full (self->video_block_pad, FALSE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); gst_pad_set_blocked_async_full (self->subtitle_block_pad, FALSE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); do_async_done (self); } @@ -1381,11 +1374,9 @@ gst_subtitle_overlay_change_state (GstElement * element, GST_SUBTITLE_OVERLAY_LOCK (self); /* Set the internal pads to blocking */ gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); GST_SUBTITLE_OVERLAY_UNLOCK (self); break; case GST_STATE_CHANGE_READY_TO_PAUSED: @@ -1452,13 +1443,13 @@ gst_subtitle_overlay_change_state (GstElement * element, if (self->video_block_pad) { pad = self->video_block_pad; gst_pad_set_blocked_async_full (pad, FALSE, _pad_blocked_cb, - gst_object_ref (self), (GDestroyNotify) gst_object_unref); + self, NULL); } if (self->subtitle_block_pad) { pad = self->subtitle_block_pad; gst_pad_set_blocked_async_full (pad, FALSE, _pad_blocked_cb, - gst_object_ref (self), (GDestroyNotify) gst_object_unref); + self, NULL); } /* Remove elements */ @@ -1518,12 +1509,10 @@ gst_subtitle_overlay_handle_message (GstBin * bin, GstMessage * message) self->subtitle_error = TRUE; gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); GST_SUBTITLE_OVERLAY_UNLOCK (self); } } @@ -1579,12 +1568,10 @@ gst_subtitle_overlay_set_property (GObject * object, guint prop_id, g_object_set (self->renderer, self->silent_property, silent, NULL); } else { gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); } GST_SUBTITLE_OVERLAY_UNLOCK (self); break; @@ -1761,12 +1748,10 @@ gst_subtitle_overlay_video_sink_setcaps (GstPad * pad, GstCaps * caps) GST_DEBUG_OBJECT (pad, "Target did not accept caps -- reconfiguring"); gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); } if (!gst_video_parse_caps_framerate (caps, &fps_n, &fps_d)) { @@ -1854,12 +1839,10 @@ gst_subtitle_overlay_video_sink_chain (GstPad * pad, GstBuffer * buffer) GST_SUBTITLE_OVERLAY_LOCK (self); self->subtitle_error = TRUE; gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); GST_SUBTITLE_OVERLAY_UNLOCK (self); return GST_FLOW_OK; @@ -1885,12 +1868,10 @@ gst_subtitle_overlay_subtitle_sink_chain (GstPad * pad, GstBuffer * buffer) GST_SUBTITLE_OVERLAY_LOCK (self); self->subtitle_error = TRUE; gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); GST_SUBTITLE_OVERLAY_UNLOCK (self); return GST_FLOW_OK; @@ -1958,12 +1939,10 @@ gst_subtitle_overlay_subtitle_sink_setcaps (GstPad * pad, GstCaps * caps) self->subtitle_error = FALSE; gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); GST_SUBTITLE_OVERLAY_UNLOCK (self); out: @@ -1999,12 +1978,10 @@ gst_subtitle_overlay_subtitle_sink_link (GstPad * pad, GstPad * peer) self->subtitle_error = FALSE; gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); GST_SUBTITLE_OVERLAY_UNLOCK (self); gst_caps_unref (caps); } @@ -2035,13 +2012,11 @@ gst_subtitle_overlay_subtitle_sink_unlink (GstPad * pad) if (self->subtitle_block_pad) gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); if (self->video_block_pad) gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); GST_SUBTITLE_OVERLAY_UNLOCK (self); gst_object_unref (self); @@ -2064,12 +2039,10 @@ gst_subtitle_overlay_subtitle_sink_event (GstPad * pad, GstEvent * event) self->subtitle_error = FALSE; if (self->subtitle_block_pad) gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); if (self->video_block_pad) gst_pad_set_blocked_async_full (self->video_block_pad, TRUE, - _pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + _pad_blocked_cb, self, NULL); GST_SUBTITLE_OVERLAY_UNLOCK (self); gst_event_unref (event); From 6ffaccd284838473f994d145c8d430546f4a14dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Wed, 19 Oct 2011 19:44:06 +0200 Subject: [PATCH 10/21] subtitleoverlay: fix leaks of pad templates and internal proxy pads --- gst/playback/gstsubtitleoverlay.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst/playback/gstsubtitleoverlay.c b/gst/playback/gstsubtitleoverlay.c index c61cc87922..c39ace8723 100644 --- a/gst/playback/gstsubtitleoverlay.c +++ b/gst/playback/gstsubtitleoverlay.c @@ -2133,6 +2133,7 @@ gst_subtitle_overlay_init (GstSubtitleOverlay * self, templ = gst_static_pad_template_get (&srctemplate); self->srcpad = gst_ghost_pad_new_no_target_from_template ("src", templ); + gst_object_unref (templ); proxypad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (self->srcpad))); @@ -2147,6 +2148,7 @@ gst_subtitle_overlay_init (GstSubtitleOverlay * self, templ = gst_static_pad_template_get (&video_sinktemplate); self->video_sinkpad = gst_ghost_pad_new_no_target_from_template ("video_sink", templ); + gst_object_unref (templ); gst_pad_set_event_function (self->video_sinkpad, GST_DEBUG_FUNCPTR (gst_subtitle_overlay_video_sink_event)); gst_pad_set_setcaps_function (self->video_sinkpad, @@ -2158,11 +2160,13 @@ gst_subtitle_overlay_init (GstSubtitleOverlay * self, GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (self->video_sinkpad))); self->video_block_pad = proxypad; + gst_object_unref (proxypad); gst_element_add_pad (GST_ELEMENT_CAST (self), self->video_sinkpad); templ = gst_static_pad_template_get (&subtitle_sinktemplate); self->subtitle_sinkpad = gst_ghost_pad_new_no_target_from_template ("subtitle_sink", templ); + gst_object_unref (templ); gst_pad_set_link_function (self->subtitle_sinkpad, GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_link)); gst_pad_set_unlink_function (self->subtitle_sinkpad, @@ -2183,6 +2187,7 @@ gst_subtitle_overlay_init (GstSubtitleOverlay * self, GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (self->subtitle_sinkpad))); self->subtitle_block_pad = proxypad; + gst_object_unref (proxypad); gst_element_add_pad (GST_ELEMENT_CAST (self), self->subtitle_sinkpad); From 2b76c7f78105b7fcb4c0253b155cacc0f9222410 Mon Sep 17 00:00:00 2001 From: "Reynaldo H. Verdejo Pinochet" Date: Thu, 20 Oct 2011 10:13:46 -0300 Subject: [PATCH 11/21] Disable ext/vorbis for the android ndk build It currently makes the build fail. Idea is to enable it back again once its building problems get sorted out. --- Android.mk | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Android.mk b/Android.mk index b3d345b78d..a78bd69214 100644 --- a/Android.mk +++ b/Android.mk @@ -63,9 +63,12 @@ GST_PLUGINS_BASE_BUILT_SOURCES := \ gst/audiorate/Android.mk \ gst/volume/Android.mk \ tools/Android.mk \ - ext/vorbis/Android.mk \ ext/ogg/Android.mk +ifneq ($(NDK_BUILD), true) +GST_PLUGINS_BASE_BUILT_SOURCES += ext/vorbis/Android.mk +endif + GST_PLUGINS_BASE_BUILT_SOURCES := $(patsubst %, $(abspath $(GST_PLUGINS_BASE_TOP))/%, $(GST_PLUGINS_BASE_BUILT_SOURCES)) @@ -121,5 +124,7 @@ CONFIGURE_TARGETS += gst-plugins-base-configure -include $(GST_PLUGINS_BASE_TOP)/gst/audiorate/Android.mk -include $(GST_PLUGINS_BASE_TOP)/gst/volume/Android.mk -include $(GST_PLUGINS_BASE_TOP)/ext/ogg/Android.mk +ifneq ($(NDK_BUILD), true) -include $(GST_PLUGINS_BASE_TOP)/ext/vorbis/Android.mk +endif -include $(GST_PLUGINS_BASE_TOP)/tools/Android.mk From 0a5fcbb080d0863ed19859043b15acfb36212d6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Fri, 21 Oct 2011 21:39:01 +0200 Subject: [PATCH 12/21] audioconvert: bury dead test program --- gst/audioconvert/Makefile.am | 9 --- gst/audioconvert/channelmixtest.c | 95 ------------------------------- 2 files changed, 104 deletions(-) delete mode 100644 gst/audioconvert/channelmixtest.c diff --git a/gst/audioconvert/Makefile.am b/gst/audioconvert/Makefile.am index b8849b6f64..1626479e82 100644 --- a/gst/audioconvert/Makefile.am +++ b/gst/audioconvert/Makefile.am @@ -26,15 +26,6 @@ noinst_HEADERS = \ gstfastrandom.h \ plugin.h -#TESTS = channelmixtest -#noinst_PROGRAMS = channelmixtest - -#channelmixtest_CFLAGS = $(GST_CFLAGS) -#channelmixtest_LDADD = libgstaudioconvert.la \ -# $(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_MAJORMINOR@.la \ -# $(GST_LIBS) - - Android.mk: Makefile.am $(BUILT_SOURCES) androgenizer \ -:PROJECT libgstaudioconvert -:SHARED libgstaudioconvert \ diff --git a/gst/audioconvert/channelmixtest.c b/gst/audioconvert/channelmixtest.c deleted file mode 100644 index 096a683061..0000000000 --- a/gst/audioconvert/channelmixtest.c +++ /dev/null @@ -1,95 +0,0 @@ -/* GStreamer - * Copyright (C) 2005 Benjamin Otte - * - * channelmixtest.c: simple test of channel mixing - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstchannelmix.h" -#include "plugin.h" - -int -main (gint argc, gchar ** argv) -{ - GstElement *bin, *src, *sink; - GstAudioConvert *c; - GstCaps *caps; - guint i, j, k; - struct - { - gchar *sinkcaps; - gchar *srccaps; - gfloat matrix[6][6]; /* use a predefined matrix here, makes stuff simpler */ - } tests[] = { - /* stereo => mono */ - { - "audio/x-raw-int, channels=2", "audio/x-raw-int, channels=1", { { - 0.5,}, { - 0.5,},}}, - /* mono => stereo */ - { - "audio/x-raw-int, channels=1", "audio/x-raw-int, channels=2", { { - 1, 1,},}} - }; - - gst_init (&argc, &argv); - - for (i = 0; i < G_N_ELEMENTS (tests); i++) { - g_print ("running test %u\n", i); - bin = gst_element_factory_make ("pipeline", NULL); - c = g_object_new (GST_TYPE_AUDIO_CONVERT, NULL); - /* avoid gst being braindead */ - gst_object_set_name (GST_OBJECT (c), "shuddup"); - src = gst_element_factory_make ("fakesrc", NULL); - sink = gst_element_factory_make ("fakesink", NULL); - gst_bin_add_many (GST_BIN (bin), src, c, sink, NULL); - caps = gst_caps_from_string (tests[i].sinkcaps); - g_assert (caps); - if (!gst_element_link_filtered (src, GST_ELEMENT (c), caps)) - g_assert_not_reached (); - gst_caps_unref (caps); - caps = gst_caps_from_string (tests[i].srccaps); - g_assert (caps); - if (!gst_element_link_filtered (GST_ELEMENT (c), sink, caps)) - g_assert_not_reached (); - gst_caps_unref (caps); - if (!gst_element_set_state (bin, GST_STATE_PLAYING)) - g_assert_not_reached (); - g_assert (c->srccaps.channels <= 6); - g_assert (c->sinkcaps.channels <= 6); - for (j = 0; j < 6; j++) { - for (k = 0; k < 6; k++) { - if (j < c->sinkcaps.channels && k < c->srccaps.channels) { - if (tests[i].matrix[j][k] != c->matrix[j][k]) { - g_printerr ("matrix[j][k] should be %g but is %g\n", - tests[i].matrix[j][k], c->matrix[j][k]); - g_assert_not_reached (); - } - } else { - g_assert (tests[i].matrix[j][k] == 0); - } - } - } - gst_object_unref (bin); - } - - return 0; -} From 133a0b17715b2b7f106bed7ea0164451e9c33e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Fri, 21 Oct 2011 21:41:03 +0200 Subject: [PATCH 13/21] oggdemux: remove avoidable call to gst_object_set_name --- ext/ogg/gstoggdemux.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index 3a880d48d5..f739df09a7 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -1692,7 +1692,9 @@ gst_ogg_chain_new_stream (GstOggChain * chain, guint32 serialno) GST_DEBUG_OBJECT (chain->ogg, "creating new stream %08x in chain %p", serialno, chain); - ret = g_object_new (GST_TYPE_OGG_PAD, NULL); + name = g_strdup_printf ("serial_%08x", serialno); + ret = g_object_new (GST_TYPE_OGG_PAD, "name", name, NULL); + g_free (name); /* we own this one */ gst_object_ref (ret); gst_object_sink (ret); @@ -1707,10 +1709,6 @@ gst_ogg_chain_new_stream (GstOggChain * chain, guint32 serialno) if (ogg_stream_init (&ret->map.stream, serialno) != 0) goto init_failed; - name = g_strdup_printf ("serial_%08x", serialno); - gst_object_set_name (GST_OBJECT (ret), name); - g_free (name); - /* FIXME: either do something with it or remove it */ list = gst_tag_list_new (); gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_SERIAL, serialno, From 54be24375745a3c3e59c4b1a16ab191575c03fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Fri, 21 Oct 2011 21:57:17 +0200 Subject: [PATCH 14/21] playbasebin: remove avoidable call to gst_object_set_name --- gst/playback/gstplaybasebin.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/playback/gstplaybasebin.c b/gst/playback/gstplaybasebin.c index 847e12ff71..bee57f6462 100644 --- a/gst/playback/gstplaybasebin.c +++ b/gst/playback/gstplaybasebin.c @@ -797,10 +797,9 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin, g_return_if_reached (); /* create stream selector */ - selector = g_object_new (GST_TYPE_STREAM_SELECTOR, NULL); padname = gst_pad_get_name (pad); name = g_strdup_printf ("selector_%s_%s", prename, padname); - gst_object_set_name (GST_OBJECT_CAST (selector), name); + selector = g_object_new (GST_TYPE_STREAM_SELECTOR, "name", name, NULL); g_free (name); /* create preroll queue */ From cf9da5c280603edde373f71ff1319aea4222130a Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 13 Oct 2011 11:34:49 -0400 Subject: [PATCH 15/21] decodebin2: Link elements before testing if they can reach the READY state This is made possible by filtering errors. This is required to let harware accelerated element query the video context. The video context is used to determine if the HW is capable, and thus if the element is supported or not. Fixes bug #662330. --- gst/playback/gstdecodebin2.c | 96 +++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 24 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 826ca85992..d1eb15413f 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -175,6 +175,8 @@ struct _GstDecodeBin gboolean expose_allstreams; /* Whether to expose unknow type streams or not */ gboolean upstream_seekable; /* if upstream is seekable */ + + GList *filtered; /* elements for which error messages are filtered */ }; struct _GstDecodeBinClass @@ -296,6 +298,7 @@ static void caps_notify_cb (GstPad * pad, GParamSpec * unused, static GstPad *find_sink_pad (GstElement * element); static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element, GstStateChange transition); +static void gst_decode_bin_handle_message (GstBin * bin, GstMessage * message); #define EXPOSE_LOCK(dbin) G_STMT_START { \ GST_LOG_OBJECT (dbin, \ @@ -588,9 +591,11 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) { GObjectClass *gobject_klass; GstElementClass *gstelement_klass; + GstBinClass *gstbin_klass; gobject_klass = (GObjectClass *) klass; gstelement_klass = (GstElementClass *) klass; + gstbin_klass = (GstBinClass *) klass; parent_class = g_type_class_peek_parent (klass); @@ -937,6 +942,9 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) gstelement_klass->change_state = GST_DEBUG_FUNCPTR (gst_decode_bin_change_state); + + gstbin_klass->handle_message = + GST_DEBUG_FUNCPTR (gst_decode_bin_handle_message); } /* Must be called with factories lock! */ @@ -1731,6 +1739,21 @@ setup_caps_delay: } } +static void +add_error_filter (GstDecodeBin * dbin, GstElement * element) +{ + GST_OBJECT_LOCK (dbin); + dbin->filtered = g_list_prepend (dbin->filtered, element); + GST_OBJECT_UNLOCK (dbin); +} + +static void +remove_error_filter (GstDecodeBin * dbin, GstElement * element) +{ + GST_OBJECT_LOCK (dbin); + dbin->filtered = g_list_remove (dbin->filtered, element); + GST_OBJECT_UNLOCK (dbin); +} /* connect_pad: * @@ -1855,45 +1878,52 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, continue; } - /* ... activate it ... We do this before adding it to the bin so that we - * don't accidentally make it post error messages that will stop - * everything. */ - if ((gst_element_set_state (element, - GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE) { - GST_WARNING_OBJECT (dbin, "Couldn't set %s to READY", - GST_ELEMENT_NAME (element)); - gst_object_unref (element); - continue; - } + /* Filter errors, this will prevent the element from causing the pipeline + * to error while we test it using READY state. */ + add_error_filter (dbin, element); - /* 2.3. Find its sink pad, this should work after activating it. */ - if (!(sinkpad = find_sink_pad (element))) { - GST_WARNING_OBJECT (dbin, "Element %s doesn't have a sink pad", - GST_ELEMENT_NAME (element)); - gst_element_set_state (element, GST_STATE_NULL); - gst_object_unref (element); - continue; - } - - /* 2.4 add it ... */ + /* ... add it ... */ if (!(gst_bin_add (GST_BIN_CAST (dbin), element))) { GST_WARNING_OBJECT (dbin, "Couldn't add %s to the bin", GST_ELEMENT_NAME (element)); - gst_object_unref (sinkpad); - gst_element_set_state (element, GST_STATE_NULL); + remove_error_filter (dbin, element); gst_object_unref (element); continue; } - /* 2.5 ...and try to link */ + /* Find its sink pad. */ + if (!(sinkpad = find_sink_pad (element))) { + GST_WARNING_OBJECT (dbin, "Element %s doesn't have a sink pad", + GST_ELEMENT_NAME (element)); + remove_error_filter (dbin, element); + gst_bin_remove (GST_BIN (dbin), element); + continue; + } + + /* ... and try to link */ if ((gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) { GST_WARNING_OBJECT (dbin, "Link failed on pad %s:%s", GST_DEBUG_PAD_NAME (sinkpad)); - gst_element_set_state (element, GST_STATE_NULL); + remove_error_filter (dbin, element); gst_object_unref (sinkpad); gst_bin_remove (GST_BIN (dbin), element); continue; } + + /* ... activate it ... */ + if ((gst_element_set_state (element, + GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE) { + GST_WARNING_OBJECT (dbin, "Couldn't set %s to READY", + GST_ELEMENT_NAME (element)); + remove_error_filter (dbin, element); + gst_object_unref (sinkpad); + gst_bin_remove (GST_BIN (dbin), element); + continue; + } + + /* Stop filtering errors. */ + remove_error_filter (dbin, element); + gst_object_unref (sinkpad); GST_LOG_OBJECT (dbin, "linked on pad %s:%s", GST_DEBUG_PAD_NAME (pad)); @@ -3993,6 +4023,24 @@ activate_failed: } } +static void +gst_decode_bin_handle_message (GstBin * bin, GstMessage * msg) +{ + GstDecodeBin *dbin = GST_DECODE_BIN (bin); + gboolean drop = FALSE; + + if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { + GST_OBJECT_LOCK (dbin); + drop = (g_list_find (dbin->filtered, GST_MESSAGE_SRC (msg)) != NULL); + GST_OBJECT_UNLOCK (dbin); + } + + if (drop) + gst_message_unref (msg); + else + GST_BIN_CLASS (parent_class)->handle_message (bin, msg); +} + gboolean gst_decode_bin_plugin_init (GstPlugin * plugin) { From f35c51c14915729f0fdf2b348f351ea7e81027cc Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Tue, 25 Oct 2011 20:04:06 +1100 Subject: [PATCH 16/21] playsinkaudioconvert: Fix warning when there is no target pad yet --- gst/playback/gstplaysinkaudioconvert.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst/playback/gstplaysinkaudioconvert.c b/gst/playback/gstplaysinkaudioconvert.c index 2c28c6eca0..2441bfe261 100644 --- a/gst/playback/gstplaysinkaudioconvert.c +++ b/gst/playback/gstplaysinkaudioconvert.c @@ -348,13 +348,18 @@ gst_play_sink_audio_convert_getcaps (GstPad * pad) GstPlaySinkAudioConvert *self = GST_PLAY_SINK_AUDIO_CONVERT (gst_pad_get_parent (pad)); GstCaps *ret; - GstPad *otherpad, *peer; + GstPad *otherpad, *peer = NULL; GST_PLAY_SINK_AUDIO_CONVERT_LOCK (self); otherpad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad)); GST_PLAY_SINK_AUDIO_CONVERT_UNLOCK (self); - peer = gst_pad_get_peer (otherpad); + if (otherpad) { + peer = gst_pad_get_peer (otherpad); + gst_object_unref (otherpad); + otherpad = NULL; + } + if (peer) { ret = gst_pad_get_caps_reffed (peer); gst_object_unref (peer); @@ -362,7 +367,6 @@ gst_play_sink_audio_convert_getcaps (GstPad * pad) ret = gst_caps_new_any (); } - gst_object_unref (otherpad); gst_object_unref (self); return ret; From 69fc8e9ffc8d16ca52b52239d06a1700ccbf78bd Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 27 Oct 2011 09:33:01 +0200 Subject: [PATCH 17/21] audiomix: add a simple audiomix example --- tests/examples/audio/.gitignore | 2 + tests/examples/audio/Makefile.am | 6 + tests/examples/audio/audiomix.c | 210 +++++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 tests/examples/audio/audiomix.c diff --git a/tests/examples/audio/.gitignore b/tests/examples/audio/.gitignore index d066146478..87308d7b48 100644 --- a/tests/examples/audio/.gitignore +++ b/tests/examples/audio/.gitignore @@ -1 +1,3 @@ +audiomix testchannels + diff --git a/tests/examples/audio/Makefile.am b/tests/examples/audio/Makefile.am index e0cc5ef0d0..f41b3e4919 100644 --- a/tests/examples/audio/Makefile.am +++ b/tests/examples/audio/Makefile.am @@ -5,3 +5,9 @@ testchannels_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) testchannels_LDADD = $(top_builddir)/gst-libs/gst/audio/libgstaudio-$(GST_MAJORMINOR).la \ $(GST_LIBS) +if HAVE_GTK +noinst_PROGRAMS = audiomix +audiomix_SOURCES = audiomix.c +audiomix_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS) -D_GNU_SOURCE +audiomix_LDADD = $(GST_LIBS) $(GTK_LIBS) $(LIBM) +endif diff --git a/tests/examples/audio/audiomix.c b/tests/examples/audio/audiomix.c new file mode 100644 index 0000000000..937f4db6f6 --- /dev/null +++ b/tests/examples/audio/audiomix.c @@ -0,0 +1,210 @@ +/* GStreamer + * + * audiomix.c: sample audio mixing application + * + * Copyright (C) 2011 Stefan Sauer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +/* global items for the interaction */ +static GtkWidget *scale; +static GObject *volumes[2]; +static gint num_vol = 0; + + +static void +value_changed_callback (GtkWidget * widget, gpointer * user_data) +{ + gdouble value = gtk_range_get_value (GTK_RANGE (widget)); + g_object_set (volumes[0], "volume", 1.0 - value, NULL); + g_object_set (volumes[1], "volume", value, NULL); +} + +static void +setup_gui (GstElement * volume, gchar * file_name1, gchar * file_name2) +{ + GtkWidget *window, *layout, *label; + gchar *name, *ext; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "audiomix"); + g_signal_connect (window, "destroy", gtk_main_quit, NULL); + + layout = gtk_table_new (2, 3, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (layout), 6); + gtk_container_add (GTK_CONTAINER (window), layout); + + /* channel labels */ + name = g_path_get_basename (file_name1); + if ((ext = strrchr (name, '.'))) + *ext = '\0'; + label = gtk_label_new (name); + g_free (name); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (layout), label, 0, 1, 0, 1); + + gtk_table_attach_defaults (GTK_TABLE (layout), gtk_label_new ("|"), 1, 2, 0, + 1); + + name = g_path_get_basename (file_name2); + if ((ext = strrchr (name, '.'))) + *ext = '\0'; + label = gtk_label_new (name); + g_free (name); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (layout), label, 2, 3, 0, 1); + + /* mix slider */ + scale = gtk_hscale_new_with_range (0.0, 1.0, 1.0 / 200.0); + gtk_range_set_value (GTK_RANGE (scale), 0.0); + gtk_widget_set_size_request (scale, 200, -1); + gtk_table_attach_defaults (GTK_TABLE (layout), scale, 0, 3, 1, 2); + g_signal_connect (scale, "value-changed", + G_CALLBACK (value_changed_callback), volume); + + gtk_widget_show_all (GTK_WIDGET (window)); +} + +static void +message_received (GstBus * bus, GstMessage * message, GstPipeline * pipeline) +{ + const GstStructure *s; + + s = gst_message_get_structure (message); + g_print ("message from \"%s\" (%s): ", + GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))), + gst_message_type_get_name (GST_MESSAGE_TYPE (message))); + if (s) { + gchar *sstr; + + sstr = gst_structure_to_string (s); + g_print ("%s\n", sstr); + g_free (sstr); + } else { + g_print ("no message details\n"); + } +} + +static void +eos_message_received (GstBus * bus, GstMessage * message, + GstPipeline * pipeline) +{ + message_received (bus, message, pipeline); + gtk_main_quit (); +} + +static void +dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer user_data) +{ + GstPad *target = GST_PAD (user_data); + + gst_pad_link (newpad, target); + gst_object_unref (target); +} + +static void +make_mixer_channel (GstElement * pipeline, GstElement * mix, gchar * file_name) +{ + GstElement *filesrc, *decodebin, *volume, *convert, *format; + GstCaps *caps; + + /* prepare mixer channel */ + filesrc = gst_element_factory_make ("filesrc", NULL); + decodebin = gst_element_factory_make ("decodebin2", NULL); + volume = gst_element_factory_make ("volume", NULL); + convert = gst_element_factory_make ("audioconvert", NULL); + format = gst_element_factory_make ("capsfilter", NULL); + gst_bin_add_many (GST_BIN (pipeline), filesrc, decodebin, volume, convert, + format, NULL); + gst_element_link (filesrc, decodebin); + gst_element_link_many (volume, convert, format, mix, NULL); + + /* configure elements */ + g_object_set (filesrc, "location", file_name, NULL); + g_object_set (volume, "volume", (num_vol == 0) ? 1.0 : 0.0, NULL); + + caps = gst_caps_from_string ("audio/x-raw-int, " + "channels = (int) 2, " + "endianness = (int) BYTE_ORDER, " + "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true"); + g_object_set (format, "caps", caps, NULL); + gst_caps_unref (caps); + + /* remember volume element */ + volumes[num_vol++] = (GObject *) volume; + + /* handle dynamic pads */ + g_signal_connect (G_OBJECT (decodebin), "pad-added", + G_CALLBACK (dynamic_link), gst_element_get_static_pad (volume, "sink")); +} + +int +main (int argc, char *argv[]) +{ + GstElement *pipeline = NULL; + GstElement *mix, *convert, *sink; + GstBus *bus; + + if (argc < 3) { + g_print ("Usage: audiomix \n"); + return 1; + } + + gst_init (&argc, &argv); + gtk_init (&argc, &argv); + + /* prepare tail of pipeline */ + pipeline = gst_pipeline_new ("audiomix"); + mix = gst_element_factory_make ("adder", NULL); + convert = gst_element_factory_make ("audioconvert", NULL); + sink = gst_element_factory_make ("autoaudiosink", NULL); + gst_bin_add_many (GST_BIN (pipeline), mix, convert, sink, NULL); + gst_element_link_many (mix, convert, sink, NULL); + + /* prepare mixer channel strips */ + make_mixer_channel (pipeline, mix, argv[1]); + make_mixer_channel (pipeline, mix, argv[2]); + + /* setup message handling */ + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH); + g_signal_connect (bus, "message::error", (GCallback) message_received, + pipeline); + g_signal_connect (bus, "message::warning", (GCallback) message_received, + pipeline); + g_signal_connect (bus, "message::eos", (GCallback) eos_message_received, + pipeline); + + /* setup GUI */ + setup_gui (pipeline, argv[1], argv[2]); + + /* go to main loop */ + gst_element_set_state (pipeline, GST_STATE_PLAYING); + gtk_main (); + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (pipeline); + + return 0; +} From 76d455825d8f6ee342c2f9b533266d5a460fbab0 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 27 Oct 2011 09:33:55 +0200 Subject: [PATCH 18/21] volume: make global vars static --- tests/examples/volume/volume.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/examples/volume/volume.c b/tests/examples/volume/volume.c index 59e4981f3c..d5bf9edbb0 100644 --- a/tests/examples/volume/volume.c +++ b/tests/examples/volume/volume.c @@ -30,8 +30,8 @@ #include /* global pointer for the scale widget */ -GtkWidget *elapsed; -GtkWidget *scale; +static GtkWidget *elapsed; +static GtkWidget *scale; #ifndef M_LN10 #define M_LN10 (log(10.0)) From 3a3b3a5b3bb8d6c79e63c062f97a87c5ef4c1d6b Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 27 Oct 2011 09:42:36 +0200 Subject: [PATCH 19/21] audio examples. fix the makefile --- tests/examples/audio/Makefile.am | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/examples/audio/Makefile.am b/tests/examples/audio/Makefile.am index f41b3e4919..0b8d10a88e 100644 --- a/tests/examples/audio/Makefile.am +++ b/tests/examples/audio/Makefile.am @@ -1,12 +1,17 @@ +if HAVE_GTK +GTK_EXAMPLES = audiomix +else +GTK_EXAMPLES = +endif + +noinst_PROGRAMS = testchannels $(GTK_EXAMPLES) -noinst_PROGRAMS = testchannels testchannels_SOURCES = testchannels.c testchannels_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) testchannels_LDADD = $(top_builddir)/gst-libs/gst/audio/libgstaudio-$(GST_MAJORMINOR).la \ $(GST_LIBS) if HAVE_GTK -noinst_PROGRAMS = audiomix audiomix_SOURCES = audiomix.c audiomix_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS) -D_GNU_SOURCE audiomix_LDADD = $(GST_LIBS) $(GTK_LIBS) $(LIBM) From 92d1f5251e3d5b08dd7e7a419fc217f3f50d5729 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 27 Oct 2011 09:51:46 +0200 Subject: [PATCH 20/21] volume: move volume example to audio --- Makefile.am | 1 + configure.ac | 1 - tests/examples/Makefile.am | 3 ++- tests/examples/audio/.gitignore | 1 + tests/examples/audio/Makefile.am | 6 +++++- tests/examples/{volume => audio}/volume.c | 0 tests/examples/volume/.gitignore | 1 - tests/examples/volume/Makefile.am | 6 ------ 8 files changed, 9 insertions(+), 10 deletions(-) rename tests/examples/{volume => audio}/volume.c (100%) delete mode 100644 tests/examples/volume/.gitignore delete mode 100644 tests/examples/volume/Makefile.am diff --git a/Makefile.am b/Makefile.am index 00201ecf38..f96c417971 100644 --- a/Makefile.am +++ b/Makefile.am @@ -77,6 +77,7 @@ CRUFT_FILES = \ $(top_builddir)/common/shave \ $(top_builddir)/common/shave-libtool \ $(top_builddir)/gst-libs/gst/audio/testchannels \ + $(top_builddir)/tests/examples/volume/volume \ $(top_builddir)/tools/gst-discoverer diff --git a/configure.ac b/configure.ac index 56eae4e380..3247887a01 100644 --- a/configure.ac +++ b/configure.ac @@ -1028,7 +1028,6 @@ tests/examples/overlay/Makefile tests/examples/seek/Makefile tests/examples/snapshot/Makefile tests/examples/playrec/Makefile -tests/examples/volume/Makefile tests/examples/v4l/Makefile tests/files/Makefile tests/icles/Makefile diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am index 14795db9e6..81731425a0 100644 --- a/tests/examples/Makefile.am +++ b/tests/examples/Makefile.am @@ -8,8 +8,9 @@ if USE_GIO GIO_SUBDIRS = gio endif -SUBDIRS = app audio dynamic $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec volume v4l encoding +SUBDIRS = app audio dynamic $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec v4l encoding DIST_SUBDIRS = app audio dynamic gio overlay seek snapshot playrec volume v4l encoding include $(top_srcdir)/common/parallel-subdirs.mak + diff --git a/tests/examples/audio/.gitignore b/tests/examples/audio/.gitignore index 87308d7b48..04fcc591b9 100644 --- a/tests/examples/audio/.gitignore +++ b/tests/examples/audio/.gitignore @@ -1,3 +1,4 @@ audiomix testchannels +volume diff --git a/tests/examples/audio/Makefile.am b/tests/examples/audio/Makefile.am index 0b8d10a88e..d8492340e9 100644 --- a/tests/examples/audio/Makefile.am +++ b/tests/examples/audio/Makefile.am @@ -1,5 +1,5 @@ if HAVE_GTK -GTK_EXAMPLES = audiomix +GTK_EXAMPLES = audiomix volume else GTK_EXAMPLES = endif @@ -15,4 +15,8 @@ if HAVE_GTK audiomix_SOURCES = audiomix.c audiomix_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS) -D_GNU_SOURCE audiomix_LDADD = $(GST_LIBS) $(GTK_LIBS) $(LIBM) + +volume_SOURCES = volume.c +volume_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS) -D_GNU_SOURCE +volume_LDADD = $(GST_LIBS) $(GTK_LIBS) $(LIBM) endif diff --git a/tests/examples/volume/volume.c b/tests/examples/audio/volume.c similarity index 100% rename from tests/examples/volume/volume.c rename to tests/examples/audio/volume.c diff --git a/tests/examples/volume/.gitignore b/tests/examples/volume/.gitignore deleted file mode 100644 index 4833bbb039..0000000000 --- a/tests/examples/volume/.gitignore +++ /dev/null @@ -1 +0,0 @@ -volume diff --git a/tests/examples/volume/Makefile.am b/tests/examples/volume/Makefile.am deleted file mode 100644 index 7b2f067bd8..0000000000 --- a/tests/examples/volume/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -if HAVE_GTK -noinst_PROGRAMS = volume -volume_SOURCES = volume.c -volume_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS) -D_GNU_SOURCE -volume_LDADD = $(GST_LIBS) $(GTK_LIBS) $(LIBM) -endif From 1a7acdc99e9355cdae4c50356346ffb0c06e7fc8 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 27 Oct 2011 23:39:31 +1100 Subject: [PATCH 21/21] build: Fix build for moved volume subdir --- tests/examples/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am index 81731425a0..f44e6e81cf 100644 --- a/tests/examples/Makefile.am +++ b/tests/examples/Makefile.am @@ -10,7 +10,7 @@ endif SUBDIRS = app audio dynamic $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec v4l encoding -DIST_SUBDIRS = app audio dynamic gio overlay seek snapshot playrec volume v4l encoding +DIST_SUBDIRS = app audio dynamic gio overlay seek snapshot playrec v4l encoding include $(top_srcdir)/common/parallel-subdirs.mak