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., 51 Franklin St, Fifth Floor,
23 * Boston, MA 02110-1301, 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
GST_START_TEST(test_parse_flac_normal)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
GST_START_TEST(test_parse_flac_drain_single)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
GST_START_TEST(test_parse_flac_drain_garbage)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
GST_START_TEST(test_parse_flac_split)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
GST_START_TEST(test_parse_flac_skip_garbage)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 */
GST_START_TEST(test_parse_flac_detect_stream)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 *
flacparse_suite(void)248 flacparse_suite (void)
249 {
250 Suite *s = suite_create ("flacparse");
251 TCase *tc_chain = tcase_create ("general");
252
253
254 /* init test context */
255 ctx_factory = "flacparse";
256 ctx_sink_template = &sinktemplate;
257 ctx_src_template = &srctemplate;
258 ctx_discard = 3;
259 ctx_headers[0].data = streaminfo_header;
260 ctx_headers[0].size = sizeof (streaminfo_header);
261 ctx_headers[1].data = comment_header;
262 ctx_headers[1].size = sizeof (comment_header);
263
264 /* custom offsets, and ts always repeatedly 0 */
265 ctx_no_metadata = TRUE;
266 suite_add_tcase (s, tc_chain);
267 tcase_add_test (tc_chain, test_parse_flac_normal);
268 tcase_add_test (tc_chain, test_parse_flac_drain_single);
269 tcase_add_test (tc_chain, test_parse_flac_drain_garbage);
270 tcase_add_test (tc_chain, test_parse_flac_split);
271 tcase_add_test (tc_chain, test_parse_flac_skip_garbage);
272
273 /* Other tests */
274 tcase_add_test (tc_chain, test_parse_flac_detect_stream);
275
276 return s;
277 }
278
279
280 /*
281 * TODO:
282 * - Both push- and pull-modes need to be tested
283 * * Pull-mode & EOS
284 */
285 GST_CHECK_MAIN (flacparse);
286