From 35ea6fdddfbf9c3a66bda5c3f3fbbe5249613f95 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 2 Nov 2015 16:19:42 +0200 Subject: [PATCH] audio: Add GstAudioClippingMeta for specifying clipping on encoded audio buffers https://bugzilla.gnome.org/show_bug.cgi?id=757153 --- docs/libs/gst-plugins-base-libs-sections.txt | 13 ++-- gst-libs/gst/audio/audio.h | 9 +++ gst-libs/gst/audio/gstaudiometa.c | 102 +++++++++++++++++++++++++++ gst-libs/gst/audio/gstaudiometa.h | 45 ++++++++++++ win32/common/libgstaudio.def | 3 + 5 files changed, 168 insertions(+), 4 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 444dc8f..5473ca3 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -184,6 +184,7 @@ GST_FRAMES_TO_CLOCK_TIME GST_CLOCK_TIME_TO_FRAMES GST_META_TAG_AUDIO_STR GST_META_TAG_AUDIO_CHANNELS_STR +GST_META_TAG_AUDIO_RATE_STR GST_AUDIO_NE GST_AUDIO_OE GST_AUDIO_RATE_RANGE @@ -222,11 +223,15 @@ GstAudioDownmixMeta gst_buffer_add_audio_downmix_meta gst_buffer_get_audio_downmix_meta gst_buffer_get_audio_downmix_meta_for_channels + +GstAudioClippingMeta +gst_buffer_add_audio_clipping_meta +gst_buffer_get_audio_clipping_meta -GST_AUDIO_DOWNMIX_META_API_TYPE -GST_AUDIO_DOWNMIX_META_INFO -gst_audio_downmix_meta_api_get_type -gst_audio_downmix_meta_get_info +GST_AUDIO_CLIPPING_META_API_TYPE +GST_AUDIO_CLIPPING_META_INFO +gst_audio_clipping_meta_api_get_type +gst_audio_clipping_meta_get_info
diff --git a/gst-libs/gst/audio/audio.h b/gst-libs/gst/audio/audio.h index 9dde1aa..07a997b 100644 --- a/gst-libs/gst/audio/audio.h +++ b/gst-libs/gst/audio/audio.h @@ -70,6 +70,15 @@ G_BEGIN_DECLS */ #define GST_META_TAG_AUDIO_CHANNELS_STR "channels" +/** + * GST_META_TAG_AUDIO_RATE_STR: + * + * This metadata stays relevant as long as sample rate is unchanged. + * + * Since: 1.8 + */ +#define GST_META_TAG_AUDIO_RATE_STR "rate" + /* * this library defines and implements some helper functions for audio * handling diff --git a/gst-libs/gst/audio/gstaudiometa.c b/gst-libs/gst/audio/gstaudiometa.c index 1c5e8a3..b540166 100644 --- a/gst-libs/gst/audio/gstaudiometa.c +++ b/gst-libs/gst/audio/gstaudiometa.c @@ -199,3 +199,105 @@ gst_audio_downmix_meta_get_info (void) } return audio_downmix_meta_info; } + +static gboolean +gst_audio_clipping_meta_init (GstMeta * meta, gpointer params, + GstBuffer * buffer) +{ + GstAudioClippingMeta *cmeta = (GstAudioClippingMeta *) meta; + + cmeta->format = GST_FORMAT_UNDEFINED; + cmeta->start = cmeta->end = 0; + + return TRUE; +} + +static gboolean +gst_audio_clipping_meta_transform (GstBuffer * dest, GstMeta * meta, + GstBuffer * buffer, GQuark type, gpointer data) +{ + GstAudioClippingMeta *smeta, *dmeta; + + smeta = (GstAudioClippingMeta *) meta; + + if (GST_META_TRANSFORM_IS_COPY (type)) { + GstMetaTransformCopy *copy = data; + + if (copy->region) + return FALSE; + + dmeta = + gst_buffer_add_audio_clipping_meta (dest, smeta->format, smeta->start, + smeta->end); + if (!dmeta) + return FALSE; + } else { + /* TODO: Could implement an automatic transform for resampling */ + /* return FALSE, if transform type is not supported */ + return FALSE; + } + + return TRUE; +} + +/** + * gst_buffer_add_audio_clipping_meta: + * @buffer: a #GstBuffer + * @format: GstFormat of @start and @stop, GST_FORMAT_DEFAULT is samples + * @start: Amount of audio to clip from start of buffer + * @end: Amount of to clip from end of buffer + * + * Attaches #GstAudioClippingMeta metadata to @buffer with the given parameters. + * + * Returns: (transfer none): the #GstAudioClippingMeta on @buffer. + * + * Since: 1.8 + */ +GstAudioClippingMeta * +gst_buffer_add_audio_clipping_meta (GstBuffer * buffer, + GstFormat format, guint64 start, guint64 end) +{ + GstAudioClippingMeta *meta; + + g_return_val_if_fail (format != GST_FORMAT_UNDEFINED, NULL); + + meta = + (GstAudioClippingMeta *) gst_buffer_add_meta (buffer, + GST_AUDIO_CLIPPING_META_INFO, NULL); + + meta->format = format; + meta->start = start; + meta->end = end; + + return meta; +} + +GType +gst_audio_clipping_meta_api_get_type (void) +{ + static volatile GType type; + static const gchar *tags[] = + { GST_META_TAG_AUDIO_STR, GST_META_TAG_AUDIO_RATE_STR, NULL }; + + if (g_once_init_enter (&type)) { + GType _type = gst_meta_api_type_register ("GstAudioClippingMetaAPI", tags); + g_once_init_leave (&type, _type); + } + return type; +} + +const GstMetaInfo * +gst_audio_clipping_meta_get_info (void) +{ + static const GstMetaInfo *audio_clipping_meta_info = NULL; + + if (g_once_init_enter (&audio_clipping_meta_info)) { + const GstMetaInfo *meta = + gst_meta_register (GST_AUDIO_CLIPPING_META_API_TYPE, + "GstAudioClippingMeta", sizeof (GstAudioClippingMeta), + gst_audio_clipping_meta_init, NULL, + gst_audio_clipping_meta_transform); + g_once_init_leave (&audio_clipping_meta_info, meta); + } + return audio_clipping_meta_info; +} diff --git a/gst-libs/gst/audio/gstaudiometa.h b/gst-libs/gst/audio/gstaudiometa.h index 8ffe176..ca58fb1 100644 --- a/gst-libs/gst/audio/gstaudiometa.h +++ b/gst-libs/gst/audio/gstaudiometa.h @@ -71,6 +71,51 @@ GstAudioDownmixMeta * gst_buffer_add_audio_downmix_meta (GstBuffer *buffer, gint to_channels, const gfloat **matrix); + +#define GST_AUDIO_CLIPPING_META_API_TYPE (gst_audio_clipping_meta_api_get_type()) +#define GST_AUDIO_CLIPPING_META_INFO (gst_audio_clipping_meta_get_info()) + +typedef struct _GstAudioClippingMeta GstAudioClippingMeta; + +/** + * GstAudioClippingMeta: + * @meta: parent #GstMeta + * @format: GstFormat of @start and @stop, GST_FORMAT_DEFAULT is samples + * @start: Amount of audio to clip from start of buffer + * @end: Amount of to clip from end of buffer + * + * Extra buffer metadata describing how much audio has to be clipped from + * the start or end of a buffer. This is used for compressed formats, where + * the first frame usually has some additional samples due to encoder and + * decoder delays, and the last frame usually has some additional samples to + * be able to fill the complete last frame. + * + * This is used to ensure that decoded data in the end has the same amount of + * samples, and multiply decoded streams can be gaplessly concatenated. + * + * Note: If clipping of the start is done by adjusting the segment, this meta + * has to be dropped from buffers as otherwise clipping could happen twice. + * + * Since: 1.8 + */ +struct _GstAudioClippingMeta { + GstMeta meta; + + GstFormat format; + guint64 start; + guint64 end; +}; + +GType gst_audio_clipping_meta_api_get_type (void); +const GstMetaInfo * gst_audio_clipping_meta_get_info (void); + +#define gst_buffer_get_audio_clipping_meta(b) ((GstAudioClippingMeta*)gst_buffer_get_meta((b), GST_AUDIO_CLIPPING_META_API_TYPE)) + +GstAudioClippingMeta * gst_buffer_add_audio_clipping_meta (GstBuffer *buffer, + GstFormat format, + guint64 start, + guint64 end); + G_END_DECLS #endif /* __GST_AUDIO_META_H__ */ diff --git a/win32/common/libgstaudio.def b/win32/common/libgstaudio.def index 93031a0..ea0ea84 100644 --- a/win32/common/libgstaudio.def +++ b/win32/common/libgstaudio.def @@ -32,6 +32,8 @@ EXPORTS gst_audio_channel_positions_to_mask gst_audio_channel_positions_to_valid_order gst_audio_check_valid_channel_positions + gst_audio_clipping_meta_api_get_type + gst_audio_clipping_meta_get_info gst_audio_clock_adjust gst_audio_clock_get_time gst_audio_clock_get_type @@ -164,6 +166,7 @@ EXPORTS gst_audio_ring_buffer_stop gst_audio_sink_get_type gst_audio_src_get_type + gst_buffer_add_audio_clipping_meta gst_buffer_add_audio_downmix_meta gst_buffer_get_audio_downmix_meta_for_channels gst_stream_volume_convert_volume -- 2.7.4