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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1554>
This commit is contained in:
Mathieu Duponchelle 2020-09-04 02:38:58 +02:00
parent 1d416750d1
commit c07e2a89ba
3 changed files with 15 additions and 8 deletions

View file

@ -3426,12 +3426,12 @@
"long-name": "Line 21 CC Encoder", "long-name": "Line 21 CC Encoder",
"pad-templates": { "pad-templates": {
"sink": { "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", "direction": "sink",
"presence": "always" "presence": "always"
}, },
"src": { "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", "direction": "src",
"presence": "always" "presence": "always"
} }

View file

@ -39,7 +39,8 @@
GST_DEBUG_CATEGORY_STATIC (gst_line_21_encoder_debug); GST_DEBUG_CATEGORY_STATIC (gst_line_21_encoder_debug);
#define GST_CAT_DEFAULT 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", static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
@ -370,6 +371,7 @@ gst_line_21_encoder_transform_ip (GstVideoFilter * filter,
vbi_sliced sliced[2]; vbi_sliced sliced[2];
gpointer iter = NULL; gpointer iter = NULL;
GstFlowReturn ret = GST_FLOW_ERROR; GstFlowReturn ret = GST_FLOW_ERROR;
guint offset;
sliced[0].id = VBI_SLICED_CAPTION_525_F1; sliced[0].id = VBI_SLICED_CAPTION_525_F1;
sliced[0].line = self->sp.start[0]; sliced[0].line = self->sp.start[0];
@ -447,9 +449,14 @@ gst_line_21_encoder_transform_ip (GstVideoFilter * filter,
if (cc_meta) if (cc_meta)
gst_buffer_remove_meta (frame->buffer, (GstMeta *) 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 = buf =
(guint8 *) GST_VIDEO_FRAME_PLANE_DATA (frame, (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, if (!vbi_raw_video_image (buf, GST_VIDEO_INFO_COMP_STRIDE (&self->info,
0) * 2, &self->sp, 0, 0, 0, 0x000000FF, 0, sliced, 2)) { 0) * 2, &self->sp, 0, 0, 0, 0x000000FF, 0, sliced, 2)) {

View file

@ -33,12 +33,12 @@ GST_START_TEST (basic)
GstVideoInfo info; GstVideoInfo info;
GstVideoCaptionMeta *in_cc_meta, *out_cc_meta; GstVideoCaptionMeta *in_cc_meta, *out_cc_meta;
guint i; guint i;
guint8 empty_data[] = { 0x90, 0x80, 0x80, 0x0, 0x80, 0x80 }; guint8 empty_data[] = { 0x8c, 0x80, 0x80, 0x0, 0x80, 0x80 };
guint8 full_data[] = { 0x90, 0x42, 0x43, 0x0, 0x44, 0x45 }; guint8 full_data[] = { 0x8c, 0x42, 0x43, 0x0, 0x44, 0x45 };
GstCaps *caps = gst_caps_new_simple ("video/x-raw", GstCaps *caps = gst_caps_new_simple ("video/x-raw",
"format", G_TYPE_STRING, "I420", "format", G_TYPE_STRING, "I420",
"width", G_TYPE_INT, 720, "width", G_TYPE_INT, 720,
"height", G_TYPE_INT, 625, "height", G_TYPE_INT, 525,
"interlace-mode", G_TYPE_STRING, "interleaved", "interlace-mode", G_TYPE_STRING, "interleaved",
NULL); NULL);
@ -62,7 +62,7 @@ GST_START_TEST (basic)
fail_unless (out_cc_meta->size == 6); fail_unless (out_cc_meta->size == 6);
for (i = 0; i < out_cc_meta->size; i++) 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); gst_buffer_unref (outbuf);