mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
ajasink: Add HANC/VANC ancillary data from GstAncillaryMeta
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5488>
This commit is contained in:
parent
efa7e70d16
commit
3ca5a2554f
3 changed files with 72 additions and 1 deletions
|
@ -559,6 +559,18 @@
|
||||||
"type": "guint",
|
"type": "guint",
|
||||||
"writable": true
|
"writable": true
|
||||||
},
|
},
|
||||||
|
"handle-ancillary-meta": {
|
||||||
|
"blurb": "Handle ancillary meta on video frames",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": true,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"default": "false",
|
||||||
|
"mutable": "null",
|
||||||
|
"readable": true,
|
||||||
|
"type": "gboolean",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
"output-cpu-core": {
|
"output-cpu-core": {
|
||||||
"blurb": "Sets the affinity of the output thread to this CPU core (-1=disabled)",
|
"blurb": "Sets the affinity of the output thread to this CPU core (-1=disabled)",
|
||||||
"conditionally-available": false,
|
"conditionally-available": false,
|
||||||
|
|
|
@ -74,6 +74,7 @@ GST_DEBUG_CATEGORY_STATIC(gst_aja_sink_debug);
|
||||||
#define DEFAULT_START_FRAME (0)
|
#define DEFAULT_START_FRAME (0)
|
||||||
#define DEFAULT_END_FRAME (0)
|
#define DEFAULT_END_FRAME (0)
|
||||||
#define DEFAULT_OUTPUT_CPU_CORE (G_MAXUINT)
|
#define DEFAULT_OUTPUT_CPU_CORE (G_MAXUINT)
|
||||||
|
#define DEFAULT_HANDLE_ANCILLARY_META (FALSE)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
@ -91,6 +92,7 @@ enum {
|
||||||
PROP_START_FRAME,
|
PROP_START_FRAME,
|
||||||
PROP_END_FRAME,
|
PROP_END_FRAME,
|
||||||
PROP_OUTPUT_CPU_CORE,
|
PROP_OUTPUT_CPU_CORE,
|
||||||
|
PROP_HANDLE_ANCILLARY_META,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -271,6 +273,22 @@ static void gst_aja_sink_class_init(GstAjaSinkClass *klass) {
|
||||||
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
G_PARAM_CONSTRUCT)));
|
G_PARAM_CONSTRUCT)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstAjaSink:handle-ancillary-meta:
|
||||||
|
*
|
||||||
|
* If set to %TRUE handle any #GstAncillaryMeta present on buffers
|
||||||
|
*
|
||||||
|
* Since: 1.24
|
||||||
|
*/
|
||||||
|
g_object_class_install_property(
|
||||||
|
gobject_class, PROP_HANDLE_ANCILLARY_META,
|
||||||
|
g_param_spec_boolean(
|
||||||
|
"handle-ancillary-meta", "Handle Ancillary Meta",
|
||||||
|
"Handle ancillary meta on video frames",
|
||||||
|
DEFAULT_HANDLE_ANCILLARY_META,
|
||||||
|
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
G_PARAM_CONSTRUCT)));
|
||||||
|
|
||||||
element_class->change_state = GST_DEBUG_FUNCPTR(gst_aja_sink_change_state);
|
element_class->change_state = GST_DEBUG_FUNCPTR(gst_aja_sink_change_state);
|
||||||
|
|
||||||
basesink_class->set_caps = GST_DEBUG_FUNCPTR(gst_aja_sink_set_caps);
|
basesink_class->set_caps = GST_DEBUG_FUNCPTR(gst_aja_sink_set_caps);
|
||||||
|
@ -309,6 +327,7 @@ static void gst_aja_sink_init(GstAjaSink *self) {
|
||||||
self->timecode_index = DEFAULT_TIMECODE_INDEX;
|
self->timecode_index = DEFAULT_TIMECODE_INDEX;
|
||||||
self->reference_source = DEFAULT_REFERENCE_SOURCE;
|
self->reference_source = DEFAULT_REFERENCE_SOURCE;
|
||||||
self->output_cpu_core = DEFAULT_OUTPUT_CPU_CORE;
|
self->output_cpu_core = DEFAULT_OUTPUT_CPU_CORE;
|
||||||
|
self->handle_ancillary_meta = DEFAULT_HANDLE_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);
|
||||||
|
@ -363,6 +382,9 @@ void gst_aja_sink_set_property(GObject *object, guint property_id,
|
||||||
case PROP_OUTPUT_CPU_CORE:
|
case PROP_OUTPUT_CPU_CORE:
|
||||||
self->output_cpu_core = g_value_get_uint(value);
|
self->output_cpu_core = g_value_get_uint(value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_HANDLE_ANCILLARY_META:
|
||||||
|
self->handle_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;
|
||||||
|
@ -416,6 +438,9 @@ void gst_aja_sink_get_property(GObject *object, guint property_id,
|
||||||
case PROP_OUTPUT_CPU_CORE:
|
case PROP_OUTPUT_CPU_CORE:
|
||||||
g_value_set_uint(value, self->output_cpu_core);
|
g_value_set_uint(value, self->output_cpu_core);
|
||||||
break;
|
break;
|
||||||
|
case PROP_HANDLE_ANCILLARY_META:
|
||||||
|
g_value_set_boolean(value, self->handle_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;
|
||||||
|
@ -1709,6 +1734,39 @@ static GstFlowReturn gst_aja_sink_render(GstBaseSink *bsink,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self->handle_ancillary_meta) {
|
||||||
|
GstAncillaryMeta *anc_meta;
|
||||||
|
iter = NULL;
|
||||||
|
while ((anc_meta = (GstAncillaryMeta *)gst_buffer_iterate_meta_filtered(
|
||||||
|
buffer, &iter, GST_ANCILLARY_META_API_TYPE))) {
|
||||||
|
const AJAAncillaryDataLocation loc(
|
||||||
|
AJAAncillaryDataLink_A,
|
||||||
|
anc_meta->c_not_y_channel ? AJAAncillaryDataChannel_C
|
||||||
|
: AJAAncillaryDataVideoStream_Y,
|
||||||
|
AJAAncillaryDataSpace_VANC, anc_meta->line, anc_meta->offset);
|
||||||
|
|
||||||
|
AJAAncillaryData pkt;
|
||||||
|
guint8 data[256];
|
||||||
|
|
||||||
|
pkt.SetDID(anc_meta->DID);
|
||||||
|
pkt.SetSID(anc_meta->SDID_block_number);
|
||||||
|
pkt.SetDataLocation(loc);
|
||||||
|
pkt.SetDataCoding(AJAAncillaryDataCoding_Digital);
|
||||||
|
|
||||||
|
for (gsize i = 0; i < (anc_meta->data_count & 0xff); i++) {
|
||||||
|
data[i] = anc_meta->data[i] & 0xff;
|
||||||
|
}
|
||||||
|
pkt.SetPayloadData(data, anc_meta->data_count & 0xff);
|
||||||
|
|
||||||
|
GST_TRACE_OBJECT(self,
|
||||||
|
"Adding ANC of %" G_GSIZE_FORMAT " bytes at (%u,%u)",
|
||||||
|
pkt.GetPayloadByteCount(), pkt.GetLocationLineNumber(),
|
||||||
|
pkt.GetLocationHorizOffset());
|
||||||
|
|
||||||
|
anc_packet_list.AddAncillaryData(pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!anc_packet_list.IsEmpty()) {
|
if (!anc_packet_list.IsEmpty()) {
|
||||||
if (self->vanc_mode == ::NTV2_VANCMODE_OFF &&
|
if (self->vanc_mode == ::NTV2_VANCMODE_OFF &&
|
||||||
::NTV2DeviceCanDoCustomAnc(self->device_id)) {
|
::NTV2DeviceCanDoCustomAnc(self->device_id)) {
|
||||||
|
@ -2177,7 +2235,7 @@ restart:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out : {
|
out: {
|
||||||
// Make sure to globally lock here as the routing settings and others are
|
// Make sure to globally lock here as the routing settings and others are
|
||||||
// global shared state
|
// global shared state
|
||||||
ShmMutexLocker locker;
|
ShmMutexLocker locker;
|
||||||
|
|
|
@ -78,6 +78,7 @@ struct _GstAjaSink {
|
||||||
GstAjaTimecodeIndex timecode_index;
|
GstAjaTimecodeIndex timecode_index;
|
||||||
gboolean rp188;
|
gboolean rp188;
|
||||||
GstAjaReferenceSource reference_source;
|
GstAjaReferenceSource reference_source;
|
||||||
|
gboolean handle_ancillary_meta;
|
||||||
|
|
||||||
gint cea608_line_number;
|
gint cea608_line_number;
|
||||||
gint cea708_line_number;
|
gint cea708_line_number;
|
||||||
|
|
Loading…
Reference in a new issue