Merge branch 'master' into 0.11
[platform/upstream/gstreamer.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_get_size (buf) == sizeof (streaminfo_header));
233       fail_unless (gst_buffer_memcmp (buf, 0, streaminfo_header,
234               sizeof (streaminfo_header)) == 0);
235     } else if (i == 1) {
236       fail_unless (gst_buffer_get_size (buf) == sizeof (comment_header));
237       fail_unless (gst_buffer_memcmp (buf, 0, comment_header,
238               sizeof (comment_header)) == 0);
239     }
240   }
241
242   gst_caps_unref (caps);
243 }
244
245 GST_END_TEST;
246
247 static Suite *
248 flacparse_suite (void)
249 {
250   Suite *s = suite_create ("flacparse");
251   TCase *tc_chain = tcase_create ("general");
252
253   suite_add_tcase (s, tc_chain);
254   tcase_add_test (tc_chain, test_parse_flac_normal);
255   tcase_add_test (tc_chain, test_parse_flac_drain_single);
256   tcase_add_test (tc_chain, test_parse_flac_drain_garbage);
257   tcase_add_test (tc_chain, test_parse_flac_split);
258   tcase_add_test (tc_chain, test_parse_flac_skip_garbage);
259
260   /* Other tests */
261   tcase_add_test (tc_chain, test_parse_flac_detect_stream);
262
263   return s;
264 }
265
266
267 /*
268  * TODO:
269  *   - Both push- and pull-modes need to be tested
270  *      * Pull-mode & EOS
271  */
272
273 int
274 main (int argc, char **argv)
275 {
276   int nf;
277
278   Suite *s = flacparse_suite ();
279   SRunner *sr = srunner_create (s);
280
281   gst_check_init (&argc, &argv);
282
283   /* init test context */
284   ctx_factory = "flacparse";
285   ctx_sink_template = &sinktemplate;
286   ctx_src_template = &srctemplate;
287   ctx_discard = 3;
288   ctx_headers[0].data = streaminfo_header;
289   ctx_headers[0].size = sizeof (streaminfo_header);
290   ctx_headers[1].data = comment_header;
291   ctx_headers[1].size = sizeof (comment_header);
292   /* custom offsets, and ts always repeatedly 0 */
293   ctx_no_metadata = TRUE;
294
295   srunner_run_all (sr, CK_NORMAL);
296   nf = srunner_ntests_failed (sr);
297   srunner_free (sr);
298
299   return nf;
300 }