a925087e0af97cea19d5ce2bb41fe00b9672a17b
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / tests / check / elements / ccconverter.c
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
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
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
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
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
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
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
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
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
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
352 GST_START_TEST (convert_cea608_raw_cea708_cdp)
353 {
354   const guint8 in1[] = { 0x81, 0x82 };
355   const guint8 in2[] = { 0x80, 0x80 };
356   const guint8 out1[] =
357       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x81, 0x82,
358     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
359     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
360     0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x6b
361   };
362   const guint8 out2[] =
363       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea, 0xf9, 0x80, 0x80,
364     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
365     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
366     0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0x6f
367   };
368   const guint8 *in[] = { in1, in2 };
369   guint in_len[] = { sizeof (in1), sizeof (in2) };
370   const guint8 *out[] = { out1, out2 };
371   guint out_len[] = { sizeof (out1), sizeof (out2) };
372   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
373       G_N_ELEMENTS (out_len), out, out_len,
374       "closedcaption/x-cea-608,format=(string)raw,framerate=(fraction)60/1",
375       "closedcaption/x-cea-708,format=(string)cdp", NULL, NULL, 0);
376 }
377
378 GST_END_TEST;
379
380 GST_START_TEST (convert_cea608_s334_1a_cea608_raw)
381 {
382   const guint8 in[] = { 0x80, 0x80, 0x80, 0x00, 0x80, 0x80 };
383   const guint8 out[] = { 0x80, 0x80 };
384   check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
385       "closedcaption/x-cea-608,format=(string)s334-1a",
386       "closedcaption/x-cea-608,format=(string)raw");
387 }
388
389 GST_END_TEST;
390
391 GST_START_TEST (convert_cea608_s334_1a_cea608_raw_too_big)
392 {
393   const guint8 in[] =
394       { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80,
395     0x80
396   };
397   const guint8 out[] = { 0x80, 0x80, 0x80, 0x80 };
398   check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
399       "closedcaption/x-cea-608,format=(string)s334-1a",
400       "closedcaption/x-cea-608,format=(string)raw");
401 }
402
403 GST_END_TEST;
404
405 GST_START_TEST (convert_cea608_s334_1a_cea708_cc_data)
406 {
407   const guint8 in[] = { 0x80, 0x80, 0x80, 0x00, 0x80, 0x80 };
408   const guint8 out[] = { 0xfc, 0x80, 0x80, 0xfd, 0x80, 0x80 };
409   check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
410       "closedcaption/x-cea-608,format=(string)s334-1a",
411       "closedcaption/x-cea-708,format=(string)cc_data");
412 }
413
414 GST_END_TEST;
415
416 GST_START_TEST (convert_cea608_s334_1a_cea708_cdp)
417 {
418   const guint8 in[] = { 0x80, 0x80, 0x80, 0x00, 0x80, 0x80 };
419   const guint8 out[] =
420       { 0x96, 0x69, 0x49, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xf4, 0xf8, 0x80, 0x80,
421     0xf9, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
422     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
423     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
424     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
425     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0xb7
426   };
427   check_conversion (in, sizeof (in), out, sizeof (out),
428       "closedcaption/x-cea-608,format=(string)s334-1a,framerate=(fraction)30/1",
429       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
430       NULL, NULL);
431 }
432
433 GST_END_TEST;
434
435 GST_START_TEST (convert_cea708_cc_data_cea608_raw)
436 {
437   const guint8 in[] = { 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80 };
438   const guint8 out[] = { 0x80, 0x80 };
439   check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
440       "closedcaption/x-cea-708,format=(string)cc_data",
441       "closedcaption/x-cea-608,format=(string)raw");
442 }
443
444 GST_END_TEST;
445
446 GST_START_TEST (convert_cea708_cc_data_cea608_s334_1a)
447 {
448   const guint8 in[] = { 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80 };
449   const guint8 out[] = { 0x80, 0x80, 0x80 };
450   check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
451       "closedcaption/x-cea-708,format=(string)cc_data",
452       "closedcaption/x-cea-608,format=(string)s334-1a");
453 }
454
455 GST_END_TEST;
456
457 GST_START_TEST (convert_cea708_cc_data_cea708_cdp)
458 {
459   const guint8 in[] = { 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80 };
460   const guint8 out[] =
461       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xf8, 0x80, 0x80,
462     0xfe, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
463     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
464     0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x6e
465   };
466   check_conversion (in, sizeof (in), out, sizeof (out),
467       "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)60/1",
468       "closedcaption/x-cea-708,format=(string)cdp", NULL, NULL);
469 }
470
471 GST_END_TEST;
472
473 GST_START_TEST (convert_cea708_cdp_cea608_raw)
474 {
475   const guint8 in1[] =
476       { 0x96, 0x69, 0x13, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xe2, 0xfc, 0x80, 0x80,
477     0xfd, 0x80, 0x80, 0x74, 0x00, 0x00, 0x8a
478   };
479   const guint8 out1[] = { 0x80, 0x80, 0x80, 0x80 };
480   const guint8 in2[] =
481       { 0x96, 0x69, 0x13, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xe2, 0xfc, 0x80, 0x81,
482     0xfd, 0x82, 0x83, 0x74, 0x00, 0x00, 0x8a
483   };
484   const guint8 out2[] = { 0x80, 0x81, 0x80, 0x80 };
485   check_conversion_tc_passthrough (in1, sizeof (in1), out1, sizeof (out1),
486       "closedcaption/x-cea-708,format=(string)cdp,framerate=30/1",
487       "closedcaption/x-cea-608,format=(string)raw");
488   check_conversion_tc_passthrough (in2, sizeof (in2), out2, sizeof (out2),
489       "closedcaption/x-cea-708,format=(string)cdp,framerate=30/1",
490       "closedcaption/x-cea-608,format=(string)raw");
491 }
492
493 GST_END_TEST;
494
495 GST_START_TEST (convert_cea708_cdp_cea608_s334_1a)
496 {
497   const guint8 in[] =
498       { 0x96, 0x69, 0x13, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xe2, 0xfc, 0x80, 0x80,
499     0xfd, 0x80, 0x80, 0x74, 0x00, 0x00, 0x8a
500   };
501   const guint8 out[] = { 0x80, 0x80, 0x80, 0x00, 0x80, 0x80 };
502   check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
503       "closedcaption/x-cea-708,format=(string)cdp,framerate=30/1",
504       "closedcaption/x-cea-608,format=(string)s334-1a");
505 }
506
507 GST_END_TEST;
508
509 GST_START_TEST (convert_cea708_cdp_cea708_cc_data)
510 {
511   const guint8 in[] =
512       { 0x96, 0x69, 0x13, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xe2, 0xfc, 0x80, 0x80,
513     0xfd, 0x80, 0x80, 0x74, 0x00, 0x00, 0x8a
514   };
515   const guint8 out[] = { 0xf8, 0x80, 0x80, 0xf9, 0x80, 0x80 };
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
523 GST_START_TEST (convert_cea708_cdp_cea708_cc_data_too_big)
524 {
525   /* tests that too large input is truncated */
526   const guint8 in[] =
527       { 0x96, 0x69, 0x2e, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xeb, 0xfc, 0x80, 0x80,
528     0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80,
529     0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80,
530     0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0x74, 0x00, 0x00, 0x8a,
531   };
532   const guint8 out[] = { 0xf8, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80,
533     0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80,
534     0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80
535   };
536   check_conversion_tc_passthrough (in, sizeof (in), out, sizeof (out),
537       "closedcaption/x-cea-708,format=(string)cdp",
538       "closedcaption/x-cea-708,format=(string)cc_data");
539 }
540
541 GST_END_TEST;
542
543 GST_START_TEST (convert_cea708_cdp_cea708_cdp_double_framerate)
544 {
545   /* tests that packets are split exactly in half when doubling the framerate */
546   const guint8 in1[] =
547       { 0x96, 0x69, 0x49, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xf4, 0xfc, 0x01, 0x02,
548     0xfd, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
549     0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12,
550     0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0xfe, 0x19, 0x1a,
551     0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e, 0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22,
552     0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26, 0xfe, 0x27, 0x28, 0x74, 0x00, 0x00, 0xd2
553   };
554   const guint8 *in[] = { in1 };
555   guint in_len[] = { sizeof (in1) };
556   GstVideoTimeCode in_tc1;
557   const GstVideoTimeCode *in_tc[] = { &in_tc1 };
558
559   const guint8 out1[] = { 0x96, 0x69, 0x30, 0x8f, 0xc3, 0x00, 0x00, 0x71, 0xc1,
560     0x82, 0x03, 0x08, 0x72, 0xea, 0xfc, 0x01, 0x02, 0xfe, 0x05, 0x06, 0xfe,
561     0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe,
562     0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16, 0x74,
563     0x00, 0x00, 0x10
564   };
565   const guint8 out2[] = { 0x96, 0x69, 0x30, 0x8f, 0xc3, 0x00, 0x01, 0x71, 0xc1,
566     0x82, 0x03, 0x09, 0x72, 0xea, 0xfd, 0x03, 0x04, 0xfe, 0x17, 0x18, 0xfe,
567     0x19, 0x1a, 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e, 0xfe, 0x1f, 0x20, 0xfe,
568     0x21, 0x22, 0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26, 0xfe, 0x27, 0x28, 0x74,
569     0x00, 0x01, 0xc4
570   };
571   const guint8 *out[] = { out1, out2 };
572   guint out_len[] = { sizeof (out1), sizeof (out2) };
573   GstVideoTimeCode out_tc1, out_tc2;
574   const GstVideoTimeCode *out_tc[] = { &out_tc1, &out_tc2 };
575
576   gst_video_time_code_init (&in_tc1, 30, 1, NULL,
577       GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 4, 0);
578   fail_unless (gst_video_time_code_is_valid (&in_tc1));
579
580   gst_video_time_code_init (&out_tc1, 60, 1, NULL,
581       GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 8, 0);
582   fail_unless (gst_video_time_code_is_valid (&out_tc1));
583   gst_video_time_code_init (&out_tc2, 60, 1, NULL,
584       GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 9, 0);
585   fail_unless (gst_video_time_code_is_valid (&out_tc2));
586
587   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
588       G_N_ELEMENTS (out_len), out, out_len,
589       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
590       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
591       in_tc, out_tc, 0);
592
593   gst_video_time_code_clear (&in_tc1);
594   gst_video_time_code_clear (&out_tc1);
595   gst_video_time_code_clear (&out_tc2);
596 }
597
598 GST_END_TEST;
599
600 GST_START_TEST (convert_cea708_cdp_cea708_cdp_half_framerate)
601 {
602   /* tests that two input packets are merged together when halving the
603    * framerate.  With cc_data compaction! */
604   const guint8 in1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
605     0xfc, 0x01, 0x02, 0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08,
606     0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10,
607     0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0x74, 0x00, 0x00, 0x7a
608   };
609   const guint8 in2[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea,
610     0xfd, 0x14, 0x15, 0xfe, 0x16, 0x17, 0xfe, 0x18, 0x19, 0xfe, 0x1a, 0x1b,
611     0xfe, 0x1c, 0x1d, 0xfe, 0x1e, 0x1f, 0xfe, 0x20, 0x21, 0xfe, 0x22, 0x23,
612     0xfe, 0x24, 0x25, 0xfe, 0x26, 0x27, 0x74, 0x00, 0x01, 0x70
613   };
614   const guint8 *in[] = { in1, in2 };
615   guint in_len[] = { sizeof (in1), sizeof (in2) };
616   GstVideoTimeCode in_tc1, in_tc2;
617   const GstVideoTimeCode *in_tc[] = { &in_tc1, &in_tc2 };
618
619   const guint8 out1[] =
620       { 0x96, 0x69, 0x4e, 0x5f, 0xc3, 0x00, 0x00, 0x71, 0xc1, 0x82, 0x03, 0x04,
621     0x72, 0xf4, 0xfc, 0x01, 0x02, 0xfd, 0x14, 0x15, 0xfe, 0x03, 0x04, 0xfe,
622     0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe,
623     0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe,
624     0x16, 0x17, 0xfe, 0x18, 0x19, 0xfe, 0x1a, 0x1b, 0xfe, 0x1c, 0x1d, 0xfe,
625     0x1e, 0x1f, 0xfe, 0x20, 0x21, 0xfe, 0x22, 0x23, 0xfe, 0x24, 0x25, 0xfe,
626     0x26, 0x27, 0x74, 0x00, 0x00, 0x07
627   };
628   const guint8 *out[] = { out1 };
629   guint out_len[] = { sizeof (out1) };
630   GstVideoTimeCode out_tc1;
631   const GstVideoTimeCode *out_tc[] = { &out_tc1 };
632
633   gst_video_time_code_init (&in_tc1, 60, 1, NULL,
634       GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 8, 0);
635   fail_unless (gst_video_time_code_is_valid (&in_tc1));
636   gst_video_time_code_init (&in_tc2, 60, 1, NULL,
637       GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 8, 0);
638   fail_unless (gst_video_time_code_is_valid (&in_tc2));
639
640   gst_video_time_code_init (&out_tc1, 30, 1, NULL,
641       GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 4, 0);
642   fail_unless (gst_video_time_code_is_valid (&out_tc1));
643
644   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
645       G_N_ELEMENTS (out_len), out, out_len,
646       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
647       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
648       in_tc, out_tc, 0);
649
650   gst_video_time_code_clear (&in_tc1);
651   gst_video_time_code_clear (&in_tc2);
652   gst_video_time_code_clear (&out_tc1);
653 }
654
655 GST_END_TEST;
656
657 GST_START_TEST (convert_cea708_cdp_cea708_cdp_max_merge)
658 {
659   /* check that 3 high framerate packets can be merged into 1 low framerate
660    * packets with the extra data on the third input packet being placed at the
661    * beginning of the second output packet */
662   const guint8 in1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
663     0xfc, 0x01, 0x02, 0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08,
664     0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10,
665     0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0x74, 0x00, 0x00, 0x7a
666   };
667   /* enough input to fully cover two output packets. Extra is discarded */
668   const guint8 *in[] = { in1, in1, in1, in1, in1, in1, in1 };
669   guint in_len[] =
670       { sizeof (in1), sizeof (in1), sizeof (in1), sizeof (in1), sizeof (in1),
671     sizeof (in1)
672   };
673
674   const guint8 out1[] =
675       { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x00, 0x72, 0xf9, 0xfc, 0x01, 0x02,
676     0xf9, 0x80, 0x80, 0xfc, 0x01, 0x02, 0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06,
677     0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e,
678     0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe, 0x03, 0x04,
679     0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
680     0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14,
681     0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
682     0x74, 0x00, 0x00, 0xcb
683   };
684   const guint8 out2[] =
685       { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x01, 0x72, 0xf9, 0xf9, 0x80, 0x80,
686     0xfc, 0x01, 0x02, 0xf9, 0x80, 0x80, 0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e,
687     0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe, 0x03, 0x04,
688     0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
689     0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14,
690     0xfe, 0x03, 0x04, 0xfe, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
691     0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12,
692     0x74, 0x00, 0x01, 0x8f
693   };
694   const guint8 *out[] = { out1, out2 };
695   guint out_len[] = { sizeof (out1), sizeof (out2) };
696   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
697       G_N_ELEMENTS (out_len), out, out_len,
698       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
699       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)24000/1001",
700       NULL, NULL, 0);
701 }
702
703 GST_END_TEST;
704
705 GST_START_TEST (convert_cea708_cdp_cea708_cdp_max_split)
706 {
707   /* test that a low framerate stream produces multiple output packets for a
708    * high framerate */
709   const guint8 in1[] =
710       { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x00, 0x72, 0xf9, 0xfc, 0x01, 0x02,
711     0xfd, 0x03, 0x04, 0xfc, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
712     0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12,
713     0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0xfe, 0x19, 0x1a,
714     0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e, 0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22,
715     0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26, 0xfe, 0x27, 0x28, 0xfe, 0x29, 0x2a,
716     0xfe, 0x2b, 0x2c, 0xfe, 0x2d, 0x2e, 0xfe, 0x2f, 0x30, 0xfe, 0x31, 0x32,
717     0x74, 0x00, 0x00, 0x12
718   };
719   const guint8 *in[] = { in1, in1 };
720   guint in_len[] = { sizeof (in1), sizeof (in1) };
721
722   const guint8 out1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
723     0xfc, 0x01, 0x02, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
724     0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14,
725     0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0x74, 0x00, 0x00, 0x30
726   };
727   const guint8 out2[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea,
728     0xfd, 0x03, 0x04, 0xfe, 0x19, 0x1a, 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e,
729     0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22, 0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26,
730     0xfe, 0x27, 0x28, 0xfe, 0x29, 0x2a, 0x74, 0x00, 0x01, 0xe5
731   };
732   const guint8 out3[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea,
733     0xfc, 0x05, 0x06, 0xfe, 0x2b, 0x2c, 0xfe, 0x2d, 0x2e, 0xfe, 0x2f, 0x30,
734     0xfe, 0x31, 0x32, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
735     0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0x74, 0x00, 0x02, 0x54
736   };
737   const guint8 out4[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea,
738     0xfd, 0x03, 0x04, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16,
739     0xfe, 0x17, 0x18, 0xfe, 0x19, 0x1a, 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e,
740     0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22, 0x74, 0x00, 0x03, 0x71
741   };
742   const guint8 *out[] = { out1, out2, out3, out4 };
743   guint out_len[] =
744       { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4) };
745   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
746       G_N_ELEMENTS (out_len), out, out_len,
747       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)24000/1001",
748       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
749       NULL, NULL, 0);
750 }
751
752 GST_END_TEST;
753
754 GST_START_TEST (convert_cea708_cdp_cea708_cdp_max_split_eos)
755 {
756   /* test that a low framerate stream produces multiple output packets for a
757    * high framerate and that an EOS will push the pending data */
758   const guint8 in1[] =
759       { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x00, 0x72, 0xf9, 0xfc, 0x01, 0x02,
760     0xfd, 0x03, 0x04, 0xfc, 0x05, 0x06, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a,
761     0xfe, 0x0b, 0x0c, 0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12,
762     0xfe, 0x13, 0x14, 0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0xfe, 0x19, 0x1a,
763     0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e, 0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22,
764     0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26, 0xfe, 0x27, 0x28, 0xfe, 0x29, 0x2a,
765     0xfe, 0x2b, 0x2c, 0xfe, 0x2d, 0x2e, 0xfe, 0x2f, 0x30, 0xfe, 0x31, 0x32,
766     0x74, 0x00, 0x00, 0x12
767   };
768   const guint8 *in[] = { in1 };
769   guint in_len[] = { sizeof (in1) };
770
771   const guint8 out1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
772     0xfc, 0x01, 0x02, 0xfe, 0x07, 0x08, 0xfe, 0x09, 0x0a, 0xfe, 0x0b, 0x0c,
773     0xfe, 0x0d, 0x0e, 0xfe, 0x0f, 0x10, 0xfe, 0x11, 0x12, 0xfe, 0x13, 0x14,
774     0xfe, 0x15, 0x16, 0xfe, 0x17, 0x18, 0x74, 0x00, 0x00, 0x30
775   };
776   const guint8 out2[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea,
777     0xfd, 0x03, 0x04, 0xfe, 0x19, 0x1a, 0xfe, 0x1b, 0x1c, 0xfe, 0x1d, 0x1e,
778     0xfe, 0x1f, 0x20, 0xfe, 0x21, 0x22, 0xfe, 0x23, 0x24, 0xfe, 0x25, 0x26,
779     0xfe, 0x27, 0x28, 0xfe, 0x29, 0x2a, 0x74, 0x00, 0x01, 0xe5
780   };
781   const guint8 out3[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea,
782     0xfc, 0x05, 0x06, 0xfe, 0x2b, 0x2c, 0xfe, 0x2d, 0x2e, 0xfe, 0x2f, 0x30,
783     0xfe, 0x31, 0x32, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
784     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0xdb
785   };
786   const guint8 *out[] = { out1, out2, out3 };
787   guint out_len[] = { sizeof (out1), sizeof (out2), sizeof (out3) };
788
789   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
790       G_N_ELEMENTS (out_len), out, out_len,
791       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)24000/1001",
792       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
793       NULL, NULL, FLAG_SEND_EOS);
794 }
795
796 GST_END_TEST;
797
798 GST_START_TEST (convert_cea708_cdp_cea708_cdp_from_drop_frame_scaling)
799 {
800   const guint8 in1[] = { 0x96, 0x69, 0x10, 0x7f, 0x43, 0x00, 0x00, 0x72, 0xe1,
801     0xfc, 0x80, 0x80, 0x74, 0x00, 0x00, 0x7a
802   };
803   const guint8 *in[] = { in1, in1 };
804   guint in_len[] = { sizeof (in1), sizeof (in1) };
805   GstVideoTimeCode in_tc1, in_tc2;
806   const GstVideoTimeCode *in_tc[] = { &in_tc1, &in_tc2 };
807
808   const guint8 out1[] =
809       { 0x96, 0x69, 0x4e, 0x5f, 0xc3, 0x00, 0x00, 0x71, 0xc0, 0x81, 0x59, 0x29,
810     0x72, 0xf4, 0xf8, 0x80, 0x80, 0xf9, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa,
811     0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
812     0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
813     0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
814     0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
815     0x00, 0x00, 0x74, 0x00, 0x00, 0xfe
816   };
817   const guint8 out2[] =
818       { 0x96, 0x69, 0x4e, 0x5f, 0xc3, 0x00, 0x01, 0x71, 0xc0, 0x82, 0x00, 0x00,
819     0x72, 0xf4, 0xf8, 0x80, 0x80, 0xf9, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa,
820     0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
821     0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
822     0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
823     0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
824     0x00, 0x00, 0x74, 0x00, 0x01, 0x7d
825   };
826   const guint8 *out[] = { out1, out2 };
827   guint out_len[] = { sizeof (out1), sizeof (out2) };
828   GstVideoTimeCode out_tc1, out_tc2;
829   const GstVideoTimeCode *out_tc[] = { &out_tc1, &out_tc2 };
830
831   gst_video_time_code_init (&in_tc1, 30000, 1001, NULL,
832       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0, 1, 59, 29, 0);
833   fail_unless (gst_video_time_code_is_valid (&in_tc1));
834
835   gst_video_time_code_init (&in_tc2, 30000, 1001, NULL,
836       GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0, 2, 0, 4, 0);
837   fail_unless (gst_video_time_code_is_valid (&in_tc2));
838
839   gst_video_time_code_init (&out_tc1, 30, 1, NULL,
840       GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 1, 59, 29, 0);
841   fail_unless (gst_video_time_code_is_valid (&out_tc1));
842
843   gst_video_time_code_init (&out_tc2, 30, 1, NULL,
844       GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 2, 0, 0, 0);
845   fail_unless (gst_video_time_code_is_valid (&out_tc2));
846
847   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
848       G_N_ELEMENTS (out_len), out, out_len,
849       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30000/1001",
850       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
851       in_tc, out_tc, FLAG_SEND_EOS);
852
853   gst_video_time_code_clear (&in_tc1);
854   gst_video_time_code_clear (&out_tc1);
855 }
856
857 GST_END_TEST;
858
859 GST_START_TEST (convert_cea708_cc_data_cea708_cdp_double_framerate)
860 {
861   const guint8 in1[] = { 0xfc, 0x80, 0x81, 0xfd, 0x82, 0x83, 0xfe, 0x84, 0x85 };
862   const guint8 in2[] = { 0xfc, 0x86, 0x87, 0xfd, 0x88, 0x89, 0xfe, 0x8a, 0x8b };
863   const guint8 *in[] = { in1, in2 };
864   guint in_len[] = { sizeof (in1), sizeof (in2) };
865   const guint8 out1[] =
866       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x80, 0x81,
867     0xfe, 0x84, 0x85, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
868     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
869     0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x60
870   };
871   const guint8 out2[] =
872       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea, 0xfd, 0x82, 0x83,
873     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
874     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
875     0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0x66
876   };
877   const guint8 out3[] =
878       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea, 0xfc, 0x86, 0x87,
879     0xfe, 0x8a, 0x8b, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
880     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
881     0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0x44
882   };
883   const guint8 out4[] =
884       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea, 0xfd, 0x88, 0x89,
885     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
886     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
887     0xfa, 0x00, 0x00, 0x74, 0x00, 0x03, 0x56
888   };
889   const guint8 *out[] = { out1, out2, out3, out4, };
890   guint out_len[] =
891       { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4), };
892   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
893       G_N_ELEMENTS (out_len), out, out_len,
894       "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1",
895       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
896       NULL, NULL, 0);
897 }
898
899 GST_END_TEST;
900
901 GST_START_TEST (convert_cea608_raw_cea708_cdp_double_framerate)
902 {
903   const guint8 in1[] = { 0x80, 0x81 };
904   const guint8 in2[] = { 0x82, 0x83 };
905   const guint8 *in[] = { in1, in2 };
906   guint in_len[] = { sizeof (in1), sizeof (in2) };
907   const guint8 out1[] =
908       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x80, 0x81,
909     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
910     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
911     0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x6d
912   };
913   const guint8 out2[] =
914       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea, 0xf9, 0x80, 0x80,
915     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
916     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
917     0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0x6f
918   };
919   const guint8 out3[] =
920       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea, 0xfc, 0x82, 0x83,
921     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
922     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
923     0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0x65
924   };
925   const guint8 out4[] =
926       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea, 0xf9, 0x80, 0x80,
927     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
928     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
929     0xfa, 0x00, 0x00, 0x74, 0x00, 0x03, 0x6b
930   };
931   const guint8 *out[] = { out1, out2, out3, out4, };
932   guint out_len[] =
933       { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4), };
934   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
935       G_N_ELEMENTS (out_len), out, out_len,
936       "closedcaption/x-cea-608,format=(string)raw,framerate=(fraction)30/1",
937       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
938       NULL, NULL, 0);
939 }
940
941 GST_END_TEST;
942
943 GST_START_TEST (convert_cea608_s334_1a_cea708_cdp_double_framerate)
944 {
945   const guint8 in1[] = { 0x80, 0x80, 0x81, 0x00, 0x82, 0x83 };
946   const guint8 in2[] = { 0x80, 0x84, 0x85, 0x00, 0x86, 0x87 };
947   const guint8 *in[] = { in1, in2 };
948   guint in_len[] = { sizeof (in1), sizeof (in2) };
949   const guint8 out1[] =
950       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x80, 0x81,
951     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
952     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
953     0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x6d
954   };
955   const guint8 out2[] =
956       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea, 0xfd, 0x82, 0x83,
957     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
958     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
959     0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0x66
960   };
961   const guint8 out3[] =
962       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea, 0xfc, 0x84, 0x85,
963     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
964     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
965     0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0x61
966   };
967   const guint8 out4[] =
968       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea, 0xfd, 0x86, 0x87,
969     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
970     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
971     0xfa, 0x00, 0x00, 0x74, 0x00, 0x03, 0x5a
972   };
973   const guint8 *out[] = { out1, out2, out3, out4, };
974   guint out_len[] =
975       { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4), };
976   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
977       G_N_ELEMENTS (out_len), out, out_len,
978       "closedcaption/x-cea-608,format=(string)s334-1a,framerate=(fraction)30/1",
979       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
980       NULL, NULL, 0);
981 }
982
983 GST_END_TEST;
984
985 GST_START_TEST (convert_cea708_cdp_cea708_cc_data_double_input_data)
986 {
987   /* caps say 60fps, data has 30fps. Ensure data is taken alternatatively from
988    * each field even if there is too much input data */
989   const guint8 in1[] =
990       { 0x96, 0x69, 0x16, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xe3, 0xfc, 0x81, 0x82,
991     0xfd, 0x83, 0x84, 0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0xff
992   };
993   /* padding buffer */
994   const guint8 in2[] =
995       { 0x96, 0x69, 0x16, 0x5f, 0x43, 0x00, 0x01, 0x72, 0xe3, 0xfc, 0x80, 0x80,
996     0xfd, 0x80, 0x80, 0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0xff
997   };
998   const guint8 in3[] =
999       { 0x96, 0x69, 0x16, 0x5f, 0x43, 0x00, 0x02, 0x72, 0xe3, 0xfc, 0x85, 0x86,
1000     0xfd, 0x87, 0x88, 0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0xff
1001   };
1002   const guint8 *in[] = { in1, in2, in3, };
1003   guint in_len[] = { sizeof (in1), sizeof (in2), sizeof (in3), };
1004   /* two buffers from the first buffer, then the first half of the third input
1005    * buffer */
1006   const guint8 out1[] = { 0xfc, 0x81, 0x82, };
1007   const guint8 out2[] = { 0xfd, 0x83, 0x84, };
1008   const guint8 out3[] = { 0xfc, 0x85, 0x86, };
1009   const guint8 *out[] = { out1, out2, out3, };
1010   guint out_len[] = { sizeof (out1), sizeof (out2), sizeof (out3), };
1011   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
1012       G_N_ELEMENTS (out_len), out, out_len,
1013       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
1014       "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)60/1",
1015       NULL, NULL, 0);
1016 }
1017
1018 GST_END_TEST;
1019
1020 GST_START_TEST (convert_cea708_cc_data_cea708_cdp_double_input_data)
1021 {
1022   /* caps say 60fps, but every buffer is cea608 field 1. Ensure data is taken
1023    * alternatatively from each field even if there is too much input data */
1024   const guint8 in1[] = { 0xfc, 0x81, 0x82 };
1025   const guint8 in2[] = { 0xfc, 0x83, 0x84 };
1026   const guint8 in3[] = { 0xfc, 0x85, 0x86 };
1027   const guint8 *in[] = { in1, in2, in3, };
1028   guint in_len[] = { sizeof (in1), sizeof (in2), sizeof (in3), };
1029   /* two buffers from the first buffer, then the first half of the third input
1030    * buffer */
1031   const guint8 out1[] =
1032       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea, 0xfc, 0x81, 0x82,
1033     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1034     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1035     0xfa, 0x00, 0x00, 0x74, 0x00, 0x00, 0x6b
1036   };
1037   /* padding buffer */
1038   const guint8 out2[] =
1039       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea, 0xf9, 0x80, 0x80,
1040     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1041     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1042     0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0x6f
1043   };
1044   const guint8 out3[] =
1045       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea, 0xfc, 0x83, 0x84,
1046     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1047     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1048     0xfa, 0x00, 0x00, 0x74, 0x00, 0x02, 0x63
1049   };
1050   const guint8 out4[] =
1051       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea, 0xf9, 0x80, 0x80,
1052     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1053     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1054     0xfa, 0x00, 0x00, 0x74, 0x00, 0x03, 0x6b
1055   };
1056   const guint8 out5[] =
1057       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x04, 0x72, 0xea, 0xfc, 0x85, 0x86,
1058     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1059     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1060     0xfa, 0x00, 0x00, 0x74, 0x00, 0x04, 0x5b
1061   };
1062   const guint8 *out[] = { out1, out2, out3, out4, out5 };
1063   guint out_len[] =
1064       { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4),
1065     sizeof (out5)
1066   };
1067   check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
1068       G_N_ELEMENTS (out_len), out, out_len,
1069       "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)60/1",
1070       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
1071       NULL, NULL, FLAG_SEND_EOS);
1072 }
1073
1074 GST_END_TEST;
1075
1076 static guint8
1077 calculate_cdp_checksum (guint8 * cdp, gsize len)
1078 {
1079   guint8 checksum = 0;
1080   gsize i;
1081
1082   for (i = 0; i < len; i++) {
1083     checksum += cdp[i];
1084   }
1085   checksum &= 0xff;
1086   return 256 - checksum;
1087 }
1088
1089 GST_START_TEST (convert_cea708_cc_data_cea708_cdp_field1_overflow)
1090 {
1091   /* caps say 60fps, but every buffer is cea608 field 1. Ensure data is taken
1092    * alternatatively from each field even if there is too much input data.
1093    * Also ensure that overflow does something sane, like dropping previous data */
1094 #define N_INPUTS 100
1095   guint8 in_data[N_INPUTS * 3];
1096   guint in_len[N_INPUTS];
1097   guint8 *in[N_INPUTS];
1098   guint i;
1099
1100 #define N_OUTPUTS 100
1101   guint8 out_data[N_OUTPUTS * 43];
1102   guint out_len[N_OUTPUTS];
1103   guint8 *out[N_OUTPUTS];
1104
1105   const guint8 out_template[] =
1106       { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea, 0xf9, 0x80, 0x80,
1107     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1108     0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
1109     0xfa, 0x00, 0x00, 0x74, 0x00, 0x01, 0x6f
1110   };
1111
1112   G_STATIC_ASSERT (sizeof (out_template) == 43);
1113
1114   /* generate input data */
1115   for (i = 0; i < N_INPUTS; i++) {
1116     in_len[i] = 3;
1117     in_data[i * 3 + 0] = 0xfc;
1118     in_data[i * 3 + 1] = 0x81 + i * 2;
1119     in_data[i * 3 + 2] = 0x81 + i * 2 + 1;
1120     in[i] = &in_data[i * 3];
1121   }
1122
1123   for (i = 0; i < N_OUTPUTS; i++) {
1124     out_len[i] = 43;
1125     memcpy (&out_data[i * 43], out_template, sizeof (out_template));
1126     /* write correct counters */
1127     out_data[i * 43 + 6] = i;
1128     out_data[i * 43 + 41] = i;
1129     /* write the correct cea608 data */
1130     if (i % 2 == 0) {
1131       gsize in_data_offset;
1132       /* take frames sequentially from the input */
1133       gsize in_idx = i / 2;
1134       /* take the first 16 input frames, then skip the next 16 frames and take
1135        * the next 16 frames etc.
1136        * 32 is the byte size of the internal cea608 field buffers that we are
1137        * overflowing but every second buffer will have cea608 field 1 in it.
1138        * 16 frames is 32 bytes stored and is enough to cause overflow */
1139       in_idx = (in_idx / 16) * 32 + in_idx % 16;
1140       in_data_offset = in_idx * 3;
1141
1142       out_data[i * 43 + 9] = in_data[in_data_offset + 0];
1143       out_data[i * 43 + 10] = in_data[in_data_offset + 1];
1144       out_data[i * 43 + 11] = in_data[in_data_offset + 2];
1145     } else {
1146       out_data[i * 43 + 9] = 0xf9;
1147       out_data[i * 43 + 10] = 0x80;
1148       out_data[i * 43 + 11] = 0x80;
1149     }
1150     out_data[i * 43 + 42] = calculate_cdp_checksum (&out_data[i * 43], 42);
1151     out[i] = &out_data[i * 43];
1152   }
1153
1154   check_conversion_multiple (G_N_ELEMENTS (in_len), (const guint8 **) in,
1155       in_len, G_N_ELEMENTS (out_len), (const guint8 **) out, out_len,
1156       "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)60/1",
1157       "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
1158       NULL, NULL, FLAG_SEND_EOS);
1159 }
1160
1161 GST_END_TEST;
1162
1163 static Suite *
1164 ccextractor_suite (void)
1165 {
1166   Suite *s = suite_create ("ccconverter");
1167   TCase *tc = tcase_create ("general");
1168
1169   suite_add_tcase (s, tc);
1170
1171   tcase_add_test (tc, cdp_requires_valid_framerate);
1172   tcase_add_test (tc, framerate_passthrough);
1173   tcase_add_test (tc, framerate_changes);
1174   tcase_add_test (tc, framerate_invalid_format);
1175   tcase_add_test (tc, convert_cea608_raw_cea608_s334_1a);
1176   tcase_add_test (tc, convert_cea608_raw_cea708_cc_data);
1177   tcase_add_test (tc, convert_cea608_raw_cea708_cdp);
1178   tcase_add_test (tc, convert_cea608_s334_1a_cea608_raw);
1179   tcase_add_test (tc, convert_cea608_s334_1a_cea608_raw_too_big);
1180   tcase_add_test (tc, convert_cea608_s334_1a_cea708_cc_data);
1181   tcase_add_test (tc, convert_cea608_s334_1a_cea708_cdp);
1182   tcase_add_test (tc, convert_cea708_cc_data_cea608_raw);
1183   tcase_add_test (tc, convert_cea708_cc_data_cea608_s334_1a);
1184   tcase_add_test (tc, convert_cea708_cc_data_cea708_cdp);
1185   tcase_add_test (tc, convert_cea708_cdp_cea608_raw);
1186   tcase_add_test (tc, convert_cea708_cdp_cea608_s334_1a);
1187   tcase_add_test (tc, convert_cea708_cdp_cea708_cc_data);
1188   tcase_add_test (tc, convert_cea708_cdp_cea708_cc_data_too_big);
1189   tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_half_framerate);
1190   tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_double_framerate);
1191   tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_max_merge);
1192   tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_max_split);
1193   tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_max_split_eos);
1194   tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_from_drop_frame_scaling);
1195   tcase_add_test (tc, convert_cea708_cc_data_cea708_cdp_double_framerate);
1196   tcase_add_test (tc, convert_cea608_raw_cea708_cdp_double_framerate);
1197   tcase_add_test (tc, convert_cea608_s334_1a_cea708_cdp_double_framerate);
1198   tcase_add_test (tc, convert_cea708_cdp_cea708_cc_data_double_input_data);
1199   tcase_add_test (tc, convert_cea708_cc_data_cea708_cdp_double_input_data);
1200   tcase_add_test (tc, convert_cea708_cc_data_cea708_cdp_field1_overflow);
1201
1202   return s;
1203 }
1204
1205 GST_CHECK_MAIN (ccextractor);