1 /*
2 * GStreamer
3 *
4 * unit test for h264parse
5 *
6 * Copyright (C) 2011 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/check.h>
27 #include <gst/video/video.h>
28 #include "parser.h"
29
30 #define SRC_CAPS_TMPL "video/x-h264, parsed=(boolean)false"
31 #define SINK_CAPS_TMPL "video/x-h264, parsed=(boolean)true"
32
33 GstStaticPadTemplate sinktemplate_bs_nal = GST_STATIC_PAD_TEMPLATE ("sink",
34 GST_PAD_SINK,
35 GST_PAD_ALWAYS,
36 GST_STATIC_CAPS (SINK_CAPS_TMPL
37 ", stream-format = (string) byte-stream, alignment = (string) nal")
38 );
39
40 GstStaticPadTemplate sinktemplate_bs_au = GST_STATIC_PAD_TEMPLATE ("sink",
41 GST_PAD_SINK,
42 GST_PAD_ALWAYS,
43 GST_STATIC_CAPS (SINK_CAPS_TMPL
44 ", stream-format = (string) byte-stream, alignment = (string) au")
45 );
46
47 GstStaticPadTemplate sinktemplate_avc_au = GST_STATIC_PAD_TEMPLATE ("sink",
48 GST_PAD_SINK,
49 GST_PAD_ALWAYS,
50 GST_STATIC_CAPS (SINK_CAPS_TMPL
51 ", stream-format = (string) avc, alignment = (string) au")
52 );
53
54 GstStaticPadTemplate sinktemplate_avc3_au = GST_STATIC_PAD_TEMPLATE ("sink",
55 GST_PAD_SINK,
56 GST_PAD_ALWAYS,
57 GST_STATIC_CAPS (SINK_CAPS_TMPL
58 ", stream-format = (string) avc3, alignment = (string) au")
59 );
60
61 GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
62 GST_PAD_SRC,
63 GST_PAD_ALWAYS,
64 GST_STATIC_CAPS (SRC_CAPS_TMPL)
65 );
66
67 /* some data */
68
69 /* AUD */
70 static guint8 h264_aud[] = {
71 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0
72 };
73
74
75 /* SPS */
76 static guint8 h264_sps[] = {
77 0x00, 0x00, 0x00, 0x01, 0x67, 0x4d, 0x40, 0x15,
78 0xec, 0xa4, 0xbf, 0x2e, 0x02, 0x20, 0x00, 0x00,
79 0x03, 0x00, 0x2e, 0xe6, 0xb2, 0x80, 0x01, 0xe2,
80 0xc5, 0xb2, 0xc0
81 };
82
83 /* PPS */
84 static guint8 h264_pps[] = {
85 0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xec, 0xb2
86 };
87
88 /* SEI buffering_period() message */
89 static guint8 h264_sei_buffering_period[] = {
90 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x01, 0xc0
91 };
92
93 /* combines to this codec-data */
94 static guint8 h264_avc_codec_data[] = {
95 0x01, 0x4d, 0x40, 0x15, 0xff, 0xe1, 0x00, 0x17,
96 0x67, 0x4d, 0x40, 0x15, 0xec, 0xa4, 0xbf, 0x2e,
97 0x02, 0x20, 0x00, 0x00, 0x03, 0x00, 0x2e, 0xe6,
98 0xb2, 0x80, 0x01, 0xe2, 0xc5, 0xb2, 0xc0, 0x01,
99 0x00, 0x04, 0x68, 0xeb, 0xec, 0xb2
100 };
101
102 /* codec-data for avc3 where there are no SPS/PPS in the codec_data */
103 static guint8 h264_avc3_codec_data[] = {
104 0x01, /* config version, always == 1 */
105 0x4d, /* profile */
106 0x40, /* profile compatibility */
107 0x15, 0xff, /* 6 reserved bits, lengthSizeMinusOne */
108 0xe0, /* 3 reserved bits, numSPS */
109 0x00 /* numPPS */
110 };
111
112 static guint8 *h264_codec_data = NULL;
113 static guint8 h264_codec_data_size = 0;
114
115
116 /* keyframes all around */
117 static guint8 h264_idrframe[] = {
118 0x00, 0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00,
119 0x10, 0xff, 0xfe, 0xf6, 0xf0, 0xfe, 0x05, 0x36,
120 0x56, 0x04, 0x50, 0x96, 0x7b, 0x3f, 0x53, 0xe1
121 };
122
123 /* truncated nal */
124 static guint8 garbage_frame[] = {
125 0x00, 0x00, 0x00, 0x01, 0x05
126 };
127
128 /* context to tweak tests */
129 static const gchar *ctx_suite;
130 static gboolean ctx_codec_data;
131
132 static gboolean
verify_buffer(buffer_verify_data_s * vdata,GstBuffer * buffer)133 verify_buffer (buffer_verify_data_s * vdata, GstBuffer * buffer)
134 {
135 if (vdata->discard) {
136 /* check separate header NALs */
137 gint i = vdata->buffer_counter;
138 guint ofs;
139 gboolean aud;
140
141 /* SEI with start code prefix with 2 0-bytes */
142 ofs = i == 2;
143 aud = i == 0;
144 fail_unless (i <= 3);
145
146 if (aud) {
147 fail_unless (gst_buffer_get_size (buffer) == sizeof (h264_aud));
148 fail_unless (gst_buffer_memcmp (buffer, 0, h264_aud,
149 gst_buffer_get_size (buffer)) == 0);
150 vdata->discard++;
151 } else {
152 i -= 1;
153
154 fail_unless (gst_buffer_get_size (buffer) == ctx_headers[i].size - ofs);
155 fail_unless (gst_buffer_memcmp (buffer, 0, ctx_headers[i].data + ofs,
156 gst_buffer_get_size (buffer)) == 0);
157 }
158 } else {
159 GstMapInfo map;
160
161 gst_buffer_map (buffer, &map, GST_MAP_READ);
162 fail_unless (map.size > 4);
163 /* only need to check avc and bs-to-nal output case */
164 if (GST_READ_UINT24_BE (map.data) == 0x01) {
165 /* in bs-to-nal, a leading 0x00 is stripped from output */
166 fail_unless (gst_buffer_get_size (buffer) ==
167 vdata->data_to_verify_size - 1);
168 fail_unless (gst_buffer_memcmp (buffer, 0, vdata->data_to_verify + 1,
169 vdata->data_to_verify_size - 1) == 0);
170 gst_buffer_unmap (buffer, &map);
171 return TRUE;
172 } else if (GST_READ_UINT32_BE (map.data) == 0x01) {
173 gboolean aud = FALSE;
174 aud = vdata->buffer_counter % 2;
175 if (aud) {
176 fail_unless (gst_buffer_get_size (buffer) == sizeof (h264_aud));
177 fail_unless (gst_buffer_memcmp (buffer, 0, h264_aud,
178 gst_buffer_get_size (buffer)) == 0);
179 gst_buffer_unmap (buffer, &map);
180 return TRUE;
181 }
182
183 /* this is not avc, use default tests from parser.c */
184 gst_buffer_unmap (buffer, &map);
185 return FALSE;
186 }
187 /* header is merged in initial frame */
188 if (vdata->buffer_counter == 0) {
189 guint8 *data = map.data;
190
191 fail_unless (map.size == vdata->data_to_verify_size +
192 ctx_headers[0].size + ctx_headers[1].size + ctx_headers[2].size);
193 fail_unless (GST_READ_UINT32_BE (data) == ctx_headers[0].size - 4);
194 fail_unless (memcmp (data + 4, ctx_headers[0].data + 4,
195 ctx_headers[0].size - 4) == 0);
196 data += ctx_headers[0].size;
197 fail_unless (GST_READ_UINT32_BE (data) == ctx_headers[1].size - 4);
198 fail_unless (memcmp (data + 4, ctx_headers[1].data + 4,
199 ctx_headers[1].size - 4) == 0);
200 data += ctx_headers[1].size;
201 fail_unless (GST_READ_UINT32_BE (data) == ctx_headers[2].size - 4);
202 fail_unless (memcmp (data + 4, ctx_headers[2].data + 4,
203 ctx_headers[2].size - 4) == 0);
204 data += ctx_headers[2].size;
205 fail_unless (GST_READ_UINT32_BE (data) == vdata->data_to_verify_size - 4);
206 fail_unless (memcmp (data + 4, vdata->data_to_verify + 4,
207 vdata->data_to_verify_size - 4) == 0);
208 } else {
209 fail_unless (GST_READ_UINT32_BE (map.data) == map.size - 4);
210 fail_unless (map.size == vdata->data_to_verify_size);
211 fail_unless (memcmp (map.data + 4, vdata->data_to_verify + 4,
212 map.size - 4) == 0);
213 }
214 gst_buffer_unmap (buffer, &map);
215 return TRUE;
216 }
217
218 return FALSE;
219 }
220
221 /* A single access unit comprising of SPS, SEI, PPS and IDR frame */
222 static gboolean
verify_buffer_bs_au(buffer_verify_data_s * vdata,GstBuffer * buffer)223 verify_buffer_bs_au (buffer_verify_data_s * vdata, GstBuffer * buffer)
224 {
225 GstMapInfo map;
226
227 fail_unless (ctx_sink_template == &sinktemplate_bs_au);
228
229 gst_buffer_map (buffer, &map, GST_MAP_READ);
230 fail_unless (map.size > 4);
231
232 if (vdata->buffer_counter == 0) {
233 guint8 *data = map.data;
234
235 /* AUD, SPS, SEI, PPS */
236 fail_unless (map.size == vdata->data_to_verify_size +
237 sizeof (h264_aud) + ctx_headers[0].size +
238 ctx_headers[1].size + ctx_headers[2].size);
239 fail_unless (memcmp (data, h264_aud, sizeof (h264_aud)) == 0);
240 data += sizeof (h264_aud);
241 fail_unless (memcmp (data, ctx_headers[0].data, ctx_headers[0].size) == 0);
242 data += ctx_headers[0].size;
243 fail_unless (memcmp (data, ctx_headers[1].data, ctx_headers[1].size) == 0);
244 data += ctx_headers[1].size;
245 fail_unless (memcmp (data, ctx_headers[2].data, ctx_headers[2].size) == 0);
246 data += ctx_headers[2].size;
247
248 /* IDR frame */
249 fail_unless (memcmp (data, vdata->data_to_verify,
250 vdata->data_to_verify_size) == 0);
251 } else {
252 /* IDR frame */
253 guint aud_size = sizeof (h264_aud);
254 fail_unless (map.size == vdata->data_to_verify_size + aud_size);
255 fail_unless (memcmp (map.data, h264_aud, aud_size) == 0);
256 fail_unless (memcmp (map.data + aud_size, vdata->data_to_verify,
257 map.size - aud_size) == 0);
258 }
259
260 gst_buffer_unmap (buffer, &map);
261 return TRUE;
262 }
263
GST_START_TEST(test_parse_normal)264 GST_START_TEST (test_parse_normal)
265 {
266 gst_parser_test_normal (h264_idrframe, sizeof (h264_idrframe));
267 }
268
269 GST_END_TEST;
270
271
GST_START_TEST(test_parse_drain_single)272 GST_START_TEST (test_parse_drain_single)
273 {
274 gst_parser_test_drain_single (h264_idrframe, sizeof (h264_idrframe));
275 }
276
277 GST_END_TEST;
278
279
GST_START_TEST(test_parse_drain_garbage)280 GST_START_TEST (test_parse_drain_garbage)
281 {
282 gst_parser_test_drain_garbage (h264_idrframe, sizeof (h264_idrframe),
283 garbage_frame, sizeof (garbage_frame));
284 }
285
286 GST_END_TEST
GST_START_TEST(test_parse_split)287 GST_START_TEST (test_parse_split)
288 {
289 gst_parser_test_split (h264_idrframe, sizeof (h264_idrframe));
290 }
291
292 GST_END_TEST;
293
294
GST_START_TEST(test_parse_skip_garbage)295 GST_START_TEST (test_parse_skip_garbage)
296 {
297 gst_parser_test_skip_garbage (h264_idrframe, sizeof (h264_idrframe),
298 garbage_frame, sizeof (garbage_frame));
299 }
300
301 GST_END_TEST;
302
303 #define structure_get_int(s,f) \
304 (g_value_get_int(gst_structure_get_value(s,f)))
305 #define fail_unless_structure_field_int_equals(s,field,num) \
306 fail_unless_equals_int (structure_get_int(s,field), num)
307
308
GST_START_TEST(test_parse_detect_stream)309 GST_START_TEST (test_parse_detect_stream)
310 {
311 GstCaps *caps;
312 GstStructure *s;
313 GstBuffer *buf;
314 const GValue *val;
315
316 /* parser does not really care that mpeg1 and mpeg2 frame data
317 * should be a bit different */
318 caps = gst_parser_test_get_output_caps (h264_idrframe, sizeof (h264_idrframe),
319 NULL);
320 fail_unless (caps != NULL);
321
322 /* Check that the negotiated caps are as expected */
323 /* When codec_data is present, parser assumes that data is version 4 */
324 GST_LOG ("h264 output caps: %" GST_PTR_FORMAT, caps);
325 s = gst_caps_get_structure (caps, 0);
326 fail_unless (gst_structure_has_name (s, "video/x-h264"));
327 fail_unless_structure_field_int_equals (s, "width", 32);
328 fail_unless_structure_field_int_equals (s, "height", 24);
329
330 if (ctx_codec_data) {
331 fail_unless (gst_structure_has_field (s, "codec_data"));
332
333 /* check codec-data in more detail */
334 val = gst_structure_get_value (s, "codec_data");
335 fail_unless (val != NULL);
336 buf = gst_value_get_buffer (val);
337 fail_unless (buf != NULL);
338 fail_unless (gst_buffer_get_size (buf) == h264_codec_data_size);
339 fail_unless (gst_buffer_memcmp (buf, 0, h264_codec_data,
340 gst_buffer_get_size (buf)) == 0);
341 }
342
343 gst_caps_unref (caps);
344 }
345
346 GST_END_TEST;
347
348 static GstStaticPadTemplate srctemplate_avc_au_and_bs_au =
349 GST_STATIC_PAD_TEMPLATE ("src",
350 GST_PAD_SRC,
351 GST_PAD_ALWAYS,
352 GST_STATIC_CAPS (SRC_CAPS_TMPL
353 ", stream-format = (string) avc, alignment = (string) au; "
354 SRC_CAPS_TMPL
355 ", stream-format = (string) byte-stream, alignment = (string) au")
356 );
357
GST_START_TEST(test_sink_caps_reordering)358 GST_START_TEST (test_sink_caps_reordering)
359 {
360 /* Upstream can handle avc and byte-stream format (in that preference order)
361 * and downstream requires byte-stream.
362 * Parser reorder upstream's caps to prefer the format requested downstream
363 * and so avoid doing useless conversions. */
364 GstElement *parser;
365 GstPad *sink, *src;
366 GstCaps *src_caps, *sink_caps;
367 GstStructure *s;
368
369 parser = gst_check_setup_element ("h264parse");
370 fail_unless (parser);
371
372 src = gst_check_setup_src_pad (parser, &srctemplate_avc_au_and_bs_au);
373 sink = gst_check_setup_sink_pad (parser, &sinktemplate_bs_au);
374
375 src_caps = gst_pad_get_pad_template_caps (src);
376 sink_caps = gst_pad_peer_query_caps (src, src_caps);
377
378 /* Sink pad has both format on its sink caps but prefer to use byte-stream */
379 g_assert_cmpuint (gst_caps_get_size (sink_caps), ==, 2);
380
381 s = gst_caps_get_structure (sink_caps, 0);
382 g_assert_cmpstr (gst_structure_get_name (s), ==, "video/x-h264");
383 g_assert_cmpstr (gst_structure_get_string (s, "alignment"), ==, "au");
384 g_assert_cmpstr (gst_structure_get_string (s, "stream-format"), ==,
385 "byte-stream");
386
387 s = gst_caps_get_structure (sink_caps, 1);
388 g_assert_cmpstr (gst_structure_get_name (s), ==, "video/x-h264");
389 g_assert_cmpstr (gst_structure_get_string (s, "alignment"), ==, "au");
390 g_assert_cmpstr (gst_structure_get_string (s, "stream-format"), ==, "avc");
391
392 gst_caps_unref (src_caps);
393 gst_caps_unref (sink_caps);
394 gst_object_unref (src);
395 gst_object_unref (sink);
396 gst_object_unref (parser);
397 }
398
399 GST_END_TEST;
400
401 static Suite *
h264parse_suite(void)402 h264parse_suite (void)
403 {
404 Suite *s = suite_create (ctx_suite);
405 TCase *tc_chain = tcase_create ("general");
406
407 suite_add_tcase (s, tc_chain);
408 tcase_add_test (tc_chain, test_parse_normal);
409 tcase_add_test (tc_chain, test_parse_drain_single);
410 tcase_add_test (tc_chain, test_parse_drain_garbage);
411 tcase_add_test (tc_chain, test_parse_split);
412 tcase_add_test (tc_chain, test_parse_skip_garbage);
413 tcase_add_test (tc_chain, test_parse_detect_stream);
414 tcase_add_test (tc_chain, test_sink_caps_reordering);
415
416 return s;
417 }
418
419 static gboolean
verify_buffer_packetized(buffer_verify_data_s * vdata,GstBuffer * buffer)420 verify_buffer_packetized (buffer_verify_data_s * vdata, GstBuffer * buffer)
421 {
422 GstMapInfo map;
423
424 gst_buffer_map (buffer, &map, GST_MAP_READ);
425
426 fail_unless (map.size > 4);
427 fail_unless (GST_READ_UINT32_BE (map.data) == 0x01);
428 if (vdata->discard) {
429 /* check separate header NALs */
430 guint8 *data;
431 gint size;
432
433 if (vdata->buffer_counter == 0) {
434 data = h264_aud;
435 size = sizeof (h264_aud);
436 vdata->discard++;
437 } else if (vdata->buffer_counter == 1) {
438 data = h264_sps;
439 size = sizeof (h264_sps);
440 } else {
441 data = h264_pps;
442 size = sizeof (h264_pps);
443 }
444
445 fail_unless (map.size == size);
446 fail_unless (memcmp (map.data + 4, data + 4, size - 4) == 0);
447 } else {
448 guint8 *data;
449 gint size;
450 gboolean aud = vdata->buffer_counter % 2;
451 if (aud) {
452 data = h264_aud;
453 size = sizeof (h264_aud);
454 } else {
455 data = (gpointer) vdata->data_to_verify;
456 size = map.size;
457 }
458
459 fail_unless (map.size == size);
460 fail_unless (memcmp (map.data + 4, data + 4, size - 4) == 0);
461 }
462 gst_buffer_unmap (buffer, &map);
463
464 return TRUE;
465 }
466
GST_START_TEST(test_parse_packetized)467 GST_START_TEST (test_parse_packetized)
468 {
469 guint8 *frame;
470 GstCaps *caps;
471 GstBuffer *cdata;
472 GstStructure *s;
473 gchar *desc;
474
475 /* make AVC frame */
476 frame = g_malloc (sizeof (h264_idrframe));
477 GST_WRITE_UINT32_BE (frame, sizeof (h264_idrframe) - 4);
478 memcpy (frame + 4, h264_idrframe + 4, sizeof (h264_idrframe) - 4);
479
480 /* some caps messing */
481 caps = gst_caps_from_string (SRC_CAPS_TMPL);
482 cdata =
483 gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, h264_codec_data,
484 h264_codec_data_size, 0, h264_codec_data_size, NULL, NULL);
485 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, cdata,
486 "stream-format", G_TYPE_STRING, "avc", NULL);
487 gst_buffer_unref (cdata);
488 desc = gst_caps_to_string (caps);
489 gst_caps_unref (caps);
490
491 caps = gst_parser_test_get_output_caps (frame, sizeof (h264_idrframe), desc);
492 g_free (desc);
493 g_free (frame);
494
495 /* minor caps checks */
496 GST_LOG ("h264 output caps: %" GST_PTR_FORMAT, caps);
497 s = gst_caps_get_structure (caps, 0);
498 fail_unless (gst_structure_has_name (s, "video/x-h264"));
499 fail_unless_structure_field_int_equals (s, "width", 32);
500 fail_unless_structure_field_int_equals (s, "height", 24);
501
502 gst_caps_unref (caps);
503 }
504
505 GST_END_TEST;
506
507 static Suite *
h264parse_packetized_suite(void)508 h264parse_packetized_suite (void)
509 {
510 Suite *s = suite_create (ctx_suite);
511 TCase *tc_chain = tcase_create ("general");
512
513 suite_add_tcase (s, tc_chain);
514 tcase_add_test (tc_chain, test_parse_packetized);
515
516 return s;
517 }
518
GST_START_TEST(test_parse_sei_closedcaptions)519 GST_START_TEST (test_parse_sei_closedcaptions)
520 {
521 GstVideoCaptionMeta *cc;
522 GstHarness *h;
523 GstBuffer *buf;
524
525 const guint8 cc_sei_plus_idr[] = {
526 0x00, 0x00, 0x00, 0x4b, 0x06, 0x04, 0x47, 0xb5, 0x00, 0x31, 0x47, 0x41,
527 0x39, 0x34, 0x03, 0xd4,
528 0xff, 0xfc, 0x80, 0x80, 0xfd, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa, 0x00,
529 0x00, 0xfa, 0x00, 0x00,
530 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
531 0xfa, 0x00, 0x00, 0xfa,
532 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
533 0x00, 0x00, 0xfa, 0x00,
534 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00,
535 0x00, 0xff, 0x80,
536 /* IDR frame (doesn't necessarily match caps) */
537 0x00, 0x00, 0x00, 0x14, 0x65, 0x88, 0x84, 0x00,
538 0x10, 0xff, 0xfe, 0xf6, 0xf0, 0xfe, 0x05, 0x36,
539 0x56, 0x04, 0x50, 0x96, 0x7b, 0x3f, 0x53, 0xe1
540 };
541 const gsize cc_sei_plus_idr_size = sizeof (cc_sei_plus_idr);
542
543 h = gst_harness_new ("h264parse");
544
545 gst_harness_set_src_caps_str (h,
546 "video/x-h264, stream-format=(string)avc, alignment=(string)au,"
547 " codec_data=(buffer)014d4015ffe10017674d4015eca4bf2e0220000003002ee6b28001e2c5b2c001000468ebecb2,"
548 " width=(int)32, height=(int)24, framerate=(fraction)30/1,"
549 " pixel-aspect-ratio=(fraction)1/1");
550
551 buf = gst_buffer_new_and_alloc (cc_sei_plus_idr_size);
552 gst_buffer_fill (buf, 0, cc_sei_plus_idr, cc_sei_plus_idr_size);
553 fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
554
555 buf = gst_harness_pull (h);
556 cc = gst_buffer_get_video_caption_meta (buf);
557 fail_unless (cc != NULL);
558 fail_unless_equals_int (cc->caption_type, GST_VIDEO_CAPTION_TYPE_CEA708_RAW);
559 fail_unless_equals_int (cc->size, 60);
560 fail_unless_equals_int (cc->data[0], 0xfc);
561 fail_unless_equals_int (cc->data[3], 0xfd);
562 gst_buffer_unref (buf);
563
564 gst_harness_teardown (h);
565 }
566
567 GST_END_TEST;
568
569 /*
570 * TODO:
571 * - Both push- and pull-modes need to be tested
572 * * Pull-mode & EOS
573 */
574
575 int
main(int argc,char ** argv)576 main (int argc, char **argv)
577 {
578 int nf = 0;
579
580 Suite *s;
581 SRunner *sr;
582
583 gst_check_init (&argc, &argv);
584
585 /* globabl init test context */
586 ctx_factory = "h264parse";
587 ctx_sink_template = &sinktemplate_bs_nal;
588 ctx_src_template = &srctemplate;
589 ctx_headers[0].data = h264_sps;
590 ctx_headers[0].size = sizeof (h264_sps);
591 ctx_headers[1].data = h264_sei_buffering_period;
592 ctx_headers[1].size = sizeof (h264_sei_buffering_period);
593 ctx_headers[2].data = h264_pps;
594 ctx_headers[2].size = sizeof (h264_pps);
595 ctx_verify_buffer = verify_buffer;
596 ctx_frame_generated = TRUE;
597 /* discard initial sps/pps buffers */
598 ctx_discard = 3;
599 /* no timing info to parse */
600 ctx_no_metadata = TRUE;
601 ctx_codec_data = FALSE;
602
603 h264_codec_data = h264_avc_codec_data;
604 h264_codec_data_size = sizeof (h264_avc_codec_data);
605
606 ctx_suite = "h264parse_to_bs_nal";
607 s = h264parse_suite ();
608 nf += gst_check_run_suite (s, ctx_suite, __FILE__ "_to_bs_nal.c");
609
610 /* setup and tweak to handle bs au output */
611 ctx_suite = "h264parse_to_bs_au";
612 ctx_sink_template = &sinktemplate_bs_au;
613 ctx_verify_buffer = verify_buffer_bs_au;
614 ctx_discard = 0;
615 ctx_frame_generated = FALSE;
616
617 s = h264parse_suite ();
618 nf += gst_check_run_suite (s, ctx_suite, __FILE__ "_to_bs_au.c");
619
620 /* setup and tweak to handle avc au output */
621 ctx_suite = "h264parse_to_avc_au";
622 ctx_sink_template = &sinktemplate_avc_au;
623 ctx_verify_buffer = verify_buffer;
624 ctx_discard = 0;
625 ctx_codec_data = TRUE;
626
627 s = h264parse_suite ();
628 sr = srunner_create (s);
629 srunner_run_all (sr, CK_NORMAL);
630 nf += srunner_ntests_failed (sr);
631 srunner_free (sr);
632
633 /* setup and tweak to handle avc3 au output */
634 h264_codec_data = h264_avc3_codec_data;
635 h264_codec_data_size = sizeof (h264_avc3_codec_data);
636 ctx_suite = "h264parse_to_avc3_au";
637 ctx_sink_template = &sinktemplate_avc3_au;
638 ctx_discard = 0;
639 ctx_codec_data = TRUE;
640
641 s = h264parse_suite ();
642 nf += gst_check_run_suite (s, ctx_suite, __FILE__ "_to_avc3_au.c");
643
644 /* setup and tweak to handle avc packetized input */
645 h264_codec_data = h264_avc_codec_data;
646 h264_codec_data_size = sizeof (h264_avc_codec_data);
647 ctx_suite = "h264parse_packetized";
648 /* turn into separate byte stream NALs */
649 ctx_sink_template = &sinktemplate_bs_nal;
650 /* and ignore inserted codec-data NALs */
651 ctx_discard = 2;
652 ctx_frame_generated = TRUE;
653 /* no more config headers */
654 ctx_headers[0].data = NULL;
655 ctx_headers[1].data = NULL;
656 ctx_headers[2].data = NULL;
657 ctx_headers[0].size = 0;
658 ctx_headers[1].size = 0;
659 ctx_headers[2].size = 0;
660 /* and need adapter buffer check */
661 ctx_verify_buffer = verify_buffer_packetized;
662
663 s = h264parse_packetized_suite ();
664 nf += gst_check_run_suite (s, ctx_suite, __FILE__ "_packetized.c");
665
666 {
667 TCase *tc_chain = tcase_create ("general");
668
669 s = suite_create ("h264parse");
670 suite_add_tcase (s, tc_chain);
671 tcase_add_test (tc_chain, test_parse_sei_closedcaptions);
672 nf += gst_check_run_suite (s, "h264parse", __FILE__);
673 }
674
675 return nf;
676 }
677