video-anc: New GstMeta for SMPTE ST-291M Ancillary Data

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5488>
This commit is contained in:
Edward Hervey 2023-10-02 17:17:36 +02:00 committed by GStreamer Marge Bot
parent 34741e1db2
commit b0de86ff68
3 changed files with 389 additions and 0 deletions

View file

@ -7,6 +7,79 @@ and/or use gtk-doc annotations. -->
<package name="gstreamer-video-1.0"/>
<c:include name="gst/video/video.h"/>
<namespace name="GstVideo" version="1.0" shared-library="libgstvideo-1.0.so.0" c:identifier-prefixes="Gst" c:symbol-prefixes="gst">
<record name="AncillaryMeta" c:type="GstAncillaryMeta" version="1.24">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">#GstMeta for carrying SMPTE-291M Ancillary data. Note that all the ADF fields
(@DID to @checksum) are 10bit values with parity/non-parity high-bits set.</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h"/>
<field name="meta" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Parent #GstMeta</doc>
<type name="Gst.Meta" c:type="GstMeta"/>
</field>
<field name="field" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">The field where the ancillary data is located</doc>
<type name="AncillaryMetaField" c:type="GstAncillaryMetaField"/>
</field>
<field name="c_not_y_channel" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Which channel (luminance or chrominance) the ancillary
data is located. 0 if content is SD or stored in the luminance channel
(default). 1 if HD and stored in the chrominance channel.</doc>
<type name="gboolean" c:type="gboolean"/>
</field>
<field name="line" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">The line on which the ancillary data is located (max 11bit). There
are two special values: 0x7ff if no line is specified (default), 0x7fe
to specify the ancillary data is on any valid line before active video</doc>
<type name="guint16" c:type="guint16"/>
</field>
<field name="offset" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">The location of the ancillary data packet in a SDI raster relative
to the start of active video (max 12bits). A value of 0 means the ADF of
the ancillary packet starts immediately following SAV. There are 3
special values: 0xfff: No specified location (default), 0xffe: within
HANC data space, 0xffd: within the ancillary data space located between
SAV and EAV</doc>
<type name="guint16" c:type="guint16"/>
</field>
<field name="DID" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Data Identified</doc>
<type name="guint16" c:type="guint16"/>
</field>
<field name="SDID_block_number" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Secondary Data identification (if type 2) or Data block
number (if type 1)</doc>
<type name="guint16" c:type="guint16"/>
</field>
<field name="data_count" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">The amount of user data</doc>
<type name="guint16" c:type="guint16"/>
</field>
<field name="data" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">The User data</doc>
<type name="guint16" c:type="guint16*"/>
</field>
<field name="checksum" writable="1">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">The checksum of the ADF</doc>
<type name="guint16" c:type="guint16"/>
</field>
<function name="get_info" c:identifier="gst_ancillary_meta_get_info">
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h"/>
<return-value transfer-ownership="none">
<type name="Gst.MetaInfo" c:type="const GstMetaInfo*"/>
</return-value>
</function>
</record>
<enumeration name="AncillaryMetaField" version="1.24" glib:type-name="GstAncillaryMetaField" glib:get-type="gst_ancillary_meta_field_get_type" c:type="GstAncillaryMetaField">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Location of a @GstAncillaryMeta.</doc>
<member name="progressive" value="0" c:identifier="GST_ANCILLARY_META_FIELD_PROGRESSIVE" glib:nick="progressive">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Progressive or no field specified (default)</doc>
</member>
<member name="interlaced_first" value="16" c:identifier="GST_ANCILLARY_META_FIELD_INTERLACED_FIRST" glib:nick="interlaced-first">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Interlaced first field</doc>
</member>
<member name="interlaced_second" value="17" c:identifier="GST_ANCILLARY_META_FIELD_INTERLACED_SECOND" glib:nick="interlaced-second">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Interlaced second field</doc>
</member>
</enumeration>
<constant name="BUFFER_POOL_OPTION_VIDEO_AFFINE_TRANSFORMATION_META" value="GstBufferPoolOptionVideoAffineTransformation" c:type="GST_BUFFER_POOL_OPTION_VIDEO_AFFINE_TRANSFORMATION_META">
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoaffinetransformationmeta.h"/>
<type name="utf8" c:type="gchar*"/>
@ -15799,6 +15872,33 @@ data.</doc>
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">An error occurred</doc>
</member>
</enumeration>
<function name="ancillary_meta_api_get_type" c:identifier="gst_ancillary_meta_api_get_type">
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h"/>
<return-value transfer-ownership="none">
<type name="GType" c:type="GType"/>
</return-value>
</function>
<function name="ancillary_meta_get_info" c:identifier="gst_ancillary_meta_get_info" moved-to="AncillaryMeta.get_info">
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h"/>
<return-value transfer-ownership="none">
<type name="Gst.MetaInfo" c:type="const GstMetaInfo*"/>
</return-value>
</function>
<function name="buffer_add_ancillary_meta" c:identifier="gst_buffer_add_ancillary_meta" version="1.24">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.c">Adds a new #GstAncillaryMeta to the @buffer. The caller is responsible for setting the appropriate
fields.</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h"/>
<return-value transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.c">A new #GstAncillaryMeta, or %NULL if an error happened.</doc>
<type name="AncillaryMeta" c:type="GstAncillaryMeta*"/>
</return-value>
<parameters>
<parameter name="buffer" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.c">A #GstBuffer</doc>
<type name="Gst.Buffer" c:type="GstBuffer*"/>
</parameter>
</parameters>
</function>
<function name="buffer_add_video_afd_meta" c:identifier="gst_buffer_add_video_afd_meta" version="1.18">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.c">Attaches #GstVideoAFDMeta metadata to @buffer with the given
parameters.</doc>
@ -16249,6 +16349,18 @@ parameters.</doc>
</parameter>
</parameters>
</function>
<function-macro name="buffer_get_ancillary_meta" c:identifier="gst_buffer_get_ancillary_meta" version="1.24" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Gets the #GstAncillaryMeta that might be present on @b.
Note: It is quite likely that there might be more than one ancillary meta on
a given buffer. This function will only return the first one. See gst_buffer_iterate_ancillary_meta() for a way to iterate over all ancillary metas of the buffer.</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h"/>
<parameters>
<parameter name="b">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">A #GstBuffer</doc>
</parameter>
</parameters>
</function-macro>
<function-macro name="buffer_get_video_afd_meta" c:identifier="gst_buffer_get_video_afd_meta" version="1.18" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Gets the #GstVideoAFDMeta that might be present on @b.
@ -16407,6 +16519,22 @@ no such metadata on @buffer.</doc>
</parameter>
</parameters>
</function-macro>
<function-macro name="buffer_iterate_ancillary_meta" c:identifier="gst_buffer_iterate_ancillary_meta" version="1.24" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">Retrieves the next #GstAncillaryMeta after the current one according to
@s. If @s points to %NULL, the first #GstAncillaryMeta will be returned (if
any).
@s will be updated with an opaque state pointer.</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h"/>
<parameters>
<parameter name="b">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">A #GstBuffer</doc>
</parameter>
<parameter name="s">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/video-anc.h">An opaque state pointer</doc>
</parameter>
</parameters>
</function-macro>
<function name="buffer_pool_config_get_video_alignment" c:identifier="gst_buffer_pool_config_get_video_alignment">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/video/gstvideopool.c">Get the video alignment from the bufferpool configuration @config in
in @align</doc>

