analytics: Add GstAnalyticsBatchMeta for batches of buffers from one or more streams
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9282>
This commit is contained in:
parent
9c2e20419b
commit
3a51f42ab0
@ -12,6 +12,172 @@ and/or use gtk-doc annotations. -->
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsmeta.h"/>
|
||||
<type name="guintptr" c:type="guintptr"/>
|
||||
</alias>
|
||||
<record name="BatchBuffer" c:type="GstAnalyticsBatchBuffer" version="1.28">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">The intended use of this struct is that analytics elements read the buffer or
|
||||
buffer list and potentially attach new #GstMeta with additional information.
|
||||
Only one of @buffer or @buffer_list is going to be set, or both are %NULL.
|
||||
|
||||
Elements that need to modify @buffer (e.g. to attach a new meta) must first
|
||||
call gst_buffer_make_writable() and store the writable buffer in this struct.
|
||||
Similarly, a writable @buffer_list must be ensured with
|
||||
gst_buffer_list_make_writable().
|
||||
|
||||
Modifying any other fields must be done with special care to ensure that the
|
||||
data flow of the stream is not broken.
|
||||
|
||||
It is possible for @buffer and @buffer_list to be %NULL, e.g. if there was no
|
||||
buffer for this batch but there were serialized events like a gap event.
|
||||
|
||||
Note that @serialized_events always contains all currently active serialized
|
||||
events and not only the changed events compared to the previous buffer.</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<field name="sticky_events" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">All sticky #GstEvent that relate to this buffer</doc>
|
||||
<array length="1" zero-terminated="0" c:type="GstEvent**">
|
||||
<type name="Gst.Event" c:type="GstEvent*"/>
|
||||
</array>
|
||||
</field>
|
||||
<field name="n_sticky_events" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">Number of sticky events.</doc>
|
||||
<type name="gsize" c:type="gsize"/>
|
||||
</field>
|
||||
<field name="serialized_events" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">All non-sticky, serialized #GstEvent that arrived
|
||||
after the previous and before this buffer</doc>
|
||||
<array length="3" zero-terminated="0" c:type="GstEvent**">
|
||||
<type name="Gst.Event" c:type="GstEvent*"/>
|
||||
</array>
|
||||
</field>
|
||||
<field name="n_serialized_events" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">Number of serialized events.</doc>
|
||||
<type name="gsize" c:type="gsize"/>
|
||||
</field>
|
||||
<field name="buffer" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">The buffer, if any.</doc>
|
||||
<type name="Gst.Buffer" c:type="GstBuffer*"/>
|
||||
</field>
|
||||
<field name="buffer_list" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">The buffer list, if any.</doc>
|
||||
<type name="Gst.BufferList" c:type="GstBufferList*"/>
|
||||
</field>
|
||||
<field name="padding" readable="0" private="1">
|
||||
<array zero-terminated="0" fixed-size="4">
|
||||
<type name="gpointer" c:type="gpointer"/>
|
||||
</array>
|
||||
</field>
|
||||
<method name="get_caps" c:identifier="gst_analytics_batch_buffer_get_caps" version="1.28">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">Gets the #GstCaps from a buffer</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<return-value transfer-ownership="none" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">The #GstCaps if there are any</doc>
|
||||
<type name="Gst.Caps" c:type="GstCaps*"/>
|
||||
</return-value>
|
||||
<parameters>
|
||||
<instance-parameter name="buffer" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">A #GstAnalyticsBatchBuffer</doc>
|
||||
<type name="BatchBuffer" c:type="GstAnalyticsBatchBuffer*"/>
|
||||
</instance-parameter>
|
||||
</parameters>
|
||||
</method>
|
||||
<method name="get_segment" c:identifier="gst_analytics_batch_buffer_get_segment" version="1.28">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">Gets the #GstSegment from a buffer</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<return-value transfer-ownership="none" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">The #GstSegment if there is one</doc>
|
||||
<type name="Gst.Segment" c:type="const GstSegment*"/>
|
||||
</return-value>
|
||||
<parameters>
|
||||
<instance-parameter name="buffer" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">A #GstAnalyticsBatchBuffer</doc>
|
||||
<type name="BatchBuffer" c:type="GstAnalyticsBatchBuffer*"/>
|
||||
</instance-parameter>
|
||||
</parameters>
|
||||
</method>
|
||||
<method name="get_stream_id" c:identifier="gst_analytics_batch_buffer_get_stream_id" version="1.28">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">Gets the current stream id from a buffer</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<return-value transfer-ownership="none" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">The stream id if there is any</doc>
|
||||
<type name="utf8" c:type="const gchar*"/>
|
||||
</return-value>
|
||||
<parameters>
|
||||
<instance-parameter name="buffer" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">A #GstAnalyticsBatchBuffer</doc>
|
||||
<type name="BatchBuffer" c:type="GstAnalyticsBatchBuffer*"/>
|
||||
</instance-parameter>
|
||||
</parameters>
|
||||
</method>
|
||||
</record>
|
||||
<record name="BatchMeta" c:type="GstAnalyticsBatchMeta" version="1.28">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">This meta represents a batch of buffers from one or more streams together
|
||||
with the relevant events to be able to interpret the buffers and to be able
|
||||
to reconstruct the original streams.
|
||||
|
||||
When used for multiple streams and batching them temporarily, caps of type
|
||||
`multistream/x-analytics-batch(meta:GstAnalyticsBatchMeta)` should be used,
|
||||
with the original caps of each stream in an array-typed `streams` field. The
|
||||
original caps of each stream might be extended by additional fields and the
|
||||
order of the streams in the array corresponds to the order of the @streams
|
||||
array of the meta. In this case, empty buffers would be used without any
|
||||
#GstMemory and
|
||||
|
||||
When used for a single stream, the original caps might be used together with
|
||||
the `meta:GstAnalyticsBatchMeta` caps feature and potentially extended by
|
||||
additional fields to describe the kind of batching and its configuration,
|
||||
e.g. that each batch is made of 25% overlapping 320x320 slices of the
|
||||
original video frame.
|
||||
|
||||
The timestamp, duration and other metadata of each batch can be retrieved
|
||||
from the parent buffer of this meta.</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<field name="meta" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">parent</doc>
|
||||
<type name="Gst.Meta" c:type="GstMeta"/>
|
||||
</field>
|
||||
<field name="streams" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">#GstAnalyticsBatchStream for this batch</doc>
|
||||
<array length="2" zero-terminated="0" c:type="GstAnalyticsBatchStream*">
|
||||
<type name="BatchStream" c:type="GstAnalyticsBatchStream"/>
|
||||
</array>
|
||||
</field>
|
||||
<field name="n_streams" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">Number of streams</doc>
|
||||
<type name="gsize" c:type="gsize"/>
|
||||
</field>
|
||||
<function name="get_info" c:identifier="gst_analytics_batch_meta_get_info" version="1.28" introspectable="0">
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
<type name="Gst.MetaInfo" c:type="const GstMetaInfo*"/>
|
||||
</return-value>
|
||||
</function>
|
||||
</record>
|
||||
<record name="BatchStream" c:type="GstAnalyticsBatchStream" version="1.28">
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<field name="index" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">Index of the stream in the meta's stream array</doc>
|
||||
<type name="guint" c:type="guint"/>
|
||||
</field>
|
||||
<field name="buffers" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">#GstAnalyticsBatchBuffer in this batch for this stream</doc>
|
||||
<array length="2" zero-terminated="0" c:type="GstAnalyticsBatchBuffer*">
|
||||
<type name="BatchBuffer" c:type="GstAnalyticsBatchBuffer"/>
|
||||
</array>
|
||||
</field>
|
||||
<field name="n_buffers" writable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">Number of buffers</doc>
|
||||
<type name="gsize" c:type="gsize"/>
|
||||
</field>
|
||||
<field name="padding" readable="0" private="1">
|
||||
<array zero-terminated="0" fixed-size="4">
|
||||
<type name="gpointer" c:type="gpointer"/>
|
||||
</array>
|
||||
</field>
|
||||
</record>
|
||||
<constant name="CAPS_FEATURE_META_GST_ANALYTICS_BATCH_META" value="meta:GstAnalyticsBatchMeta" c:type="GST_CAPS_FEATURE_META_GST_ANALYTICS_BATCH_META" version="1.28">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h">The caps feature to be used on streams that make use of this meta.</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<type name="utf8" c:type="gchar*"/>
|
||||
</constant>
|
||||
<record name="ClsMtd" c:type="GstAnalyticsClsMtd" version="1.24">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsclassificationmtd.h">Handle containing data required to use gst_analytics_cls_mtd APIs. This type
|
||||
is generally expected to be allocated on the stack.</doc>
|
||||
@ -1747,6 +1913,32 @@ Get the opaque id identifying the relatable type</doc>
|
||||
</return-value>
|
||||
</function>
|
||||
</record>
|
||||
<function name="batch_meta_api_get_type" c:identifier="gst_analytics_batch_meta_api_get_type" version="1.28" introspectable="0">
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
<type name="GType" c:type="GType"/>
|
||||
</return-value>
|
||||
</function>
|
||||
<function name="batch_meta_get_info" c:identifier="gst_analytics_batch_meta_get_info" moved-to="BatchMeta.get_info" version="1.28" introspectable="0">
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
<type name="Gst.MetaInfo" c:type="const GstMetaInfo*"/>
|
||||
</return-value>
|
||||
</function>
|
||||
<function name="buffer_add_analytics_batch_meta" c:identifier="gst_buffer_add_analytics_batch_meta" version="1.28">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">Adds a #GstAnalyticsBatchMeta to a buffer or returns the existing one</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">The new #GstAnalyticsBatchMeta</doc>
|
||||
<type name="BatchMeta" c:type="GstAnalyticsBatchMeta*"/>
|
||||
</return-value>
|
||||
<parameters>
|
||||
<parameter name="buffer" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">A writable #GstBuffer</doc>
|
||||
<type name="Gst.Buffer" c:type="GstBuffer*"/>
|
||||
</parameter>
|
||||
</parameters>
|
||||
</function>
|
||||
<function name="buffer_add_analytics_relation_meta" c:identifier="gst_buffer_add_analytics_relation_meta" version="1.24">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsmeta.c">Attach a analysis-results-meta-relation meta (#GstAnalyticsRelationMeta)to @buffer.
|
||||
|
||||
@ -1800,6 +1992,20 @@ analysis meta.</doc>
|
||||
</parameter>
|
||||
</parameters>
|
||||
</function>
|
||||
<function name="buffer_get_analytics_batch_meta" c:identifier="gst_buffer_get_analytics_batch_meta" version="1.28">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">Gets the #GstAnalyticsBatchMeta from a buffer</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.h"/>
|
||||
<return-value transfer-ownership="none" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">The #GstAnalyticsBatchMeta if there is one</doc>
|
||||
<type name="BatchMeta" c:type="GstAnalyticsBatchMeta*"/>
|
||||
</return-value>
|
||||
<parameters>
|
||||
<parameter name="buffer" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsbatchmeta.c">A #GstBuffer</doc>
|
||||
<type name="Gst.Buffer" c:type="GstBuffer*"/>
|
||||
</parameter>
|
||||
</parameters>
|
||||
</function>
|
||||
<function name="buffer_get_analytics_relation_meta" c:identifier="gst_buffer_get_analytics_relation_meta" version="1.24">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsmeta.c">Retrives the meta or %NULL if it doesn't exist</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsmeta.h"/>
|
||||
|
@ -0,0 +1,300 @@
|
||||
/*
|
||||
* GStreamer
|
||||
*
|
||||
* Copyright (C) 2025 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* gstanalyticsbatchmeta.c
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "gstanalyticsbatchmeta.h"
|
||||
|
||||
static gboolean
|
||||
gst_analytics_batch_meta_transform (GstBuffer * dest, GstMeta * meta,
|
||||
GstBuffer * buffer, GQuark type, gpointer data)
|
||||
{
|
||||
GstAnalyticsBatchMeta *dmeta, *smeta;
|
||||
|
||||
smeta = (GstAnalyticsBatchMeta *) meta;
|
||||
|
||||
if (GST_META_TRANSFORM_IS_COPY (type)) {
|
||||
smeta = (GstAnalyticsBatchMeta *) meta;
|
||||
dmeta = gst_buffer_add_analytics_batch_meta (dest);
|
||||
if (!dmeta)
|
||||
return FALSE;
|
||||
GST_TRACE ("copy analytics batch metadata");
|
||||
|
||||
dmeta->streams = g_new (GstAnalyticsBatchStream, smeta->n_streams);
|
||||
for (gsize i = 0; i < smeta->n_streams; i++) {
|
||||
GstAnalyticsBatchStream *sstream = &smeta->streams[i];
|
||||
GstAnalyticsBatchStream *dstream = &dmeta->streams[i];
|
||||
|
||||
dstream->index = sstream->index;
|
||||
dstream->buffers = g_new (GstAnalyticsBatchBuffer, sstream->n_buffers);
|
||||
for (gsize j = 0; j < sstream->n_buffers; j++) {
|
||||
GstAnalyticsBatchBuffer *sbuffer = &sstream->buffers[j];
|
||||
GstAnalyticsBatchBuffer *dbuffer = &dstream->buffers[j];
|
||||
|
||||
dbuffer->sticky_events = g_new (GstEvent *, sbuffer->n_sticky_events);
|
||||
for (gsize k = 0; k < sbuffer->n_sticky_events; k++) {
|
||||
dbuffer->sticky_events[k] = gst_event_ref (sbuffer->sticky_events[k]);
|
||||
}
|
||||
dbuffer->n_sticky_events = sbuffer->n_sticky_events;
|
||||
|
||||
dbuffer->serialized_events =
|
||||
g_new (GstEvent *, sbuffer->n_serialized_events);
|
||||
for (gsize k = 0; k < sbuffer->n_serialized_events; k++) {
|
||||
dbuffer->serialized_events[k] =
|
||||
gst_event_ref (sbuffer->serialized_events[k]);
|
||||
}
|
||||
dbuffer->n_serialized_events = sbuffer->n_serialized_events;
|
||||
|
||||
dbuffer->buffer =
|
||||
sbuffer->buffer ? gst_buffer_ref (sbuffer->buffer) : NULL;
|
||||
dbuffer->buffer_list =
|
||||
sbuffer->
|
||||
buffer_list ? gst_buffer_list_ref (sbuffer->buffer_list) : NULL;
|
||||
}
|
||||
dstream->n_buffers = sstream->n_buffers;
|
||||
}
|
||||
dmeta->n_streams = smeta->n_streams;
|
||||
|
||||
} else {
|
||||
GST_WARNING
|
||||
("gst_analytics_batch_meta_transform: transform type %u not supported",
|
||||
type);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_analytics_batch_meta_init (GstMeta * meta, gpointer params,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstAnalyticsBatchMeta *bmeta = (GstAnalyticsBatchMeta *) meta;
|
||||
|
||||
bmeta->streams = NULL;
|
||||
bmeta->n_streams = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_analytics_batch_meta_free (GstMeta * meta, GstBuffer * buffer)
|
||||
{
|
||||
GstAnalyticsBatchMeta *bmeta = (GstAnalyticsBatchMeta *) meta;
|
||||
|
||||
for (gsize i = 0; i < bmeta->n_streams; i++) {
|
||||
GstAnalyticsBatchStream *stream = &bmeta->streams[i];
|
||||
|
||||
for (gsize j = 0; j < stream->n_buffers; j++) {
|
||||
GstAnalyticsBatchBuffer *buffer = &stream->buffers[j];
|
||||
|
||||
for (gsize k = 0; k < buffer->n_sticky_events; k++) {
|
||||
gst_clear_event (&buffer->sticky_events[k]);
|
||||
}
|
||||
g_clear_pointer (&buffer->sticky_events, g_free);
|
||||
for (gsize k = 0; k < buffer->n_serialized_events; k++) {
|
||||
gst_clear_event (&buffer->serialized_events[k]);
|
||||
}
|
||||
g_clear_pointer (&buffer->serialized_events, g_free);
|
||||
gst_clear_buffer (&buffer->buffer);
|
||||
gst_clear_buffer_list (&buffer->buffer_list);
|
||||
}
|
||||
|
||||
g_clear_pointer (&stream->buffers, g_free);
|
||||
}
|
||||
|
||||
g_free (bmeta->streams);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_analytics_batch_meta_api_get_type: (skip)
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
GType
|
||||
gst_analytics_batch_meta_api_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
static const gchar *tags[] = { NULL };
|
||||
|
||||
if (g_once_init_enter (&type)) {
|
||||
GType _type = gst_meta_api_type_register ("GstAnalyticsBatchMetaAPI", tags);
|
||||
g_once_init_leave (&type, _type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_analytics_batch_meta_get_info: (skip)
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
const GstMetaInfo *
|
||||
gst_analytics_batch_meta_get_info (void)
|
||||
{
|
||||
static const GstMetaInfo *tmeta_info = NULL;
|
||||
|
||||
if (g_once_init_enter (&tmeta_info)) {
|
||||
const GstMetaInfo *meta =
|
||||
gst_meta_register (gst_analytics_batch_meta_api_get_type (),
|
||||
"GstAnalyticsBatchMeta",
|
||||
sizeof (GstAnalyticsBatchMeta),
|
||||
gst_analytics_batch_meta_init,
|
||||
gst_analytics_batch_meta_free,
|
||||
gst_analytics_batch_meta_transform);
|
||||
g_once_init_leave (&tmeta_info, meta);
|
||||
}
|
||||
return tmeta_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_add_analytics_batch_meta:
|
||||
* @buffer: A writable #GstBuffer
|
||||
*
|
||||
* Adds a #GstAnalyticsBatchMeta to a buffer or returns the existing one
|
||||
*
|
||||
* Returns: (transfer none): The new #GstAnalyticsBatchMeta
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
|
||||
GstAnalyticsBatchMeta *
|
||||
gst_buffer_add_analytics_batch_meta (GstBuffer * buffer)
|
||||
{
|
||||
return (GstAnalyticsBatchMeta *) gst_buffer_add_meta (buffer,
|
||||
gst_analytics_batch_meta_get_info (), NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_get_analytics_batch_meta:
|
||||
* @buffer: A #GstBuffer
|
||||
*
|
||||
* Gets the #GstAnalyticsBatchMeta from a buffer
|
||||
*
|
||||
* Returns: (nullable)(transfer none): The #GstAnalyticsBatchMeta if there is one
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
GstAnalyticsBatchMeta *
|
||||
gst_buffer_get_analytics_batch_meta (GstBuffer * buffer)
|
||||
{
|
||||
return (GstAnalyticsBatchMeta *) gst_buffer_get_meta (buffer,
|
||||
GST_ANALYTICS_BATCH_META_API_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_analytics_batch_buffer_get_stream_id:
|
||||
* @buffer: A #GstAnalyticsBatchBuffer
|
||||
*
|
||||
* Gets the current stream id from a buffer
|
||||
*
|
||||
* Returns: (nullable) (transfer none): The stream id if there is any
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
const gchar *
|
||||
gst_analytics_batch_buffer_get_stream_id (GstAnalyticsBatchBuffer * buffer)
|
||||
{
|
||||
g_return_val_if_fail (buffer != NULL, NULL);
|
||||
|
||||
if (!buffer->sticky_events)
|
||||
return NULL;
|
||||
|
||||
for (gsize i = 0; i < buffer->n_sticky_events; i++) {
|
||||
GstEvent *event = buffer->sticky_events[i];
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START) {
|
||||
const gchar *stream_id;
|
||||
|
||||
gst_event_parse_stream_start (event, &stream_id);
|
||||
|
||||
return stream_id;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_analytics_batch_buffer_get_caps:
|
||||
* @buffer: A #GstAnalyticsBatchBuffer
|
||||
*
|
||||
* Gets the #GstCaps from a buffer
|
||||
*
|
||||
* Returns: (nullable) (transfer none): The #GstCaps if there are any
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
GstCaps *
|
||||
gst_analytics_batch_buffer_get_caps (GstAnalyticsBatchBuffer * buffer)
|
||||
{
|
||||
g_return_val_if_fail (buffer != NULL, NULL);
|
||||
|
||||
if (!buffer->sticky_events)
|
||||
return NULL;
|
||||
|
||||
for (gsize i = 0; i < buffer->n_sticky_events; i++) {
|
||||
GstEvent *event = buffer->sticky_events[i];
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS) {
|
||||
GstCaps *caps;
|
||||
|
||||
gst_event_parse_caps (event, &caps);
|
||||
|
||||
return caps;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_analytics_batch_buffer_get_segment:
|
||||
* @buffer: A #GstAnalyticsBatchBuffer
|
||||
*
|
||||
* Gets the #GstSegment from a buffer
|
||||
*
|
||||
* Returns: (nullable) (transfer none): The #GstSegment if there is one
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
const GstSegment *
|
||||
gst_analytics_batch_buffer_get_segment (GstAnalyticsBatchBuffer * buffer)
|
||||
{
|
||||
g_return_val_if_fail (buffer != NULL, NULL);
|
||||
|
||||
if (!buffer->sticky_events)
|
||||
return NULL;
|
||||
|
||||
for (gsize i = 0; i < buffer->n_sticky_events; i++) {
|
||||
GstEvent *event = buffer->sticky_events[i];
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
|
||||
const GstSegment *segment;
|
||||
|
||||
gst_event_parse_segment (event, &segment);
|
||||
|
||||
return segment;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* GStreamer
|
||||
*
|
||||
* Copyright (C) 2025 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* gstanalyticsbatchmeta.h
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef __GST_ANALYTICS_BATCH_META_H__
|
||||
#define __GST_ANALYTICS_BATCH_META_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/analytics/analytics-meta-prelude.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GstAnalyticsBatchBuffer:
|
||||
* @sticky_events: (nullable) (array length=n_sticky_events): All sticky #GstEvent that relate to this buffer
|
||||
* @n_sticky_events: Number of sticky events.
|
||||
* @serialized_events: (nullable) (array length=n_serialized_events): All non-sticky, serialized #GstEvent that arrived
|
||||
* after the previous and before this buffer
|
||||
* @n_serialized_events: Number of serialized events.
|
||||
* @buffer: (nullable): The buffer, if any.
|
||||
* @buffer_list: (nullable): The buffer list, if any.
|
||||
*
|
||||
* The intended use of this struct is that analytics elements read the buffer or
|
||||
* buffer list and potentially attach new #GstMeta with additional information.
|
||||
* Only one of @buffer or @buffer_list is going to be set, or both are %NULL.
|
||||
*
|
||||
* Elements that need to modify @buffer (e.g. to attach a new meta) must first
|
||||
* call gst_buffer_make_writable() and store the writable buffer in this struct.
|
||||
* Similarly, a writable @buffer_list must be ensured with
|
||||
* gst_buffer_list_make_writable().
|
||||
*
|
||||
* Modifying any other fields must be done with special care to ensure that the
|
||||
* data flow of the stream is not broken.
|
||||
*
|
||||
* It is possible for @buffer and @buffer_list to be %NULL, e.g. if there was no
|
||||
* buffer for this batch but there were serialized events like a gap event.
|
||||
*
|
||||
* Note that @serialized_events always contains all currently active serialized
|
||||
* events and not only the changed events compared to the previous buffer.
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
typedef struct _GstAnalyticsBatchBuffer {
|
||||
GstEvent **sticky_events;
|
||||
gsize n_sticky_events;
|
||||
|
||||
GstEvent **serialized_events;
|
||||
gsize n_serialized_events;
|
||||
|
||||
GstBuffer *buffer;
|
||||
GstBufferList *buffer_list;
|
||||
|
||||
/* <private> */
|
||||
gpointer padding[GST_PADDING];
|
||||
} GstAnalyticsBatchBuffer;
|
||||
|
||||
/**
|
||||
* GstAnalyticsBatchStream:
|
||||
* @index: Index of the stream in the meta's stream array
|
||||
* @buffers: (nullable) (array length=n_buffers): #GstAnalyticsBatchBuffer in this batch for this stream
|
||||
* @n_buffers: Number of buffers
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
typedef struct _GstAnalyticsBatchStream {
|
||||
guint index;
|
||||
|
||||
GstAnalyticsBatchBuffer *buffers;
|
||||
gsize n_buffers;
|
||||
|
||||
/* <private> */
|
||||
gpointer padding[GST_PADDING];
|
||||
} GstAnalyticsBatchStream;
|
||||
|
||||
/**
|
||||
* GstAnalyticsBatchMeta:
|
||||
* @meta: parent
|
||||
* @streams: (nullable) (array length=n_streams): #GstAnalyticsBatchStream for this batch
|
||||
* @n_streams: Number of streams
|
||||
*
|
||||
* This meta represents a batch of buffers from one or more streams together
|
||||
* with the relevant events to be able to interpret the buffers and to be able
|
||||
* to reconstruct the original streams.
|
||||
*
|
||||
* When used for multiple streams and batching them temporarily, caps of type
|
||||
* `multistream/x-analytics-batch(meta:GstAnalyticsBatchMeta)` should be used,
|
||||
* with the original caps of each stream in an array-typed `streams` field. The
|
||||
* original caps of each stream might be extended by additional fields and the
|
||||
* order of the streams in the array corresponds to the order of the @streams
|
||||
* array of the meta. In this case, empty buffers would be used without any
|
||||
* #GstMemory and
|
||||
*
|
||||
* When used for a single stream, the original caps might be used together with
|
||||
* the `meta:GstAnalyticsBatchMeta` caps feature and potentially extended by
|
||||
* additional fields to describe the kind of batching and its configuration,
|
||||
* e.g. that each batch is made of 25% overlapping 320x320 slices of the
|
||||
* original video frame.
|
||||
*
|
||||
* The timestamp, duration and other metadata of each batch can be retrieved
|
||||
* from the parent buffer of this meta.
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
typedef struct _GstAnalyticsBatchMeta
|
||||
{
|
||||
GstMeta meta;
|
||||
|
||||
GstAnalyticsBatchStream *streams;
|
||||
gsize n_streams;
|
||||
} GstAnalyticsBatchMeta;
|
||||
|
||||
/**
|
||||
* GST_ANALYTICS_BATCH_META_API_TYPE:
|
||||
*
|
||||
* The Analytics Batch Meta API type
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
#define GST_ANALYTICS_BATCH_META_API_TYPE \
|
||||
(gst_analytics_batch_meta_api_get_type())
|
||||
|
||||
/**
|
||||
* GST_ANALYTICS_BATCH_META_INFO: (skip)
|
||||
*
|
||||
* The Analytics Batch Meta API Info
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
#define GST_ANALYTICS_BATCH_META_INFO \
|
||||
(gst_analytics_batch_meta_get_info())
|
||||
|
||||
/**
|
||||
* GST_CAPS_FEATURE_META_GST_ANALYTICS_BATCH_META:
|
||||
*
|
||||
* The caps feature to be used on streams that make use of this meta.
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
#define GST_CAPS_FEATURE_META_GST_ANALYTICS_BATCH_META "meta:GstAnalyticsBatchMeta"
|
||||
|
||||
GST_ANALYTICS_META_API
|
||||
GType gst_analytics_batch_meta_api_get_type (void);
|
||||
|
||||
GST_ANALYTICS_META_API
|
||||
const GstMetaInfo *gst_analytics_batch_meta_get_info (void);
|
||||
|
||||
GST_ANALYTICS_META_API
|
||||
GstAnalyticsBatchMeta *
|
||||
gst_buffer_add_analytics_batch_meta (GstBuffer * buffer);
|
||||
|
||||
GST_ANALYTICS_META_API
|
||||
GstAnalyticsBatchMeta *
|
||||
gst_buffer_get_analytics_batch_meta (GstBuffer * buffer);
|
||||
|
||||
GST_ANALYTICS_META_API
|
||||
const gchar *
|
||||
gst_analytics_batch_buffer_get_stream_id (GstAnalyticsBatchBuffer * buffer);
|
||||
|
||||
GST_ANALYTICS_META_API
|
||||
GstCaps *
|
||||
gst_analytics_batch_buffer_get_caps (GstAnalyticsBatchBuffer * buffer);
|
||||
|
||||
GST_ANALYTICS_META_API
|
||||
const GstSegment *
|
||||
gst_analytics_batch_buffer_get_segment (GstAnalyticsBatchBuffer * buffer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
@ -3,6 +3,7 @@ analytics_sources = files( 'gstanalyticsmeta.c',
|
||||
'gstanalyticsobjectdetectionmtd.c',
|
||||
'gstanalyticsobjecttrackingmtd.c',
|
||||
'gstanalyticssegmentationmtd.c',
|
||||
'gstanalyticsbatchmeta.c',
|
||||
'gsttensormeta.c',
|
||||
'gsttensor.c',
|
||||
'gstanalytics_image_util.c')
|
||||
@ -14,6 +15,7 @@ analytics_headers = files( 'analytics.h',
|
||||
'gstanalyticsobjectdetectionmtd.h',
|
||||
'gstanalyticsobjecttrackingmtd.h',
|
||||
'gstanalyticssegmentationmtd.h',
|
||||
'gstanalyticsbatchmeta.h',
|
||||
'gsttensormeta.h',
|
||||
'gsttensor.h',
|
||||
'gstanalytics_image_util.h')
|
||||
|
Loading…
x
Reference in New Issue
Block a user