Tizen 2.0 Release
[framework/multimedia/gst-plugins-good0.10.git] / tests / check / elements / rglimiter.c
1 /* GStreamer ReplayGain limiter
2  *
3  * Copyright (C) 2007 Rene Stadler <mail@renestadler.de>
4  *
5  * rglimiter.c: Unit test for the rglimiter element
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  * 
12  * This library is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  * 
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  */
22
23 #include <gst/check/gstcheck.h>
24
25 #include <math.h>
26
27 /* For ease of programming we use globals to keep refs for our floating
28  * src and sink pads we create; otherwise we always have to do get_pad,
29  * get_peer, and then remove references in every test function */
30 static GstPad *mysrcpad, *mysinkpad;
31
32 #define RG_LIMITER_CAPS_TEMPLATE_STRING   \
33   "audio/x-raw-float, "                   \
34   "width = (int) 32, "                    \
35   "endianness = (int) BYTE_ORDER, "       \
36   "channels = (int) [ 1, MAX ], "         \
37   "rate = (int) [ 1, MAX ]"
38
39 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
40     GST_PAD_SINK,
41     GST_PAD_ALWAYS,
42     GST_STATIC_CAPS (RG_LIMITER_CAPS_TEMPLATE_STRING)
43     );
44 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
45     GST_PAD_SRC,
46     GST_PAD_ALWAYS,
47     GST_STATIC_CAPS (RG_LIMITER_CAPS_TEMPLATE_STRING)
48     );
49
50 static GstElement *
51 setup_rglimiter (void)
52 {
53   GstElement *element;
54
55   GST_DEBUG ("setup_rglimiter");
56   element = gst_check_setup_element ("rglimiter");
57   mysrcpad = gst_check_setup_src_pad (element, &srctemplate, NULL);
58   mysinkpad = gst_check_setup_sink_pad (element, &sinktemplate, NULL);
59   gst_pad_set_active (mysrcpad, TRUE);
60   gst_pad_set_active (mysinkpad, TRUE);
61
62   return element;
63 }
64
65 static void
66 cleanup_rglimiter (GstElement * element)
67 {
68   GST_DEBUG ("cleanup_rglimiter");
69
70   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
71   g_list_free (buffers);
72   buffers = NULL;
73
74   gst_check_teardown_src_pad (element);
75   gst_check_teardown_sink_pad (element);
76   gst_check_teardown_element (element);
77 }
78
79 static void
80 set_playing_state (GstElement * element)
81 {
82   fail_unless (gst_element_set_state (element,
83           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
84       "Could not set state to PLAYING");
85 }
86
87 static const gfloat test_input[] = {
88   -2.0, -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0, 2.0
89 };
90
91 static const gfloat test_output[] = {
92   -0.99752737684336523,         /* -2.0  */
93   -0.88079707797788243,         /* -1.0  */
94   -0.7310585786300049,          /* -0.75 */
95   -0.5, -0.25, 0.0, 0.25, 0.5,
96   0.7310585786300049,           /* 0.75 */
97   0.88079707797788243,          /* 1.0  */
98   0.99752737684336523,          /* 2.0  */
99 };
100
101 static GstBuffer *
102 create_test_buffer (void)
103 {
104   GstBuffer *buf = gst_buffer_new_and_alloc (sizeof (test_input));
105   GstCaps *caps;
106
107   memcpy (GST_BUFFER_DATA (buf), test_input, sizeof (test_input));
108
109   caps = gst_caps_new_simple ("audio/x-raw-float",
110       "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1,
111       "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
112   gst_buffer_set_caps (buf, caps);
113   gst_caps_unref (caps);
114
115   ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
116
117   return buf;
118 }
119
120 static void
121 verify_test_buffer (GstBuffer * buf)
122 {
123   gfloat *output = (gfloat *) GST_BUFFER_DATA (buf);
124   gint i;
125
126   fail_unless (GST_BUFFER_SIZE (buf) == sizeof (test_output));
127   for (i = 0; i < G_N_ELEMENTS (test_input); i++)
128     fail_unless (ABS (output[i] - test_output[i]) < 1.e-6,
129         "Incorrect output value %.6f for input %.2f, expected %.6f",
130         output[i], test_input[i], test_output[i]);
131 }
132
133 /* Start of tests. */
134
135 GST_START_TEST (test_no_buffer)
136 {
137   GstElement *element = setup_rglimiter ();
138
139   set_playing_state (element);
140
141   cleanup_rglimiter (element);
142 }
143
144 GST_END_TEST;
145
146 GST_START_TEST (test_disabled)
147 {
148   GstElement *element = setup_rglimiter ();
149   GstBuffer *buf, *out_buf;
150
151   g_object_set (element, "enabled", FALSE, NULL);
152   set_playing_state (element);
153
154   buf = create_test_buffer ();
155   fail_unless (gst_pad_push (mysrcpad, buf) == GST_FLOW_OK);
156   fail_unless (g_list_length (buffers) == 1);
157   out_buf = buffers->data;
158   fail_if (out_buf == NULL);
159   buffers = g_list_remove (buffers, out_buf);
160   ASSERT_BUFFER_REFCOUNT (out_buf, "out_buf", 1);
161   fail_unless (buf == out_buf);
162   gst_buffer_unref (out_buf);
163
164   cleanup_rglimiter (element);
165 }
166
167 GST_END_TEST;
168
169 GST_START_TEST (test_limiting)
170 {
171   GstElement *element = setup_rglimiter ();
172   GstBuffer *buf, *out_buf;
173
174   set_playing_state (element);
175
176   /* Mutable variant. */
177   buf = create_test_buffer ();
178   GST_DEBUG ("push mutable buffer");
179   fail_unless (gst_pad_push (mysrcpad, buf) == GST_FLOW_OK);
180   fail_unless (g_list_length (buffers) == 1);
181   out_buf = buffers->data;
182   fail_if (out_buf == NULL);
183   ASSERT_BUFFER_REFCOUNT (out_buf, "out_buf", 1);
184   verify_test_buffer (out_buf);
185
186   /* Immutable variant. */
187   buf = create_test_buffer ();
188   /* Extra ref: */
189   gst_buffer_ref (buf);
190   ASSERT_BUFFER_REFCOUNT (buf, "buf", 2);
191   GST_DEBUG ("push immutable buffer");
192   fail_unless (gst_pad_push (mysrcpad, buf) == GST_FLOW_OK);
193   ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
194   fail_unless (g_list_length (buffers) == 2);
195   out_buf = g_list_last (buffers)->data;
196   fail_if (out_buf == NULL);
197   ASSERT_BUFFER_REFCOUNT (out_buf, "out_buf", 1);
198   fail_unless (buf != out_buf);
199   /* Drop our extra ref: */
200   gst_buffer_unref (buf);
201   verify_test_buffer (out_buf);
202
203   cleanup_rglimiter (element);
204 }
205
206 GST_END_TEST;
207
208 GST_START_TEST (test_gap)
209 {
210   GstElement *element = setup_rglimiter ();
211   GstBuffer *buf, *out_buf;
212
213   set_playing_state (element);
214
215   buf = create_test_buffer ();
216   GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_GAP);
217   fail_unless (gst_pad_push (mysrcpad, buf) == GST_FLOW_OK);
218   fail_unless (g_list_length (buffers) == 1);
219   out_buf = buffers->data;
220   fail_if (out_buf == NULL);
221   ASSERT_BUFFER_REFCOUNT (out_buf, "out_buf", 1);
222
223   /* Verify that the baseclass does not lift the GAP flag: */
224   fail_unless (GST_BUFFER_FLAG_IS_SET (out_buf, GST_BUFFER_FLAG_GAP));
225
226   g_assert (GST_BUFFER_SIZE (out_buf) == GST_BUFFER_SIZE (buf));
227   /* We cheated by passing an input buffer with non-silence that has the GAP
228    * flag set.  The element cannot know that however and must have skipped
229    * adjusting the buffer because of the flag, which we can easily verify: */
230   fail_if (memcmp (GST_BUFFER_DATA (out_buf),
231           GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (out_buf)) != 0);
232
233   cleanup_rglimiter (element);
234 }
235
236 GST_END_TEST;
237
238 static Suite *
239 rglimiter_suite (void)
240 {
241   Suite *s = suite_create ("rglimiter");
242   TCase *tc_chain = tcase_create ("general");
243
244   suite_add_tcase (s, tc_chain);
245
246   tcase_add_test (tc_chain, test_no_buffer);
247   tcase_add_test (tc_chain, test_disabled);
248   tcase_add_test (tc_chain, test_limiting);
249   tcase_add_test (tc_chain, test_gap);
250
251   return s;
252 }
253
254 int
255 main (int argc, char **argv)
256 {
257   gint nf;
258
259   Suite *s = rglimiter_suite ();
260   SRunner *sr = srunner_create (s);
261
262   gst_check_init (&argc, &argv);
263
264   srunner_run_all (sr, CK_ENV);
265   nf = srunner_ntests_failed (sr);
266   srunner_free (sr);
267
268   return nf;
269 }