tests: update for new audio caps
[platform/upstream/gstreamer.git] / tests / check / elements / gdpdepay.c
1 /* GStreamer
2  *
3  * Copyright (C) 2006 Thomas Vander Stichele <thomas at apestaart dot org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22 #include <string.h>
23 #include <unistd.h>
24
25 #include <gst/check/gstcheck.h>
26 #include <gst/dataprotocol/dataprotocol.h>
27
28 /* For ease of programming we use globals to keep refs for our floating
29  * src and sink pads we create; otherwise we always have to do get_pad,
30  * get_peer, and then remove references in every test function */
31 static GstPad *mysrcpad, *mysinkpad, *myshsinkpad;
32
33 #define FORMATS "{ S8, "GST_AUDIO_NE(S16)" }"
34
35 #define AUDIO_CAPS_TEMPLATE_STRING \
36     "audio/x-raw, " \
37     "format = (string) "FORMATS", " \
38     "rate = (int) [ 1, MAX ], " \
39     "channels = (int) [ 1, 8 ]"
40
41 #define AUDIO_CAPS_STRING \
42     "audio/x-raw, " \
43     "format = (string) "GST_AUDIO_NE(S16)", " \
44     "rate = (int) 1000, " \
45     "channels = (int) 2"
46
47 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
48     GST_PAD_SINK,
49     GST_PAD_ALWAYS,
50     GST_STATIC_CAPS (AUDIO_CAPS_TEMPLATE_STRING)
51     );
52 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
53     GST_PAD_SRC,
54     GST_PAD_ALWAYS,
55     GST_STATIC_CAPS ("application/x-gdp")
56     );
57
58 /* takes over reference for outcaps */
59 static GstElement *
60 setup_gdpdepay (void)
61 {
62   GstElement *gdpdepay;
63
64   GST_DEBUG ("setup_gdpdepay");
65   gdpdepay = gst_check_setup_element ("gdpdepay");
66   mysrcpad = gst_check_setup_src_pad (gdpdepay, &srctemplate, NULL);
67   mysinkpad = gst_check_setup_sink_pad (gdpdepay, &sinktemplate, NULL);
68   gst_pad_set_active (mysrcpad, TRUE);
69   gst_pad_set_active (mysinkpad, TRUE);
70
71   return gdpdepay;
72 }
73
74 static void
75 cleanup_gdpdepay (GstElement * gdpdepay)
76 {
77   GST_DEBUG ("cleanup_gdpdepay");
78
79   gst_pad_set_active (mysrcpad, FALSE);
80   if (mysinkpad)
81     gst_pad_set_active (mysinkpad, FALSE);
82   if (myshsinkpad)
83     gst_pad_set_active (myshsinkpad, FALSE);
84   gst_check_teardown_src_pad (gdpdepay);
85   gst_check_teardown_sink_pad (gdpdepay);
86   gst_check_teardown_element (gdpdepay);
87   mysinkpad = NULL;
88   myshsinkpad = NULL;
89 }
90
91 static void
92 gdpdepay_push_per_byte (const gchar * reason, const guint8 * bytes,
93     guint length)
94 {
95   int i;
96   GstBuffer *inbuffer;
97
98   for (i = 0; i < length; ++i) {
99     inbuffer = gst_buffer_new_and_alloc (1);
100     gst_buffer_fill (inbuffer, 0, &bytes[i], 1);
101     fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK,
102         "%s: failed pushing byte buffer", reason);
103   }
104 }
105
106 GST_START_TEST (test_audio_per_byte)
107 {
108   GstCaps *caps;
109   GstPad *srcpad;
110   GstElement *gdpdepay;
111   GstBuffer *buffer, *outbuffer;
112   guint8 *header, *payload;
113   guint len;
114   GstDPPacketizer *pk;
115
116   pk = gst_dp_packetizer_new (GST_DP_VERSION_1_0);
117
118   gdpdepay = setup_gdpdepay ();
119   srcpad = gst_element_get_static_pad (gdpdepay, "src");
120
121   fail_unless (gst_element_set_state (gdpdepay,
122           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
123       "could not set to playing");
124
125   caps = gst_pad_get_caps (srcpad);
126   fail_unless (gst_caps_is_any (caps));
127   gst_caps_unref (caps);
128   fail_if (gst_pad_get_negotiated_caps (srcpad));
129
130   /* create caps and buffer packets and push them */
131   caps = gst_caps_from_string (AUDIO_CAPS_STRING);
132   fail_unless (pk->packet_from_caps (caps, 0, &len, &header, &payload));
133   gst_caps_unref (caps);
134   gdpdepay_push_per_byte ("caps header", header, len);
135   fail_unless_equals_int (g_list_length (buffers), 0);
136   gdpdepay_push_per_byte ("caps payload", payload,
137       gst_dp_header_payload_length (header));
138   fail_unless_equals_int (g_list_length (buffers), 0);
139   caps = gst_pad_get_caps (srcpad);
140   fail_if (gst_caps_is_any (caps));
141   gst_caps_unref (caps);
142
143   g_free (header);
144   g_free (payload);
145
146   buffer = gst_buffer_new_and_alloc (4);
147   gst_buffer_fill (buffer, 0, "f00d", 4);
148   GST_BUFFER_TIMESTAMP (buffer) = GST_SECOND;
149   GST_BUFFER_DURATION (buffer) = GST_SECOND / 10;
150   fail_unless (pk->header_from_buffer (buffer, 0, &len, &header));
151   gdpdepay_push_per_byte ("buffer header", header, len);
152   fail_unless_equals_int (g_list_length (buffers), 0);
153   gdpdepay_push_per_byte ("buffer payload", (const guint8 *) "f00d",
154       gst_dp_header_payload_length (header));
155   g_free (header);
156   gst_buffer_unref (buffer);
157
158   fail_unless_equals_int (g_list_length (buffers), 1);
159   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
160   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuffer), GST_SECOND);
161   fail_unless_equals_uint64 (GST_BUFFER_DURATION (outbuffer), GST_SECOND / 10);
162
163   buffers = g_list_remove (buffers, outbuffer);
164   gst_buffer_unref (outbuffer);
165
166   fail_unless (gst_element_set_state (gdpdepay,
167           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
168
169   ASSERT_OBJECT_REFCOUNT (gdpdepay, "gdpdepay", 1);
170   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
171   g_list_free (buffers);
172   buffers = NULL;
173   gst_object_unref (srcpad);
174   cleanup_gdpdepay (gdpdepay);
175
176   gst_dp_packetizer_free (pk);
177 }
178
179 GST_END_TEST;
180
181 GST_START_TEST (test_audio_in_one_buffer)
182 {
183   GstCaps *caps;
184   GstPad *srcpad;
185   GstElement *gdpdepay;
186   GstBuffer *buffer, *inbuffer;
187   guint8 *caps_header, *caps_payload, *buf_header;
188   guint header_len, payload_len;
189   guint i;
190   GstDPPacketizer *pk;
191
192   pk = gst_dp_packetizer_new (GST_DP_VERSION_1_0);
193
194   gdpdepay = setup_gdpdepay ();
195   srcpad = gst_element_get_static_pad (gdpdepay, "src");
196
197   fail_unless (gst_element_set_state (gdpdepay,
198           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
199       "could not set to playing");
200
201   /* make sure no caps are set yet */
202   caps = gst_pad_get_caps (srcpad);
203   fail_unless (gst_caps_is_any (caps));
204   gst_caps_unref (caps);
205   fail_if (gst_pad_get_negotiated_caps (srcpad));
206
207   /* create caps and buffer packets and push them as one buffer */
208   caps = gst_caps_from_string (AUDIO_CAPS_STRING);
209   fail_unless (pk->packet_from_caps (caps, 0, &header_len, &caps_header,
210           &caps_payload));
211
212   buffer = gst_buffer_new_and_alloc (4);
213   gst_buffer_fill (buffer, 0, "f00d", 4);
214   fail_unless (pk->header_from_buffer (buffer, 0, &header_len, &buf_header));
215
216   payload_len = gst_dp_header_payload_length (caps_header);
217
218   inbuffer = gst_buffer_new_and_alloc (2 * GST_DP_HEADER_LENGTH +
219       payload_len + gst_buffer_get_size (buffer));
220   gst_buffer_fill (inbuffer, 0, caps_header, GST_DP_HEADER_LENGTH);
221   i = GST_DP_HEADER_LENGTH;
222   gst_buffer_fill (inbuffer, i, caps_payload, payload_len);
223   i += payload_len;
224   gst_buffer_fill (inbuffer, i, buf_header, GST_DP_HEADER_LENGTH);
225   i += GST_DP_HEADER_LENGTH;
226   gst_buffer_fill (inbuffer, i, "f00d", 4);
227
228   gst_caps_unref (caps);
229   gst_buffer_unref (buffer);
230
231   g_free (caps_header);
232   g_free (caps_payload);
233   g_free (buf_header);
234
235   /* now push it */
236   gst_pad_push (mysrcpad, inbuffer);
237
238   /* the buffer is still queued */
239   fail_unless_equals_int (g_list_length (buffers), 1);
240
241   fail_unless (gst_element_set_state (gdpdepay,
242           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
243
244   gst_object_unref (srcpad);
245   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
246   g_list_free (buffers);
247   buffers = NULL;
248   ASSERT_OBJECT_REFCOUNT (gdpdepay, "gdpdepay", 1);
249   cleanup_gdpdepay (gdpdepay);
250
251   gst_dp_packetizer_free (pk);
252 }
253
254 GST_END_TEST;
255
256 static GstStaticPadTemplate shsinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
257     GST_PAD_SINK,
258     GST_PAD_ALWAYS,
259     GST_STATIC_CAPS ("application/x-gst-test-streamheader")
260     );
261
262 static GstElement *
263 setup_gdpdepay_streamheader (void)
264 {
265   GstElement *gdpdepay;
266
267   GST_DEBUG ("setup_gdpdepay");
268   gdpdepay = gst_check_setup_element ("gdpdepay");
269   mysrcpad = gst_check_setup_src_pad (gdpdepay, &srctemplate, NULL);
270   myshsinkpad = gst_check_setup_sink_pad (gdpdepay, &shsinktemplate, NULL);
271   gst_pad_set_active (mysrcpad, TRUE);
272   gst_pad_set_active (myshsinkpad, TRUE);
273
274   return gdpdepay;
275 }
276
277 /* this tests deserialization of a GDP stream where the serialized caps
278  * have a streamheader set */
279 GST_START_TEST (test_streamheader)
280 {
281   GstCaps *caps, *padcaps;
282   GstPad *srcpad;
283   GstElement *gdpdepay;
284   GstBuffer *buffer, *inbuffer, *outbuffer, *shbuffer;
285   guint8 *caps_header, *caps_payload, *buf_header, *data;
286   gsize size;
287   guint header_len, payload_len;
288   guint i;
289   GstStructure *structure;
290   GValue array = { 0 };
291   GValue value = { 0 };
292   GstDPPacketizer *pk;
293
294   pk = gst_dp_packetizer_new (GST_DP_VERSION_1_0);
295
296   gdpdepay = setup_gdpdepay_streamheader ();
297   srcpad = gst_element_get_static_pad (gdpdepay, "src");
298   ASSERT_OBJECT_REFCOUNT (gdpdepay, "gdpdepay", 1);
299
300   fail_unless (gst_element_set_state (gdpdepay,
301           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
302       "could not set to playing");
303
304   /* make sure no caps are set yet */
305   caps = gst_pad_get_caps (srcpad);
306   fail_unless (gst_caps_is_any (caps));
307   gst_caps_unref (caps);
308   fail_if (gst_pad_get_negotiated_caps (srcpad));
309
310   /* create a streamheader buffer and the caps containing it */
311   caps = gst_caps_from_string ("application/x-gst-test-streamheader");
312   structure = gst_caps_get_structure (caps, 0);
313   buffer = gst_buffer_new_and_alloc (4);
314   gst_buffer_fill (buffer, 0, "f00d", 4);
315   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
316   g_value_init (&array, GST_TYPE_ARRAY);
317   g_value_init (&value, GST_TYPE_BUFFER);
318   shbuffer = gst_buffer_copy (buffer);
319   gst_value_set_buffer (&value, shbuffer);
320   gst_buffer_unref (shbuffer);
321   gst_value_array_append_value (&array, &value);
322   g_value_unset (&value);
323   gst_structure_set_value (structure, "streamheader", &array);
324   g_value_unset (&array);
325
326   gst_buffer_set_caps (buffer, caps);
327
328   /* create GDP packets for the caps and the buffer, and put them in one
329    * GDP buffer */
330   fail_unless (pk->packet_from_caps (caps, 0, &header_len, &caps_header,
331           &caps_payload));
332
333   fail_unless (pk->header_from_buffer (buffer, 0, &header_len, &buf_header));
334
335   payload_len = gst_dp_header_payload_length (caps_header);
336
337   data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
338   inbuffer = gst_buffer_new_and_alloc (2 * GST_DP_HEADER_LENGTH +
339       payload_len + size);
340   gst_buffer_fill (inbuffer, 0, caps_header, GST_DP_HEADER_LENGTH);
341   i = GST_DP_HEADER_LENGTH;
342   gst_buffer_fill (inbuffer, i, caps_payload, payload_len);
343   i += payload_len;
344   gst_buffer_fill (inbuffer, i, buf_header, GST_DP_HEADER_LENGTH);
345   i += GST_DP_HEADER_LENGTH;
346   gst_buffer_fill (inbuffer, i, data, size);
347   gst_buffer_unmap (buffer, data, size);
348
349   gst_caps_unref (caps);
350   gst_buffer_unref (buffer);
351
352   g_free (caps_header);
353   g_free (caps_payload);
354   g_free (buf_header);
355
356   /* now push it */
357   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
358   gst_pad_push (mysrcpad, inbuffer);
359
360   /* our only output buffer is the streamheader buffer */
361   fail_unless_equals_int (g_list_length (buffers), 1);
362   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
363   buffers = g_list_remove (buffers, outbuffer);
364   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
365   fail_unless (GST_BUFFER_FLAG_IS_SET (outbuffer, GST_BUFFER_FLAG_IN_CAPS));
366
367   padcaps = gst_pad_get_negotiated_caps (myshsinkpad);
368   caps = gst_buffer_get_caps (outbuffer);
369   fail_if (caps == NULL);
370   fail_if (padcaps == NULL);
371   GST_DEBUG ("caps: %" GST_PTR_FORMAT ", padcaps: %" GST_PTR_FORMAT, caps,
372       padcaps);
373   fail_unless (gst_caps_is_equal (padcaps, caps));
374
375   /* FIXME: get streamheader, compare data with buffer */
376   gst_buffer_unref (outbuffer);
377   gst_caps_unref (padcaps);
378   gst_caps_unref (caps);
379
380   /* clean up */
381   fail_unless (gst_element_set_state (gdpdepay,
382           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
383
384   gst_object_unref (srcpad);
385   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
386   g_list_free (buffers);
387   buffers = NULL;
388   ASSERT_OBJECT_REFCOUNT (gdpdepay, "gdpdepay", 1);
389   cleanup_gdpdepay (gdpdepay);
390
391   gst_dp_packetizer_free (pk);
392 }
393
394 GST_END_TEST;
395
396 static Suite *
397 gdpdepay_suite (void)
398 {
399   Suite *s = suite_create ("gdpdepay");
400   TCase *tc_chain = tcase_create ("general");
401
402   suite_add_tcase (s, tc_chain);
403   tcase_add_test (tc_chain, test_audio_per_byte);
404   tcase_add_test (tc_chain, test_audio_in_one_buffer);
405   tcase_add_test (tc_chain, test_streamheader);
406
407   return s;
408 }
409
410 GST_CHECK_MAIN (gdpdepay);