upload tizen1.0 source
[framework/multimedia/gst-plugins-good0.10.git] / tests / check / elements / flacparse.c
1 /*
2  * GStreamer
3  *
4  * unit test for flacparse
5  *
6  * Copyright (C) 2010 Nokia Corporation. All rights reserved.
7  *
8  * Contact: Stefan Kost <stefan.kost@nokia.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  */
25
26 #include <gst/check/gstcheck.h>
27 #include "parser.h"
28
29 #define SRC_CAPS_TMPL  "audio/x-flac, framed=(boolean)false"
30 #define SINK_CAPS_TMPL  "audio/x-flac, framed=(boolean)true"
31
32 GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
33     GST_PAD_SINK,
34     GST_PAD_ALWAYS,
35     GST_STATIC_CAPS (SINK_CAPS_TMPL)
36     );
37
38 GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
39     GST_PAD_SRC,
40     GST_PAD_ALWAYS,
41     GST_STATIC_CAPS (SRC_CAPS_TMPL)
42     );
43
44 /* some data */
45 static guint8 streaminfo_header[] = {
46   0x7f, 0x46, 0x4c, 0x41, 0x43, 0x01, 0x00, 0x00,
47   0x02, 0x66, 0x4c, 0x61, 0x43, 0x00, 0x00, 0x00,
48   0x22, 0x12, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00,
49   0x00, 0x00, 0x00, 0x0a, 0xc4, 0x40, 0xf0, 0x00,
50   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52   0x00, 0x00, 0x00
53 };
54
55 static guint8 comment_header[] = {
56   0x84, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
57   0x00, 0x00, 0x00, 0x00
58 };
59
60 static guint8 flac_frame[] = {
61   0xff, 0xf8, 0xa9, 0x08, 0x00, 0x50, 0x18, 0x06,
62   0x6a, 0x0c, 0xce, 0x13, 0x24, 0x19, 0x68, 0x00,
63   0x46, 0x23, 0x08, 0xca, 0xcb, 0x58, 0x9c, 0x26,
64   0x92, 0x30, 0xa6, 0x29, 0x8a, 0xca, 0xd1, 0x18,
65   0xae, 0x26, 0x5c, 0x90, 0x60, 0xbf, 0x11, 0xad,
66   0x43, 0x02, 0x06, 0x26, 0xbd, 0x35, 0xdd, 0xa3,
67   0x11, 0xa6, 0x4d, 0x18, 0x8c, 0x9a, 0xe4, 0x62,
68   0xd9, 0x23, 0x11, 0x8b, 0xcb, 0x56, 0x55, 0x45,
69   0xc2, 0x18, 0x56, 0xa2, 0xe2, 0xe1, 0x18, 0x99,
70   0x54, 0x98, 0x46, 0x4d, 0x08, 0x70, 0x9a, 0x64,
71   0xc4, 0x18, 0x4f, 0x27, 0x64, 0x31, 0x66, 0x27,
72   0x79, 0x19, 0x3c, 0x8c, 0x8c, 0xa3, 0x44, 0x18,
73   0x23, 0xd2, 0x6b, 0x8b, 0x64, 0x8c, 0x21, 0x84,
74   0xd6, 0x23, 0x13, 0x13, 0x2d, 0x44, 0xca, 0x5a,
75   0x23, 0x09, 0x93, 0x25, 0x18, 0x10, 0x61, 0x38,
76   0xb4, 0x60, 0x8f, 0x2c, 0x8d, 0x26, 0xb4, 0xc9,
77   0xd9, 0x19, 0x19, 0x34, 0xd7, 0x31, 0x06, 0x10,
78   0xc4, 0x30, 0x83, 0x17, 0xe2, 0x0c, 0x2c, 0xc4,
79   0xc8, 0xc9, 0x3c, 0x5e, 0x93, 0x11, 0x8a, 0x62,
80   0x64, 0x8c, 0x26, 0x23, 0x22, 0x30, 0x9a, 0x58,
81   0x86, 0x04, 0x18, 0x4c, 0xab, 0x2b, 0x26, 0x5c,
82   0x46, 0x88, 0xcb, 0xb1, 0x0d, 0x26, 0xbb, 0x5e,
83   0x8c, 0xa7, 0x64, 0x31, 0x3d, 0x31, 0x06, 0x26,
84   0x43, 0x17, 0xa3, 0x08, 0x61, 0x06, 0x17, 0xc4,
85   0x62, 0xec, 0x4d, 0x4b, 0x2e, 0x2d, 0x4a, 0x94,
86   0xa4, 0xc2, 0x31, 0x4c, 0x4c, 0x20, 0xc0, 0x83,
87   0x14, 0x8c, 0x27, 0x8b, 0x31, 0x23, 0x2f, 0x23,
88   0x11, 0x91, 0x94, 0x65, 0x1a, 0x20, 0xc2, 0x18,
89   0x86, 0x51, 0x88, 0x62, 0x7c, 0x43, 0x2e, 0xa3,
90   0x04, 0x18, 0x8c, 0x20, 0xc2, 0xf5, 0xaa, 0x94,
91   0xc2, 0x31, 0x32, 0xd2, 0xb2, 0xa2, 0x30, 0xba,
92   0x10, 0xc2, 0xb5, 0x89, 0xa5, 0x18, 0x10, 0x62,
93   0x9a, 0x10, 0x61, 0x19, 0x72, 0x71, 0x1a, 0xb9,
94   0x0c, 0x23, 0x46, 0x10, 0x62, 0x78, 0x81, 0x82,
95   0x3d, 0x75, 0xea, 0x6b, 0x51, 0x8b, 0x61, 0x06,
96   0x08, 0x62, 0x32, 0x5e, 0x84, 0x18, 0x27, 0x25,
97   0xc2, 0x6a, 0x4b, 0x51, 0x31, 0x34, 0x5e, 0x29,
98   0xa1, 0x3c, 0x4d, 0x26, 0x23, 0x10, 0xc2, 0x6b,
99   0xb1, 0x0d, 0x11, 0xae, 0x46, 0x88, 0x31, 0x35,
100   0xb1, 0x06, 0x08, 0x79, 0x7e, 0x4f, 0x53, 0x23,
101   0x29, 0xa4, 0x30, 0x20, 0x30, 0x23, 0x5a, 0xb2,
102   0xc8, 0x60, 0x9c, 0x93, 0x13, 0x17, 0x92, 0x98,
103   0x46, 0x13, 0x54, 0x53, 0x08, 0xcb, 0x13, 0xa1,
104   0x1a, 0x89, 0xe5, 0x46, 0x08, 0x18, 0x10, 0x30,
105   0x9d, 0x68, 0xc2, 0x1c, 0x46, 0x46, 0xae, 0x62,
106   0x1a, 0x46, 0x4e, 0x4d, 0x34, 0x8c, 0xbd, 0x26,
107   0xc0, 0x40, 0x62, 0xc9, 0xa9, 0x31, 0x74, 0xa8,
108   0x99, 0x52, 0xb0, 0x8c, 0xa9, 0x29, 0x84, 0x61,
109   0x19, 0x54, 0x43, 0x02, 0x06, 0x04, 0x32, 0xe5,
110   0x18, 0x21, 0x91, 0x8b, 0xf2, 0xcc, 0x10, 0x30,
111   0x8e, 0x23, 0xc4, 0x76, 0x43, 0x08, 0x30, 0x83,
112   0x08, 0x62, 0x6c, 0x4e, 0xe2, 0x35, 0x96, 0xd0,
113   0x8e, 0x89, 0x97, 0x42, 0x18, 0x91, 0x84, 0x61,
114   0x3c, 0x26, 0xa5, 0x2c, 0x4e, 0x17, 0x94, 0xb8,
115   0xb5, 0xa4, 0xcb, 0x88, 0xc9, 0x84, 0x18, 0xb9,
116   0x84, 0x19, 0x23, 0x2d, 0xa4, 0x64, 0x62, 0x18,
117   0x86, 0x53, 0x93, 0xcb, 0x30, 0x8f, 0x2f, 0x93,
118   0x55, 0xc4, 0xd7, 0x08, 0x62, 0xb8, 0x46, 0x84,
119   0x68, 0xa3, 0x02, 0xaf, 0x33
120 };
121
122 static guint8 garbage_frame[] = {
123   0xff, 0xff, 0xff, 0xff, 0xff
124 };
125
126
127 GST_START_TEST (test_parse_flac_normal)
128 {
129   gst_parser_test_normal (flac_frame, sizeof (flac_frame));
130 }
131
132 GST_END_TEST;
133
134
135 GST_START_TEST (test_parse_flac_drain_single)
136 {
137   gst_parser_test_drain_single (flac_frame, sizeof (flac_frame));
138 }
139
140 GST_END_TEST;
141
142
143 GST_START_TEST (test_parse_flac_drain_garbage)
144 {
145   /* We always output the after frame garbage too because we
146    * have no way of detecting it
147    */
148 #if 0
149   gst_parser_test_drain_garbage (flac_frame, sizeof (flac_frame),
150       garbage_frame, sizeof (garbage_frame));
151 #endif
152   guint8 frame[sizeof (flac_frame) + sizeof (garbage_frame)];
153
154   memcpy (frame, flac_frame, sizeof (flac_frame));
155   memcpy (frame + sizeof (flac_frame), garbage_frame, sizeof (garbage_frame));
156
157   gst_parser_test_drain_single (frame, sizeof (frame));
158 }
159
160 GST_END_TEST;
161
162
163 GST_START_TEST (test_parse_flac_split)
164 {
165   gst_parser_test_split (flac_frame, sizeof (flac_frame));
166 }
167
168 GST_END_TEST;
169
170
171 GST_START_TEST (test_parse_flac_skip_garbage)
172 {
173   /* We always include the garbage into the frame because
174    * we have no easy way for finding the real end of the
175    * frame. The decoder will later skip the garbage
176    */
177 #if 0
178   gst_parser_test_skip_garbage (flac_frame, sizeof (flac_frame),
179       garbage_frame, sizeof (garbage_frame));
180 #endif
181   guint8 frame[sizeof (flac_frame) + sizeof (garbage_frame)];
182
183   memcpy (frame, flac_frame, sizeof (flac_frame));
184   memcpy (frame + sizeof (flac_frame), garbage_frame, sizeof (garbage_frame));
185
186   gst_parser_test_normal (frame, sizeof (frame));
187 }
188
189 GST_END_TEST;
190
191
192 #define structure_get_int(s,f) \
193     (g_value_get_int(gst_structure_get_value(s,f)))
194 #define fail_unless_structure_field_int_equals(s,field,num) \
195     fail_unless_equals_int (structure_get_int(s,field), num)
196 /*
197  * Test if the parser handles raw stream and codec_data info properly.
198  */
199 GST_START_TEST (test_parse_flac_detect_stream)
200 {
201   GstCaps *caps;
202   GstStructure *s;
203   const GValue *streamheader;
204   GArray *bufarr;
205   gint i;
206
207   /* Push random data. It should get through since the parser should be
208    * initialized because it got codec_data in the caps */
209   caps = gst_parser_test_get_output_caps (flac_frame, sizeof (flac_frame),
210       SRC_CAPS_TMPL);
211   fail_unless (caps != NULL);
212
213   /* Check that the negotiated caps are as expected */
214   /* When codec_data is present, parser assumes that data is version 4 */
215   GST_LOG ("flac output caps: %" GST_PTR_FORMAT, caps);
216   s = gst_caps_get_structure (caps, 0);
217   fail_unless (gst_structure_has_name (s, "audio/x-flac"));
218   fail_unless_structure_field_int_equals (s, "channels", 1);
219   fail_unless_structure_field_int_equals (s, "rate", 44100);
220   fail_unless (gst_structure_has_field (s, "streamheader"));
221   streamheader = gst_structure_get_value (s, "streamheader");
222   fail_unless (G_VALUE_TYPE (streamheader) == GST_TYPE_ARRAY);
223   bufarr = g_value_peek_pointer (streamheader);
224   fail_unless (bufarr->len == 2);
225   for (i = 0; i < bufarr->len; i++) {
226     GstBuffer *buf;
227     GValue *bufval = &g_array_index (bufarr, GValue, i);
228
229     fail_unless (G_VALUE_TYPE (bufval) == GST_TYPE_BUFFER);
230     buf = g_value_peek_pointer (bufval);
231     if (i == 0) {
232       fail_unless (GST_BUFFER_SIZE (buf) == sizeof (streaminfo_header));
233       fail_unless (memcmp (buf, streaminfo_header, sizeof (streaminfo_header)));
234     } else if (i == 1) {
235       fail_unless (GST_BUFFER_SIZE (buf) == sizeof (comment_header));
236       fail_unless (memcmp (buf, comment_header, sizeof (comment_header)));
237     }
238   }
239
240   gst_caps_unref (caps);
241 }
242
243 GST_END_TEST;
244
245 GST_START_TEST (test_parse_flac_set_index)
246 {
247   GstElement *parse;
248   GstIndex *idx;
249
250   idx = gst_index_factory_make ("memindex");
251   if (idx == NULL)
252     return;
253   parse = gst_element_factory_make ("flacparse", NULL);
254   fail_unless (parse != NULL);
255   gst_object_ref_sink (idx);
256   gst_element_set_index (parse, GST_INDEX (idx));
257   gst_object_unref (idx);
258   gst_object_unref (parse);
259 }
260
261 GST_END_TEST;
262
263 static Suite *
264 flacparse_suite (void)
265 {
266   Suite *s = suite_create ("flacparse");
267   TCase *tc_chain = tcase_create ("general");
268
269   suite_add_tcase (s, tc_chain);
270   tcase_add_test (tc_chain, test_parse_flac_normal);
271   tcase_add_test (tc_chain, test_parse_flac_drain_single);
272   tcase_add_test (tc_chain, test_parse_flac_drain_garbage);
273   tcase_add_test (tc_chain, test_parse_flac_split);
274   tcase_add_test (tc_chain, test_parse_flac_skip_garbage);
275
276   /* Other tests */
277   tcase_add_test (tc_chain, test_parse_flac_detect_stream);
278   tcase_add_test (tc_chain, test_parse_flac_set_index);
279
280   return s;
281 }
282
283
284 /*
285  * TODO:
286  *   - Both push- and pull-modes need to be tested
287  *      * Pull-mode & EOS
288  */
289
290 int
291 main (int argc, char **argv)
292 {
293   int nf;
294
295   Suite *s = flacparse_suite ();
296   SRunner *sr = srunner_create (s);
297
298   gst_check_init (&argc, &argv);
299
300   /* init test context */
301   ctx_factory = "flacparse";
302   ctx_sink_template = &sinktemplate;
303   ctx_src_template = &srctemplate;
304   ctx_discard = 3;
305   ctx_headers[0].data = streaminfo_header;
306   ctx_headers[0].size = sizeof (streaminfo_header);
307   ctx_headers[1].data = comment_header;
308   ctx_headers[1].size = sizeof (comment_header);
309   /* custom offsets, and ts always repeatedly 0 */
310   ctx_no_metadata = TRUE;
311
312   srunner_run_all (sr, CK_NORMAL);
313   nf = srunner_ntests_failed (sr);
314   srunner_free (sr);
315
316   return nf;
317 }