mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 12:49:40 +00:00
Add support for extracting CEA608 S334-1 Closed Captions and add a property to select which ones to extract
This commit is contained in:
parent
eadd35363a
commit
e53a017ee7
4 changed files with 131 additions and 3 deletions
|
@ -1057,6 +1057,34 @@ GType gst_aja_timecode_index_get_type(void) {
|
|||
return (GType)id;
|
||||
}
|
||||
|
||||
GType gst_aja_closed_caption_capture_mode_get_type(void) {
|
||||
static gsize id = 0;
|
||||
static const GEnumValue modes[] = {
|
||||
{GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_AND_CEA608,
|
||||
"cea708-and-cea608",
|
||||
"CEA708 S334-2 and CEA608 S334-1 Annex A Closed Captions"},
|
||||
{GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_OR_CEA608, "cea708-or-cea608",
|
||||
"CEA708 S334-2 or if not existing CEA608 S334-1 Annex A Closed "
|
||||
"Captions"},
|
||||
{GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA608_OR_CEA708, "cea608-or-cea708",
|
||||
"CEA608 S334-1 Annex A or if not existing CEA708 S334-2 Closed "
|
||||
"Captions"},
|
||||
{GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_ONLY, "cea708-only",
|
||||
"CEA708 S334-2 Closed Captions only"},
|
||||
{GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA608_ONLY, "cea608-only",
|
||||
"CEA608 S334-1 Annex A Closed Captions only"},
|
||||
{GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_NONE, "none",
|
||||
"Don't capture Closed Captions"},
|
||||
{0, NULL, NULL}};
|
||||
|
||||
if (g_once_init_enter(&id)) {
|
||||
GType tmp = g_enum_register_static("GstAjaClosedCaptionCaptureMode", modes);
|
||||
g_once_init_leave(&id, tmp);
|
||||
}
|
||||
|
||||
return (GType)id;
|
||||
}
|
||||
|
||||
void gst_aja_common_init(void) {
|
||||
GST_DEBUG_CATEGORY_INIT(gst_aja_debug, "aja", 0,
|
||||
"Debug category for AJA plugin");
|
||||
|
|
|
@ -277,6 +277,20 @@ typedef enum {
|
|||
G_GNUC_INTERNAL
|
||||
GType gst_aja_timecode_index_get_type(void);
|
||||
|
||||
typedef enum {
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_AND_CEA608,
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_OR_CEA608,
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA608_OR_CEA708,
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_ONLY,
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA608_ONLY,
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_NONE,
|
||||
} GstAjaClosedCaptionCaptureMode;
|
||||
|
||||
#define GST_TYPE_AJA_CLOSED_CAPTION_CAPTURE_MODE \
|
||||
(gst_aja_closed_caption_capture_mode_get_type())
|
||||
G_GNUC_INTERNAL
|
||||
GType gst_aja_closed_caption_capture_mode_get_type(void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void gst_aja_common_init(void);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <ajaanc/includes/ancillarydata_cea608_vanc.h>
|
||||
#include <ajaanc/includes/ancillarydata_cea708.h>
|
||||
#include <ajaanc/includes/ancillarylist.h>
|
||||
#include <ajantv2/includes/ntv2rp188.h>
|
||||
|
@ -41,6 +42,8 @@ GST_DEBUG_CATEGORY_STATIC(gst_aja_src_debug);
|
|||
#define DEFAULT_AUDIO_SOURCE (GST_AJA_AUDIO_SOURCE_EMBEDDED)
|
||||
#define DEFAULT_TIMECODE_INDEX (GST_AJA_TIMECODE_INDEX_VITC)
|
||||
#define DEFAULT_REFERENCE_SOURCE (GST_AJA_REFERENCE_SOURCE_FREERUN)
|
||||
#define DEFAULT_CLOSED_CAPTION_CAPTURE_MODE \
|
||||
(GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_AND_CEA608)
|
||||
#define DEFAULT_QUEUE_SIZE (16)
|
||||
#define DEFAULT_START_FRAME (8)
|
||||
#define DEFAULT_END_FRAME (8)
|
||||
|
@ -57,6 +60,7 @@ enum {
|
|||
PROP_AUDIO_SOURCE,
|
||||
PROP_TIMECODE_INDEX,
|
||||
PROP_REFERENCE_SOURCE,
|
||||
PROP_CLOSED_CAPTION_CAPTURE_MODE,
|
||||
PROP_START_FRAME,
|
||||
PROP_END_FRAME,
|
||||
PROP_QUEUE_SIZE,
|
||||
|
@ -218,6 +222,16 @@ static void gst_aja_src_class_init(GstAjaSrcClass *klass) {
|
|||
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT)));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class, PROP_CLOSED_CAPTION_CAPTURE_MODE,
|
||||
g_param_spec_enum(
|
||||
"closed-caption-capture-mode", "Closed Caption Capture Mode",
|
||||
"Closed Caption Capture Mode",
|
||||
GST_TYPE_AJA_CLOSED_CAPTION_CAPTURE_MODE,
|
||||
DEFAULT_CLOSED_CAPTION_CAPTURE_MODE,
|
||||
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT)));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class, PROP_CAPTURE_CPU_CORE,
|
||||
g_param_spec_uint(
|
||||
|
@ -274,6 +288,7 @@ static void gst_aja_src_init(GstAjaSrc *self) {
|
|||
self->audio_source = DEFAULT_AUDIO_SOURCE;
|
||||
self->timecode_index = DEFAULT_TIMECODE_INDEX;
|
||||
self->reference_source = DEFAULT_REFERENCE_SOURCE;
|
||||
self->closed_caption_capture_mode = DEFAULT_CLOSED_CAPTION_CAPTURE_MODE;
|
||||
self->capture_cpu_core = DEFAULT_CAPTURE_CPU_CORE;
|
||||
|
||||
self->queue =
|
||||
|
@ -326,6 +341,10 @@ void gst_aja_src_set_property(GObject *object, guint property_id,
|
|||
case PROP_REFERENCE_SOURCE:
|
||||
self->reference_source = (GstAjaReferenceSource)g_value_get_enum(value);
|
||||
break;
|
||||
case PROP_CLOSED_CAPTION_CAPTURE_MODE:
|
||||
self->closed_caption_capture_mode =
|
||||
(GstAjaClosedCaptionCaptureMode)g_value_get_enum(value);
|
||||
break;
|
||||
case PROP_CAPTURE_CPU_CORE:
|
||||
self->capture_cpu_core = g_value_get_uint(value);
|
||||
break;
|
||||
|
@ -376,6 +395,9 @@ void gst_aja_src_get_property(GObject *object, guint property_id, GValue *value,
|
|||
case PROP_REFERENCE_SOURCE:
|
||||
g_value_set_enum(value, self->reference_source);
|
||||
break;
|
||||
case PROP_CLOSED_CAPTION_CAPTURE_MODE:
|
||||
g_value_set_enum(value, self->closed_caption_capture_mode);
|
||||
break;
|
||||
case PROP_CAPTURE_CPU_CORE:
|
||||
g_value_set_uint(value, self->capture_cpu_core);
|
||||
break;
|
||||
|
@ -1680,17 +1702,80 @@ static GstFlowReturn gst_aja_src_create(GstPushSrc *psrc, GstBuffer **buffer) {
|
|||
//
|
||||
// See AJA SDK support ticket #4844.
|
||||
guint32 n_vanc_packets = anc_packets.CountAncillaryData();
|
||||
|
||||
// Check if we have either CEA608 or CEA708 packets, or both.
|
||||
bool have_cea608 = false;
|
||||
bool have_cea708 = false;
|
||||
for (guint32 i = 0; i < n_vanc_packets; i++) {
|
||||
AJAAncillaryData *packet = anc_packets.GetAncillaryDataAtIndex(i);
|
||||
|
||||
if (packet->GetDID() == AJAAncillaryData_Cea608_Vanc_DID &&
|
||||
packet->GetSID() == AJAAncillaryData_Cea608_Vanc_SID &&
|
||||
packet->GetPayloadData() && packet->GetPayloadByteCount() &&
|
||||
AJA_SUCCESS(packet->ParsePayloadData())) {
|
||||
GST_TRACE_OBJECT(
|
||||
self, "Found CEA608 VANC of %" G_GSIZE_FORMAT " bytes at line %u",
|
||||
packet->GetPayloadByteCount(), packet->GetLocationLineNumber());
|
||||
have_cea608 = true;
|
||||
} else if (packet->GetDID() == AJAAncillaryData_CEA708_DID &&
|
||||
packet->GetSID() == AJAAncillaryData_CEA708_SID &&
|
||||
packet->GetPayloadData() && packet->GetPayloadByteCount() &&
|
||||
AJA_SUCCESS(packet->ParsePayloadData())) {
|
||||
GST_TRACE_OBJECT(
|
||||
self, "Found CEA708 CDP VANC of %" G_GSIZE_FORMAT " bytes at line %u",
|
||||
packet->GetPayloadByteCount(), packet->GetLocationLineNumber());
|
||||
have_cea708 = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Decide based on the closed-caption-capture-mode property and closed
|
||||
// caption availability which ones to add as metadata to the output buffer.
|
||||
bool want_cea608 =
|
||||
have_cea608 &&
|
||||
(self->closed_caption_capture_mode ==
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_AND_CEA608 ||
|
||||
self->closed_caption_capture_mode ==
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA608_OR_CEA708 ||
|
||||
self->closed_caption_capture_mode ==
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA608_ONLY ||
|
||||
(!have_cea708 &&
|
||||
self->closed_caption_capture_mode ==
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_OR_CEA608));
|
||||
|
||||
bool want_cea708 =
|
||||
have_cea708 &&
|
||||
(self->closed_caption_capture_mode ==
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_AND_CEA608 ||
|
||||
self->closed_caption_capture_mode ==
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_OR_CEA608 ||
|
||||
self->closed_caption_capture_mode ==
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA708_ONLY ||
|
||||
(!have_cea608 &&
|
||||
self->closed_caption_capture_mode ==
|
||||
GST_AJA_CLOSED_CAPTION_CAPTURE_MODE_CEA608_OR_CEA708));
|
||||
|
||||
bool aspect_ratio_flag = false;
|
||||
bool have_afd_bar = false;
|
||||
for (guint32 i = 0; i < n_vanc_packets; i++) {
|
||||
AJAAncillaryData *packet = anc_packets.GetAncillaryDataAtIndex(i);
|
||||
|
||||
if (packet->GetDID() == AJAAncillaryData_CEA708_DID &&
|
||||
packet->GetSID() == AJAAncillaryData_CEA708_SID &&
|
||||
if (want_cea608 && packet->GetDID() == AJAAncillaryData_Cea608_Vanc_DID &&
|
||||
packet->GetSID() == AJAAncillaryData_Cea608_Vanc_SID &&
|
||||
packet->GetPayloadData() && packet->GetPayloadByteCount() &&
|
||||
AJA_SUCCESS(packet->ParsePayloadData())) {
|
||||
GST_TRACE_OBJECT(
|
||||
self, "Found CEA708 CDP VANC of %" G_GSIZE_FORMAT " bytes at line %u",
|
||||
self, "Adding CEA608 VANC of %" G_GSIZE_FORMAT " bytes at line %u",
|
||||
packet->GetPayloadByteCount(), packet->GetLocationLineNumber());
|
||||
gst_buffer_add_video_caption_meta(
|
||||
*buffer, GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A,
|
||||
packet->GetPayloadData(), packet->GetPayloadByteCount());
|
||||
} else if (want_cea708 && packet->GetDID() == AJAAncillaryData_CEA708_DID &&
|
||||
packet->GetSID() == AJAAncillaryData_CEA708_SID &&
|
||||
packet->GetPayloadData() && packet->GetPayloadByteCount() &&
|
||||
AJA_SUCCESS(packet->ParsePayloadData())) {
|
||||
GST_TRACE_OBJECT(
|
||||
self,
|
||||
"Adding CEA708 CDP VANC of %" G_GSIZE_FORMAT " bytes at line %u",
|
||||
packet->GetPayloadByteCount(), packet->GetLocationLineNumber());
|
||||
gst_buffer_add_video_caption_meta(
|
||||
*buffer, GST_VIDEO_CAPTION_TYPE_CEA708_CDP, packet->GetPayloadData(),
|
||||
|
|
|
@ -69,6 +69,7 @@ struct _GstAjaSrc {
|
|||
GstAjaAudioSource audio_source;
|
||||
GstAjaTimecodeIndex timecode_index;
|
||||
GstAjaReferenceSource reference_source;
|
||||
GstAjaClosedCaptionCaptureMode closed_caption_capture_mode;
|
||||
guint queue_size;
|
||||
guint start_frame, end_frame;
|
||||
guint capture_cpu_core;
|
||||
|
|
Loading…
Reference in a new issue