1 /* GStreamer
2 *
3 * unit test for volume
4 *
5 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
6 *
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.
11 *
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.
16 *
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., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gst/base/gstbasetransform.h>
28 #include <gst/check/gstcheck.h>
29 #include <gst/audio/streamvolume.h>
30 #include <gst/controller/gstinterpolationcontrolsource.h>
31 #include <gst/controller/gstdirectcontrolbinding.h>
32
33 /* For ease of programming we use globals to keep refs for our floating
34 * src and sink pads we create; otherwise we always have to do get_pad,
35 * get_peer, and then remove references in every test function */
36 static GstPad *mysrcpad, *mysinkpad;
37
38 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
39 #define FORMATS1 "{ S8, S16LE, S24LE, S32LE, F32LE, F64LE }"
40 #define FORMATS2 "S8"
41 #define FORMATS3 "S16LE"
42 #define FORMATS4 "S24LE"
43 #define FORMATS5 "S32LE"
44 #define FORMATS6 "F32LE"
45 #define FORMATS7 "F64LE"
46 #define FORMATS8 "U16LE"
47 #else
48 #define FORMATS1 "{ S8, S16BE, S24BE, S32BE, F32BE, F64BE }"
49 #define FORMATS2 "S8"
50 #define FORMATS3 "S16BE"
51 #define FORMATS4 "S24BE"
52 #define FORMATS5 "S32BE"
53 #define FORMATS6 "F32BE"
54 #define FORMATS7 "F64BE"
55 #define FORMATS8 "U16BE"
56 #endif
57
58 #define VOLUME_CAPS_TEMPLATE_STRING \
59 "audio/x-raw, " \
60 "format = (string) "FORMATS1", " \
61 "channels = (int) [ 1, MAX ], " \
62 "rate = (int) [ 1, MAX ], " \
63 "layout = (string) interleaved"
64
65 #define VOLUME_CAPS_STRING_S8 \
66 "audio/x-raw, " \
67 "format = (string) "FORMATS2", " \
68 "channels = (int) 1, " \
69 "rate = (int) 44100," \
70 "layout = (string) interleaved"
71
72 #define VOLUME_CAPS_STRING_S16 \
73 "audio/x-raw, " \
74 "format = (string) "FORMATS3", " \
75 "channels = (int) 1, " \
76 "rate = (int) 44100," \
77 "layout = (string) interleaved"
78
79 #define VOLUME_CAPS_STRING_S24 \
80 "audio/x-raw, " \
81 "format = (string) "FORMATS4", " \
82 "channels = (int) 1, " \
83 "rate = (int) 44100," \
84 "layout = (string) interleaved"
85
86 #define VOLUME_CAPS_STRING_S32 \
87 "audio/x-raw, " \
88 "format = (string) "FORMATS5", " \
89 "channels = (int) 1, " \
90 "rate = (int) 44100," \
91 "layout = (string) interleaved"
92
93 #define VOLUME_CAPS_STRING_F32 \
94 "audio/x-raw, " \
95 "format = (string) "FORMATS6", " \
96 "channels = (int) 1, " \
97 "rate = (int) 44100," \
98 "layout = (string) interleaved"
99
100 #define VOLUME_CAPS_STRING_F64 \
101 "audio/x-raw, " \
102 "format = (string) "FORMATS7", " \
103 "channels = (int) 1, " \
104 "rate = (int) 44100," \
105 "layout = (string) interleaved"
106
107 #define VOLUME_WRONG_CAPS_STRING \
108 "audio/x-raw, " \
109 "format = (string) "FORMATS8", " \
110 "channels = (int) 1, " \
111 "rate = (int) 44100," \
112 "layout = (string) interleaved"
113
114
115 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
116 GST_PAD_SINK,
117 GST_PAD_ALWAYS,
118 GST_STATIC_CAPS (VOLUME_CAPS_TEMPLATE_STRING)
119 );
120 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
121 GST_PAD_SRC,
122 GST_PAD_ALWAYS,
123 GST_STATIC_CAPS (VOLUME_CAPS_TEMPLATE_STRING)
124 );
125
126 static GstElement *
setup_volume(void)127 setup_volume (void)
128 {
129 GstElement *volume;
130
131 GST_DEBUG ("setup_volume");
132 volume = gst_check_setup_element ("volume");
133 mysrcpad = gst_check_setup_src_pad (volume, &srctemplate);
134 mysinkpad = gst_check_setup_sink_pad (volume, &sinktemplate);
135 gst_pad_set_active (mysrcpad, TRUE);
136 gst_pad_set_active (mysinkpad, TRUE);
137
138 return volume;
139 }
140
141 static void
cleanup_volume(GstElement * volume)142 cleanup_volume (GstElement * volume)
143 {
144 GST_DEBUG ("cleanup_volume");
145
146 g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
147 g_list_free (buffers);
148 buffers = NULL;
149
150 gst_pad_set_active (mysrcpad, FALSE);
151 gst_pad_set_active (mysinkpad, FALSE);
152 gst_check_teardown_src_pad (volume);
153 gst_check_teardown_sink_pad (volume);
154 gst_check_teardown_element (volume);
155 }
156
GST_START_TEST(test_get_set)157 GST_START_TEST (test_get_set)
158 {
159 GstElement *volume = gst_element_factory_make ("volume", NULL);
160 gdouble val;
161
162 fail_unless (volume != NULL);
163 g_object_get (G_OBJECT (volume), "volume", &val, NULL);
164 fail_unless (val == 1.0);
165 fail_unless (val == gst_stream_volume_get_volume (GST_STREAM_VOLUME (volume),
166 GST_STREAM_VOLUME_FORMAT_LINEAR));
167
168 g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
169 g_object_get (G_OBJECT (volume), "volume", &val, NULL);
170 fail_unless (val == 0.5);
171 fail_unless (val == gst_stream_volume_get_volume (GST_STREAM_VOLUME (volume),
172 GST_STREAM_VOLUME_FORMAT_LINEAR));
173
174 gst_stream_volume_set_volume (GST_STREAM_VOLUME (volume),
175 GST_STREAM_VOLUME_FORMAT_LINEAR, 1.0);
176 g_object_get (G_OBJECT (volume), "volume", &val, NULL);
177 fail_unless (val == 1.0);
178 fail_unless (val == gst_stream_volume_get_volume (GST_STREAM_VOLUME (volume),
179 GST_STREAM_VOLUME_FORMAT_LINEAR));
180
181 gst_object_unref (volume);
182 }
183
184 GST_END_TEST;
185
GST_START_TEST(test_unity_s8)186 GST_START_TEST (test_unity_s8)
187 {
188 GstElement *volume;
189 GstBuffer *inbuffer, *outbuffer;
190 GstCaps *caps;
191 gint8 in[2] = { 64, -16 };
192 gint8 *res;
193 GstMapInfo map;
194
195 volume = setup_volume ();
196 fail_unless (gst_element_set_state (volume,
197 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
198 "could not set to playing");
199
200 inbuffer = gst_buffer_new_and_alloc (2);
201 gst_buffer_fill (inbuffer, 0, in, 2);
202 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
203 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
204 gst_caps_unref (caps);
205 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
206
207 /* pushing gives away my reference ... */
208 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
209 /* ... but it ends up being collected on the global buffer list */
210 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
211 fail_unless_equals_int (g_list_length (buffers), 1);
212 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
213 fail_unless (inbuffer == outbuffer);
214 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
215 res = (gint8 *) map.data;
216 GST_INFO ("expected %+5d %+5d real %+5d %+5d", in[0], in[1], res[0], res[1]);
217 fail_unless (memcmp (res, in, 2) == 0);
218 gst_buffer_unmap (outbuffer, &map);
219
220 /* cleanup */
221 cleanup_volume (volume);
222 }
223
224 GST_END_TEST;
225
GST_START_TEST(test_half_s8)226 GST_START_TEST (test_half_s8)
227 {
228 GstElement *volume;
229 GstBuffer *inbuffer;
230 GstBuffer *outbuffer;
231 GstCaps *caps;
232 gint8 in[2] = { 64, -16 };
233 gint8 out[2] = { 32, -8 };
234 gint8 *res;
235 GstMapInfo map;
236
237 volume = setup_volume ();
238 g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
239 fail_unless (gst_element_set_state (volume,
240 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
241 "could not set to playing");
242
243 inbuffer = gst_buffer_new_and_alloc (2);
244 gst_buffer_fill (inbuffer, 0, in, 2);
245 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
246 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
247 gst_caps_unref (caps);
248 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
249 /* FIXME: reffing the inbuffer should make the transformation not be
250 * inplace
251 gst_buffer_ref (inbuffer);
252 */
253
254 /* pushing gives away my reference ... */
255 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
256 /* ... but it ends up being modified inplace and
257 * collected on the global buffer list */
258 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
259 fail_unless_equals_int (g_list_length (buffers), 1);
260 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
261 fail_unless (inbuffer == outbuffer);
262 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
263 res = (gint8 *) map.data;
264 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], res[0],
265 res[1]);
266 fail_unless (memcmp (res, out, 2) == 0);
267 gst_buffer_unmap (outbuffer, &map);
268
269 /* cleanup */
270 cleanup_volume (volume);
271 }
272
273 GST_END_TEST;
274
GST_START_TEST(test_double_s8)275 GST_START_TEST (test_double_s8)
276 {
277 GstElement *volume;
278 GstBuffer *inbuffer;
279 GstBuffer *outbuffer;
280 GstCaps *caps;
281 gint8 in[2] = { 64, -16 };
282 gint8 out[2] = { 127, -32 }; /* notice the clamped sample */
283 gint8 *res;
284 GstMapInfo map;
285
286 volume = setup_volume ();
287 g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
288 fail_unless (gst_element_set_state (volume,
289 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
290 "could not set to playing");
291
292 inbuffer = gst_buffer_new_and_alloc (2);
293 gst_buffer_fill (inbuffer, 0, in, 2);
294 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
295 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
296 gst_caps_unref (caps);
297 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
298 /* FIXME: reffing the inbuffer should make the transformation not be
299 * inplace
300 gst_buffer_ref (inbuffer);
301 */
302
303 /* pushing gives away my reference ... */
304 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
305 /* ... but it ends up being modified inplace and
306 * collected on the global buffer list */
307 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
308 fail_unless_equals_int (g_list_length (buffers), 1);
309 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
310 fail_unless (inbuffer == outbuffer);
311 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
312 res = (gint8 *) map.data;
313 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], res[0],
314 res[1]);
315 fail_unless (memcmp (res, out, 2) == 0);
316 gst_buffer_unmap (outbuffer, &map);
317
318 /* cleanup */
319 cleanup_volume (volume);
320 }
321
322 GST_END_TEST;
323
GST_START_TEST(test_ten_s8)324 GST_START_TEST (test_ten_s8)
325 {
326 GstElement *volume;
327 GstBuffer *inbuffer;
328 GstBuffer *outbuffer;
329 GstCaps *caps;
330 gint8 in[2] = { 64, -10 };
331 gint8 out[2] = { 127, -100 }; /* notice the clamped sample */
332 gint8 *res;
333 GstMapInfo map;
334
335 volume = setup_volume ();
336 g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
337 fail_unless (gst_element_set_state (volume,
338 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
339 "could not set to playing");
340
341 inbuffer = gst_buffer_new_and_alloc (2);
342 gst_buffer_fill (inbuffer, 0, in, 2);
343 fail_unless (gst_buffer_memcmp (inbuffer, 0, in, 2) == 0);
344 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
345 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
346 gst_caps_unref (caps);
347 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
348 /* FIXME: reffing the inbuffer should make the transformation not be
349 * inplace
350 gst_buffer_ref (inbuffer);
351 */
352
353 /* pushing gives away my reference ... */
354 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
355 /* ... but it ends up being modified inplace and
356 * collected on the global buffer list */
357 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
358 fail_unless_equals_int (g_list_length (buffers), 1);
359 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
360 fail_unless (inbuffer == outbuffer);
361 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
362 res = (gint8 *) map.data;
363 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], res[0],
364 res[1]);
365 fail_unless (memcmp (res, out, 2) == 0);
366 gst_buffer_unmap (outbuffer, &map);
367
368 /* cleanup */
369 cleanup_volume (volume);
370 }
371
372 GST_END_TEST;
373
GST_START_TEST(test_mute_s8)374 GST_START_TEST (test_mute_s8)
375 {
376 GstElement *volume;
377 GstBuffer *inbuffer;
378 GstBuffer *outbuffer;
379 GstCaps *caps;
380 gint8 in[2] = { 64, -16 };
381 gint8 out[2] = { 0, 0 };
382 GstMapInfo map;
383
384 volume = setup_volume ();
385 g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
386 fail_unless (gst_element_set_state (volume,
387 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
388 "could not set to playing");
389
390 inbuffer = gst_buffer_new_and_alloc (2);
391 gst_buffer_fill (inbuffer, 0, in, 2);
392 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
393 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
394 gst_caps_unref (caps);
395 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
396 /* FIXME: reffing the inbuffer should make the transformation not be
397 * inplace
398 gst_buffer_ref (inbuffer);
399 */
400
401 /* pushing gives away my reference ... */
402 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
403 /* ... but it ends up being modified inplace and
404 * collected on the global buffer list */
405 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
406 fail_unless_equals_int (g_list_length (buffers), 1);
407 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
408 fail_unless (inbuffer == outbuffer);
409 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
410 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], map.data[0],
411 map.data[1]);
412 fail_unless (memcmp (map.data, out, 2) == 0);
413 gst_buffer_unmap (outbuffer, &map);
414
415 /* cleanup */
416 cleanup_volume (volume);
417 }
418
419 GST_END_TEST;
420
GST_START_TEST(test_unity_s16)421 GST_START_TEST (test_unity_s16)
422 {
423 GstElement *volume;
424 GstBuffer *inbuffer, *outbuffer;
425 GstCaps *caps;
426 gint16 in[2] = { 16384, -256 };
427 GstMapInfo map;
428
429 volume = setup_volume ();
430 fail_unless (gst_element_set_state (volume,
431 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
432 "could not set to playing");
433
434 inbuffer = gst_buffer_new_and_alloc (4);
435 gst_buffer_fill (inbuffer, 0, in, 4);
436 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
437 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
438 gst_caps_unref (caps);
439 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
440
441 /* pushing gives away my reference ... */
442 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
443 /* ... but it ends up being collected on the global buffer list */
444 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
445 fail_unless_equals_int (g_list_length (buffers), 1);
446 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
447 fail_unless (inbuffer == outbuffer);
448 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
449 GST_INFO ("expected %+5d %+5d real %+5d %+5d", in[0], in[1], map.data[0],
450 map.data[1]);
451 fail_unless (memcmp (map.data, in, 4) == 0);
452 gst_buffer_unmap (outbuffer, &map);
453
454 /* cleanup */
455 cleanup_volume (volume);
456 }
457
458 GST_END_TEST;
459
GST_START_TEST(test_half_s16)460 GST_START_TEST (test_half_s16)
461 {
462 GstElement *volume;
463 GstBuffer *inbuffer;
464 GstBuffer *outbuffer;
465 GstCaps *caps;
466 gint16 in[2] = { 16384, -256 };
467 gint16 out[2] = { 8192, -128 };
468 GstMapInfo map;
469
470 volume = setup_volume ();
471 g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
472 fail_unless (gst_element_set_state (volume,
473 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
474 "could not set to playing");
475
476 inbuffer = gst_buffer_new_and_alloc (4);
477 gst_buffer_fill (inbuffer, 0, in, 4);
478 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
479 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
480 gst_caps_unref (caps);
481 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
482 /* FIXME: reffing the inbuffer should make the transformation not be
483 * inplace
484 gst_buffer_ref (inbuffer);
485 */
486
487 /* pushing gives away my reference ... */
488 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
489 /* ... but it ends up being modified inplace and
490 * collected on the global buffer list */
491 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
492 fail_unless_equals_int (g_list_length (buffers), 1);
493 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
494 fail_unless (inbuffer == outbuffer);
495 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
496 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], map.data[0],
497 map.data[1]);
498 fail_unless (memcmp (map.data, out, 4) == 0);
499 gst_buffer_unmap (outbuffer, &map);
500
501 /* cleanup */
502 cleanup_volume (volume);
503 }
504
505 GST_END_TEST;
506
GST_START_TEST(test_double_s16)507 GST_START_TEST (test_double_s16)
508 {
509 GstElement *volume;
510 GstBuffer *inbuffer;
511 GstBuffer *outbuffer;
512 GstCaps *caps;
513 gint16 in[2] = { 16384, -256 };
514 gint16 out[2] = { 32767, -512 }; /* notice the clamped sample */
515 GstMapInfo map;
516
517 volume = setup_volume ();
518 g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
519 fail_unless (gst_element_set_state (volume,
520 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
521 "could not set to playing");
522
523 inbuffer = gst_buffer_new_and_alloc (4);
524 gst_buffer_fill (inbuffer, 0, in, 4);
525 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
526 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
527 gst_caps_unref (caps);
528 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
529 /* FIXME: reffing the inbuffer should make the transformation not be
530 * inplace
531 gst_buffer_ref (inbuffer);
532 */
533
534 /* pushing gives away my reference ... */
535 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
536 /* ... but it ends up being modified inplace and
537 * collected on the global buffer list */
538 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
539 fail_unless_equals_int (g_list_length (buffers), 1);
540 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
541 fail_unless (inbuffer == outbuffer);
542 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
543 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], map.data[0],
544 map.data[1]);
545 fail_unless (memcmp (map.data, out, 4) == 0);
546 gst_buffer_unmap (outbuffer, &map);
547
548 /* cleanup */
549 cleanup_volume (volume);
550 }
551
552 GST_END_TEST;
553
GST_START_TEST(test_ten_s16)554 GST_START_TEST (test_ten_s16)
555 {
556 GstElement *volume;
557 GstBuffer *inbuffer;
558 GstBuffer *outbuffer;
559 GstCaps *caps;
560 gint16 in[2] = { 16384, -10 };
561 gint16 out[2] = { 32767, -100 }; /* notice the clamped sample */
562 GstMapInfo map;
563
564 volume = setup_volume ();
565 g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
566 fail_unless (gst_element_set_state (volume,
567 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
568 "could not set to playing");
569
570 inbuffer = gst_buffer_new_and_alloc (4);
571 gst_buffer_fill (inbuffer, 0, in, 4);
572 fail_unless (gst_buffer_memcmp (inbuffer, 0, in, 4) == 0);
573 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
574 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
575 gst_caps_unref (caps);
576 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
577 /* FIXME: reffing the inbuffer should make the transformation not be
578 * inplace
579 gst_buffer_ref (inbuffer);
580 */
581
582 /* pushing gives away my reference ... */
583 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
584 /* ... but it ends up being modified inplace and
585 * collected on the global buffer list */
586 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
587 fail_unless_equals_int (g_list_length (buffers), 1);
588 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
589 fail_unless (inbuffer == outbuffer);
590 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
591 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], map.data[0],
592 map.data[1]);
593 fail_unless (memcmp (map.data, out, 4) == 0);
594 gst_buffer_unmap (outbuffer, &map);
595
596 /* cleanup */
597 cleanup_volume (volume);
598 }
599
600 GST_END_TEST;
601
602
GST_START_TEST(test_mute_s16)603 GST_START_TEST (test_mute_s16)
604 {
605 GstElement *volume;
606 GstBuffer *inbuffer;
607 GstBuffer *outbuffer;
608 GstCaps *caps;
609 gint16 in[2] = { 16384, -256 };
610 gint16 out[2] = { 0, 0 };
611 GstMapInfo map;
612
613 volume = setup_volume ();
614 g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
615 fail_unless (gst_element_set_state (volume,
616 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
617 "could not set to playing");
618
619 inbuffer = gst_buffer_new_and_alloc (4);
620 gst_buffer_fill (inbuffer, 0, in, 4);
621 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
622 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
623 gst_caps_unref (caps);
624 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
625 /* FIXME: reffing the inbuffer should make the transformation not be
626 * inplace
627 gst_buffer_ref (inbuffer);
628 */
629
630 /* pushing gives away my reference ... */
631 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
632 /* ... but it ends up being modified inplace and
633 * collected on the global buffer list */
634 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
635 fail_unless_equals_int (g_list_length (buffers), 1);
636 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
637 fail_unless (inbuffer == outbuffer);
638 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
639 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], map.data[0],
640 map.data[1]);
641 fail_unless (memcmp (map.data, out, 4) == 0);
642 gst_buffer_unmap (outbuffer, &map);
643
644 /* cleanup */
645 cleanup_volume (volume);
646 }
647
648 GST_END_TEST;
649
650 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
651 #define get_unaligned_i24(_x) ( (((guint8*)_x)[0]) | ((((guint8*)_x)[1]) << 8) | ((((gint8*)_x)[2]) << 16) )
652 #define write_unaligned_u24(_x,samp) do { (((guint8*)_x)[0]) = samp & 0xFF; (((guint8*)_x)[1]) = (samp >> 8) & 0xFF; (((guint8*)_x)[2]) = (samp >> 16) & 0xFF; } while (0)
653 #else /* BIG ENDIAN */
654 #define get_unaligned_i24(_x) ( (((guint8*)_x)[2]) | ((((guint8*)_x)[1]) << 8) | ((((gint8*)_x)[0]) << 16) )
655 #define write_unaligned_u24(_x,samp) do { (((guint8*)_x)[0]) = (samp >> 16) & 0xFF; (((guint8*)_x)[1]) = (samp >> 8) & 0xFF; (((guint8*)_x)[2]) = samp & 0xFF; } while (0)
656 #endif
657
GST_START_TEST(test_unity_s24)658 GST_START_TEST (test_unity_s24)
659 {
660 GstElement *volume;
661 GstBuffer *inbuffer, *outbuffer;
662 GstCaps *caps;
663 gint32 in_32[2] = { 4194304, -4096 };
664 guint8 in[6];
665 GstMapInfo map;
666 gint32 res_32[2];
667
668 write_unaligned_u24 (in, in_32[0]);
669 write_unaligned_u24 (in + 3, in_32[1]);
670
671 volume = setup_volume ();
672 fail_unless (gst_element_set_state (volume,
673 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
674 "could not set to playing");
675
676 inbuffer = gst_buffer_new_and_alloc (6);
677 gst_buffer_fill (inbuffer, 0, in, 6);
678 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
679 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
680 gst_caps_unref (caps);
681 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
682
683 /* pushing gives away my reference ... */
684 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
685 /* ... but it ends up being collected on the global buffer list */
686 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
687 fail_unless_equals_int (g_list_length (buffers), 1);
688 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
689 fail_unless (inbuffer == outbuffer);
690 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
691
692 res_32[0] = get_unaligned_i24 (map.data);
693 res_32[1] = get_unaligned_i24 ((map.data + 3));
694
695 GST_INFO ("expected %+5d %+5d real %+5d %+5d", in_32[0], in_32[1], res_32[0],
696 res_32[1]);
697 fail_unless (memcmp (map.data, in, 6) == 0);
698 gst_buffer_unmap (outbuffer, &map);
699
700 /* cleanup */
701 cleanup_volume (volume);
702 }
703
704 GST_END_TEST;
705
GST_START_TEST(test_half_s24)706 GST_START_TEST (test_half_s24)
707 {
708 GstElement *volume;
709 GstBuffer *inbuffer;
710 GstBuffer *outbuffer;
711 GstCaps *caps;
712 gint32 in_32[2] = { 4194304, -4096 };
713 guint8 in[6];
714 GstMapInfo map;
715 gint32 res_32[2];
716 gint32 out_32[2] = { 2097152, -2048 };
717
718 write_unaligned_u24 (in, in_32[0]);
719 write_unaligned_u24 (in + 3, in_32[1]);
720
721 volume = setup_volume ();
722 g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
723 fail_unless (gst_element_set_state (volume,
724 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
725 "could not set to playing");
726
727 inbuffer = gst_buffer_new_and_alloc (6);
728 gst_buffer_fill (inbuffer, 0, in, 6);
729 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
730 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
731 gst_caps_unref (caps);
732 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
733 /* FIXME: reffing the inbuffer should make the transformation not be
734 * inplace
735 gst_buffer_ref (inbuffer);
736 */
737
738 /* pushing gives away my reference ... */
739 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
740 /* ... but it ends up being modified inplace and
741 * collected on the global buffer list */
742 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
743 fail_unless_equals_int (g_list_length (buffers), 1);
744 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
745 fail_unless (inbuffer == outbuffer);
746 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
747
748 res_32[0] = get_unaligned_i24 (map.data);
749 res_32[1] = get_unaligned_i24 ((map.data + 3));
750
751 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out_32[0], out_32[1],
752 res_32[0], res_32[1]);
753 fail_unless (memcmp (res_32, out_32, 8) == 0);
754 gst_buffer_unmap (outbuffer, &map);
755
756 /* cleanup */
757 cleanup_volume (volume);
758 }
759
760 GST_END_TEST;
761
GST_START_TEST(test_double_s24)762 GST_START_TEST (test_double_s24)
763 {
764 GstElement *volume;
765 GstBuffer *inbuffer;
766 GstBuffer *outbuffer;
767 GstCaps *caps;
768 gint32 in_32[2] = { 4194304, -4096 };
769 guint8 in[6];
770 GstMapInfo map;
771 gint32 res_32[2];
772 gint32 out_32[2] = { 8388607, -8192 }; /* notice the clamped sample */
773
774 write_unaligned_u24 (in, in_32[0]);
775 write_unaligned_u24 (in + 3, in_32[1]);
776
777 volume = setup_volume ();
778 g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
779 fail_unless (gst_element_set_state (volume,
780 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
781 "could not set to playing");
782
783 inbuffer = gst_buffer_new_and_alloc (6);
784 gst_buffer_fill (inbuffer, 0, in, 6);
785 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
786 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
787 gst_caps_unref (caps);
788 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
789 /* FIXME: reffing the inbuffer should make the transformation not be
790 * inplace
791 gst_buffer_ref (inbuffer);
792 */
793
794 /* pushing gives away my reference ... */
795 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
796 /* ... but it ends up being modified inplace and
797 * collected on the global buffer list */
798 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
799 fail_unless_equals_int (g_list_length (buffers), 1);
800 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
801 fail_unless (inbuffer == outbuffer);
802 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
803
804 res_32[0] = get_unaligned_i24 (map.data);
805 res_32[1] = get_unaligned_i24 ((map.data + 3));
806
807 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out_32[0], out_32[1],
808 res_32[0], res_32[1]);
809 fail_unless (memcmp (res_32, out_32, 8) == 0);
810 gst_buffer_unmap (outbuffer, &map);
811
812 /* cleanup */
813 cleanup_volume (volume);
814 }
815
816 GST_END_TEST;
817
GST_START_TEST(test_ten_s24)818 GST_START_TEST (test_ten_s24)
819 {
820 GstElement *volume;
821 GstBuffer *inbuffer;
822 GstBuffer *outbuffer;
823 GstCaps *caps;
824 gint32 in_32[2] = { 4194304, -10 };
825 guint8 in[6];
826 GstMapInfo map;
827 gint32 res_32[2];
828 gint32 out_32[2] = { 8388607, -100 }; /* notice the clamped sample */
829
830 write_unaligned_u24 (in, in_32[0]);
831 write_unaligned_u24 (in + 3, in_32[1]);
832
833 volume = setup_volume ();
834 g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
835 fail_unless (gst_element_set_state (volume,
836 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
837 "could not set to playing");
838
839 inbuffer = gst_buffer_new_and_alloc (6);
840 gst_buffer_fill (inbuffer, 0, in, 6);
841 fail_unless (gst_buffer_memcmp (inbuffer, 0, in, 6) == 0);
842 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
843 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
844 gst_caps_unref (caps);
845 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
846 /* FIXME: reffing the inbuffer should make the transformation not be
847 * inplace
848 gst_buffer_ref (inbuffer);
849 */
850
851 /* pushing gives away my reference ... */
852 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
853 /* ... but it ends up being modified inplace and
854 * collected on the global buffer list */
855 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
856 fail_unless_equals_int (g_list_length (buffers), 1);
857 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
858 fail_unless (inbuffer == outbuffer);
859 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
860
861 res_32[0] = get_unaligned_i24 (map.data);
862 res_32[1] = get_unaligned_i24 ((map.data + 3));
863
864 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out_32[0], out_32[1],
865 res_32[0], res_32[1]);
866 fail_unless (memcmp (res_32, out_32, 8) == 0);
867 gst_buffer_unmap (outbuffer, &map);
868
869 /* cleanup */
870 cleanup_volume (volume);
871 }
872
873 GST_END_TEST;
874
GST_START_TEST(test_mute_s24)875 GST_START_TEST (test_mute_s24)
876 {
877 GstElement *volume;
878 GstBuffer *inbuffer;
879 GstBuffer *outbuffer;
880 GstCaps *caps;
881 gint32 in_32[2] = { 4194304, -4096 };
882 guint8 in[6];
883 GstMapInfo map;
884 gint32 res_32[2];
885 gint32 out_32[2] = { 0, 0 }; /* notice the clamped sample */
886
887 write_unaligned_u24 (in, in_32[0]);
888 write_unaligned_u24 (in + 3, in_32[1]);
889
890 volume = setup_volume ();
891 g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
892 fail_unless (gst_element_set_state (volume,
893 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
894 "could not set to playing");
895
896 inbuffer = gst_buffer_new_and_alloc (6);
897 gst_buffer_fill (inbuffer, 0, in, 6);
898 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
899 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
900 gst_caps_unref (caps);
901 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
902 /* FIXME: reffing the inbuffer should make the transformation not be
903 * inplace
904 gst_buffer_ref (inbuffer);
905 */
906
907 /* pushing gives away my reference ... */
908 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
909 /* ... but it ends up being modified inplace and
910 * collected on the global buffer list */
911 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
912 fail_unless_equals_int (g_list_length (buffers), 1);
913 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
914 fail_unless (inbuffer == outbuffer);
915
916 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
917
918 res_32[0] = get_unaligned_i24 (map.data);
919 res_32[1] = get_unaligned_i24 ((map.data + 3));
920
921 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out_32[0], out_32[1],
922 res_32[0], res_32[1]);
923 fail_unless (memcmp (res_32, out_32, 8) == 0);
924 gst_buffer_unmap (outbuffer, &map);
925
926 /* cleanup */
927 cleanup_volume (volume);
928 }
929
930 GST_END_TEST;
931
GST_START_TEST(test_unity_s32)932 GST_START_TEST (test_unity_s32)
933 {
934 GstElement *volume;
935 GstBuffer *inbuffer, *outbuffer;
936 GstCaps *caps;
937 gint32 in[2] = { 1073741824, -65536 };
938 GstMapInfo map;
939
940 volume = setup_volume ();
941 fail_unless (gst_element_set_state (volume,
942 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
943 "could not set to playing");
944
945 inbuffer = gst_buffer_new_and_alloc (8);
946 gst_buffer_fill (inbuffer, 0, in, 8);
947 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
948 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
949 gst_caps_unref (caps);
950 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
951
952 /* pushing gives away my reference ... */
953 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
954 /* ... but it ends up being collected on the global buffer list */
955 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
956 fail_unless_equals_int (g_list_length (buffers), 1);
957 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
958 fail_unless (inbuffer == outbuffer);
959 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
960 GST_INFO ("expected %+5d %+5d real %+5d %+5d", in[0], in[1], map.data[0],
961 map.data[1]);
962 fail_unless (memcmp (map.data, in, 8) == 0);
963 gst_buffer_unmap (outbuffer, &map);
964
965 /* cleanup */
966 cleanup_volume (volume);
967 }
968
969 GST_END_TEST;
970
GST_START_TEST(test_half_s32)971 GST_START_TEST (test_half_s32)
972 {
973 GstElement *volume;
974 GstBuffer *inbuffer;
975 GstBuffer *outbuffer;
976 GstCaps *caps;
977 gint32 in[2] = { 1073741824, -65536 };
978 gint32 out[2] = { 536870912, -32768 };
979 GstMapInfo map;
980
981 volume = setup_volume ();
982 g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
983 fail_unless (gst_element_set_state (volume,
984 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
985 "could not set to playing");
986
987 inbuffer = gst_buffer_new_and_alloc (8);
988 gst_buffer_fill (inbuffer, 0, in, 8);
989 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
990 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
991 gst_caps_unref (caps);
992 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
993 /* FIXME: reffing the inbuffer should make the transformation not be
994 * inplace
995 gst_buffer_ref (inbuffer);
996 */
997
998 /* pushing gives away my reference ... */
999 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1000 /* ... but it ends up being modified inplace and
1001 * collected on the global buffer list */
1002 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1003 fail_unless_equals_int (g_list_length (buffers), 1);
1004 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1005 fail_unless (inbuffer == outbuffer);
1006 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1007 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], map.data[0],
1008 map.data[1]);
1009 fail_unless (memcmp (map.data, out, 8) == 0);
1010 gst_buffer_unmap (outbuffer, &map);
1011
1012 /* cleanup */
1013 cleanup_volume (volume);
1014 }
1015
1016 GST_END_TEST;
1017
GST_START_TEST(test_double_s32)1018 GST_START_TEST (test_double_s32)
1019 {
1020 GstElement *volume;
1021 GstBuffer *inbuffer;
1022 GstBuffer *outbuffer;
1023 GstCaps *caps;
1024 gint32 in[2] = { 1073741824, -65536 };
1025 gint32 out[2] = { 2147483647, -131072 }; /* notice the clamped sample */
1026 GstMapInfo map;
1027
1028 volume = setup_volume ();
1029 g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
1030 fail_unless (gst_element_set_state (volume,
1031 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1032 "could not set to playing");
1033
1034 inbuffer = gst_buffer_new_and_alloc (8);
1035 gst_buffer_fill (inbuffer, 0, in, 8);
1036 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
1037 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1038 gst_caps_unref (caps);
1039 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1040 /* FIXME: reffing the inbuffer should make the transformation not be
1041 * inplace
1042 gst_buffer_ref (inbuffer);
1043 */
1044
1045 /* pushing gives away my reference ... */
1046 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1047 /* ... but it ends up being modified inplace and
1048 * collected on the global buffer list */
1049 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1050 fail_unless_equals_int (g_list_length (buffers), 1);
1051 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1052 fail_unless (inbuffer == outbuffer);
1053 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1054 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], map.data[0],
1055 map.data[1]);
1056 fail_unless (memcmp (map.data, out, 8) == 0);
1057 gst_buffer_unmap (outbuffer, &map);
1058
1059 /* cleanup */
1060 cleanup_volume (volume);
1061 }
1062
1063 GST_END_TEST;
1064
GST_START_TEST(test_ten_s32)1065 GST_START_TEST (test_ten_s32)
1066 {
1067 GstElement *volume;
1068 GstBuffer *inbuffer;
1069 GstBuffer *outbuffer;
1070 GstCaps *caps;
1071 gint32 in[2] = { 1073741824, -10 };
1072 gint32 out[2] = { 2147483647, -100 }; /* notice the clamped sample */
1073 GstMapInfo map;
1074
1075 volume = setup_volume ();
1076 g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
1077 fail_unless (gst_element_set_state (volume,
1078 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1079 "could not set to playing");
1080
1081 inbuffer = gst_buffer_new_and_alloc (8);
1082 gst_buffer_fill (inbuffer, 0, in, 8);
1083 fail_unless (gst_buffer_memcmp (inbuffer, 0, in, 8) == 0);
1084 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
1085 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1086 gst_caps_unref (caps);
1087 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1088 /* FIXME: reffing the inbuffer should make the transformation not be
1089 * inplace
1090 gst_buffer_ref (inbuffer);
1091 */
1092
1093 /* pushing gives away my reference ... */
1094 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1095 /* ... but it ends up being modified inplace and
1096 * collected on the global buffer list */
1097 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1098 fail_unless_equals_int (g_list_length (buffers), 1);
1099 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1100 fail_unless (inbuffer == outbuffer);
1101 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1102 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], map.data[0],
1103 map.data[1]);
1104 fail_unless (memcmp (map.data, out, 8) == 0);
1105 gst_buffer_unmap (outbuffer, &map);
1106
1107 /* cleanup */
1108 cleanup_volume (volume);
1109 }
1110
1111 GST_END_TEST;
1112
GST_START_TEST(test_mute_s32)1113 GST_START_TEST (test_mute_s32)
1114 {
1115 GstElement *volume;
1116 GstBuffer *inbuffer;
1117 GstBuffer *outbuffer;
1118 GstCaps *caps;
1119 gint32 in[2] = { 1073741824, -65536 };
1120 gint32 out[2] = { 0, 0 };
1121 GstMapInfo map;
1122
1123 volume = setup_volume ();
1124 g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
1125 fail_unless (gst_element_set_state (volume,
1126 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1127 "could not set to playing");
1128
1129 inbuffer = gst_buffer_new_and_alloc (8);
1130 gst_buffer_fill (inbuffer, 0, in, 8);
1131 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
1132 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1133 gst_caps_unref (caps);
1134 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1135 /* FIXME: reffing the inbuffer should make the transformation not be
1136 * inplace
1137 gst_buffer_ref (inbuffer);
1138 */
1139
1140 /* pushing gives away my reference ... */
1141 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1142 /* ... but it ends up being modified inplace and
1143 * collected on the global buffer list */
1144 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1145 fail_unless_equals_int (g_list_length (buffers), 1);
1146 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1147 fail_unless (inbuffer == outbuffer);
1148 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1149 GST_INFO ("expected %+5d %+5d real %+5d %+5d", out[0], out[1], map.data[0],
1150 map.data[1]);
1151 fail_unless (memcmp (map.data, out, 8) == 0);
1152 gst_buffer_unmap (outbuffer, &map);
1153
1154 /* cleanup */
1155 cleanup_volume (volume);
1156 }
1157
1158 GST_END_TEST;
1159
GST_START_TEST(test_unity_f32)1160 GST_START_TEST (test_unity_f32)
1161 {
1162 GstElement *volume;
1163 GstBuffer *inbuffer, *outbuffer;
1164 GstCaps *caps;
1165 gfloat in[2] = { 0.75, -0.25 }, *res;
1166 GstMapInfo map;
1167
1168 volume = setup_volume ();
1169 fail_unless (gst_element_set_state (volume,
1170 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1171 "could not set to playing");
1172
1173 inbuffer = gst_buffer_new_and_alloc (8);
1174 gst_buffer_fill (inbuffer, 0, in, sizeof (in));
1175 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1176 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1177 gst_caps_unref (caps);
1178 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1179
1180 /* pushing gives away my reference ... */
1181 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1182 /* ... but it ends up being collected on the global buffer list */
1183 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1184 fail_unless_equals_int (g_list_length (buffers), 1);
1185 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1186 fail_unless (inbuffer == outbuffer);
1187 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1188 res = (gfloat *) map.data;
1189 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", in[0], in[1],
1190 res[0], res[1]);
1191 fail_unless_equals_float (res[0], in[0]);
1192 fail_unless_equals_float (res[1], in[1]);
1193 gst_buffer_unmap (outbuffer, &map);
1194
1195 /* cleanup */
1196 cleanup_volume (volume);
1197 }
1198
1199 GST_END_TEST;
1200
GST_START_TEST(test_half_f32)1201 GST_START_TEST (test_half_f32)
1202 {
1203 GstElement *volume;
1204 GstBuffer *inbuffer;
1205 GstBuffer *outbuffer;
1206 GstCaps *caps;
1207 gfloat in[2] = { 0.75, -0.25 };
1208 gfloat out[2] = { 0.375, -0.125 };
1209 gfloat *res;
1210 GstMapInfo map;
1211
1212 volume = setup_volume ();
1213 g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
1214 fail_unless (gst_element_set_state (volume,
1215 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1216 "could not set to playing");
1217
1218 inbuffer = gst_buffer_new_and_alloc (8);
1219 gst_buffer_fill (inbuffer, 0, in, 8);
1220 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1221 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1222 gst_caps_unref (caps);
1223 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1224 /* FIXME: reffing the inbuffer should make the transformation not be
1225 * inplace
1226 gst_buffer_ref (inbuffer);
1227 */
1228
1229 /* pushing gives away my reference ... */
1230 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1231 /* ... but it ends up being modified inplace and
1232 * collected on the global buffer list */
1233 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1234 fail_unless_equals_int (g_list_length (buffers), 1);
1235 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1236 fail_unless (inbuffer == outbuffer);
1237 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1238 res = (gfloat *) map.data;
1239 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", out[0], out[1],
1240 res[0], res[1]);
1241 fail_unless_equals_float (res[0], out[0]);
1242 fail_unless_equals_float (res[1], out[1]);
1243 gst_buffer_unmap (outbuffer, &map);
1244
1245 /* cleanup */
1246 cleanup_volume (volume);
1247 }
1248
1249 GST_END_TEST;
1250
GST_START_TEST(test_double_f32)1251 GST_START_TEST (test_double_f32)
1252 {
1253 GstElement *volume;
1254 GstBuffer *inbuffer;
1255 GstBuffer *outbuffer;
1256 GstCaps *caps;
1257 gfloat in[2] = { 0.75, -0.25 };
1258 gfloat out[2] = { 1.5, -0.5 }; /* nothing is clamped */
1259 gfloat *res;
1260 GstMapInfo map;
1261
1262 volume = setup_volume ();
1263 g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
1264 fail_unless (gst_element_set_state (volume,
1265 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1266 "could not set to playing");
1267
1268 inbuffer = gst_buffer_new_and_alloc (8);
1269 gst_buffer_fill (inbuffer, 0, in, 8);
1270 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1271 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1272 gst_caps_unref (caps);
1273 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1274 /* FIXME: reffing the inbuffer should make the transformation not be
1275 * inplace
1276 gst_buffer_ref (inbuffer);
1277 */
1278
1279 /* pushing gives away my reference ... */
1280 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1281 /* ... but it ends up being modified inplace and
1282 * collected on the global buffer list */
1283 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1284 fail_unless_equals_int (g_list_length (buffers), 1);
1285 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1286 fail_unless (inbuffer == outbuffer);
1287 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1288 res = (gfloat *) map.data;
1289 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", out[0], out[1],
1290 res[0], res[1]);
1291 fail_unless_equals_float (res[0], out[0]);
1292 fail_unless_equals_float (res[1], out[1]);
1293 gst_buffer_unmap (outbuffer, &map);
1294
1295 /* cleanup */
1296 cleanup_volume (volume);
1297 }
1298
1299 GST_END_TEST;
1300
GST_START_TEST(test_ten_f32)1301 GST_START_TEST (test_ten_f32)
1302 {
1303 GstElement *volume;
1304 GstBuffer *inbuffer;
1305 GstBuffer *outbuffer;
1306 GstCaps *caps;
1307 gfloat in[2] = { 0.75, -0.25 };
1308 gfloat out[2] = { 7.5, -2.5 }; /* nothing is clamped */
1309 gfloat *res;
1310 GstMapInfo map;
1311
1312 volume = setup_volume ();
1313 g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
1314 fail_unless (gst_element_set_state (volume,
1315 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1316 "could not set to playing");
1317
1318 inbuffer = gst_buffer_new_and_alloc (8);
1319 gst_buffer_fill (inbuffer, 0, in, 8);
1320 fail_unless (gst_buffer_memcmp (inbuffer, 0, in, 8) == 0);
1321 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1322 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1323 gst_caps_unref (caps);
1324 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1325 /* FIXME: reffing the inbuffer should make the transformation not be
1326 * inplace
1327 gst_buffer_ref (inbuffer);
1328 */
1329
1330 /* pushing gives away my reference ... */
1331 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1332 /* ... but it ends up being modified inplace and
1333 * collected on the global buffer list */
1334 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1335 fail_unless_equals_int (g_list_length (buffers), 1);
1336 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1337 fail_unless (inbuffer == outbuffer);
1338 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1339 res = (gfloat *) map.data;
1340 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", out[0], out[1],
1341 res[0], res[1]);
1342 fail_unless_equals_float (res[0], out[0]);
1343 fail_unless_equals_float (res[1], out[1]);
1344 gst_buffer_unmap (outbuffer, &map);
1345
1346 /* cleanup */
1347 cleanup_volume (volume);
1348 }
1349
1350 GST_END_TEST;
1351
1352
GST_START_TEST(test_mute_f32)1353 GST_START_TEST (test_mute_f32)
1354 {
1355 GstElement *volume;
1356 GstBuffer *inbuffer;
1357 GstBuffer *outbuffer;
1358 GstCaps *caps;
1359 gfloat in[2] = { 0.75, -0.25 };
1360 gfloat out[2] = { 0, 0 };
1361 gfloat *res;
1362 GstMapInfo map;
1363
1364 volume = setup_volume ();
1365 g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
1366 fail_unless (gst_element_set_state (volume,
1367 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1368 "could not set to playing");
1369
1370 inbuffer = gst_buffer_new_and_alloc (8);
1371 gst_buffer_fill (inbuffer, 0, in, 8);
1372 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1373 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1374 gst_caps_unref (caps);
1375 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1376 /* FIXME: reffing the inbuffer should make the transformation not be
1377 * inplace
1378 gst_buffer_ref (inbuffer);
1379 */
1380
1381 /* pushing gives away my reference ... */
1382 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1383 /* ... but it ends up being modified inplace and
1384 * collected on the global buffer list */
1385 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1386 fail_unless_equals_int (g_list_length (buffers), 1);
1387 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1388 fail_unless (inbuffer == outbuffer);
1389 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1390 res = (gfloat *) map.data;
1391 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", out[0], out[1],
1392 res[0], res[1]);
1393 fail_unless_equals_float (res[0], out[0]);
1394 fail_unless_equals_float (res[1], out[1]);
1395 gst_buffer_unmap (outbuffer, &map);
1396
1397 /* cleanup */
1398 cleanup_volume (volume);
1399 }
1400
1401 GST_END_TEST;
1402
GST_START_TEST(test_unity_f64)1403 GST_START_TEST (test_unity_f64)
1404 {
1405 GstElement *volume;
1406 GstBuffer *inbuffer, *outbuffer;
1407 GstCaps *caps;
1408 gdouble in[2] = { 0.75, -0.25 };
1409 gdouble *res;
1410 GstMapInfo map;
1411
1412 volume = setup_volume ();
1413 fail_unless (gst_element_set_state (volume,
1414 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1415 "could not set to playing");
1416
1417 inbuffer = gst_buffer_new_and_alloc (16);
1418 gst_buffer_fill (inbuffer, 0, in, 16);
1419 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1420 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1421 gst_caps_unref (caps);
1422 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1423
1424 /* pushing gives away my reference ... */
1425 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1426 /* ... but it ends up being collected on the global buffer list */
1427 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1428 fail_unless_equals_int (g_list_length (buffers), 1);
1429 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1430 fail_unless (inbuffer == outbuffer);
1431 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1432 res = (gdouble *) map.data;
1433 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", in[0], in[1],
1434 res[0], res[1]);
1435 fail_unless_equals_float (res[0], in[0]);
1436 fail_unless_equals_float (res[1], in[1]);
1437 gst_buffer_unmap (outbuffer, &map);
1438
1439 /* cleanup */
1440 cleanup_volume (volume);
1441 }
1442
1443 GST_END_TEST;
1444
GST_START_TEST(test_half_f64)1445 GST_START_TEST (test_half_f64)
1446 {
1447 GstElement *volume;
1448 GstBuffer *inbuffer;
1449 GstBuffer *outbuffer;
1450 GstCaps *caps;
1451 gdouble in[2] = { 0.75, -0.25 };
1452 gdouble out[2] = { 0.375, -0.125 };
1453 gdouble *res;
1454 GstMapInfo map;
1455
1456 volume = setup_volume ();
1457 g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
1458 fail_unless (gst_element_set_state (volume,
1459 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1460 "could not set to playing");
1461
1462 inbuffer = gst_buffer_new_and_alloc (16);
1463 gst_buffer_fill (inbuffer, 0, in, 16);
1464 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1465 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1466 gst_caps_unref (caps);
1467 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1468 /* FIXME: reffing the inbuffer should make the transformation not be
1469 * inplace
1470 gst_buffer_ref (inbuffer);
1471 */
1472
1473 /* pushing gives away my reference ... */
1474 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1475 /* ... but it ends up being modified inplace and
1476 * collected on the global buffer list */
1477 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1478 fail_unless_equals_int (g_list_length (buffers), 1);
1479 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1480 fail_unless (inbuffer == outbuffer);
1481 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1482 res = (gdouble *) map.data;
1483 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", out[0], out[1],
1484 res[0], res[1]);
1485 fail_unless_equals_float (res[0], out[0]);
1486 fail_unless_equals_float (res[1], out[1]);
1487 gst_buffer_unmap (outbuffer, &map);
1488
1489 /* cleanup */
1490 cleanup_volume (volume);
1491 }
1492
1493 GST_END_TEST;
1494
GST_START_TEST(test_double_f64)1495 GST_START_TEST (test_double_f64)
1496 {
1497 GstElement *volume;
1498 GstBuffer *inbuffer;
1499 GstBuffer *outbuffer;
1500 GstCaps *caps;
1501 gdouble in[2] = { 0.75, -0.25 };
1502 gdouble out[2] = { 1.5, -0.5 }; /* nothing is clamped */
1503 gdouble *res;
1504 GstMapInfo map;
1505
1506 volume = setup_volume ();
1507 g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
1508 fail_unless (gst_element_set_state (volume,
1509 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1510 "could not set to playing");
1511
1512 inbuffer = gst_buffer_new_and_alloc (16);
1513 gst_buffer_fill (inbuffer, 0, in, 16);
1514 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1515 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1516 gst_caps_unref (caps);
1517 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1518 /* FIXME: reffing the inbuffer should make the transformation not be
1519 * inplace
1520 gst_buffer_ref (inbuffer);
1521 */
1522
1523 /* pushing gives away my reference ... */
1524 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1525 /* ... but it ends up being modified inplace and
1526 * collected on the global buffer list */
1527 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1528 fail_unless_equals_int (g_list_length (buffers), 1);
1529 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1530 fail_unless (inbuffer == outbuffer);
1531 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1532 res = (gdouble *) map.data;
1533 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", out[0], out[1],
1534 res[0], res[1]);
1535 fail_unless_equals_float (res[0], out[0]);
1536 fail_unless_equals_float (res[1], out[1]);
1537 gst_buffer_unmap (outbuffer, &map);
1538
1539 /* cleanup */
1540 cleanup_volume (volume);
1541 }
1542
1543 GST_END_TEST;
1544
GST_START_TEST(test_ten_f64)1545 GST_START_TEST (test_ten_f64)
1546 {
1547 GstElement *volume;
1548 GstBuffer *inbuffer;
1549 GstBuffer *outbuffer;
1550 GstCaps *caps;
1551 gdouble in[2] = { 0.75, -0.25 };
1552 gdouble out[2] = { 7.5, -2.5 }; /* nothing is clamped */
1553 gdouble *res;
1554 GstMapInfo map;
1555
1556 volume = setup_volume ();
1557 g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
1558 fail_unless (gst_element_set_state (volume,
1559 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1560 "could not set to playing");
1561
1562 inbuffer = gst_buffer_new_and_alloc (16);
1563 gst_buffer_fill (inbuffer, 0, in, 16);
1564 fail_unless (gst_buffer_memcmp (inbuffer, 0, in, 16) == 0);
1565 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1566 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1567 gst_caps_unref (caps);
1568 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1569 /* FIXME: reffing the inbuffer should make the transformation not be
1570 * inplace
1571 gst_buffer_ref (inbuffer);
1572 */
1573
1574 /* pushing gives away my reference ... */
1575 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1576 /* ... but it ends up being modified inplace and
1577 * collected on the global buffer list */
1578 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1579 fail_unless_equals_int (g_list_length (buffers), 1);
1580 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1581 fail_unless (inbuffer == outbuffer);
1582 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1583 res = (gdouble *) map.data;
1584 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", out[0], out[1],
1585 res[0], res[1]);
1586 fail_unless_equals_float (res[0], out[0]);
1587 fail_unless_equals_float (res[1], out[1]);
1588 gst_buffer_unmap (outbuffer, &map);
1589
1590 /* cleanup */
1591 cleanup_volume (volume);
1592 }
1593
1594 GST_END_TEST;
1595
1596
GST_START_TEST(test_mute_f64)1597 GST_START_TEST (test_mute_f64)
1598 {
1599 GstElement *volume;
1600 GstBuffer *inbuffer;
1601 GstBuffer *outbuffer;
1602 GstCaps *caps;
1603 gdouble in[2] = { 0.75, -0.25 };
1604 gdouble out[2] = { 0, 0 };
1605 gdouble *res;
1606 GstMapInfo map;
1607
1608 volume = setup_volume ();
1609 g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
1610 fail_unless (gst_element_set_state (volume,
1611 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1612 "could not set to playing");
1613
1614 inbuffer = gst_buffer_new_and_alloc (16);
1615 gst_buffer_fill (inbuffer, 0, in, 16);
1616 caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1617 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1618 gst_caps_unref (caps);
1619 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1620 /* FIXME: reffing the inbuffer should make the transformation not be
1621 * inplace
1622 gst_buffer_ref (inbuffer);
1623 */
1624
1625 /* pushing gives away my reference ... */
1626 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1627 /* ... but it ends up being modified inplace and
1628 * collected on the global buffer list */
1629 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1630 fail_unless_equals_int (g_list_length (buffers), 1);
1631 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1632 fail_unless (inbuffer == outbuffer);
1633 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1634 res = (gdouble *) map.data;
1635 GST_INFO ("expected %+1.4f %+1.4f real %+1.4f %+1.4f", out[0], out[1],
1636 res[0], res[1]);
1637 fail_unless_equals_float (res[0], out[0]);
1638 fail_unless_equals_float (res[1], out[1]);
1639 gst_buffer_unmap (outbuffer, &map);
1640
1641 /* cleanup */
1642 cleanup_volume (volume);
1643 }
1644
1645 GST_END_TEST;
1646
GST_START_TEST(test_wrong_caps)1647 GST_START_TEST (test_wrong_caps)
1648 {
1649 GstElement *volume;
1650 GstBuffer *inbuffer;
1651 gint16 in[2] = { 16384, -256 };
1652 GstBus *bus;
1653 GstMessage *message;
1654 GstCaps *caps;
1655
1656 volume = setup_volume ();
1657 bus = gst_bus_new ();
1658
1659 fail_unless (gst_element_set_state (volume,
1660 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1661 "could not set to playing");
1662
1663 inbuffer = gst_buffer_new_and_alloc (4);
1664 gst_buffer_fill (inbuffer, 0, in, 4);
1665 caps = gst_caps_from_string (VOLUME_WRONG_CAPS_STRING);
1666 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1667 gst_caps_unref (caps);
1668 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1669 gst_buffer_ref (inbuffer);
1670
1671 /* set a bus here so we avoid getting state change messages */
1672 gst_element_set_bus (volume, bus);
1673
1674 /* pushing gives an error because it can't negotiate with wrong caps */
1675 fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer),
1676 GST_FLOW_NOT_NEGOTIATED);
1677 /* ... and the buffer would have been lost if we didn't ref it ourselves */
1678 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1679 gst_buffer_unref (inbuffer);
1680 fail_unless_equals_int (g_list_length (buffers), 0);
1681
1682 /* volume_set_caps should not have been called since basetransform caught
1683 * the negotiation problem */
1684 fail_if ((message = gst_bus_pop (bus)) != NULL);
1685
1686 /* cleanup */
1687 gst_element_set_bus (volume, NULL);
1688 gst_object_unref (GST_OBJECT (bus));
1689 cleanup_volume (volume);
1690 }
1691
1692 GST_END_TEST;
1693
GST_START_TEST(test_passthrough)1694 GST_START_TEST (test_passthrough)
1695 {
1696 GstElement *volume;
1697 GstBuffer *inbuffer, *outbuffer;
1698 GstCaps *caps;
1699 gint16 *out, in[2] = { 16384, -256 };
1700 GstMapInfo map;
1701
1702 volume = setup_volume ();
1703 g_object_set (G_OBJECT (volume), "volume", 1.0, NULL);
1704 fail_unless (gst_element_set_state (volume,
1705 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1706 "could not set to playing");
1707
1708 inbuffer = gst_buffer_new_and_alloc (4);
1709 gst_buffer_fill (inbuffer, 0, in, 4);
1710 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
1711 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1712 gst_caps_unref (caps);
1713 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1714
1715 /* pushing gives away my reference ... */
1716 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1717 /* ... but it ends up being collected on the global buffer list */
1718 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1719 fail_unless_equals_int (g_list_length (buffers), 1);
1720 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1721 fail_unless (inbuffer == outbuffer);
1722 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1723 out = (gint16 *) map.data;
1724 GST_INFO ("expected %+5d %+5d real %+5d %+5d", in[0], in[1], out[0], out[1]);
1725 fail_unless (memcmp (map.data, in, 4) == 0);
1726 gst_buffer_unmap (outbuffer, &map);
1727
1728 /* cleanup */
1729 cleanup_volume (volume);
1730 }
1731
1732 GST_END_TEST;
1733
GST_START_TEST(test_controller_usability)1734 GST_START_TEST (test_controller_usability)
1735 {
1736 GstControlSource *cs;
1737 GstTimedValueControlSource *tvcs;
1738 GstControlBinding *cb;
1739 GstElement *volume;
1740
1741 volume = setup_volume ();
1742
1743 /* this shouldn't crash, whether this mode is implemented or not */
1744 cs = gst_interpolation_control_source_new ();
1745 g_object_set (cs, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
1746 cb = gst_direct_control_binding_new (GST_OBJECT_CAST (volume), "volume", cs);
1747 gst_object_add_control_binding (GST_OBJECT_CAST (volume), cb);
1748
1749 tvcs = (GstTimedValueControlSource *) cs;
1750 gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0);
1751 gst_timed_value_control_source_set (tvcs, 5 * GST_SECOND, 1.0);
1752 gst_timed_value_control_source_set (tvcs, 10 * GST_SECOND, 0.0);
1753
1754 gst_object_unref (cs);
1755 gst_object_remove_control_binding (GST_OBJECT_CAST (volume), cb);
1756
1757 cleanup_volume (volume);
1758 }
1759
1760 GST_END_TEST;
1761
GST_START_TEST(test_controller_processing)1762 GST_START_TEST (test_controller_processing)
1763 {
1764 GstControlSource *cs;
1765 GstTimedValueControlSource *tvcs;
1766 GstElement *volume;
1767 GstBuffer *inbuffer, *outbuffer;
1768 GstCaps *caps;
1769 gint16 *out, in[2] = { 16384, -256 };
1770 GstMapInfo map;
1771 GstSegment seg;
1772
1773 volume = setup_volume ();
1774
1775 cs = gst_interpolation_control_source_new ();
1776 g_object_set (cs, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
1777 gst_object_add_control_binding (GST_OBJECT_CAST (volume),
1778 gst_direct_control_binding_new (GST_OBJECT_CAST (volume), "volume", cs));
1779
1780 /* the value range for volume is 0.0 ... 10.0 */
1781 tvcs = (GstTimedValueControlSource *) cs;
1782 gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.1);
1783
1784 fail_unless (gst_element_set_state (volume,
1785 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1786 "could not set to playing");
1787
1788 inbuffer = gst_buffer_new_and_alloc (4);
1789 gst_buffer_fill (inbuffer, 0, in, 4);
1790 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
1791 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1792 GST_BUFFER_TIMESTAMP (inbuffer) = 0;
1793 gst_caps_unref (caps);
1794 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1795
1796 gst_segment_init (&seg, GST_FORMAT_TIME);
1797 fail_unless (gst_pad_push_event (mysrcpad,
1798 gst_event_new_segment (&seg)) == TRUE);
1799
1800 /* pushing gives away my reference ... */
1801 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1802 /* ... but it ends up being collected on the global buffer list */
1803 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1804 fail_unless_equals_int (g_list_length (buffers), 1);
1805 fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1806 fail_unless (inbuffer == outbuffer);
1807 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
1808 out = (gint16 *) map.data;
1809 GST_INFO ("expected %+5d %+5d real %+5d %+5d", in[0], in[1], out[0], out[1]);
1810 fail_unless (memcmp (map.data, in, 4) == 0);
1811 gst_buffer_unmap (outbuffer, &map);
1812
1813 gst_object_unref (cs);
1814 cleanup_volume (volume);
1815 }
1816
1817 GST_END_TEST;
1818
GST_START_TEST(test_controller_defaults_at_ts0)1819 GST_START_TEST (test_controller_defaults_at_ts0)
1820 {
1821 GstControlSource *cs;
1822 GstTimedValueControlSource *tvcs;
1823 GstElement *volume;
1824 GstBuffer *inbuffer;
1825 GstCaps *caps;
1826 GstSegment seg;
1827
1828 volume = setup_volume ();
1829
1830 cs = gst_interpolation_control_source_new ();
1831 g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
1832 gst_object_add_control_binding (GST_OBJECT_CAST (volume),
1833 gst_direct_control_binding_new (GST_OBJECT_CAST (volume), "volume", cs));
1834
1835 /* make a control curve that does not start at ts=0, the element will use
1836 * the current property value (default) until the control curve starts
1837 */
1838 tvcs = (GstTimedValueControlSource *) cs;
1839 gst_timed_value_control_source_set (tvcs, GST_SECOND / 100, 0.1);
1840 gst_timed_value_control_source_set (tvcs, GST_SECOND, 1.0);
1841
1842 fail_unless (gst_element_set_state (volume,
1843 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1844 "could not set to playing");
1845
1846 /* controller curve starts at sample: 441 */
1847 inbuffer = gst_buffer_new_and_alloc (1000 * sizeof (gint16));
1848 gst_buffer_memset (inbuffer, 0, 0, 1000 * sizeof (gint16));
1849 caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
1850 gst_check_setup_events (mysrcpad, volume, caps, GST_FORMAT_TIME);
1851 GST_BUFFER_TIMESTAMP (inbuffer) = 0;
1852 gst_caps_unref (caps);
1853
1854 gst_segment_init (&seg, GST_FORMAT_TIME);
1855 fail_unless (gst_pad_push_event (mysrcpad,
1856 gst_event_new_segment (&seg)) == TRUE);
1857
1858 /* pushing gives away my reference ... */
1859 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1860
1861 gst_object_unref (cs);
1862 cleanup_volume (volume);
1863 }
1864
1865 GST_END_TEST;
1866
1867
1868 static Suite *
volume_suite(void)1869 volume_suite (void)
1870 {
1871 Suite *s = suite_create ("volume");
1872 TCase *tc_chain = tcase_create ("general");
1873
1874 suite_add_tcase (s, tc_chain);
1875 tcase_add_test (tc_chain, test_get_set);
1876 tcase_add_test (tc_chain, test_unity_s8);
1877 tcase_add_test (tc_chain, test_half_s8);
1878 tcase_add_test (tc_chain, test_double_s8);
1879 tcase_add_test (tc_chain, test_ten_s8);
1880 tcase_add_test (tc_chain, test_mute_s8);
1881 tcase_add_test (tc_chain, test_unity_s16);
1882 tcase_add_test (tc_chain, test_half_s16);
1883 tcase_add_test (tc_chain, test_double_s16);
1884 tcase_add_test (tc_chain, test_ten_s16);
1885 tcase_add_test (tc_chain, test_mute_s16);
1886 tcase_add_test (tc_chain, test_unity_s24);
1887 tcase_add_test (tc_chain, test_half_s24);
1888 tcase_add_test (tc_chain, test_double_s24);
1889 tcase_add_test (tc_chain, test_ten_s24);
1890 tcase_add_test (tc_chain, test_mute_s24);
1891 tcase_add_test (tc_chain, test_unity_s32);
1892 tcase_add_test (tc_chain, test_half_s32);
1893 tcase_add_test (tc_chain, test_double_s32);
1894 tcase_add_test (tc_chain, test_ten_s32);
1895 tcase_add_test (tc_chain, test_mute_s32);
1896 tcase_add_test (tc_chain, test_unity_f32);
1897 tcase_add_test (tc_chain, test_half_f32);
1898 tcase_add_test (tc_chain, test_double_f32);
1899 tcase_add_test (tc_chain, test_ten_f32);
1900 tcase_add_test (tc_chain, test_mute_f32);
1901 tcase_add_test (tc_chain, test_unity_f64);
1902 tcase_add_test (tc_chain, test_half_f64);
1903 tcase_add_test (tc_chain, test_double_f64);
1904 tcase_add_test (tc_chain, test_ten_f64);
1905 tcase_add_test (tc_chain, test_mute_f64);
1906 tcase_add_test (tc_chain, test_wrong_caps);
1907 tcase_add_test (tc_chain, test_passthrough);
1908 tcase_add_test (tc_chain, test_controller_usability);
1909 tcase_add_test (tc_chain, test_controller_processing);
1910 tcase_add_test (tc_chain, test_controller_defaults_at_ts0);
1911
1912 return s;
1913 }
1914
1915 GST_CHECK_MAIN (volume)
1916