View file

@ -30,6 +30,11 @@
* SECTION:gstvideoanc
* @title: GstVideo Ancillary
* @short_description: Utilities for Ancillary data, VBI and Closed Caption
* @private_symbols:
* - GST_ANCILLARY_META_INFO
* - GST_ANCILLARY_META_API_TYPE
* - gst_ancillary_meta_get_info
* - gst_ancillary_meta_api_get_type
*
* A collection of objects and methods to assist with handling Ancillary Data
* present in Vertical Blanking Interval as well as Closed Caption.
@ -1119,6 +1124,117 @@ gst_video_caption_type_to_caps (GstVideoCaptionType type)
return caption_caps;
}
/* Ancillary Meta Implementation */
GType
gst_ancillary_meta_api_get_type (void)
{
static GType type = 0;
if (g_once_init_enter (&type)) {
static const gchar *tags[] = { NULL };
GType _type = gst_meta_api_type_register ("GstAncillaryMetaAPI", tags);
GST_INFO ("registering");
g_once_init_leave (&type, _type);
}
return type;
}
static gboolean
gst_ancillary_meta_init (GstMeta * meta, gpointer params, GstBuffer * buffer)
{
GstAncillaryMeta *ameta = (GstAncillaryMeta *) meta;
/* Set sensible default values */
ameta->field = GST_ANCILLARY_META_FIELD_PROGRESSIVE;
ameta->c_not_y_channel = 0;
ameta->line = 0x7ff;
ameta->offset = 0xfff;
ameta->DID = ameta->SDID_block_number = ameta->data_count = 0;
ameta->data = NULL;
ameta->checksum = 0;
return TRUE;
}
static void
gst_ancillary_meta_free (GstMeta * meta, GstBuffer * buffer)
{
GstAncillaryMeta *ameta = (GstAncillaryMeta *) meta;
g_free (ameta->data);
}
static gboolean
gst_ancillary_meta_transform (GstBuffer * dest, GstMeta * meta,
GstBuffer * buffer, GQuark type, gpointer data)
{
GstAncillaryMeta *dmeta, *smeta;
/* We always copy over the ancillary meta */
smeta = (GstAncillaryMeta *) meta;
dmeta =
(GstAncillaryMeta *) gst_buffer_add_meta (dest, GST_ANCILLARY_META_INFO,
NULL);
dmeta->field = smeta->field;
dmeta->c_not_y_channel = smeta->c_not_y_channel;
dmeta->line = smeta->line;
dmeta->offset = smeta->offset;
dmeta->DID = smeta->DID;
dmeta->SDID_block_number = smeta->SDID_block_number;
dmeta->data_count = smeta->data_count;
dmeta->data = g_memdup2 (smeta->data, (smeta->data_count & 0xff) * 2);
dmeta->checksum = smeta->checksum;
return TRUE;
}
const GstMetaInfo *
gst_ancillary_meta_get_info (void)
{
static const GstMetaInfo *meta_info = NULL;
if (g_once_init_enter ((GstMetaInfo **) & meta_info)) {
const GstMetaInfo *mi = gst_meta_register (GST_ANCILLARY_META_API_TYPE,
"GstAncillaryMeta",
sizeof (GstAncillaryMeta),
gst_ancillary_meta_init,
gst_ancillary_meta_free,
gst_ancillary_meta_transform);
g_once_init_leave ((GstMetaInfo **) & meta_info, (GstMetaInfo *) mi);
}
return meta_info;
}
/**
* gst_buffer_add_ancillary_meta:
* @buffer: A #GstBuffer
*
* Adds a new #GstAncillaryMeta to the @buffer. The caller is responsible for setting the appropriate
* fields.
*
* Since: 1.24
*
* Returns: (transfer none): A new #GstAncillaryMeta, or %NULL if an error happened.
*/
GstAncillaryMeta *
gst_buffer_add_ancillary_meta (GstBuffer * buffer)
{
GstAncillaryMeta *meta;
meta =
(GstAncillaryMeta *) gst_buffer_add_meta (buffer, GST_ANCILLARY_META_INFO,
NULL);
g_assert (meta != NULL);
return meta;
}
/* Active Format Description (AFD) Meta implementation */
GType

