mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
Merge branch 'master' into 0.11
Conflicts: configure.ac gst-libs/gst/audio/gstbaseaudiosink.c gst/audioconvert/channelmixtest.c gst/playback/gstplaybasebin.c gst/playback/gstsubtitleoverlay.c tests/examples/Makefile.am tests/examples/audio/Makefile.am
This commit is contained in:
commit
016d036137
20 changed files with 347 additions and 165 deletions
|
@ -61,9 +61,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))
|
||||
|
||||
|
||||
|
@ -119,5 +122,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
|
||||
|
|
|
@ -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
|
||||
|
||||
CRUFT_DIRS = \
|
||||
|
|
|
@ -1697,7 +1697,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_sink (ret);
|
||||
|
||||
|
@ -1711,10 +1713,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,
|
||||
|
@ -3077,6 +3075,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -428,9 +428,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 */
|
||||
|
@ -482,7 +479,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)
|
||||
|
@ -668,6 +665,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;
|
||||
|
||||
|
|
|
@ -1031,7 +1031,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 */
|
||||
|
|
|
@ -1335,8 +1335,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, rate);
|
||||
diff_s = gst_util_uint64_scale_int (diff, GST_SECOND, rate);
|
||||
|
||||
/* timestamps drifted apart from previous samples too much, we need to
|
||||
* resync. We log this as an element warning. */
|
||||
GST_WARNING_OBJECT (sink,
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2005 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* 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, channels=2", "audio/x-raw, channels=1", { {
|
||||
0.5,}, {
|
||||
0.5,},}},
|
||||
/* mono => stereo */
|
||||
{
|
||||
"audio/x-raw, channels=1", "audio/x-raw, 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;
|
||||
}
|
|
@ -174,6 +174,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
|
||||
|
@ -289,6 +291,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, \
|
||||
|
@ -584,9 +587,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);
|
||||
|
||||
|
@ -898,6 +903,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! */
|
||||
|
@ -1692,6 +1700,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:
|
||||
*
|
||||
|
@ -1856,45 +1879,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));
|
||||
|
||||
|
@ -3162,6 +3192,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;
|
||||
}
|
||||
|
||||
|
@ -4003,6 +4036,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)
|
||||
{
|
||||
|
|
|
@ -336,13 +336,18 @@ gst_play_sink_audio_convert_getcaps (GstPad * pad, GstCaps * filter)
|
|||
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 (peer, filter);
|
||||
gst_object_unref (peer);
|
||||
|
@ -350,7 +355,6 @@ gst_play_sink_audio_convert_getcaps (GstPad * pad, GstCaps * filter)
|
|||
ret = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
}
|
||||
|
||||
gst_object_unref (otherpad);
|
||||
gst_object_unref (self);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -122,8 +122,7 @@ block_video (GstSubtitleOverlay * self)
|
|||
if (self->video_block_pad) {
|
||||
self->video_block_id =
|
||||
gst_pad_add_probe (self->video_block_pad, GST_PROBE_TYPE_BLOCK,
|
||||
_pad_blocked_cb, gst_object_ref (self),
|
||||
(GDestroyNotify) gst_object_unref);
|
||||
_pad_blocked_cb, self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,8 +145,7 @@ block_subtitle (GstSubtitleOverlay * self)
|
|||
if (self->subtitle_block_pad) {
|
||||
self->subtitle_block_id =
|
||||
gst_pad_add_probe (self->subtitle_block_pad, GST_PROBE_TYPE_BLOCK,
|
||||
_pad_blocked_cb, gst_object_ref (self),
|
||||
(GDestroyNotify) gst_object_unref);
|
||||
_pad_blocked_cb, self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -805,7 +803,6 @@ _pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data,
|
|||
/* Unblock pads */
|
||||
unblock_video (self);
|
||||
unblock_subtitle (self);
|
||||
|
||||
goto out;
|
||||
} else if (target) {
|
||||
gst_object_unref (target);
|
||||
|
@ -2059,6 +2056,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)));
|
||||
|
@ -2073,6 +2071,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_chain_function (self->video_sinkpad,
|
||||
|
@ -2082,12 +2081,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,
|
||||
|
@ -2105,6 +2105,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);
|
||||
|
||||
|
|
|
@ -1920,8 +1920,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",
|
||||
|
|
|
@ -2826,8 +2826,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",
|
||||
|
|
|
@ -8,8 +8,9 @@ if USE_GIO
|
|||
GIO_SUBDIRS = gio
|
||||
endif
|
||||
|
||||
SUBDIRS = app audio dynamic $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec volume encoding
|
||||
SUBDIRS = app audio dynamic $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec encoding
|
||||
|
||||
DIST_SUBDIRS = app audio dynamic gio overlay seek snapshot playrec volume encoding
|
||||
DIST_SUBDIRS = app audio dynamic gio overlay seek snapshot playrec encoding
|
||||
|
||||
include $(top_srcdir)/common/parallel-subdirs.mak
|
||||
|
||||
|
|
3
tests/examples/audio/.gitignore
vendored
3
tests/examples/audio/.gitignore
vendored
|
@ -1 +1,4 @@
|
|||
audiomix
|
||||
testchannels
|
||||
volume
|
||||
|
||||
|
|
|
@ -1,6 +1,21 @@
|
|||
if HAVE_GTK
|
||||
GTK_EXAMPLES = audiomix volume
|
||||
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
|
||||
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
|
||||
|
|
210
tests/examples/audio/audiomix.c
Normal file
210
tests/examples/audio/audiomix.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
/* GStreamer
|
||||
*
|
||||
* audiomix.c: sample audio mixing application
|
||||
*
|
||||
* Copyright (C) 2011 Stefan Sauer <ensonic@users.sf.net>
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* 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 <file1> <file2>\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;
|
||||
}
|
|
@ -30,8 +30,8 @@
|
|||
#include <gtk/gtk.h>
|
||||
|
||||
/* 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))
|
1
tests/examples/volume/.gitignore
vendored
1
tests/examples/volume/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
volume
|
|
@ -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
|
Loading…
Reference in a new issue