1 /* GStreamer
2 *
3 * Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
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., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 #include <gst/gst.h>
25 #include <gst/video/video.h>
26 #include <gst/check/gstcheck.h>
27 #include <gst/check/gstharness.h>
28
29 #include <string.h>
30
31 enum CheckConversionFlags
32 {
33 FLAG_NONE,
34 FLAG_SEND_EOS = 1,
35 };
36
GST_START_TEST(cdp_requires_valid_framerate)37 GST_START_TEST (cdp_requires_valid_framerate)
38 {
39 GstHarness *h;
40 GstBuffer *buffer;
41 GstMapInfo map;
42
43 h = gst_harness_new ("ccconverter");
44
45 /* Enforce conversion to CDP */
46 gst_harness_set_sink_caps_str (h,
47 "closedcaption/x-cea-708,format=(string)cdp");
48
49 /* Try without a framerate first, this has to fail */
50 gst_harness_set_src_caps_str (h,
51 "closedcaption/x-cea-708,format=(string)cc_data");
52
53 buffer = gst_buffer_new_and_alloc (3);
54 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
55 map.data[0] = 0xfc;
56 map.data[1] = 0x80;
57 map.data[2] = 0x80;
58 gst_buffer_unmap (buffer, &map);
59 fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
60 GST_FLOW_NOT_NEGOTIATED);
61
62 /* Now set a framerate only on the sink caps, this should still fail:
63 * We can't come up with a framerate
64 */
65 gst_harness_set_sink_caps_str (h,
66 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1");
67
68 fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
69 GST_FLOW_NOT_NEGOTIATED);
70
71 /* Then try with a change of framerate, this should work */
72 gst_harness_set_sink_caps_str (h,
73 "closedcaption/x-cea-708,format=(string)cdp");
74 gst_harness_set_src_caps_str (h,
75 "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1");
76
77 fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
78 GST_FLOW_OK);
79
80 /* Then try with an invalid CDP framerate, this should fail */
81 gst_harness_set_sink_caps_str (h,
82 "closedcaption/x-cea-708,format=(string)cdp");
83 gst_harness_set_src_caps_str (h,
84 "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)29/1");
85
86 fail_unless_equals_int (gst_harness_push (h, buffer),
87 GST_FLOW_NOT_NEGOTIATED);
88
89 gst_harness_teardown (h);
90 }
91
92 GST_END_TEST;
93
GST_START_TEST(framerate_passthrough)94 GST_START_TEST (framerate_passthrough)
95 {
96 GstHarness *h;
97 GstBuffer *buffer;
98 GstMapInfo map;
99 GstCaps *caps, *expected_caps;
100
101 h = gst_harness_new ("ccconverter");
102
103 gst_harness_set_src_caps_str (h,
104 "closedcaption/x-cea-608,format=(string)s334-1a,framerate=(fraction)30/1");
105
106 gst_harness_set_sink_caps_str (h,
107 "closedcaption/x-cea-708,format=(string)cc_data");
108
109 buffer = gst_buffer_new_and_alloc (3);
110 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
111 map.data[0] = 0x00;
112 map.data[1] = 0x80;
113 map.data[2] = 0x80;
114 gst_buffer_unmap (buffer, &map);
115
116 fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
117 GST_FLOW_OK);
118
119 caps = gst_pad_get_current_caps (h->sinkpad);
120 fail_unless (caps);
121 expected_caps =
122 gst_caps_from_string
123 ("closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1");
124 gst_check_caps_equal (caps, expected_caps);
125 gst_caps_unref (caps);
126 gst_caps_unref (expected_caps);
127
128 /* Now try between the same formats, should still pass through */
129 gst_harness_set_src_caps_str (h,
130 "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1");
131
132 gst_harness_set_sink_caps_str (h,
133 "closedcaption/x-cea-708,format=(string)cc_data");
134
135 fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
136 GST_FLOW_OK);
137
138 caps = gst_pad_get_current_caps (h->sinkpad);
139 fail_unless (caps);
140 expected_caps =
141 gst_caps_from_string
142 ("closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1");
143 gst_check_caps_equal (caps, expected_caps);
144 gst_caps_unref (caps);
145 gst_caps_unref (expected_caps);
146
147 /* And another time with the same format but only framerate on the output
148 * side. This should fail as we can't just come up with a framerate! */
149 gst_harness_set_src_caps_str (h,
150 "closedcaption/x-cea-708,format=(string)cc_data");
151
152 gst_harness_set_sink_caps_str (h,
153 "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1");
154
155 fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
156 GST_FLOW_NOT_NEGOTIATED);
157
158 /* Now try cdp -> cc_data with framerate passthrough */
159 gst_harness_set_src_caps_str (h,
160 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1");
161
162 gst_harness_set_sink_caps_str (h,
163 "closedcaption/x-cea-708,format=(string)cc_data");
164
165 fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
166 GST_FLOW_OK);
167
168 gst_buffer_unref (buffer);
169 gst_harness_teardown (h);
170 }
171
172 GST_END_TEST;
173
GST_START_TEST(framerate_changes)174 GST_START_TEST (framerate_changes)
175 {
176 GstHarness *h;
177 GstBuffer *buffer;
178 GstMapInfo map;
179
180 h = gst_harness_new ("ccconverter");
181
182 buffer = gst_buffer_new_and_alloc (3);
183 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
184 map.data[0] = 0x00;
185 map.data[1] = 0x80;
186 map.data[2] = 0x80;
187 gst_buffer_unmap (buffer, &map);
188
189 /* success case */
190 gst_harness_set_src_caps_str (h,
191 "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1");
192 gst_harness_set_sink_caps_str (h,
193 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1");
194 fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
195 GST_FLOW_OK);
196
197 /* test an invalid cdp framerate */
198 gst_harness_set_sink_caps_str (h,
199 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)1111/1");
200 fail_unless_equals_int (gst_harness_push (h, buffer),
201 GST_FLOW_NOT_NEGOTIATED);
202
203 gst_harness_teardown (h);
204 }
205
206 GST_END_TEST;
207
GST_START_TEST(framerate_invalid_format)208 GST_START_TEST (framerate_invalid_format)
209 {
210 GstHarness *h;
211 GstBuffer *buffer;
212 GstMapInfo map;
213 guint i, j;
214
215 const gchar *failure_caps[] = {
216 /* all of these combinations should fail with different framerates */
217 "closedcaption/x-cea-608,format=(string)raw",
218 "closedcaption/x-cea-608,format=(string)s334-1a",
219 "closedcaption/x-cea-708,format=(string)cc_data",
220 };
221
222 h = gst_harness_new ("ccconverter");
223
224 buffer = gst_buffer_new_and_alloc (3);
225 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
226 map.data[0] = 0x00;
227 map.data[1] = 0x80;
228 map.data[2] = 0x80;
229 gst_buffer_unmap (buffer, &map);
230
231 /* framerate conversion failure cases */
232 for (i = 0; i < G_N_ELEMENTS (failure_caps); i++) {
233 for (j = 0; j < G_N_ELEMENTS (failure_caps); j++) {
234 gchar *srccaps, *sinkcaps;
235
236 srccaps =
237 g_strdup_printf ("%s%s", failure_caps[i],
238 ",framerate=(fraction)30/1");
239 sinkcaps =
240 g_strdup_printf ("%s%s", failure_caps[i],
241 ",framerate=(fraction)60/1");
242
243 GST_INFO ("attempting conversion from %s", srccaps);
244 GST_INFO (" to %s", sinkcaps);
245
246 gst_harness_set_src_caps_str (h, srccaps);
247 gst_harness_set_sink_caps_str (h, sinkcaps);
248 fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
249 GST_FLOW_NOT_NEGOTIATED);
250
251 g_free (srccaps);
252 g_free (sinkcaps);
253 }
254 }
255
256 gst_buffer_unref (buffer);
257 gst_harness_teardown (h);
258 }
259
260 GST_END_TEST;
261
262 static void
check_conversion_multiple(guint n_in,const guint8 ** in,guint * in_len,guint n_out,const guint8 ** out,guint * out_len,const gchar * in_caps,const gchar * out_caps,const GstVideoTimeCode ** in_tc,const GstVideoTimeCode ** out_tc,enum CheckConversionFlags flags)263 check_conversion_multiple (guint n_in, const guint8 ** in, guint * in_len,
264 guint n_out, const guint8 ** out, guint * out_len, const gchar * in_caps,
265 const gchar * out_caps, const GstVideoTimeCode ** in_tc,
266 const GstVideoTimeCode ** out_tc, enum CheckConversionFlags flags)
267 {
268 GstHarness *h;
269 GstBuffer *buffer;
270 GstVideoTimeCodeMeta *out_tc_meta;
271 int i = 0;
272
273 h = gst_harness_new ("ccconverter");
274
275 gst_harness_set_src_caps_str (h, in_caps);
276 gst_harness_set_sink_caps_str (h, out_caps);
277
278 for (i = 0; i < n_in; i++) {
279 buffer =
280 gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, (gpointer) in[i],
281 in_len[i], 0, in_len[i], NULL, NULL);
282 GST_INFO ("pushing buffer %u %" GST_PTR_FORMAT, i, buffer);
283 if (in_tc && in_tc[i])
284 gst_buffer_add_video_time_code_meta (buffer, in_tc[i]);
285 fail_unless_equals_int (gst_harness_push (h, buffer), GST_FLOW_OK);
286 }
287
288 if (flags & FLAG_SEND_EOS)
289 fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
290
291 for (i = 0; i < n_out; i++) {
292 buffer = gst_harness_pull (h);
293
294 GST_INFO ("pulled buffer %u %" GST_PTR_FORMAT, i, buffer);
295 fail_unless (buffer != NULL);
296 gst_check_buffer_data (buffer, out[i], out_len[i]);
297 out_tc_meta = gst_buffer_get_video_time_code_meta (buffer);
298 fail_if (out_tc_meta == NULL && out_tc != NULL && out_tc[i] != NULL);
299 if (out_tc_meta && out_tc && out_tc[i])
300 fail_unless (gst_video_time_code_compare (&out_tc_meta->tc,
301 out_tc[i]) == 0);
302
303 gst_buffer_unref (buffer);
304 }
305
306 gst_harness_teardown (h);
307 }
308
309 static void
check_conversion(const guint8 * in,guint in_len,const guint8 * out,guint out_len,const gchar * in_caps,const gchar * out_caps,const GstVideoTimeCode * in_tc,const GstVideoTimeCode * out_tc)310 check_conversion (const guint8 * in, guint in_len, const guint8 * out,
311 guint out_len, const gchar * in_caps, const gchar * out_caps,
312 const GstVideoTimeCode * in_tc, const GstVideoTimeCode * out_tc)
313 {
314 check_conversion_multiple (1, &in, &in_len, 1, &out, &out_len, in_caps,
315 out_caps, &in_tc, &out_tc, 0);
316 }
317
318 static void
check_conversion_tc_passthrough(const guint8 * in,guint in_len,const guint8 * out,guint out_len,const gchar * in_caps,const gchar * out_caps)319 check_conversion_tc_passthrough (const guint8 * in, guint in_len,
320 const guint8 * out, guint out_len, const gchar * in_caps,
321 const gchar * out_caps)
322 {
323 GstVideoTimeCode tc;
324 gst_video_time_code_init (&tc, 30, 1, NULL, GST_VIDEO_TIME_CODE_FLAGS_NONE,
325 1, 2, 3, 4, 0);
326 check_conversion (in, in_len, out, out_len, in_caps, out_caps, &tc, &tc);
327 gst_video_time_code_clear (&tc);
328 }
329
GST_START_TEST(convert_cea608_raw_cea608_s334_1a)330 GST_START_TEST (convert_cea608_raw_cea608_s334_1a)
331 {
332 const guint8 in[] = { 0x80, 0x80 };
333 const guint8 out[] = { 0x80, 0x80, 0x80 };
334 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
335 "closedcaption/x-cea-608,format=(string)raw",
336 "closedcaption/x-cea-608,format=(string)s334-1a");
337 }
338
339 GST_END_TEST;
340
GST_START_TEST(convert_cea608_raw_cea708_cc_data)341 GST_START_TEST (convert_cea608_raw_cea708_cc_data)
342 {
343 const guint8 in[] = { 0x80, 0x80 };
344 const guint8 out[] = { 0xfc, 0x80, 0x80 };
345 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
346 "closedcaption/x-cea-608,format=(string)raw",
347 "closedcaption/x-cea-708,format=(string)cc_data");
348 }
349
350 GST_END_TEST;
351
GST_START_TEST(convert_cea608_raw_cea708_cdp)352 GST_START_TEST (convert_cea608_raw_cea708_cdp)
353 {
354 const guint8 in[] = { 0x80, 0x80 };
355 const guint8 out[] =
356 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x80, 0x80,
357 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
358 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
359 0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x6e
360 };
361 check_conversion (in, sizeof (in), out, sizeof (out),
362 "closedcaption/x-cea-608,format=(string)raw,framerate=(fraction)60/1",
363 "closedcaption/x-cea-708,format=(string)cdp", NULL, NULL);
364 }
365
366 GST_END_TEST;
367
GST_START_TEST(convert_cea608_s334_1a_cea608_raw)368 GST_START_TEST (convert_cea608_s334_1a_cea608_raw)
369 {
370 const guint8 in[] = { 0x80, 0x80, 0x80, 0x00, 0x80, 0x80 };
371 const guint8 out[] = { 0x80, 0x80 };
372 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
373 "closedcaption/x-cea-608,format=(string)s334-1a",
374 "closedcaption/x-cea-608,format=(string)raw");
375 }
376
377 GST_END_TEST;
378
GST_START_TEST(convert_cea608_s334_1a_cea608_raw_too_big)379 GST_START_TEST (convert_cea608_s334_1a_cea608_raw_too_big)
380 {
381 const guint8 in[] =
382 { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80,
383 0x80
384 };
385 const guint8 out[] = { 0x80, 0x80, 0x80, 0x80 };
386 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
387 "closedcaption/x-cea-608,format=(string)s334-1a",
388 "closedcaption/x-cea-608,format=(string)raw");
389 }
390
391 GST_END_TEST;
392
GST_START_TEST(convert_cea608_s334_1a_cea708_cc_data)393 GST_START_TEST (convert_cea608_s334_1a_cea708_cc_data)
394 {
395 const guint8 in[] = { 0x80, 0x80, 0x80, 0x00, 0x80, 0x80 };
396 const guint8 out[] = { 0xfc, 0x80, 0x80, 0xfd, 0x80, 0x80 };
397 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
398 "closedcaption/x-cea-608,format=(string)s334-1a",
399 "closedcaption/x-cea-708,format=(string)cc_data");
400 }
401
402 GST_END_TEST;
403
GST_START_TEST(convert_cea608_s334_1a_cea708_cdp)404 GST_START_TEST (convert_cea608_s334_1a_cea708_cdp)
405 {
406 const guint8 in[] = { 0x80, 0x80, 0x80, 0x00, 0x80, 0x80 };
407 const guint8 out[] =
408 { 0x96, 0x69, 0x49, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xf4, 0xfc, 0x80, 0x80,
409 0xfd, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
410 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
411 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
412 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
413 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0xaf
414 };
415 check_conversion (in, sizeof (in), out, sizeof (out),
416 "closedcaption/x-cea-608,format=(string)s334-1a,framerate=(fraction)30/1",
417 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
418 NULL, NULL);
419 }
420
421 GST_END_TEST;
422
GST_START_TEST(convert_cea708_cc_data_cea608_raw)423 GST_START_TEST (convert_cea708_cc_data_cea608_raw)
424 {
425 const guint8 in[] = { 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80 };
426 const guint8 out[] = { 0x80, 0x80 };
427 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
428 "closedcaption/x-cea-708,format=(string)cc_data",
429 "closedcaption/x-cea-608,format=(string)raw");
430 }
431
432 GST_END_TEST;
433
GST_START_TEST(convert_cea708_cc_data_cea608_s334_1a)434 GST_START_TEST (convert_cea708_cc_data_cea608_s334_1a)
435 {
436 const guint8 in[] = { 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80 };
437 const guint8 out[] = { 0x80, 0x80, 0x80 };
438 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
439 "closedcaption/x-cea-708,format=(string)cc_data",
440 "closedcaption/x-cea-608,format=(string)s334-1a");
441 }
442
443 GST_END_TEST;
444
GST_START_TEST(convert_cea708_cc_data_cea708_cdp)445 GST_START_TEST (convert_cea708_cc_data_cea708_cdp)
446 {
447 const guint8 in[] = { 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80 };
448 const guint8 out[] =
449 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x80, 0x80,
450 0xfe, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
451 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
452 0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x6a
453 };
454 check_conversion (in, sizeof (in), out, sizeof (out),
455 "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)60/1",
456 "closedcaption/x-cea-708,format=(string)cdp", NULL, NULL);
457 }
458
459 GST_END_TEST;
460
GST_START_TEST(convert_cea708_cdp_cea608_raw)461 GST_START_TEST (convert_cea708_cdp_cea608_raw)
462 {
463 const guint8 in[] =
464 { 0x96, 0x69, 0x13, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xe2, 0xfc, 0x80, 0x80,
465 0xfe, 0x80, 0x80, 0x74, 0x00, 0x00, 0x8a
466 };
467 const guint8 out[] = { 0x80, 0x80 };
468 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
469 "closedcaption/x-cea-708,format=(string)cdp",
470 "closedcaption/x-cea-608,format=(string)raw");
471 }
472
473 GST_END_TEST;
474
GST_START_TEST(convert_cea708_cdp_cea608_s334_1a)475 GST_START_TEST (convert_cea708_cdp_cea608_s334_1a)
476 {
477 const guint8 in[] =
478 { 0x96, 0x69, 0x13, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xe2, 0xfc, 0x80, 0x80,
479 0xfe, 0x80, 0x80, 0x74, 0x00, 0x00, 0x8a
480 };
481 const guint8 out[] = { 0x80, 0x80, 0x80 };
482 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
483 "closedcaption/x-cea-708,format=(string)cdp",
484 "closedcaption/x-cea-608,format=(string)s334-1a");
485 }
486
487 GST_END_TEST;
488
GST_START_TEST(convert_cea708_cdp_cea708_cc_data)489 GST_START_TEST (convert_cea708_cdp_cea708_cc_data)
490 {
491 const guint8 in[] =
492 { 0x96, 0x69, 0x13, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xe2, 0xfc, 0x80, 0x80,
493 0xfe, 0x80, 0x80, 0x74, 0x00, 0x00, 0x8a
494 };
495 const guint8 out[] = { 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80 };
496 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
497 "closedcaption/x-cea-708,format=(string)cdp",
498 "closedcaption/x-cea-708,format=(string)cc_data");
499 }
500
501 GST_END_TEST;
502
GST_START_TEST(convert_cea708_cdp_cea708_cc_data_too_big)503 GST_START_TEST (convert_cea708_cdp_cea708_cc_data_too_big)
504 {
505 /* tests that too large input is truncated */
506 const guint8 in[] =
507 { 0x96, 0x69, 0x2e, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xeb, 0xfc, 0x80, 0x80,
508 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80,
509 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80,
510 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0x74, 0x00, 0x00, 0x8a,
511 };
512 const guint8 out[] = { 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80,
513 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80,
514 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80
515 };
516 check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
517 "closedcaption/x-cea-708,format=(string)cdp",
518 "closedcaption/x-cea-708,format=(string)cc_data");
519 }
520
521 GST_END_TEST;
522
GST_START_TEST(convert_cea708_cdp_cea708_cdp_double_framerate)523 GST_START_TEST (convert_cea708_cdp_cea708_cdp_double_framerate)
524 {
525 /* tests that packets are split exactly in half when doubling the framerate */
526 const guint8 in1[] =
527 { 0x96, 0x69, 0x49, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xf4, 0xfc, 0x01, 0x02,
528 0xfc, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
529 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12,
530 0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0xfe, 0x19, 0x1a,
531 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e, 0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22,
532 0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26, 0xfe, 0x27, 0x28, 0x74, 0x00, 0x00, 0xd2
533 };
534 const guint8 *in[] = { in1 };
535 guint in_len[] = { sizeof (in1) };
536 GstVideoTimeCode in_tc1;
537 const GstVideoTimeCode *in_tc[] = { &in_tc1 };
538
539 const guint8 out1[] = { 0x96, 0x69, 0x30, 0x8f, 0xc3, 0x00, 0x00, 0x71, 0xc1,
540 0x82, 0x03, 0x08, 0x72, 0xea, 0xfc, 0x01, 0x02, 0xfe, 0x05, 0x06, 0xfe,
541 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe,
542 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16, 0x74,
543 0x00, 0x00, 0x10
544 };
545 const guint8 out2[] = { 0x96, 0x69, 0x30, 0x8f, 0xc3, 0x00, 0x01, 0x71, 0xc1,
546 0x82, 0x03, 0x09, 0x72, 0xea, 0xfc, 0x03, 0x04, 0xfe, 0x17, 0x18, 0xfe,
547 0x19, 0x1a, 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e, 0xfe, 0x1f, 0x20, 0xfe,
548 0x21, 0x22, 0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26, 0xfe, 0x27, 0x28, 0x74,
549 0x00, 0x01, 0xc5
550 };
551 const guint8 *out[] = { out1, out2 };
552 guint out_len[] = { sizeof (out1), sizeof (out2) };
553 GstVideoTimeCode out_tc1, out_tc2;
554 const GstVideoTimeCode *out_tc[] = { &out_tc1, &out_tc2 };
555
556 gst_video_time_code_init (&in_tc1, 30, 1, NULL,
557 GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 4, 0);
558 fail_unless (gst_video_time_code_is_valid (&in_tc1));
559
560 gst_video_time_code_init (&out_tc1, 60, 1, NULL,
561 GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 8, 0);
562 fail_unless (gst_video_time_code_is_valid (&out_tc1));
563 gst_video_time_code_init (&out_tc2, 60, 1, NULL,
564 GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 9, 0);
565 fail_unless (gst_video_time_code_is_valid (&out_tc2));
566
567 check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
568 G_N_ELEMENTS (out_len), out, out_len,
569 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
570 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
571 in_tc, out_tc, 0);
572
573 gst_video_time_code_clear (&in_tc1);
574 gst_video_time_code_clear (&out_tc1);
575 gst_video_time_code_clear (&out_tc2);
576 }
577
578 GST_END_TEST;
579
GST_START_TEST(convert_cea708_cdp_cea708_cdp_half_framerate)580 GST_START_TEST (convert_cea708_cdp_cea708_cdp_half_framerate)
581 {
582 /* tests that two input packets are merged together when halving the
583 * framerate. With cc_data compaction! */
584 const guint8 in1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
585 0xfc, 0x01, 0x02, 0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08,
586 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10,
587 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0x74, 0x00, 0x00, 0x7a
588 };
589 const guint8 in2[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea,
590 0xfc, 0x14, 0x15, 0xfe, 0x16, 0x17, 0xfe, 0x18, 0x19, 0xfe, 0x1a, 0x1b,
591 0xfe, 0x1c, 0x1d, 0xfe, 0x1e, 0x1f, 0xfe, 0x20, 0x21, 0xfe, 0x22, 0x23,
592 0xfe, 0x24, 0x25, 0xfe, 0x26, 0x27, 0x74, 0x00, 0x01, 0x70
593 };
594 const guint8 *in[] = { in1, in2 };
595 guint in_len[] = { sizeof (in1), sizeof (in2) };
596 GstVideoTimeCode in_tc1, in_tc2;
597 const GstVideoTimeCode *in_tc[] = { &in_tc1, &in_tc2 };
598
599 const guint8 out1[] =
600 { 0x96, 0x69, 0x4e, 0x5f, 0xc3, 0x00, 0x00, 0x71, 0xc1, 0x82, 0x03, 0x04,
601 0x72, 0xf4, 0xfc, 0x01, 0x02, 0xfc, 0x14, 0x15, 0xfe, 0x03, 0x04, 0xfe,
602 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe,
603 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe,
604 0x16, 0x17, 0xfe, 0x18, 0x19, 0xfe, 0x1a, 0x1b, 0xfe, 0x1c, 0x1d, 0xfe,
605 0x1e, 0x1f, 0xfe, 0x20, 0x21, 0xfe, 0x22, 0x23, 0xfe, 0x24, 0x25, 0xfe,
606 0x26, 0x27, 0x74, 0x00, 0x00, 0x08
607 };
608 const guint8 *out[] = { out1 };
609 guint out_len[] = { sizeof (out1) };
610 GstVideoTimeCode out_tc1;
611 const GstVideoTimeCode *out_tc[] = { &out_tc1 };
612
613 gst_video_time_code_init (&in_tc1, 60, 1, NULL,
614 GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 8, 0);
615 fail_unless (gst_video_time_code_is_valid (&in_tc1));
616 gst_video_time_code_init (&in_tc2, 60, 1, NULL,
617 GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 8, 0);
618 fail_unless (gst_video_time_code_is_valid (&in_tc2));
619
620 gst_video_time_code_init (&out_tc1, 30, 1, NULL,
621 GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 4, 0);
622 fail_unless (gst_video_time_code_is_valid (&out_tc1));
623
624 check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
625 G_N_ELEMENTS (out_len), out, out_len,
626 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
627 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
628 in_tc, out_tc, 0);
629
630 gst_video_time_code_clear (&in_tc1);
631 gst_video_time_code_clear (&in_tc2);
632 gst_video_time_code_clear (&out_tc1);
633 }
634
635 GST_END_TEST;
636
GST_START_TEST(convert_cea708_cdp_cea708_cdp_max_merge)637 GST_START_TEST (convert_cea708_cdp_cea708_cdp_max_merge)
638 {
639 /* check that 3 high framerate packets can be merged into 1 low framerate
640 * packets with the extra data on the third input packet being placed at the
641 * beginning of the second output packet */
642 const guint8 in1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
643 0xfc, 0x01, 0x02, 0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08,
644 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10,
645 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0x74, 0x00, 0x00, 0x7a
646 };
647 /* enough input to fully cover two output packets. Extra is discarded */
648 const guint8 *in[] = { in1, in1, in1, in1, in1, in1, in1 };
649 guint in_len[] =
650 { sizeof (in1), sizeof (in1), sizeof (in1), sizeof (in1), sizeof (in1),
651 sizeof (in1)
652 };
653
654 const guint8 out1[] =
655 { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x00, 0x72, 0xf9, 0xfc, 0x01, 0x02,
656 0xfc, 0x01, 0x02, 0xfc, 0x01, 0x02, 0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06,
657 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e,
658 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe, 0x03, 0x04,
659 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
660 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14,
661 0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
662 0x74, 0x00, 0x00, 0xc5
663 };
664 const guint8 out2[] =
665 { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x01, 0x72, 0xf9, 0xfc, 0x01, 0x02,
666 0xfc, 0x01, 0x02, 0xfc, 0x01, 0x02, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e,
667 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe, 0x03, 0x04,
668 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
669 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14,
670 0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
671 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12,
672 0x74, 0x00, 0x01, 0x83
673 };
674 const guint8 *out[] = { out1, out2 };
675 guint out_len[] = { sizeof (out1), sizeof (out2) };
676 check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
677 G_N_ELEMENTS (out_len), out, out_len,
678 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
679 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)24000/1001",
680 NULL, NULL, 0);
681 }
682
683 GST_END_TEST;
684
GST_START_TEST(convert_cea708_cdp_cea708_cdp_max_split)685 GST_START_TEST (convert_cea708_cdp_cea708_cdp_max_split)
686 {
687 /* test that a low framerate stream produces multiple output packets for a
688 * high framerate */
689 const guint8 in1[] =
690 { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x00, 0x72, 0xf9, 0xfc, 0x01, 0x02,
691 0xfc, 0x03, 0x04, 0xfc, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
692 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12,
693 0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0xfe, 0x19, 0x1a,
694 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e, 0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22,
695 0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26, 0xfe, 0x27, 0x28, 0xfe, 0x29, 0x2a,
696 0xfe, 0x2b, 0x2c, 0xfe, 0x2d, 0x2e, 0xfe, 0x2f, 0x30, 0xfe, 0x31, 0x32,
697 0x74, 0x00, 0x00, 0x12
698 };
699 const guint8 *in[] = { in1, in1 };
700 guint in_len[] = { sizeof (in1), sizeof (in1) };
701
702 const guint8 out1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
703 0xfc, 0x01, 0x02, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
704 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14,
705 0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0x74, 0x00, 0x00, 0x30
706 };
707 const guint8 out2[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea,
708 0xfc, 0x03, 0x04, 0xfe, 0x19, 0x1a, 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e,
709 0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22, 0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26,
710 0xfe, 0x27, 0x28, 0xfe, 0x29, 0x2a, 0x74, 0x00, 0x01, 0xe6
711 };
712 const guint8 out3[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea,
713 0xfc, 0x05, 0x06, 0xfe, 0x2b, 0x2c, 0xfe, 0x2d, 0x2e, 0xfe, 0x2f, 0x30,
714 0xfe, 0x31, 0x32, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
715 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0x74, 0x00, 0x02, 0x54
716 };
717 const guint8 out4[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea,
718 0xfc, 0x01, 0x02, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16,
719 0xfe, 0x17, 0x18, 0xfe, 0x19, 0x1a, 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e,
720 0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22, 0x74, 0x00, 0x03, 0x76
721 };
722 const guint8 *out[] = { out1, out2, out3, out4 };
723 guint out_len[] =
724 { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4) };
725 check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
726 G_N_ELEMENTS (out_len), out, out_len,
727 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)24000/1001",
728 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
729 NULL, NULL, 0);
730 }
731
732 GST_END_TEST;
733
GST_START_TEST(convert_cea708_cdp_cea708_cdp_max_split_eos)734 GST_START_TEST (convert_cea708_cdp_cea708_cdp_max_split_eos)
735 {
736 /* test that a low framerate stream produces multiple output packets for a
737 * high framerate and that an EOS will push the pending data */
738 const guint8 in1[] =
739 { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x00, 0x72, 0xf9, 0xfc, 0x01, 0x02,
740 0xfc, 0x03, 0x04, 0xfc, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
741 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12,
742 0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0xfe, 0x19, 0x1a,
743 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e, 0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22,
744 0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26, 0xfe, 0x27, 0x28, 0xfe, 0x29, 0x2a,
745 0xfe, 0x2b, 0x2c, 0xfe, 0x2d, 0x2e, 0xfe, 0x2f, 0x30, 0xfe, 0x31, 0x32,
746 0x74, 0x00, 0x00, 0x12
747 };
748 const guint8 *in[] = { in1 };
749 guint in_len[] = { sizeof (in1) };
750
751 const guint8 out1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
752 0xfc, 0x01, 0x02, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
753 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14,
754 0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0x74, 0x00, 0x00, 0x30
755 };
756 const guint8 out2[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea,
757 0xfc, 0x03, 0x04, 0xfe, 0x19, 0x1a, 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e,
758 0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22, 0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26,
759 0xfe, 0x27, 0x28, 0xfe, 0x29, 0x2a, 0x74, 0x00, 0x01, 0xe6
760 };
761 const guint8 out3[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea,
762 0xfc, 0x05, 0x06, 0xfe, 0x2b, 0x2c, 0xfe, 0x2d, 0x2e, 0xfe, 0x2f, 0x30,
763 0xfe, 0x31, 0x32, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
764 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0xdb
765 };
766 const guint8 *out[] = { out1, out2, out3 };
767 guint out_len[] = { sizeof (out1), sizeof (out2), sizeof (out3) };
768
769 check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
770 G_N_ELEMENTS (out_len), out, out_len,
771 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)24000/1001",
772 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
773 NULL, NULL, FLAG_SEND_EOS);
774 }
775
776 GST_END_TEST;
777
GST_START_TEST(convert_cea708_cdp_cea708_cdp_from_drop_frame_scaling)778 GST_START_TEST (convert_cea708_cdp_cea708_cdp_from_drop_frame_scaling)
779 {
780 const guint8 in1[] = { 0x96, 0x69, 0x10, 0x7f, 0x43, 0x00, 0x00, 0x72, 0xe1,
781 0xfc, 0x80, 0x80, 0x74, 0x00, 0x00, 0x7a
782 };
783 const guint8 *in[] = { in1, in1 };
784 guint in_len[] = { sizeof (in1), sizeof (in1) };
785 GstVideoTimeCode in_tc1, in_tc2;
786 const GstVideoTimeCode *in_tc[] = { &in_tc1, &in_tc2 };
787
788 const guint8 out1[] =
789 { 0x96, 0x69, 0x4e, 0x5f, 0xc3, 0x00, 0x00, 0x71, 0xc0, 0x81, 0x59, 0x29,
790 0x72, 0xf4, 0xfc, 0x80, 0x80, 0xf8, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa,
791 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
792 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
793 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
794 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
795 0x00, 0x00, 0x74, 0x00, 0x00, 0xfb
796 };
797 const guint8 out2[] =
798 { 0x96, 0x69, 0x4e, 0x5f, 0xc3, 0x00, 0x01, 0x71, 0xc0, 0x82, 0x00, 0x00,
799 0x72, 0xf4, 0xfc, 0x80, 0x80, 0xf8, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa,
800 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
801 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
802 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
803 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
804 0x00, 0x00, 0x74, 0x00, 0x01, 0x7a
805 };
806 const guint8 *out[] = { out1, out2 };
807 guint out_len[] = { sizeof (out1), sizeof (out2) };
808 GstVideoTimeCode out_tc1, out_tc2;
809 const GstVideoTimeCode *out_tc[] = { &out_tc1, &out_tc2 };
810
811 gst_video_time_code_init (&in_tc1, 30000, 1001, NULL,
812 GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0, 1, 59, 29, 0);
813 fail_unless (gst_video_time_code_is_valid (&in_tc1));
814
815 gst_video_time_code_init (&in_tc2, 30000, 1001, NULL,
816 GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0, 2, 0, 4, 0);
817 fail_unless (gst_video_time_code_is_valid (&in_tc2));
818
819 gst_video_time_code_init (&out_tc1, 30, 1, NULL,
820 GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 1, 59, 29, 0);
821 fail_unless (gst_video_time_code_is_valid (&out_tc1));
822
823 gst_video_time_code_init (&out_tc2, 30, 1, NULL,
824 GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 2, 0, 0, 0);
825 fail_unless (gst_video_time_code_is_valid (&out_tc2));
826
827 check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
828 G_N_ELEMENTS (out_len), out, out_len,
829 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30000/1001",
830 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
831 in_tc, out_tc, FLAG_SEND_EOS);
832
833 gst_video_time_code_clear (&in_tc1);
834 gst_video_time_code_clear (&out_tc1);
835 }
836
837 GST_END_TEST;
838
GST_START_TEST(convert_cea708_cc_data_cea708_cdp_double_framerate)839 GST_START_TEST (convert_cea708_cc_data_cea708_cdp_double_framerate)
840 {
841 const guint8 in1[] = { 0xfc, 0x80, 0x81, 0xfc, 0x82, 0x83, 0xfe, 0x84, 0x85 };
842 const guint8 in2[] = { 0xfc, 0x86, 0x87, 0xfc, 0x88, 0x89, 0xfe, 0x8a, 0x8b };
843 const guint8 *in[] = { in1, in2 };
844 guint in_len[] = { sizeof (in1), sizeof (in2) };
845 const guint8 out1[] =
846 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x80, 0x81,
847 0xfe, 0x84, 0x85, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
848 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
849 0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x60
850 };
851 const guint8 out2[] =
852 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea, 0xfc, 0x82, 0x83,
853 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
854 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
855 0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0x67
856 };
857 const guint8 out3[] =
858 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea, 0xfc, 0x86, 0x87,
859 0xfe, 0x8a, 0x8b, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
860 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
861 0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0x44
862 };
863 const guint8 out4[] =
864 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea, 0xfc, 0x88, 0x89,
865 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
866 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
867 0xfa, 0x00, 0x00, 0x74, 0x00, 0x03, 0x57
868 };
869 const guint8 *out[] = { out1, out2, out3, out4, };
870 guint out_len[] =
871 { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4), };
872 check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
873 G_N_ELEMENTS (out_len), out, out_len,
874 "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1",
875 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
876 NULL, NULL, 0);
877 }
878
879 GST_END_TEST;
880
GST_START_TEST(convert_cea608_raw_cea708_cdp_double_framerate)881 GST_START_TEST (convert_cea608_raw_cea708_cdp_double_framerate)
882 {
883 const guint8 in1[] = { 0x80, 0x81, 0x82, 0x83 };
884 const guint8 in2[] = { 0x84, 0x85, 0x86, 0x87 };
885 const guint8 *in[] = { in1, in2 };
886 guint in_len[] = { sizeof (in1), sizeof (in2) };
887 const guint8 out1[] =
888 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x80, 0x81,
889 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
890 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
891 0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x6d
892 };
893 const guint8 out2[] =
894 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea, 0xfc, 0x82, 0x83,
895 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
896 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
897 0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0x67
898 };
899 const guint8 out3[] =
900 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea, 0xfc, 0x84, 0x85,
901 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
902 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
903 0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0x61
904 };
905 const guint8 out4[] =
906 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea, 0xfc, 0x86, 0x87,
907 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
908 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
909 0xfa, 0x00, 0x00, 0x74, 0x00, 0x03, 0x5b
910 };
911 const guint8 *out[] = { out1, out2, out3, out4, };
912 guint out_len[] =
913 { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4), };
914 check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
915 G_N_ELEMENTS (out_len), out, out_len,
916 "closedcaption/x-cea-608,format=(string)raw,framerate=(fraction)30/1",
917 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
918 NULL, NULL, 0);
919 }
920
921 GST_END_TEST;
922
GST_START_TEST(convert_cea608_s334_1a_cea708_cdp_double_framerate)923 GST_START_TEST (convert_cea608_s334_1a_cea708_cdp_double_framerate)
924 {
925 const guint8 in1[] = { 0x80, 0x80, 0x81, 0x00, 0x82, 0x83 };
926 const guint8 in2[] = { 0x80, 0x84, 0x85, 0x00, 0x86, 0x87 };
927 const guint8 *in[] = { in1, in2 };
928 guint in_len[] = { sizeof (in1), sizeof (in2) };
929 const guint8 out1[] =
930 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x80, 0x81,
931 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
932 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
933 0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x6d
934 };
935 const guint8 out2[] =
936 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea, 0xfd, 0x82, 0x83,
937 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
938 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
939 0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0x66
940 };
941 const guint8 out3[] =
942 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea, 0xfc, 0x84, 0x85,
943 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
944 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
945 0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0x61
946 };
947 const guint8 out4[] =
948 { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea, 0xfd, 0x86, 0x87,
949 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
950 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
951 0xfa, 0x00, 0x00, 0x74, 0x00, 0x03, 0x5a
952 };
953 const guint8 *out[] = { out1, out2, out3, out4, };
954 guint out_len[] =
955 { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4), };
956 check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
957 G_N_ELEMENTS (out_len), out, out_len,
958 "closedcaption/x-cea-608,format=(string)s334-1a,framerate=(fraction)30/1",
959 "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
960 NULL, NULL, 0);
961 }
962
963 GST_END_TEST;
964
965 static Suite *
ccextractor_suite(void)966 ccextractor_suite (void)
967 {
968 Suite *s = suite_create ("ccconverter");
969 TCase *tc = tcase_create ("general");
970
971 suite_add_tcase (s, tc);
972
973 tcase_add_test (tc, cdp_requires_valid_framerate);
974 tcase_add_test (tc, framerate_passthrough);
975 tcase_add_test (tc, framerate_changes);
976 tcase_add_test (tc, framerate_invalid_format);
977 tcase_add_test (tc, convert_cea608_raw_cea608_s334_1a);
978 tcase_add_test (tc, convert_cea608_raw_cea708_cc_data);
979 tcase_add_test (tc, convert_cea608_raw_cea708_cdp);
980 tcase_add_test (tc, convert_cea608_s334_1a_cea608_raw);
981 tcase_add_test (tc, convert_cea608_s334_1a_cea608_raw_too_big);
982 tcase_add_test (tc, convert_cea608_s334_1a_cea708_cc_data);
983 tcase_add_test (tc, convert_cea608_s334_1a_cea708_cdp);
984 tcase_add_test (tc, convert_cea708_cc_data_cea608_raw);
985 tcase_add_test (tc, convert_cea708_cc_data_cea608_s334_1a);
986 tcase_add_test (tc, convert_cea708_cc_data_cea708_cdp);
987 tcase_add_test (tc, convert_cea708_cdp_cea608_raw);
988 tcase_add_test (tc, convert_cea708_cdp_cea608_s334_1a);
989 tcase_add_test (tc, convert_cea708_cdp_cea708_cc_data);
990 tcase_add_test (tc, convert_cea708_cdp_cea708_cc_data_too_big);
991 tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_half_framerate);
992 tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_double_framerate);
993 tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_max_merge);
994 tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_max_split);
995 tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_max_split_eos);
996 tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_from_drop_frame_scaling);
997 tcase_add_test (tc, convert_cea708_cc_data_cea708_cdp_double_framerate);
998 tcase_add_test (tc, convert_cea608_raw_cea708_cdp_double_framerate);
999 tcase_add_test (tc, convert_cea608_s334_1a_cea708_cdp_double_framerate);
1000
1001 return s;
1002 }
1003
1004 GST_CHECK_MAIN (ccextractor);
1005