From: Stefan Kost Date: Sun, 28 May 2006 19:42:27 +0000 (+0000) Subject: gst/adder/gstadder.c: Make it easier to copy&paste X-Git-Tag: RELEASE-0_10_8~40 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=213de8658617d346e26274c2023d30c965e0d30a;p=platform%2Fupstream%2Fgst-plugins-base.git gst/adder/gstadder.c: Make it easier to copy&paste Original commit message from CVS: * gst/adder/gstadder.c: (gst_adder_get_type): Make it easier to copy&paste * gst/volume/Makefile.am: * gst/volume/gstvolume.c: (volume_update_real_volume), (gst_volume_set_volume), (gst_volume_set_mute), (gst_volume_class_init), (volume_process_int16), (volume_set_caps), (volume_transform_ip), (volume_update_mute), (volume_update_volume): * gst/volume/gstvolume.h: Add own debug category, move duplicate code to helper function, fix property texts, add more comments and prepare ffor liboil-goodness * tests/check/Makefile.am: * tests/check/elements/volume.c: (GST_START_TEST), (volume_suite): add test for mute and passtrough case, be a bit more verbose to track failure * tests/check/generic/states.c: (GST_START_TEST): catch elements that fail to instantiate --- diff --git a/ChangeLog b/ChangeLog index c54641c..5a52078 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2006-05-28 Stefan Kost + + * gst/adder/gstadder.c: (gst_adder_get_type): + Make it easier to copy&paste + + * gst/volume/Makefile.am: + * gst/volume/gstvolume.c: (volume_update_real_volume), + (gst_volume_set_volume), (gst_volume_set_mute), + (gst_volume_class_init), (volume_process_int16), (volume_set_caps), + (volume_transform_ip), (volume_update_mute), + (volume_update_volume): + * gst/volume/gstvolume.h: + Add own debug category, move duplicate code to helper function, fix + property texts, add more comments and prepare ffor liboil-goodness + + * tests/check/Makefile.am: + * tests/check/elements/volume.c: (GST_START_TEST), (volume_suite): + add test for mute and passtrough case, be a bit more verbose to track + failure + + * tests/check/generic/states.c: (GST_START_TEST): + catch elements that fail to instantiate + 2006-05-28 Edward Hervey * tests/check/pipelines/simple-launch-lines.c: diff --git a/common b/common index 764c5f2..2f06c5c 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 764c5f25101d20da7f26942c36ba840ba65c63d7 +Subproject commit 2f06c5cbc778e158d2429b09efc6740ff5281295 diff --git a/gst/adder/gstadder.c b/gst/adder/gstadder.c index 354e7fa..f685ec0 100644 --- a/gst/adder/gstadder.c +++ b/gst/adder/gstadder.c @@ -65,8 +65,8 @@ #define MIN_UINT_16 ((guint16)(0x0000)) #define MIN_UINT_8 ((guint8) (0x00)) -GST_DEBUG_CATEGORY_STATIC (gst_adder_debug); #define GST_CAT_DEFAULT gst_adder_debug +GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); /* elementfactory information */ static const GstElementDetails adder_details = GST_ELEMENT_DETAILS ("Adder", @@ -124,7 +124,7 @@ gst_adder_get_type (void) adder_type = g_type_register_static (GST_TYPE_ELEMENT, "GstAdder", &adder_info, 0); - GST_DEBUG_CATEGORY_INIT (gst_adder_debug, "adder", 0, + GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "adder", 0, "audio channel mixing element"); } return adder_type; diff --git a/gst/volume/Makefile.am b/gst/volume/Makefile.am index 8d7c724..9fa35f0 100644 --- a/gst/volume/Makefile.am +++ b/gst/volume/Makefile.am @@ -1,7 +1,7 @@ plugin_LTLIBRARIES = libgstvolume.la libgstvolume_la_SOURCES = gstvolume.c -libgstvolume_la_CFLAGS = $(GST_CFLAGS) $(GST_CONTROLLER_CFLAGS) +libgstvolume_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GST_CONTROLLER_CFLAGS) libgstvolume_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvolume_la_LIBADD = \ $(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-$(GST_MAJORMINOR).la \ diff --git a/gst/volume/gstvolume.c b/gst/volume/gstvolume.c index ca5b4ae..2ffdf90 100644 --- a/gst/volume/gstvolume.c +++ b/gst/volume/gstvolume.c @@ -66,6 +66,9 @@ /* number of steps we use for the mixer interface to go from 0.0 to 1.0 */ # define VOLUME_STEPS 100 +#define GST_CAT_DEFAULT gst_volume_debug +GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); + static const GstElementDetails volume_details = GST_ELEMENT_DETAILS ("Volume", "Filter/Effect/Audio", "Set volume on audio/raw streams", @@ -159,6 +162,22 @@ static void volume_process_float (GstVolume * this, GstClockTime tstamp, static void volume_process_int16 (GstVolume * this, GstClockTime tstamp, gpointer bytes, gint n_bytes); +/* helper functions */ + +static void +volume_update_real_volume (GstVolume * this) +{ + if (this->mute) { + this->real_vol_f = 0.0; + this->real_vol_i = 0; + } else { + this->real_vol_f = this->volume_f; + this->real_vol_i = this->volume_i; + } +} + +/* Mixer interface */ + static gboolean gst_volume_interface_supported (GstImplementsInterface * iface, GType type) { @@ -194,13 +213,7 @@ gst_volume_set_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes) this->volume_f = (gfloat) volumes[0] / VOLUME_STEPS; this->volume_i = this->volume_f * VOLUME_UNITY_INT; - if (this->mute) { - this->real_vol_f = 0.0; - this->real_vol_i = 0; - } else { - this->real_vol_f = this->volume_f; - this->real_vol_i = this->volume_i; - } + volume_update_real_volume (this); } static void @@ -224,13 +237,7 @@ gst_volume_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute) this->mute = mute; - if (this->mute) { - this->real_vol_f = 0.0; - this->real_vol_i = 0; - } else { - this->real_vol_f = this->volume_f; - this->real_vol_i = this->volume_i; - } + volume_update_real_volume (this); } static void @@ -245,6 +252,8 @@ gst_volume_mixer_init (GstMixerClass * klass) klass->set_mute = gst_volume_set_mute; } +/* Element class */ + static void gst_volume_dispose (GObject * object) { @@ -290,10 +299,12 @@ gst_volume_class_init (GstVolumeClass * klass) FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VOLUME, - g_param_spec_double ("volume", "volume", "volume", + g_param_spec_double ("volume", "Volume", "volume factor", 0.0, VOLUME_MAX_DOUBLE, 1.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); + GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "volume", 0, "Volume gain"); + trans_class->transform_ip = GST_DEBUG_FUNCPTR (volume_transform_ip); trans_class->set_caps = GST_DEBUG_FUNCPTR (volume_set_caps); } @@ -322,21 +333,10 @@ gst_volume_init (GstVolume * this, GstVolumeClass * g_class) } } -/* based on the caps' structure, install the correct volume_process method */ -static void -volume_funcfind (GstVolume * this, const GstStructure * structure) -{ - const gchar *mimetype; - - mimetype = gst_structure_get_name (structure); - - if (strcmp (mimetype, "audio/x-raw-int") == 0) - this->process = volume_process_int16; - else if (strcmp (mimetype, "audio/x-raw-float") == 0) - this->process = volume_process_float; - else - this->process = NULL; -} +/* NOTE: although it might be tempting to have volume_process_mute() which uses + * memset(bytes, 0, nbytes) for the vol=0 case, this has the downside that + * unmuting would unly take place after processing a buffer. + */ static void volume_process_float (GstVolume * this, GstClockTime tstamp, @@ -351,6 +351,9 @@ volume_process_float (GstVolume * this, GstClockTime tstamp, for (i = 0; i < num_samples; i++) { *data++ *= this->real_vol_f; } + /* FIXME: need... liboil... + oil_scalarmultiply_f32_ns (data, data, &this->real_vol_f, num_samples); + */ } static void @@ -363,16 +366,20 @@ volume_process_int16 (GstVolume * this, GstClockTime tstamp, data = (gint16 *) bytes; num_samples = n_bytes / sizeof (gint16); - /* FIXME: need... liboil... */ - /* only clamp if the gain is greater than 1.0 */ + /* FIXME: need... liboil... + * oil_scalarmultiply_s16_ns ? + */ + + /* only clamp if the gain is greater than 1.0 + * FIXME: real_vol_i can change while processing the buffer! + */ if (this->real_vol_i > VOLUME_UNITY_INT) { for (i = 0; i < num_samples; i++) { /* we use bitshifting instead of dividing by UNITY_INT for speed */ val = (gint) * data; *data++ = - (gint16) CLAMP ((this->real_vol_i * - val) >> VOLUME_UNITY_BIT_SHIFT, VOLUME_MIN_INT16, - VOLUME_MAX_INT16); + (gint16) CLAMP ((this->real_vol_i * val) >> VOLUME_UNITY_BIT_SHIFT, + VOLUME_MIN_INT16, VOLUME_MAX_INT16); } } else { for (i = 0; i < num_samples; i++) { @@ -390,14 +397,22 @@ static gboolean volume_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps) { GstVolume *this = GST_VOLUME (base); + const gchar *mimetype; GST_DEBUG_OBJECT (this, "set_caps: in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps, outcaps); - volume_funcfind (this, gst_caps_get_structure (incaps, 0)); + mimetype = gst_structure_get_name (gst_caps_get_structure (incaps, 0)); - if (!this->process) + /* based on mimetype, install the correct volume_process method */ + if (strcmp (mimetype, "audio/x-raw-int") == 0) + this->process = volume_process_int16; + else if (strcmp (mimetype, "audio/x-raw-float") == 0) + this->process = volume_process_float; + else { + this->process = NULL; goto invalid_format; + } return TRUE; @@ -420,6 +435,10 @@ volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf) GstVolume *this = GST_VOLUME (base); GstClockTime timestamp; + /* don't process data in passthrough-mode (requires #343196) + if (!gst_buffer_is_writable (outbuf)) return GST_FLOW_OK; + */ + timestamp = GST_BUFFER_TIMESTAMP (outbuf); if (GST_CLOCK_TIME_IS_VALID (timestamp)) @@ -444,13 +463,7 @@ volume_update_mute (const GValue * value, gpointer data) this->mute = (g_value_get_int (value) == 1); } - if (this->mute) { - this->real_vol_f = 0.0; - this->real_vol_i = 0; - } else { - this->real_vol_f = this->volume_f; - this->real_vol_i = this->volume_i; - } + volume_update_real_volume (this); } static void @@ -462,13 +475,8 @@ volume_update_volume (const GValue * value, gpointer data) this->volume_f = g_value_get_double (value); this->volume_i = this->volume_f * VOLUME_UNITY_INT; - if (this->mute) { - this->real_vol_f = 0.0; - this->real_vol_i = 0; - } else { - this->real_vol_f = this->volume_f; - this->real_vol_i = this->volume_i; - } + + volume_update_real_volume (this); } static void diff --git a/gst/volume/gstvolume.h b/gst/volume/gstvolume.h index 7cdfaa8..5b6de36 100644 --- a/gst/volume/gstvolume.h +++ b/gst/volume/gstvolume.h @@ -36,17 +36,12 @@ G_BEGIN_DECLS (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VOLUME,GstVolume)) #define GST_IS_VOLUME(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VOLUME)) -#define GST_IS_VOLUME_CLASS(obj) \ +#define GST_IS_VOLUME_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VOLUME)) typedef struct _GstVolume GstVolume; typedef struct _GstVolumeClass GstVolumeClass; -typedef enum { - GST_VOLUME_FORMAT_INT=1, - GST_VOLUME_FORMAT_FLOAT -} GstVolumeFormat; - /** * GstVolume: * @@ -60,7 +55,7 @@ struct _GstVolume { gboolean mute; gint volume_i, real_vol_i; /* the _i(nt) values get synchronized with the */ gfloat volume_f, real_vol_f; /* _f(loat) values on each update */ - + GList *tracklist; }; diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index f66689f..372133f 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -102,6 +102,14 @@ elements_audioconvert_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(CFLAGS) $(AM_CFLAGS) +elements_volume_LDADD = \ + $(GST_BASE_LIBS) \ + $(LDADD) + +elements_volume_CFLAGS = \ + $(GST_BASE_CFLAGS) \ + $(CFLAGS) $(AM_CFLAGS) + libs_video_LDADD = \ $(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_MAJORMINOR@.la \ $(LDADD) diff --git a/tests/check/elements/volume.c b/tests/check/elements/volume.c index 9377673..0e37c75 100644 --- a/tests/check/elements/volume.c +++ b/tests/check/elements/volume.c @@ -22,6 +22,7 @@ #include +#include #include GList *buffers = NULL; @@ -107,6 +108,7 @@ GST_START_TEST (test_unity) GstBuffer *inbuffer, *outbuffer; GstCaps *caps; gint16 in[2] = { 16384, -256 }; + gint16 *res; volume = setup_volume (); fail_unless (gst_element_set_state (volume, @@ -127,6 +129,9 @@ GST_START_TEST (test_unity) fail_unless_equals_int (g_list_length (buffers), 1); fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL); fail_unless (inbuffer == outbuffer); + res = (gint16 *) GST_BUFFER_DATA (outbuffer); + GST_INFO ("expected %+5ld %+5ld real %+5ld %+5ld", in[0], in[1], res[0], + res[1]); fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0); /* cleanup */ @@ -143,6 +148,7 @@ GST_START_TEST (test_half) GstCaps *caps; gint16 in[2] = { 16384, -256 }; gint16 out[2] = { 8192, -128 }; + gint16 *res; volume = setup_volume (); g_object_set (G_OBJECT (volume), "volume", 0.5, NULL); @@ -170,6 +176,9 @@ GST_START_TEST (test_half) fail_unless_equals_int (g_list_length (buffers), 1); fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL); fail_unless (inbuffer == outbuffer); + res = (gint16 *) GST_BUFFER_DATA (outbuffer); + GST_INFO ("expected %+5ld %+5ld real %+5ld %+5ld", out[0], out[1], res[0], + res[1]); fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 4) == 0); /* cleanup */ @@ -186,6 +195,7 @@ GST_START_TEST (test_double) GstCaps *caps; gint16 in[2] = { 16384, -256 }; gint16 out[2] = { 32767, -512 }; /* notice the clamped sample */ + gint16 *res; volume = setup_volume (); g_object_set (G_OBJECT (volume), "volume", 2.0, NULL); @@ -213,6 +223,9 @@ GST_START_TEST (test_double) fail_unless_equals_int (g_list_length (buffers), 1); fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL); fail_unless (inbuffer == outbuffer); + res = (gint16 *) GST_BUFFER_DATA (outbuffer); + GST_INFO ("expected %+5ld %+5ld real %+5ld %+5ld", out[0], out[1], res[0], + res[1]); fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 4) == 0); /* cleanup */ @@ -221,6 +234,55 @@ GST_START_TEST (test_double) GST_END_TEST; + +GST_START_TEST (test_mute) +{ + GstElement *volume; + GstBuffer *inbuffer; + GstBuffer *outbuffer; + GstCaps *caps; + gint16 in[2] = { 16384, -256 }; + gint16 out[2] = { 0, 0 }; + gint16 *res; + + volume = setup_volume (); + g_object_set (G_OBJECT (volume), "mute", TRUE, NULL); + fail_unless (gst_element_set_state (volume, + GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, + "could not set to playing"); + + inbuffer = gst_buffer_new_and_alloc (4); + memcpy (GST_BUFFER_DATA (inbuffer), in, 4); + fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0); + caps = gst_caps_from_string (VOLUME_CAPS_STRING); + gst_buffer_set_caps (inbuffer, caps); + gst_caps_unref (caps); + ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); + /* FIXME: reffing the inbuffer should make the transformation not be + * inplace + gst_buffer_ref (inbuffer); + */ + + /* pushing gives away my reference ... */ + fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); + /* ... but it ends up being modified inplace and + * collected on the global buffer list */ + ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); + fail_unless_equals_int (g_list_length (buffers), 1); + fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL); + fail_unless (inbuffer == outbuffer); + res = (gint16 *) GST_BUFFER_DATA (outbuffer); + GST_INFO ("expected %+5ld %+5ld real %+5ld %+5ld", out[0], out[1], res[0], + res[1]); + fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 4) == 0); + + /* cleanup */ + cleanup_volume (volume); +} + +GST_END_TEST; + + GST_START_TEST (test_wrong_caps) { GstElement *volume; @@ -269,6 +331,47 @@ GST_START_TEST (test_wrong_caps) GST_END_TEST; +GST_START_TEST (test_passthrough) +{ + GstElement *volume; + GstBuffer *inbuffer, *outbuffer; + GstCaps *caps; + gint16 in[2] = { 16384, -256 }; + gint16 *res; + + volume = setup_volume (); + g_object_set (G_OBJECT (volume), "volume", 2.0, NULL); + gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (volume), TRUE); + fail_unless (gst_element_set_state (volume, + GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, + "could not set to playing"); + + inbuffer = gst_buffer_new_and_alloc (4); + memcpy (GST_BUFFER_DATA (inbuffer), in, 4); + caps = gst_caps_from_string (VOLUME_CAPS_STRING); + gst_buffer_set_caps (inbuffer, caps); + gst_caps_unref (caps); + ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); + + /* pushing gives away my reference ... */ + fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); + /* ... but it ends up being collected on the global buffer list */ + ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); + fail_unless_equals_int (g_list_length (buffers), 1); + fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL); + fail_unless (inbuffer == outbuffer); + res = (gint16 *) GST_BUFFER_DATA (outbuffer); + GST_INFO ("expected %+5ld %+5ld real %+5ld %+5ld", in[0], in[1], res[0], + res[1]); + fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0); + + /* cleanup */ + cleanup_volume (volume); +} + +GST_END_TEST; + + Suite * volume_suite (void) { @@ -279,7 +382,9 @@ volume_suite (void) tcase_add_test (tc_chain, test_unity); tcase_add_test (tc_chain, test_half); tcase_add_test (tc_chain, test_double); + tcase_add_test (tc_chain, test_mute); tcase_add_test (tc_chain, test_wrong_caps); + tcase_add_test (tc_chain, test_passthrough); return s; } diff --git a/tests/check/generic/states.c b/tests/check/generic/states.c index 15eb189..cfdd739 100644 --- a/tests/check/generic/states.c +++ b/tests/check/generic/states.c @@ -62,6 +62,11 @@ GST_START_TEST (test_state_changes) GST_DEBUG ("testing element %s", name); element = gst_element_factory_make (name, name); + if (!element) { + GST_WARNING ("failed to create element %s", name); + continue; + } + if (GST_IS_PIPELINE (element)) { GST_DEBUG ("element %s is a pipeline", name); }