View file

@ -103,6 +103,151 @@ typedef enum {
GST_VIDEO_ANCILLARY_DID16_S2016_3_AFD_BAR = 0x4105,
} GstVideoAncillaryDID16;
/**
* GstAncillaryMetaField:
* @GST_ANCILLARY_META_FIELD_PROGRESSIVE: Progressive or no field specified (default)
* @GST_ANCILLARY_META_FIELD_INTERLACED_FIRST: Interlaced first field
* @GST_ANCILLARY_META_FIELD_INTERLACED_SECOND: Interlaced second field
*
* Location of a @GstAncillaryMeta.
*
* Since: 1.24
*/
typedef enum {
GST_ANCILLARY_META_FIELD_PROGRESSIVE = 0x00,
GST_ANCILLARY_META_FIELD_INTERLACED_FIRST = 0x10,
GST_ANCILLARY_META_FIELD_INTERLACED_SECOND = 0x11,
} GstAncillaryMetaField;
/**
* GstAncillaryMeta:
* @meta: Parent #GstMeta
* @field: The field where the ancillary data is located
* @c_not_y_channel: Which channel (luminance or chrominance) the ancillary
* data is located. 0 if content is SD or stored in the luminance channel
* (default). 1 if HD and stored in the chrominance channel.
* @line: The line on which the ancillary data is located (max 11bit). There
* are two special values: 0x7ff if no line is specified (default), 0x7fe
* to specify the ancillary data is on any valid line before active video
* @offset: The location of the ancillary data packet in a SDI raster relative
* to the start of active video (max 12bits). A value of 0 means the ADF of
* the ancillary packet starts immediately following SAV. There are 3
* special values: 0xfff: No specified location (default), 0xffe: within
* HANC data space, 0xffd: within the ancillary data space located between
* SAV and EAV
* @DID: Data Identified
* @SDID_block_number: Secondary Data identification (if type 2) or Data block
* number (if type 1)
* @data_count: The amount of user data
* @data: The User data
* @checksum: The checksum of the ADF
*
* #GstMeta for carrying SMPTE-291M Ancillary data. Note that all the ADF fields
* (@DID to @checksum) are 10bit values with parity/non-parity high-bits set.
*
* Since: 1.24
*/
typedef struct {
GstMeta meta;
GstAncillaryMetaField field; /* Field location */
gboolean c_not_y_channel; /* 1 if content is HD and the ANC data is stored
in the chrominance channel. 0 if content is
SD or the ANC data is stored in the luminance
channel (default) */
guint16 line; /* The line on which this ANC data is located.
*
* 11bit value
*
* Special values:
* * 0x7ff : No line specified (default)
* * 0x7fe : Any valid line before active video */
guint16 offset; /* Location of the ANC data packet in a SDI
* raster relative to SAV. A value of 0 means
* the ADF of the ANC data packet beings
* immediately following SAV.
*
* 12bits value
*
* The unit is 10-bit words of the indicated
* data stream and data channel
*
* Special values:
* * 0xfff: No specified horizontal location (default)
* * 0xffe: Within HANC data space
* * 0xffd: Within the ancillary data space located
* between SAV and EAV
*/
/* EXCLUDED from ANC RTP are the multi-stream properties (ex: stereoscopic
* video). That information should be conveyed by having separate VANC
* streams */
/* What follows are all the fields making up a ST 291 ADF packet. All of the
* fields are stored as 10bit, including the parity/non-parity high-bits set.
*
* To access the 8bit content, just cast the value */
guint16 DID; /* Data Identifier (10 bit) */
guint16 SDID_block_number; /* Secondary data identification (If type 2) or
* Data Block number (if type 1). Value is
* 10bit */
guint16 data_count; /* The amount of User Data. Only the low 8 bits are to be used */
guint16 *data; /* The User Data (10bit) */
guint16 checksum; /* The checksum (10bit) */
} GstAncillaryMeta;
GST_VIDEO_API GType gst_ancillary_meta_api_get_type(void);
#define GST_ANCILLARY_META_API_TYPE (gst_ancillary_meta_api_get_type())
GST_VIDEO_API const GstMetaInfo *gst_ancillary_meta_get_info(void);
#define GST_ANCILLARY_META_INFO (gst_ancillary_meta_get_info())
GST_VIDEO_API GstAncillaryMeta *
gst_buffer_add_ancillary_meta(GstBuffer *buffer);
/**
* gst_buffer_get_ancillary_meta:
* @b: A #GstBuffer
*
* Gets the #GstAncillaryMeta that might be present on @b.
*
* Note: It is quite likely that there might be more than one ancillary meta on
* a given buffer. This function will only return the first one. See gst_buffer_iterate_ancillary_meta() for a way to iterate over all ancillary metas of the buffer.
*
* Since: 1.24
*
* Returns: The first #GstAncillaryMeta present on @b, or %NULL if none are
* present.
*/
#define gst_buffer_get_ancillary_meta(b) \
((GstAncillaryMeta*)gst_buffer_get_meta((b), GST_ANCILLARY_META_API_TYPE)
/**
* gst_buffer_iterate_ancillary_meta:
* @b: A #GstBuffer
* @s: (out caller-allocates): An opaque state pointer
*
* Retrieves the next #GstAncillaryMeta after the current one according to
* @s. If @s points to %NULL, the first #GstAncillaryMeta will be returned (if
* any).
*
* @s will be updated with an opaque state pointer.
*
* Since: 1.24
*
* Returns: (transfer none) (nullable): The next #GstAncillaryMeta present on @b
* or %NULL when there are no more items.
*/
#define gst_buffer_iterate_ancillary_meta(b, s) \
((GstAncillaryMeta*)gst_buffer_iterate_meta_filtered((b), (s), GST_ANCILLARY_META_API_TYPE))
/**
* GstVideoAFDValue:
* @GST_VIDEO_AFD_UNAVAILABLE: Unavailable (see note 0 below).