From c07e2a89ba96350965c59a97eaa4b442183fbe6f Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Fri, 4 Sep 2020 02:38:58 +0200 Subject: [PATCH] line21enc: heavily constrain video height We can only determine a correct placement for the CC line with: * height == 525 (standard NTSC, line 21 / 22) * height == 486 (NTSC usable lines + 6 lines for VBI, line 1 / 2) Part-of: --- docs/plugins/gst_plugins_cache.json | 4 ++-- ext/closedcaption/gstline21enc.c | 11 +++++++++-- tests/check/elements/line21.c | 8 ++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/docs/plugins/gst_plugins_cache.json b/docs/plugins/gst_plugins_cache.json index ecda85becf..e69a334c36 100644 --- a/docs/plugins/gst_plugins_cache.json +++ b/docs/plugins/gst_plugins_cache.json @@ -3426,12 +3426,12 @@ "long-name": "Line 21 CC Encoder", "pad-templates": { "sink": { - "caps": "video/x-raw:\n format: { I420, YUY2, YVYU, UYVY, VYUY }\n width: 720\n height: [ 23, 2147483647 ]\n interlace-mode: interleaved\n", + "caps": "video/x-raw:\n format: { I420, YUY2, YVYU, UYVY, VYUY }\n width: 720\n height: { (int)525, (int)486 }\n interlace-mode: interleaved\n", "direction": "sink", "presence": "always" }, "src": { - "caps": "video/x-raw:\n format: { I420, YUY2, YVYU, UYVY, VYUY }\n width: 720\n height: [ 23, 2147483647 ]\n interlace-mode: interleaved\n", + "caps": "video/x-raw:\n format: { I420, YUY2, YVYU, UYVY, VYUY }\n width: 720\n height: { (int)525, (int)486 }\n interlace-mode: interleaved\n", "direction": "src", "presence": "always" } diff --git a/ext/closedcaption/gstline21enc.c b/ext/closedcaption/gstline21enc.c index 424b625c85..6c9d13c094 100644 --- a/ext/closedcaption/gstline21enc.c +++ b/ext/closedcaption/gstline21enc.c @@ -39,7 +39,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_line_21_encoder_debug); #define GST_CAT_DEFAULT gst_line_21_encoder_debug -#define CAPS "video/x-raw, format={ I420, YUY2, YVYU, UYVY, VYUY }, width=(int)720, height=(int)[ 23, MAX ], interlace-mode=interleaved" +/* FIXME: add and test support for PAL resolutions */ +#define CAPS "video/x-raw, format={ I420, YUY2, YVYU, UYVY, VYUY }, width=(int)720, height=(int){ 525, 486 }, interlace-mode=interleaved" static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, @@ -370,6 +371,7 @@ gst_line_21_encoder_transform_ip (GstVideoFilter * filter, vbi_sliced sliced[2]; gpointer iter = NULL; GstFlowReturn ret = GST_FLOW_ERROR; + guint offset; sliced[0].id = VBI_SLICED_CAPTION_525_F1; sliced[0].line = self->sp.start[0]; @@ -447,9 +449,14 @@ gst_line_21_encoder_transform_ip (GstVideoFilter * filter, if (cc_meta) gst_buffer_remove_meta (frame->buffer, (GstMeta *) cc_meta); + /* When dealing with standard NTSC resolution, field 1 goes at line 21, + * when dealing with a reduced height the image has 3 VBI lines at the + * top and 3 at the bottom, and field 1 goes at line 1 */ + offset = self->info.height == 525 ? 21 : 1; + buf = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (frame, - 0) + 21 * GST_VIDEO_INFO_COMP_STRIDE (&self->info, 0); + 0) + offset * GST_VIDEO_INFO_COMP_STRIDE (&self->info, 0); if (!vbi_raw_video_image (buf, GST_VIDEO_INFO_COMP_STRIDE (&self->info, 0) * 2, &self->sp, 0, 0, 0, 0x000000FF, 0, sliced, 2)) { diff --git a/tests/check/elements/line21.c b/tests/check/elements/line21.c index 02547ec5a0..2a507fa94e 100644 --- a/tests/check/elements/line21.c +++ b/tests/check/elements/line21.c @@ -33,12 +33,12 @@ GST_START_TEST (basic) GstVideoInfo info; GstVideoCaptionMeta *in_cc_meta, *out_cc_meta; guint i; - guint8 empty_data[] = { 0x90, 0x80, 0x80, 0x0, 0x80, 0x80 }; - guint8 full_data[] = { 0x90, 0x42, 0x43, 0x0, 0x44, 0x45 }; + guint8 empty_data[] = { 0x8c, 0x80, 0x80, 0x0, 0x80, 0x80 }; + guint8 full_data[] = { 0x8c, 0x42, 0x43, 0x0, 0x44, 0x45 }; GstCaps *caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "I420", "width", G_TYPE_INT, 720, - "height", G_TYPE_INT, 625, + "height", G_TYPE_INT, 525, "interlace-mode", G_TYPE_STRING, "interleaved", NULL); @@ -62,7 +62,7 @@ GST_START_TEST (basic) fail_unless (out_cc_meta->size == 6); for (i = 0; i < out_cc_meta->size; i++) - fail_unless (out_cc_meta->data[i] == empty_data[i]); + fail_unless_equals_int (out_cc_meta->data[i], empty_data[i]); gst_buffer_unref (outbuf);