closedcaption: Replace GST_VIDEO_CAPTION_TYPE_CEA608_IN_CEA708_RAW with CEA608_S334_1A

As a side-effect we can now actually store the line offset in the
line21dec element, and have to perform fewer transformations in the
decklink elements (which were also buggy as they assumed a single byte
triplet per meta).
This commit is contained in:
Sebastian Dröge 2018-12-10 15:54:49 +02:00 committed by Sebastian Dröge
parent f9e4ed99b0
commit 48f48cc4ba
5 changed files with 23 additions and 32 deletions

View file

@ -48,7 +48,7 @@ static GstStaticPadTemplate captiontemplate =
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_REQUEST, GST_PAD_REQUEST,
GST_STATIC_CAPS GST_STATIC_CAPS
("closedcaption/x-cea-608,format={ (string) raw, (string) cc_data}; " ("closedcaption/x-cea-608,format={ (string) raw, (string) s334-1a}; "
"closedcaption/x-cea-708,format={ (string) cc_data, (string) cdp }")); "closedcaption/x-cea-708,format={ (string) cc_data, (string) cdp }"));
G_DEFINE_TYPE (GstCCCombiner, gst_cc_combiner, GST_TYPE_AGGREGATOR); G_DEFINE_TYPE (GstCCCombiner, gst_cc_combiner, GST_TYPE_AGGREGATOR);
@ -353,9 +353,8 @@ gst_cc_combiner_sink_event (GstAggregator * aggregator,
if (gst_structure_has_name (s, "closedcaption/x-cea-608")) { if (gst_structure_has_name (s, "closedcaption/x-cea-608")) {
if (strcmp (format, "raw") == 0) { if (strcmp (format, "raw") == 0) {
self->current_caption_type = GST_VIDEO_CAPTION_TYPE_CEA608_RAW; self->current_caption_type = GST_VIDEO_CAPTION_TYPE_CEA608_RAW;
} else if (strcmp (format, "cc_data") == 0) { } else if (strcmp (format, "s334-1a") == 0) {
self->current_caption_type = self->current_caption_type = GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A;
GST_VIDEO_CAPTION_TYPE_CEA608_IN_CEA708_RAW;
} else { } else {
g_assert_not_reached (); g_assert_not_reached ();
} }

View file

@ -57,7 +57,7 @@ static GstStaticPadTemplate captiontemplate =
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_SOMETIMES, GST_PAD_SOMETIMES,
GST_STATIC_CAPS GST_STATIC_CAPS
("closedcaption/x-cea-608,format={ (string) raw, (string) cc_data}; " ("closedcaption/x-cea-608,format={ (string) raw, (string) s334-1a}; "
"closedcaption/x-cea-708,format={ (string) cc_data, (string) cdp }")); "closedcaption/x-cea-708,format={ (string) cc_data, (string) cdp }"));
G_DEFINE_TYPE (GstCCExtractor, gst_cc_extractor, GST_TYPE_ELEMENT); G_DEFINE_TYPE (GstCCExtractor, gst_cc_extractor, GST_TYPE_ELEMENT);
@ -284,9 +284,9 @@ create_caps_from_caption_type (GstVideoCaptionType caption_type,
caption_caps = gst_caps_new_simple ("closedcaption/x-cea-608", caption_caps = gst_caps_new_simple ("closedcaption/x-cea-608",
"format", G_TYPE_STRING, "raw", NULL); "format", G_TYPE_STRING, "raw", NULL);
break; break;
case GST_VIDEO_CAPTION_TYPE_CEA608_IN_CEA708_RAW: case GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A:
caption_caps = gst_caps_new_simple ("closedcaption/x-cea-608", caption_caps = gst_caps_new_simple ("closedcaption/x-cea-608",
"format", G_TYPE_STRING, "cc_data", NULL); "format", G_TYPE_STRING, "s334-1a", NULL);
break; break;
case GST_VIDEO_CAPTION_TYPE_CEA708_RAW: case GST_VIDEO_CAPTION_TYPE_CEA708_RAW:
caption_caps = gst_caps_new_simple ("closedcaption/x-cea-708", caption_caps = gst_caps_new_simple ("closedcaption/x-cea-708",

View file

@ -408,13 +408,25 @@ gst_line_21_decoder_scan (GstLine21Decoder * self, GstVideoFrame * frame)
GST_DEBUG_OBJECT (self, "No CC found"); GST_DEBUG_OBJECT (self, "No CC found");
self->line21_offset = -1; self->line21_offset = -1;
} else { } else {
guint8 ccdata[6] = { 0xfc, 0x80, 0x80, 0xfd, 0x80, 0x80 }; /* Initialize the ccdata */ guint base_line1 = 0, base_line2 = 0;
guint8 ccdata[6] = { 0x80, 0x80, 0x80, 0x00, 0x80, 0x80 }; /* Initialize the ccdata */
if (GST_VIDEO_FRAME_HEIGHT (frame) == 525) {
base_line1 = 9;
base_line2 = 272;
} else if (GST_VIDEO_FRAME_HEIGHT (frame) == 625) {
base_line1 = 5;
base_line2 = 318;
}
ccdata[0] |= (base_line1 < i ? i - base_line1 : 0) & 0x1f;
ccdata[1] = sliced[0].data[0]; ccdata[1] = sliced[0].data[0];
ccdata[2] = sliced[0].data[1]; ccdata[2] = sliced[0].data[1];
ccdata[3] |= (base_line2 < i ? i - base_line2 : 0) & 0x1f;
ccdata[4] = sliced[1].data[0]; ccdata[4] = sliced[1].data[0];
ccdata[5] = sliced[1].data[1]; ccdata[5] = sliced[1].data[1];
gst_buffer_add_video_caption_meta (frame->buffer, gst_buffer_add_video_caption_meta (frame->buffer,
GST_VIDEO_CAPTION_TYPE_CEA608_IN_CEA708_RAW, ccdata, 6); GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A, ccdata, 6);
GST_TRACE_OBJECT (self, GST_TRACE_OBJECT (self,
"Got CC 0x%02x 0x%02x / 0x%02x 0x%02x '%c%c / %c%c'", ccdata[1], "Got CC 0x%02x 0x%02x / 0x%02x 0x%02x '%c%c / %c%c'", ccdata[1],
ccdata[2], ccdata[4], ccdata[5], ccdata[2], ccdata[4], ccdata[5],

View file

@ -808,26 +808,11 @@ gst_decklink_video_sink_prepare (GstBaseSink * bsink, GstBuffer * buffer)
break; break;
} }
case GST_VIDEO_CAPTION_TYPE_CEA608_IN_CEA708_RAW:{ case GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A:{
guint8 data[3];
/* This is the offset from line 9 for 525-line fields and from line
* 5 for 625-line fields.
*
* The highest bit is set for field 1 but not for field 0
*/
data[0] =
self->info.height ==
525 ? self->caption_line - 9 : self->caption_line - 5;
if (cc_meta->data[0] == 0xFD)
data[0] |= 0x80;
data[1] = cc_meta->data[1];
data[2] = cc_meta->data[2];
if (!gst_video_vbi_encoder_add_ancillary (self->vbiencoder, if (!gst_video_vbi_encoder_add_ancillary (self->vbiencoder,
FALSE, FALSE,
GST_VIDEO_ANCILLARY_DID16_S334_EIA_708 >> 8, GST_VIDEO_ANCILLARY_DID16_S334_EIA_708 >> 8,
GST_VIDEO_ANCILLARY_DID16_S334_EIA_708 & 0xff, data, 3)) GST_VIDEO_ANCILLARY_DID16_S334_EIA_708 & 0xff, cc_meta->data, cc_meta->size))
GST_WARNING_OBJECT (self, "Couldn't add meta to ancillary data"); GST_WARNING_OBJECT (self, "Couldn't add meta to ancillary data");
got_captions = TRUE; got_captions = TRUE;

View file

@ -850,13 +850,8 @@ extract_cc_from_vbi (GstDecklinkVideoSrc * self, GstBuffer ** buffer,
GST_DEBUG_OBJECT (self, GST_DEBUG_OBJECT (self,
"Adding CEA-608 meta to buffer for line %d", fi); "Adding CEA-608 meta to buffer for line %d", fi);
GST_MEMDUMP_OBJECT (self, "CEA608", gstanc.data, gstanc.data_count); GST_MEMDUMP_OBJECT (self, "CEA608", gstanc.data, gstanc.data_count);
/* The first byte actually contains the field and line offset but
* for CEA608-in-CEA708 we can't store the line offset, and it's
* generally not needed
*/
gstanc.data[0] = (gstanc.data[0] & 0x80) ? 0xFD : 0xFC;
gst_buffer_add_video_caption_meta (*buffer, gst_buffer_add_video_caption_meta (*buffer,
GST_VIDEO_CAPTION_TYPE_CEA608_IN_CEA708_RAW, gstanc.data, GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A, gstanc.data,
gstanc.data_count); gstanc.data_count);
break; break;
default: default: