audio: Add GstAudioClippingMeta for specifying clipping on encoded audio buffers
authorSebastian Dröge <sebastian@centricular.com>
Mon, 2 Nov 2015 14:19:42 +0000 (16:19 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 3 Nov 2015 18:35:33 +0000 (20:35 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=757153

docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/audio/audio.h
gst-libs/gst/audio/gstaudiometa.c
gst-libs/gst/audio/gstaudiometa.h
win32/common/libgstaudio.def

index 444dc8f..5473ca3 100644 (file)
@@ -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
 <SUBSECTION Standard>
-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
 </SECTION>
 
 <SECTION>
index 9dde1aa..07a997b 100644 (file)
@@ -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
index 1c5e8a3..b540166 100644 (file)
@@ -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;
+}
index 8ffe176..ca58fb1 100644 (file)
@@ -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__ */
index 93031a0..ea0ea84 100644 (file)
@@ -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