5 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
25 #include <gst/check/gstcheck.h>
27 GList *buffers = NULL;
28 gboolean have_eos = FALSE;
30 /* For ease of programming we use globals to keep refs for our floating
31 * src and sink pads we create; otherwise we always have to do get_pad,
32 * get_peer, and then remove references in every test function */
33 GstPad *mysrcpad, *mysinkpad;
36 #define VOLUME_CAPS_TEMPLATE_STRING \
38 "channels = (int) [ 1, MAX ], " \
39 "rate = (int) [ 1, MAX ], " \
40 "endianness = (int) BYTE_ORDER, " \
41 "width = (int) 16, " \
42 "depth = (int) 16, " \
43 "signed = (bool) TRUE"
45 #define VOLUME_CAPS_STRING \
47 "channels = (int) 1, " \
48 "rate = (int) 44100, " \
49 "endianness = (int) BYTE_ORDER, " \
50 "width = (int) 16, " \
51 "depth = (int) 16, " \
52 "signed = (bool) TRUE"
54 #define VOLUME_WRONG_CAPS_STRING \
56 "channels = (int) 1, " \
57 "rate = (int) 44100, " \
58 "endianness = (int) BYTE_ORDER, " \
59 "width = (int) 16, " \
60 "depth = (int) 16, " \
61 "signed = (bool) FALSE"
64 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
67 GST_STATIC_CAPS (VOLUME_CAPS_TEMPLATE_STRING)
69 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
72 GST_STATIC_CAPS (VOLUME_CAPS_TEMPLATE_STRING)
80 GST_DEBUG ("setup_volume");
81 volume = gst_check_setup_element ("volume");
82 mysrcpad = gst_check_setup_src_pad (volume, &srctemplate, NULL);
83 mysinkpad = gst_check_setup_sink_pad (volume, &sinktemplate, NULL);
88 cleanup_volume (GstElement * volume)
90 GST_DEBUG ("cleanup_volume");
92 g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
93 g_list_free (buffers);
96 gst_check_teardown_src_pad (volume);
97 gst_check_teardown_sink_pad (volume);
98 gst_check_teardown_element (volume);
101 GST_START_TEST (test_unity)
104 GstBuffer *inbuffer, *outbuffer;
105 gint16 in[2] = { 16384, -256 };
107 volume = setup_volume ();
108 fail_unless (gst_element_set_state (volume,
109 GST_STATE_PLAYING) == GST_STATE_SUCCESS, "could not set to playing");
111 inbuffer = gst_buffer_new_and_alloc (4);
112 memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
113 gst_buffer_set_caps (inbuffer, gst_caps_from_string (VOLUME_CAPS_STRING));
114 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
116 /* pushing gives away my reference ... */
117 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
118 /* ... but it ends up being collected on the global buffer list */
119 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
120 fail_unless_equals_int (g_list_length (buffers), 1);
121 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
122 fail_unless (inbuffer == outbuffer);
123 fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
126 cleanup_volume (volume);
131 GST_START_TEST (test_half)
135 GstBuffer *outbuffer;
136 gint16 in[2] = { 16384, -256 };
137 gint16 out[2] = { 8192, -128 };
139 volume = setup_volume ();
140 g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
141 fail_unless (gst_element_set_state (volume,
142 GST_STATE_PLAYING) == GST_STATE_SUCCESS, "could not set to playing");
144 inbuffer = gst_buffer_new_and_alloc (4);
145 memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
146 fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
147 gst_buffer_set_caps (inbuffer, gst_caps_from_string (VOLUME_CAPS_STRING));
148 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
149 /* FIXME: reffing the inbuffer should make the transformation not be
151 gst_buffer_ref (inbuffer);
154 /* pushing gives away my reference ... */
155 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
156 /* ... but it ends up being modified inplace and
157 * collected on the global buffer list */
158 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
159 fail_unless_equals_int (g_list_length (buffers), 1);
160 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
161 fail_unless (inbuffer == outbuffer);
162 fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 4) == 0);
165 cleanup_volume (volume);
170 GST_START_TEST (test_double)
174 GstBuffer *outbuffer;
175 gint16 in[2] = { 16384, -256 };
176 gint16 out[2] = { 32767, -512 }; /* notice the clamped sample */
178 volume = setup_volume ();
179 g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
180 fail_unless (gst_element_set_state (volume,
181 GST_STATE_PLAYING) == GST_STATE_SUCCESS, "could not set to playing");
183 inbuffer = gst_buffer_new_and_alloc (4);
184 memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
185 fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
186 gst_buffer_set_caps (inbuffer, gst_caps_from_string (VOLUME_CAPS_STRING));
187 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
188 /* FIXME: reffing the inbuffer should make the transformation not be
190 gst_buffer_ref (inbuffer);
193 /* pushing gives away my reference ... */
194 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
195 /* ... but it ends up being modified inplace and
196 * collected on the global buffer list */
197 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
198 fail_unless_equals_int (g_list_length (buffers), 1);
199 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
200 fail_unless (inbuffer == outbuffer);
201 fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 4) == 0);
204 cleanup_volume (volume);
209 GST_START_TEST (test_wrong_caps)
212 GstBuffer *inbuffer, *outbuffer;
213 gint16 in[2] = { 16384, -256 };
217 volume = setup_volume ();
218 bus = gst_bus_new ();
220 fail_unless (gst_element_set_state (volume,
221 GST_STATE_PLAYING) == GST_STATE_SUCCESS, "could not set to playing");
223 inbuffer = gst_buffer_new_and_alloc (4);
224 memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
225 gst_buffer_set_caps (inbuffer,
226 gst_caps_from_string (VOLUME_WRONG_CAPS_STRING));
227 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
228 gst_buffer_ref (inbuffer);
230 /* set a bus here so we avoid getting state change messages */
231 gst_element_set_bus (volume, bus);
233 /* pushing gives an error because it can't negotiate with wrong caps */
234 fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer),
235 GST_FLOW_NOT_NEGOTIATED);
236 /* ... and the buffer would have been lost if we didn't ref it ourselves */
237 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
238 gst_buffer_unref (inbuffer);
239 fail_unless_equals_int (g_list_length (buffers), 0);
241 /* volume_set_caps should not have been called since basetransform caught
242 * the negotiation problem */
243 fail_if ((message = gst_bus_pop (bus)) != NULL);
246 gst_element_set_bus (volume, NULL);
247 gst_object_unref (GST_OBJECT (bus));
248 cleanup_volume (volume);
257 Suite *s = suite_create ("volume");
258 TCase *tc_chain = tcase_create ("general");
260 suite_add_tcase (s, tc_chain);
261 tcase_add_test (tc_chain, test_unity);
262 tcase_add_test (tc_chain, test_half);
263 tcase_add_test (tc_chain, test_double);
264 tcase_add_test (tc_chain, test_wrong_caps);
270 main (int argc, char **argv)
274 Suite *s = volume_suite ();
275 SRunner *sr = srunner_create (s);
277 gst_check_init (&argc, &argv);
279 srunner_run_all (sr, CK_NORMAL);
280 nf = srunner_ntests_failed (sr);