ajasrc: Add GstAncillaryMeta for any HANC/VANC ancillary data that is captured
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5488>
This commit is contained in:
parent
b0de86ff68
commit
efa7e70d16
@ -719,6 +719,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"attach-ancillary-meta": {
|
||||||
|
"blurb": "Attach ancillary meta to video frames",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": true,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"default": "false",
|
||||||
|
"mutable": "null",
|
||||||
|
"readable": true,
|
||||||
|
"type": "gboolean",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
"audio-source": {
|
"audio-source": {
|
||||||
"blurb": "Audio source to use",
|
"blurb": "Audio source to use",
|
||||||
"conditionally-available": false,
|
"conditionally-available": false,
|
||||||
|
@ -78,6 +78,7 @@ GST_DEBUG_CATEGORY_STATIC(gst_aja_src_debug);
|
|||||||
#define DEFAULT_START_FRAME (8)
|
#define DEFAULT_START_FRAME (8)
|
||||||
#define DEFAULT_END_FRAME (8)
|
#define DEFAULT_END_FRAME (8)
|
||||||
#define DEFAULT_CAPTURE_CPU_CORE (G_MAXUINT)
|
#define DEFAULT_CAPTURE_CPU_CORE (G_MAXUINT)
|
||||||
|
#define DEFAULT_ATTACH_ANCILLARY_META (FALSE)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -98,6 +99,7 @@ enum {
|
|||||||
PROP_QUEUE_SIZE,
|
PROP_QUEUE_SIZE,
|
||||||
PROP_CAPTURE_CPU_CORE,
|
PROP_CAPTURE_CPU_CORE,
|
||||||
PROP_SIGNAL,
|
PROP_SIGNAL,
|
||||||
|
PROP_ATTACH_ANCILLARY_META,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make these plain C structs for usage in GstQueueArray
|
// Make these plain C structs for usage in GstQueueArray
|
||||||
@ -352,6 +354,22 @@ static void gst_aja_src_class_init(GstAjaSrcClass *klass) {
|
|||||||
"True if there is a valid input signal available", FALSE,
|
"True if there is a valid input signal available", FALSE,
|
||||||
(GParamFlags)(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
|
(GParamFlags)(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstAjaSrc:attach-ancillary-meta:
|
||||||
|
*
|
||||||
|
* If set to %TRUE attach any ancillary data as #GstAncillaryMeta on buffers
|
||||||
|
*
|
||||||
|
* Since: 1.24
|
||||||
|
*/
|
||||||
|
g_object_class_install_property(
|
||||||
|
gobject_class, PROP_ATTACH_ANCILLARY_META,
|
||||||
|
g_param_spec_boolean(
|
||||||
|
"attach-ancillary-meta", "Attach Ancillary Meta",
|
||||||
|
"Attach ancillary meta to video frames",
|
||||||
|
DEFAULT_ATTACH_ANCILLARY_META,
|
||||||
|
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
G_PARAM_CONSTRUCT)));
|
||||||
|
|
||||||
element_class->change_state = GST_DEBUG_FUNCPTR(gst_aja_src_change_state);
|
element_class->change_state = GST_DEBUG_FUNCPTR(gst_aja_src_change_state);
|
||||||
|
|
||||||
basesrc_class->get_caps = GST_DEBUG_FUNCPTR(gst_aja_src_get_caps);
|
basesrc_class->get_caps = GST_DEBUG_FUNCPTR(gst_aja_src_get_caps);
|
||||||
@ -394,6 +412,7 @@ static void gst_aja_src_init(GstAjaSrc *self) {
|
|||||||
self->reference_source = DEFAULT_REFERENCE_SOURCE;
|
self->reference_source = DEFAULT_REFERENCE_SOURCE;
|
||||||
self->closed_caption_capture_mode = DEFAULT_CLOSED_CAPTION_CAPTURE_MODE;
|
self->closed_caption_capture_mode = DEFAULT_CLOSED_CAPTION_CAPTURE_MODE;
|
||||||
self->capture_cpu_core = DEFAULT_CAPTURE_CPU_CORE;
|
self->capture_cpu_core = DEFAULT_CAPTURE_CPU_CORE;
|
||||||
|
self->attach_ancillary_meta = DEFAULT_ATTACH_ANCILLARY_META;
|
||||||
|
|
||||||
self->queue =
|
self->queue =
|
||||||
gst_queue_array_new_for_struct(sizeof(QueueItem), self->queue_size);
|
gst_queue_array_new_for_struct(sizeof(QueueItem), self->queue_size);
|
||||||
@ -459,6 +478,9 @@ void gst_aja_src_set_property(GObject *object, guint property_id,
|
|||||||
case PROP_CAPTURE_CPU_CORE:
|
case PROP_CAPTURE_CPU_CORE:
|
||||||
self->capture_cpu_core = g_value_get_uint(value);
|
self->capture_cpu_core = g_value_get_uint(value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ATTACH_ANCILLARY_META:
|
||||||
|
self->attach_ancillary_meta = g_value_get_boolean(value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -521,6 +543,9 @@ void gst_aja_src_get_property(GObject *object, guint property_id, GValue *value,
|
|||||||
case PROP_SIGNAL:
|
case PROP_SIGNAL:
|
||||||
g_value_set_boolean(value, self->signal);
|
g_value_set_boolean(value, self->signal);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ATTACH_ANCILLARY_META:
|
||||||
|
g_value_set_boolean(value, self->attach_ancillary_meta);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -2014,6 +2039,50 @@ next_item:
|
|||||||
gst_buffer_add_video_bar_meta(*buffer, field2 ? 1 : 0, is_letterbox, bar1,
|
gst_buffer_add_video_bar_meta(*buffer, field2 ? 1 : 0, is_letterbox, bar1,
|
||||||
bar2);
|
bar2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't attach other ANC as ancillary meta if not requested to do so.
|
||||||
|
if (!self->attach_ancillary_meta) continue;
|
||||||
|
|
||||||
|
// Skip non-SMPTE 291M ancillary data
|
||||||
|
if (packet->GetDataCoding() != AJAAncillaryDataCoding_Digital) continue;
|
||||||
|
|
||||||
|
const guint8 *in_data = packet->GetPayloadData();
|
||||||
|
guint data_count = packet->GetDC();
|
||||||
|
|
||||||
|
guint16 line_number = packet->GetLocationLineNumber();
|
||||||
|
guint16 horiz_offset = packet->GetLocationHorizOffset();
|
||||||
|
|
||||||
|
if (!in_data || data_count == 0) {
|
||||||
|
GST_TRACE_OBJECT(self, "ANC %s (%04x) at (%u,%u) has no payload data",
|
||||||
|
packet->IDAsString().c_str(), packet->GetDIDSID(),
|
||||||
|
line_number, horiz_offset);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_TRACE_OBJECT(self,
|
||||||
|
"Adding ANC meta for %s (%04x) at (%u,%u) of size %u",
|
||||||
|
packet->IDAsString().c_str(), packet->GetDIDSID(),
|
||||||
|
line_number, horiz_offset, data_count);
|
||||||
|
GstAncillaryMeta *anc_meta = gst_buffer_add_ancillary_meta(*buffer);
|
||||||
|
|
||||||
|
anc_meta->c_not_y_channel = packet->IsChromaChannel();
|
||||||
|
anc_meta->line = line_number;
|
||||||
|
anc_meta->offset = horiz_offset;
|
||||||
|
|
||||||
|
packet->GeneratePayloadData();
|
||||||
|
anc_meta->DID = AJAAncillaryData::AddEvenParity(packet->GetDID());
|
||||||
|
anc_meta->SDID_block_number =
|
||||||
|
AJAAncillaryData::AddEvenParity(packet->GetSID());
|
||||||
|
|
||||||
|
anc_meta->data_count = AJAAncillaryData::AddEvenParity(data_count);
|
||||||
|
|
||||||
|
guint16 *data = g_new(guint16, packet->GetDC());
|
||||||
|
for (guint i = 0; i < data_count; i++) {
|
||||||
|
data[i] = AJAAncillaryData::AddEvenParity(in_data[i]);
|
||||||
|
}
|
||||||
|
anc_meta->data = data;
|
||||||
|
|
||||||
|
anc_meta->checksum = packet->Calculate9BitChecksum();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool caps_changed = false;
|
bool caps_changed = false;
|
||||||
|
@ -77,6 +77,7 @@ struct _GstAjaSrc {
|
|||||||
guint start_frame, end_frame;
|
guint start_frame, end_frame;
|
||||||
guint capture_cpu_core;
|
guint capture_cpu_core;
|
||||||
gboolean signal;
|
gboolean signal;
|
||||||
|
gboolean attach_ancillary_meta;
|
||||||
|
|
||||||
NTV2AudioSystem audio_system;
|
NTV2AudioSystem audio_system;
|
||||||
NTV2VideoFormat video_format;
|
NTV2VideoFormat video_format;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user