From 050083ee4f673f423cabf2504bbbea7de150166e Mon Sep 17 00:00:00 2001 From: Michael Fien Date: Fri, 20 Oct 2017 16:42:32 -0400 Subject: [PATCH] Add MPEG2-TS descriptor support for KLV metadata --- gst-libs/gst/codecparsers/Makefile.am | 6 +- gst-libs/gst/codecparsers/gstklvmeta.c | 137 ++++++++++++++++++++++++++++++ gst-libs/gst/codecparsers/gstklvmeta.h | 73 ++++++++++++++++ gst-libs/gst/mpegts/gstmpegtsdescriptor.c | 64 ++++++++++++++ gst-libs/gst/mpegts/gstmpegtsdescriptor.h | 12 +++ gst/mpegtsmux/Makefile.am | 1 + 6 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 gst-libs/gst/codecparsers/gstklvmeta.c create mode 100644 gst-libs/gst/codecparsers/gstklvmeta.h diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index e7d8248..627e590 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -7,7 +7,8 @@ libgstcodecparsers_@GST_API_VERSION@_la_SOURCES = \ gstjpegparser.c \ gstmpegvideometa.c \ gstjpeg2000sampling.c \ - gstvp9parser.c vp9utils.c + gstvp9parser.c vp9utils.c \ + gstklvmeta.c libgstcodecparsers_@GST_API_VERSION@includedir = \ $(includedir)/gstreamer-@GST_API_VERSION@/gst/codecparsers @@ -20,7 +21,8 @@ libgstcodecparsers_@GST_API_VERSION@include_HEADERS = \ gstjpegparser.h \ gstmpegvideometa.h \ gstjpeg2000sampling.h \ - gstvp9parser.h + gstvp9parser.h \ + gstklvmeta.h libgstcodecparsers_@GST_API_VERSION@_la_CFLAGS = \ $(GST_PLUGINS_BAD_CFLAGS) \ diff --git a/gst-libs/gst/codecparsers/gstklvmeta.c b/gst-libs/gst/codecparsers/gstklvmeta.c new file mode 100644 index 0000000..6f1e1b2 --- /dev/null +++ b/gst-libs/gst/codecparsers/gstklvmeta.c @@ -0,0 +1,137 @@ +/* + * GStreamer + * Copyright (C) 2017 Michael Fien + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstklvmeta.h" + +GST_DEBUG_CATEGORY (klv_meta_debug); +#define GST_CAT_DEFAULT klv_meta_debug + +static gboolean +gst_klv_meta_init (GstKlvMeta * klv_meta, gpointer params, GstBuffer * buffer) +{ + klv_meta->metadata_service_id = 0; + klv_meta->sequence_number = 0; + klv_meta->flags = 0; + klv_meta->au_cell_data_length = 0; + + return TRUE; +} + +static void +gst_klv_meta_free (GstKlvMeta * klv_meta, GstBuffer * buffer) +{ +} + +static gboolean +gst_klv_meta_transform (GstBuffer * dest, GstMeta * meta, + GstBuffer * buffer, GQuark type, gpointer data) +{ + GstKlvMeta *smeta, *dmeta; + + smeta = (GstKlvMeta *) 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 = + gst_buffer_add_klv_meta (dest, smeta->metadata_service_id, + smeta->sequence_number, smeta->flags, smeta->au_cell_data_length); + + if (!dmeta) + return FALSE; + } + } else { + /* return FALSE, if transform type is not supported */ + return FALSE; + } + + return TRUE; +} + +GType +gst_klv_meta_api_get_type (void) +{ + static volatile GType type; + static const gchar *tags[] = { "au_header", NULL }; /* don't know what to set here */ + + if (g_once_init_enter (&type)) { + GType _type = gst_meta_api_type_register ("GstKlvMetaAPI", tags); + GST_DEBUG_CATEGORY_INIT (klv_meta_debug, "klvmeta", 0, "KLV GstMeta"); + + g_once_init_leave (&type, _type); + } + return type; +} + +const GstMetaInfo * +gst_klv_meta_get_info (void) +{ + static const GstMetaInfo *klv_meta_info = NULL; + + if (g_once_init_enter ((GstMetaInfo **) & klv_meta_info)) { + const GstMetaInfo *meta = gst_meta_register (GST_KLV_META_API_TYPE, + "GstKlvMeta", sizeof (GstKlvMeta), + (GstMetaInitFunction) gst_klv_meta_init, + (GstMetaFreeFunction) gst_klv_meta_free, + (GstMetaTransformFunction) gst_klv_meta_transform); + g_once_init_leave ((GstMetaInfo **) & klv_meta_info, (GstMetaInfo *) meta); + } + + return klv_meta_info; +} + +/** + * gst_buffer_add_klv_meta: + * @buffer: a #GstBuffer + * + * Creates and adds a #GstKlvMeta to a @buffer. + * + * Returns: (transfer full): a newly created #GstKlvMeta + * + * Since: 1.2 + */ +GstKlvMeta * +gst_buffer_add_klv_meta (GstBuffer * buffer, + const guint8 metadata_service_id, + const guint8 sequence_number, + const guint8 flags, const guint16 au_cell_data_length) +{ + GstKlvMeta *klv_meta; + + klv_meta = + (GstKlvMeta *) gst_buffer_add_meta (buffer, GST_KLV_META_INFO, NULL); + + GST_DEBUG + ("metadata_service_id:%i, sequence_number:%i, flags:%i, au_cell_data_length:%i", + metadata_service_id, sequence_number, flags, au_cell_data_length); + + klv_meta->metadata_service_id = metadata_service_id; + klv_meta->sequence_number = sequence_number; + klv_meta->flags = flags; + klv_meta->au_cell_data_length = au_cell_data_length; + + return klv_meta; +} diff --git a/gst-libs/gst/codecparsers/gstklvmeta.h b/gst-libs/gst/codecparsers/gstklvmeta.h new file mode 100644 index 0000000..56d7e00 --- /dev/null +++ b/gst-libs/gst/codecparsers/gstklvmeta.h @@ -0,0 +1,73 @@ +/* Gstreamer + * Copyright (C) <2017> Michael Fien + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_KLV_META_H__ +#define __GST_KLV_META_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GstKlvMeta GstKlvMeta; + +GType gst_klv_meta_api_get_type (void); +#define GST_KLV_META_API_TYPE (gst_klv_meta_api_get_type()) +#define GST_KLV_META_INFO (gst_klv_meta_get_info()) +const GstMetaInfo * gst_klv_meta_get_info (void); + +/** + * GstKlvMeta: + * @meta: parent #GstMeta + * @metadata_service_id: the Metadata service id + * @sequence_number: the sequence number + * @flags: the flags + * @au_cell_data_length: the AU cell data length + * + * Extra buffer metadata describing Metadata AU header. + * + * Can be used by mpegtsmuxer add metadata au header back to + * synchronous KLV metadata per MISB 0604. + * + * The various fields are only valid during the lifetime of the #GstKlvMeta. + * If elements wish to use those for longer, they are required to make a copy. + * + * Since: 1.2 + */ +struct _GstKlvMeta { + GstMeta meta; + + guint8 metadata_service_id; + guint8 sequence_number; + guint8 flags; + guint16 au_cell_data_length; +}; + + +#define gst_buffer_get_klv_meta(b) ((GstKlvMeta*)gst_buffer_get_meta((b),GST_KLV_META_API_TYPE)) + +GstKlvMeta * +gst_buffer_add_klv_meta (GstBuffer * buffer, + const guint8 metadata_service_id, + const guint8 sequence_number, + const guint8 flags, + const guint16 au_cell_data_length); + +G_END_DECLS + +#endif diff --git a/gst-libs/gst/mpegts/gstmpegtsdescriptor.c b/gst-libs/gst/mpegts/gstmpegtsdescriptor.c index 079716e..2fd89b0 100644 --- a/gst-libs/gst/mpegts/gstmpegtsdescriptor.c +++ b/gst-libs/gst/mpegts/gstmpegtsdescriptor.c @@ -4,6 +4,7 @@ * * Authors: * Edward Hervey + * Michael Fien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -1151,3 +1152,66 @@ gst_mpegts_descriptor_from_custom_with_extension (guint8 tag, return descriptor; } + +/* GST_MTS_DESC_METADATA (0x26) */ +/** + * gst_mpegts_descriptor_from_metadata: + * @format_identifier: (transfer none): a 4 character format identifier string + * @additional_info: (transfer none) (allow-none): pointer to optional additional info + * @additional_info_length: length of the optional @additional_info + * + * Creates a %GST_MTS_DESC_METADATA #GstMpegtsDescriptor + * + * Return: #GstMpegtsDescriptor, %NULL on failure + */ +GstMpegtsDescriptor * +gst_mpegts_descriptor_from_metadata (guint application_format, guint format) +{ + GstMpegtsDescriptor *descriptor; + + descriptor = _new_descriptor (GST_MTS_DESC_METADATA, 9); + + descriptor->data[2] = (application_format & 0xff00) >> 8; + descriptor->data[3] = (application_format & 0xff); + descriptor->data[4] = format; + descriptor->data[5] = 'K'; + descriptor->data[6] = 'L'; + descriptor->data[7] = 'V'; + descriptor->data[8] = 'A'; + descriptor->data[9] = 0; + descriptor->data[10] = 0x0f; + + return descriptor; +} + +/* GST_MTS_DESC_METADATA_STD (0x27) */ +/** + * gst_mpegts_descriptor_from_metadata_std: + * @format_identifier: (transfer none): a 4 character format identifier string + * @additional_info: (transfer none) (allow-none): pointer to optional additional info + * @additional_info_length: length of the optional @additional_info + * + * Creates a %GST_MTS_DESC_METADATA_STD #GstMpegtsDescriptor + * + * Return: #GstMpegtsDescriptor, %NULL on failure + */ +GstMpegtsDescriptor * +gst_mpegts_descriptor_from_metadata_std (guint input_leak_rate, + guint buffer_size, guint output_leak_rate) +{ + GstMpegtsDescriptor *descriptor; + + descriptor = _new_descriptor (GST_MTS_DESC_METADATA_STD, 9); + + descriptor->data[2] = ((input_leak_rate & 0xff0000) >> 16) | 0xc0; + descriptor->data[3] = (input_leak_rate & 0xff00) >> 8; + descriptor->data[4] = input_leak_rate & 0xff; + descriptor->data[5] = ((buffer_size & 0xff0000) >> 16) | 0xc0; + descriptor->data[6] = (buffer_size & 0xff00) >> 8;; + descriptor->data[7] = buffer_size & 0xff; + descriptor->data[8] = ((output_leak_rate & 0xff0000) >> 16) | 0xc0; + descriptor->data[9] = (output_leak_rate & 0xff00) >> 8;; + descriptor->data[10] = output_leak_rate & 0xff; + + return descriptor; +} diff --git a/gst-libs/gst/mpegts/gstmpegtsdescriptor.h b/gst-libs/gst/mpegts/gstmpegtsdescriptor.h index 55edecc..8beedeb 100644 --- a/gst-libs/gst/mpegts/gstmpegtsdescriptor.h +++ b/gst-libs/gst/mpegts/gstmpegtsdescriptor.h @@ -4,6 +4,7 @@ * * Authors: * Edward Hervey + * Michael Fien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -289,6 +290,17 @@ gboolean gst_mpegts_descriptor_parse_ca (GstMpegtsDescriptor *descriptor, const guint8 **private_data, gsize *private_data_size); +/* GST_MTS_DESC_METADATA (0x26) */ +GST_EXPORT +GstMpegtsDescriptor * +gst_mpegts_descriptor_from_metadata (guint application_format, guint format); + +/* GST_MTS_DESC_METADATA_STD (0x27) */ +GST_EXPORT +GstMpegtsDescriptor * +gst_mpegts_descriptor_from_metadata_std ( guint input_leak_rate, + guint buffer_size, guint output_leak_rate); + /* GST_MTS_DESC_ISO_639_LANGUAGE (0x0A) */ /** * GstMpegtsISO639AudioType: diff --git a/gst/mpegtsmux/Makefile.am b/gst/mpegtsmux/Makefile.am index 2421fa1..34ac5ea 100644 --- a/gst/mpegtsmux/Makefile.am +++ b/gst/mpegtsmux/Makefile.am @@ -14,6 +14,7 @@ libgstmpegtsmux_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) libgstmpegtsmux_la_LIBADD = $(top_builddir)/gst/mpegtsmux/tsmux/libtsmux.la \ $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ \ + $(top_builddir)/gst-libs/gst/codecparsers/libgstcodecparsers-$(GST_API_VERSION).la \ -lgstaudio-@GST_API_VERSION@ -lgsttag-@GST_API_VERSION@ \ -lgstpbutils-@GST_API_VERSION@ \ $(GST_BASE_LIBS) $(GST_LIBS) -- 1.9.1