gstreamer/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstlcevcmeta.c

231 lines
5.8 KiB
C
Raw Normal View History

/* GStreamer LCEVC meta
* Copyright (C) <2024> V-Nova International Limited
*
* 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
#include "gstlcevcmeta.h"
/**
* SECTION:gstlcevcmeta
* @title: GstMeta for LCEVC
* @short_description: LCEVC related GstMeta
*
*/
#define GST_CAT_DEFAULT lcevcmeta_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static gboolean
gst_lcevc_meta_init (GstMeta * meta, gpointer params, GstBuffer * buffer)
{
GstLcevcMeta *emeta = (GstLcevcMeta *) meta;
emeta->id = 0;
emeta->enhancement_data = NULL;
return TRUE;
}
static void
gst_lcevc_meta_free (GstMeta * meta, GstBuffer * buffer)
{
GstLcevcMeta *emeta = (GstLcevcMeta *) meta;
g_clear_pointer (&emeta->enhancement_data, gst_buffer_unref);
}
static gboolean
gst_lcevc_meta_transform (GstBuffer * dest, GstMeta * meta,
GstBuffer * buffer, GQuark type, gpointer data)
{
GstLcevcMeta *dmeta, *smeta;
smeta = (GstLcevcMeta *) meta;
if (GST_META_TRANSFORM_IS_COPY (type)) {
GstMetaTransformCopy *copy = data;
if (!copy->region) {
/* only copy if the complete data is copied as well */
dmeta = (GstLcevcMeta *) gst_buffer_add_meta (dest,
GST_LCEVC_META_INFO, NULL);
if (!dmeta)
return FALSE;
GST_TRACE ("copying lcevc metadata");
dmeta->id = smeta->id;
g_clear_pointer (&dmeta->enhancement_data, gst_buffer_unref);
dmeta->enhancement_data = gst_buffer_copy (smeta->enhancement_data);
}
} else {
/* return FALSE, if transform type is not supported */
return FALSE;
}
return TRUE;
}
/**
* gst_lcevc_meta_api_get_type:
*
* Gets the #GType of the LCEVC meta API.
*
* Returns: the #GType of the LCEVC meta API.
*
* Since: 1.26
*/
GType
gst_lcevc_meta_api_get_type (void)
{
static GType type = 0;
static const gchar *tags[] = { "video", NULL };
if (g_once_init_enter (&type)) {
GType _type = gst_meta_api_type_register ("GstLcevcMetaAPI", tags);
g_once_init_leave (&type, _type);
}
return type;
}
/**
* gst_lcevc_meta_get_info:
*
* Gets the #GstMetaInfo of the LCEVC meta.
*
* Returns: (transfer none) : the #GstLcevcMeta of the LCEVC meta.
*
* Since: 1.26
*/
const GstMetaInfo *
gst_lcevc_meta_get_info (void)
{
static const GstMetaInfo *lcevc_meta_info = NULL;
if (g_once_init_enter ((GstMetaInfo **) & lcevc_meta_info)) {
GST_DEBUG_CATEGORY_INIT (lcevcmeta_debug, "lcevcmeta", 0, "LCEVC Metadata");
const GstMetaInfo *meta = gst_meta_register (GST_LCEVC_META_API_TYPE,
"GstLcevcMeta",
sizeof (GstLcevcMeta),
(GstMetaInitFunction) gst_lcevc_meta_init,
(GstMetaFreeFunction) gst_lcevc_meta_free,
gst_lcevc_meta_transform);
g_once_init_leave ((GstMetaInfo **) & lcevc_meta_info,
(GstMetaInfo *) meta);
}
return lcevc_meta_info;
}
/**
* gst_buffer_get_lcevc_meta:
* @buffer: a #GstBuffer
*
* Find the #GstLcevcMeta on @buffer with the lowest @id.
*
* Buffers can contain multiple #GstLcevcMeta metadata items when dealing with
* multiview buffers.
*
* Returns: (transfer none) (nullable): the #GstLcevcMeta with lowest id (usually 0) or %NULL when there
* is no such metadata on @buffer.
*
* Since: 1.26
*/
GstLcevcMeta *
gst_buffer_get_lcevc_meta (GstBuffer * buffer)
{
gpointer state = NULL;
GstLcevcMeta *out = NULL;
GstMeta *meta;
const GstMetaInfo *info = GST_LCEVC_META_INFO;
while ((meta = gst_buffer_iterate_meta (buffer, &state))) {
if (meta->info->api == info->api) {
GstLcevcMeta *vmeta = (GstLcevcMeta *) meta;
if (vmeta->id == 0)
return vmeta; /* Early out for id 0 */
if (out == NULL || vmeta->id < out->id)
out = vmeta;
}
}
return out;
}
/**
* gst_buffer_get_lcevc_meta_id:
* @buffer: a #GstBuffer
* @id: a metadata id
*
* Find the #GstLcevcMeta on @buffer with the given @id.
*
* Buffers can contain multiple #GstLcevcMeta metadata items when dealing with
* multiview buffers.
*
* Returns: (transfer none) (nullable): the #GstLcevcMeta with @id or %NULL when there is no such metadata
* on @buffer.
*
* Since: 1.26
*/
GstLcevcMeta *
gst_buffer_get_lcevc_meta_id (GstBuffer * buffer, gint id)
{
gpointer state = NULL;
GstMeta *meta;
const GstMetaInfo *info = GST_LCEVC_META_INFO;
while ((meta = gst_buffer_iterate_meta (buffer, &state))) {
if (meta->info->api == info->api) {
GstLcevcMeta *vmeta = (GstLcevcMeta *) meta;
if (vmeta->id == id)
return vmeta;
}
}
return NULL;
}
/**
* gst_buffer_add_lcevc_meta:
* @buffer: a #GstBuffer
* @enhancement_data: (transfer none): the parsed LCEVC enhancement data
*
* Attaches GstLcevcMeta metadata to @buffer.
*
* Returns: (transfer none): the #GstLcevcMeta on @buffer.
*
* Since: 1.26
*/
GstLcevcMeta *
gst_buffer_add_lcevc_meta (GstBuffer * buffer, GstBuffer * enhancement_data)
{
GstLcevcMeta *meta;
meta = (GstLcevcMeta *) gst_buffer_add_meta (buffer, GST_LCEVC_META_INFO,
NULL);
if (!meta)
return NULL;
meta->id = 0;
g_clear_pointer (&meta->enhancement_data, gst_buffer_unref);
meta->enhancement_data = gst_buffer_ref (enhancement_data);
return meta;
}