summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2020-03-13 10:54:02 +1100
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2020-05-11 12:30:31 +0000
commit7d028af67580c0478de12ba53da2c9f4d172ab7f (patch)
tree25a2e3d25030affba4f17c581f3e131e0fc9e0d0 /tests
parentddc7563ac9dd679e01b2659c8fd1e0d4c335a869 (diff)
downloadgstreamer-plugins-bad-7d028af67580c0478de12ba53da2c9f4d172ab7f.tar.gz
ccconverter: implement support for CDP framerate conversions
- Any format involving CDP is supported. - Time codes (if present) are scaled as well. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1116>
Diffstat (limited to 'tests')
-rw-r--r--tests/check/elements/ccconverter.c422
1 files changed, 401 insertions, 21 deletions
diff --git a/tests/check/elements/ccconverter.c b/tests/check/elements/ccconverter.c
index 0fc3df856..0234c7d05 100644
--- a/tests/check/elements/ccconverter.c
+++ b/tests/check/elements/ccconverter.c
@@ -28,6 +28,12 @@
#include <string.h>
+enum CheckConversionFlags
+{
+ FLAG_NONE,
+ FLAG_SEND_EOS = 1,
+};
+
GST_START_TEST (cdp_requires_framerate)
{
GstHarness *h;
@@ -54,7 +60,7 @@ GST_START_TEST (cdp_requires_framerate)
GST_FLOW_NOT_NEGOTIATED);
/* Now set a framerate only on the sink caps, this should still fail:
- * We can't do framerate conversion!
+ * We can't come up with a framerate
*/
gst_harness_set_sink_caps_str (h,
"closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1");
@@ -62,7 +68,7 @@ GST_START_TEST (cdp_requires_framerate)
fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
GST_FLOW_NOT_NEGOTIATED);
- /* Then try with a framerate, this should work now */
+ /* Then try with a change of framerate, this should work */
gst_harness_set_sink_caps_str (h,
"closedcaption/x-cea-708,format=(string)cdp");
gst_harness_set_src_caps_str (h,
@@ -144,41 +150,97 @@ GST_START_TEST (framerate_passthrough)
GST_END_TEST;
+GST_START_TEST (framerate_changes)
+{
+ GstHarness *h;
+ GstBuffer *buffer;
+ GstMapInfo map;
+
+ h = gst_harness_new ("ccconverter");
+
+ buffer = gst_buffer_new_and_alloc (3);
+ gst_buffer_map (buffer, &map, GST_MAP_WRITE);
+ map.data[0] = 0x00;
+ map.data[1] = 0x80;
+ map.data[2] = 0x80;
+ gst_buffer_unmap (buffer, &map);
+
+ /* success case */
+ gst_harness_set_src_caps_str (h,
+ "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1");
+ gst_harness_set_sink_caps_str (h,
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1");
+ fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
+ GST_FLOW_OK);
+
+ /* test an invalid cdp framerate */
+ gst_harness_set_sink_caps_str (h,
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)1111/1");
+ fail_unless_equals_int (gst_harness_push (h, buffer),
+ GST_FLOW_NOT_NEGOTIATED);
+
+ gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
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)
+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)
{
GstHarness *h;
GstBuffer *buffer;
GstVideoTimeCodeMeta *out_tc_meta;
+ int i = 0;
h = gst_harness_new ("ccconverter");
gst_harness_set_src_caps_str (h, in_caps);
gst_harness_set_sink_caps_str (h, out_caps);
- buffer =
- gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, (gpointer) in,
- in_len, 0, in_len, NULL, NULL);
- if (in_tc)
- gst_buffer_add_video_time_code_meta (buffer, in_tc);
-
- buffer = gst_harness_push_and_pull (h, buffer);
-
- fail_unless (buffer != NULL);
- gst_check_buffer_data (buffer, out, out_len);
- out_tc_meta = gst_buffer_get_video_time_code_meta (buffer);
- fail_if (out_tc_meta == NULL && out_tc != NULL);
- if (out_tc_meta)
- fail_unless (gst_video_time_code_compare (&out_tc_meta->tc, out_tc) == 0);
-
- gst_buffer_unref (buffer);
+ for (i = 0; i < n_in; i++) {
+ buffer =
+ gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, (gpointer) in[i],
+ in_len[i], 0, in_len[i], NULL, NULL);
+ GST_INFO ("pushing buffer %u %" GST_PTR_FORMAT, i, buffer);
+ if (in_tc && in_tc[i])
+ gst_buffer_add_video_time_code_meta (buffer, in_tc[i]);
+ fail_unless_equals_int (gst_harness_push (h, buffer), GST_FLOW_OK);
+ }
+
+ if (flags & FLAG_SEND_EOS)
+ fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
+
+ for (i = 0; i < n_out; i++) {
+ buffer = gst_harness_pull (h);
+
+ GST_INFO ("pulled buffer %u %" GST_PTR_FORMAT, i, buffer);
+ fail_unless (buffer != NULL);
+ gst_check_buffer_data (buffer, out[i], out_len[i]);
+ out_tc_meta = gst_buffer_get_video_time_code_meta (buffer);
+ fail_if (out_tc_meta == NULL && out_tc != NULL && out_tc[i] != NULL);
+ if (out_tc_meta && out_tc && out_tc[i])
+ fail_unless (gst_video_time_code_compare (&out_tc_meta->tc,
+ out_tc[i]) == 0);
+
+ gst_buffer_unref (buffer);
+ }
gst_harness_teardown (h);
}
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)
+{
+ check_conversion_multiple (1, &in, &in_len, 1, &out, &out_len, in_caps,
+ out_caps, &in_tc, &out_tc, 0);
+}
+
+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)
@@ -362,6 +424,7 @@ GST_END_TEST;
GST_START_TEST (convert_cea708_cdp_cea708_cc_data_too_big)
{
+ /* tests that too large input is truncated */
const guint8 in[] =
{ 0x96, 0x69, 0x2e, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xeb, 0xfc, 0x80, 0x80,
0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x80,
@@ -379,6 +442,316 @@ GST_START_TEST (convert_cea708_cdp_cea708_cc_data_too_big)
GST_END_TEST;
+GST_START_TEST (convert_cea708_cdp_cea708_cdp_double_framerate)
+{
+ /* tests that packets are split exactly in half when doubling the framerate */
+ const guint8 in1[] =
+ { 0x96, 0x69, 0x49, 0x5f, 0x43, 0x00, 0x00, 0x72, 0xf4, 0xfc, 0x80, 0x80,
+ 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
+ 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x00, 0xd2
+ };
+ const guint8 *in[] = { in1 };
+ guint in_len[] = { sizeof (in1) };
+ GstVideoTimeCode in_tc1;
+ const GstVideoTimeCode *in_tc[] = { &in_tc1 };
+
+ const guint8 out1[] = { 0x96, 0x69, 0x30, 0x8f, 0xc3, 0x00, 0x00, 0x71, 0xd0,
+ 0xa0, 0x30, 0x00, 0x72, 0xea, 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74,
+ 0x00, 0x00, 0xe4
+ };
+ const guint8 out2[] = { 0x96, 0x69, 0x30, 0x8f, 0xc3, 0x00, 0x01, 0x71, 0xd0,
+ 0xa0, 0x30, 0x10, 0x72, 0xea, 0xfe, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc,
+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74,
+ 0x00, 0x01, 0xca
+ };
+ const guint8 *out[] = { out1, out2 };
+ guint out_len[] = { sizeof (out1), sizeof (out2) };
+ GstVideoTimeCode out_tc1, out_tc2;
+ const GstVideoTimeCode *out_tc[] = { &out_tc1, &out_tc2 };
+
+ gst_video_time_code_init (&in_tc1, 30, 1, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 4, 0);
+ fail_unless (gst_video_time_code_is_valid (&in_tc1));
+
+ gst_video_time_code_init (&out_tc1, 60, 1, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 8, 0);
+ fail_unless (gst_video_time_code_is_valid (&out_tc1));
+ gst_video_time_code_init (&out_tc2, 60, 1, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 9, 0);
+ fail_unless (gst_video_time_code_is_valid (&out_tc2));
+
+ check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
+ G_N_ELEMENTS (out_len), out, out_len,
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
+ in_tc, out_tc, 0);
+
+ gst_video_time_code_clear (&in_tc1);
+ gst_video_time_code_clear (&out_tc1);
+ gst_video_time_code_clear (&out_tc2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (convert_cea708_cdp_cea708_cdp_half_framerate)
+{
+ /* tests that two input packets are merged together when halving the
+ * framerate */
+ const guint8 in1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
+ 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x00, 0x7a
+ };
+ const guint8 in2[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea,
+ 0xfe, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x01, 0x70
+ };
+ const guint8 *in[] = { in1, in2 };
+ guint in_len[] = { sizeof (in1), sizeof (in2) };
+ GstVideoTimeCode in_tc1, in_tc2;
+ const GstVideoTimeCode *in_tc[] = { &in_tc1, &in_tc2 };
+
+ const guint8 out1[] =
+ { 0x96, 0x69, 0x4e, 0x5f, 0xc3, 0x00, 0x00, 0x71, 0xd0, 0xa0, 0x30, 0x00,
+ 0x72, 0xf4, 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfc,
+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0x74, 0x00, 0x00, 0x2a
+ };
+ const guint8 *out[] = { out1 };
+ guint out_len[] = { sizeof (out1) };
+ GstVideoTimeCode out_tc1;
+ const GstVideoTimeCode *out_tc[] = { &out_tc1 };
+
+ gst_video_time_code_init (&in_tc1, 60, 1, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 8, 0);
+ fail_unless (gst_video_time_code_is_valid (&in_tc1));
+ gst_video_time_code_init (&in_tc2, 60, 1, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 8, 0);
+ fail_unless (gst_video_time_code_is_valid (&in_tc2));
+
+ gst_video_time_code_init (&out_tc1, 30, 1, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_NONE, 1, 2, 3, 4, 0);
+ fail_unless (gst_video_time_code_is_valid (&out_tc1));
+
+ check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
+ G_N_ELEMENTS (out_len), out, out_len,
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1",
+ in_tc, out_tc, 0);
+
+ gst_video_time_code_clear (&in_tc1);
+ gst_video_time_code_clear (&in_tc2);
+ gst_video_time_code_clear (&out_tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (convert_cea708_cdp_cea708_cdp_max_merge)
+{
+ /* check that a low framerate packet can be split into 3 high framerate
+ * packets with the extra data on the third input packet being placed at the
+ * beginning of the second output packet */
+ const guint8 in1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
+ 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x00, 0x7a
+ };
+ /* enough input to fully cover two output packets. Extra is discarded */
+ const guint8 *in[] = { in1, in1, in1, in1, in1, in1, in1 };
+ guint in_len[] =
+ { sizeof (in1), sizeof (in1), sizeof (in1), sizeof (in1), sizeof (in1),
+ sizeof (in1)
+ };
+
+ const guint8 out1[] =
+ { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x00, 0x72, 0xf9, 0xfc, 0x80, 0x80,
+ 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80,
+ 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0x74, 0x00, 0x00, 0x12
+ };
+ const guint8 out2[] =
+ { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x01, 0x72, 0xf9, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0x74, 0x00, 0x01, 0x1a
+ };
+ const guint8 *out[] = { out1, out2 };
+ guint out_len[] = { sizeof (out1), sizeof (out2) };
+ check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
+ G_N_ELEMENTS (out_len), out, out_len,
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)24000/1001",
+ NULL, NULL, 0);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (convert_cea708_cdp_cea708_cdp_max_split)
+{
+ /* test that a low framerate stream produces multiple output packets for a
+ * high framerate */
+ const guint8 in1[] =
+ { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x00, 0x72, 0xf9, 0xfc, 0x80, 0x80,
+ 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80,
+ 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0x74, 0x00, 0x00, 0x12
+ };
+ const guint8 *in[] = { in1, in1 };
+ guint in_len[] = { sizeof (in1), sizeof (in1) };
+
+ const guint8 out1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
+ 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x00, 0x7a
+ };
+ const guint8 out2[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea,
+ 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x01, 0x78
+ };
+ const guint8 out3[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea,
+ 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x02, 0x6c
+ };
+ const guint8 out4[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x03, 0x72, 0xea,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x03, 0x74
+ };
+ const guint8 *out[] = { out1, out2, out3, out4 };
+ guint out_len[] =
+ { sizeof (out1), sizeof (out2), sizeof (out3), sizeof (out4) };
+ check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
+ G_N_ELEMENTS (out_len), out, out_len,
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)24000/1001",
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
+ NULL, NULL, 0);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (convert_cea708_cdp_cea708_cdp_max_split_eos)
+{
+ /* test that a low framerate stream produces multiple output packets for a
+ * high framerate and that an EOS will push the pending data */
+ const guint8 in1[] =
+ { 0x96, 0x69, 0x58, 0x1f, 0x43, 0x00, 0x00, 0x72, 0xf9, 0xfc, 0x80, 0x80,
+ 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80,
+ 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0x74, 0x00, 0x00, 0x12
+ };
+ const guint8 *in[] = { in1 };
+ guint in_len[] = { sizeof (in1) };
+
+ const guint8 out1[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x00, 0x72, 0xea,
+ 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x00, 0x7a
+ };
+ const guint8 out2[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x01, 0x72, 0xea,
+ 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x01, 0x78
+ };
+ const guint8 out3[] = { 0x96, 0x69, 0x2b, 0x8f, 0x43, 0x00, 0x02, 0x72, 0xea,
+ 0xfc, 0x80, 0x80, 0xfe, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf9, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x02, 0x75
+ };
+ const guint8 *out[] = { out1, out2, out3 };
+ guint out_len[] = { sizeof (out1), sizeof (out2), sizeof (out3) };
+
+ check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
+ G_N_ELEMENTS (out_len), out, out_len,
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)24000/1001",
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
+ NULL, NULL, FLAG_SEND_EOS);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (convert_cea708_cdp_cea708_cdp_from_drop_frame_scaling)
+{
+ const guint8 in1[] = { 0x96, 0x69, 0x10, 0x7f, 0x43, 0x00, 0x00, 0x72, 0xe1,
+ 0xfc, 0x80, 0x80, 0x74, 0x00, 0x00, 0x7a
+ };
+ const guint8 *in[] = { in1, in1 };
+ guint in_len[] = { sizeof (in1), sizeof (in1) };
+ GstVideoTimeCode in_tc1, in_tc2;
+ const GstVideoTimeCode *in_tc[] = { &in_tc1, &in_tc2 };
+
+ const guint8 out1[] =
+ { 0x96, 0x69, 0x30, 0x8f, 0xc3, 0x00, 0x00, 0x71, 0xc0, 0x90, 0x12, 0x12,
+ 0x72, 0xea, 0xfc, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x00, 0x16
+ };
+ const guint8 out2[] =
+ { 0x96, 0x69, 0x30, 0x8f, 0xc3, 0x00, 0x01, 0x71, 0xc0, 0xa0, 0x00, 0x00,
+ 0x72, 0xea, 0xfc, 0x80, 0x80, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x74, 0x00, 0x01, 0x28
+ };
+ const guint8 *out[] = { out1, out2 };
+ guint out_len[] = { sizeof (out1), sizeof (out2) };
+ GstVideoTimeCode out_tc1, out_tc2;
+ const GstVideoTimeCode *out_tc[] = { &out_tc1, &out_tc2 };
+
+ gst_video_time_code_init (&in_tc1, 60000, 1001, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0, 1, 59, 59, 0);
+ fail_unless (gst_video_time_code_is_valid (&in_tc1));
+
+ gst_video_time_code_init (&in_tc2, 60000, 1001, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 0, 2, 0, 4, 0);
+ fail_unless (gst_video_time_code_is_valid (&in_tc2));
+
+ gst_video_time_code_init (&out_tc1, 60, 1, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 1, 59, 59, 0);
+ fail_unless (gst_video_time_code_is_valid (&out_tc1));
+
+ gst_video_time_code_init (&out_tc2, 60, 1, NULL,
+ GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 2, 0, 0, 0);
+ fail_unless (gst_video_time_code_is_valid (&out_tc2));
+
+ check_conversion_multiple (G_N_ELEMENTS (in_len), in, in_len,
+ G_N_ELEMENTS (out_len), out, out_len,
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60000/1001",
+ "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)60/1",
+ in_tc, out_tc, FLAG_SEND_EOS);
+
+ gst_video_time_code_clear (&in_tc1);
+ gst_video_time_code_clear (&out_tc1);
+}
+
+GST_END_TEST;
+
static Suite *
ccextractor_suite (void)
{
@@ -389,6 +762,7 @@ ccextractor_suite (void)
tcase_add_test (tc, cdp_requires_framerate);
tcase_add_test (tc, framerate_passthrough);
+ tcase_add_test (tc, framerate_changes);
tcase_add_test (tc, convert_cea608_raw_cea608_s334_1a);
tcase_add_test (tc, convert_cea608_raw_cea708_cc_data);
tcase_add_test (tc, convert_cea608_raw_cea708_cdp);
@@ -403,6 +777,12 @@ ccextractor_suite (void)
tcase_add_test (tc, convert_cea708_cdp_cea608_s334_1a);
tcase_add_test (tc, convert_cea708_cdp_cea708_cc_data);
tcase_add_test (tc, convert_cea708_cdp_cea708_cc_data_too_big);
+ tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_half_framerate);
+ tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_double_framerate);
+ tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_max_merge);
+ tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_max_split);
+ tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_max_split_eos);
+ tcase_add_test (tc, convert_cea708_cdp_cea708_cdp_from_drop_frame_scaling);
return s;
}