From b33d70e97ff1679de5b9f85155693afe9912afd9 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Fri, 18 May 2018 16:22:47 +0300 Subject: [PATCH] libs: audio: add a new gst_audio_buffer_truncate() function Essentially this moves the truncation logic out of gst_audio_buffer_clip() so that it can be used in other places, like in audiorate. https://bugzilla.gnome.org/show_bug.cgi?id=796740 --- gst-libs/gst/audio/audio.c | 100 +++++++++++++++++++++++++++++++-------------- gst-libs/gst/audio/audio.h | 3 ++ 2 files changed, 73 insertions(+), 30 deletions(-) diff --git a/gst-libs/gst/audio/audio.c b/gst-libs/gst/audio/audio.c index 79b976b..9c7ed04 100644 --- a/gst-libs/gst/audio/audio.c +++ b/gst-libs/gst/audio/audio.c @@ -222,37 +222,10 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment, ret = gst_buffer_make_writable (ret); GST_BUFFER_DURATION (ret) = duration; } - } else if (meta && meta->info.layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) { - /* modify only the meta to avoid making copies of the planes */ - gint i; - - ret = gst_buffer_make_writable (buffer); - meta = gst_buffer_get_audio_meta (buffer); - - meta->samples = size; - for (i = 0; i < meta->info.channels; i++) { - meta->offsets[i] += trim * bpf / meta->info.channels; - } - - GST_BUFFER_TIMESTAMP (ret) = timestamp; - - if (change_duration) - GST_BUFFER_DURATION (ret) = duration; - if (change_offset) - GST_BUFFER_OFFSET (ret) = offset; - if (change_offset_end) - GST_BUFFER_OFFSET_END (ret) = offset_end; } else { - /* resize the buffer, effectively cutting out all - * the samples that are no longer relevant */ - - /* convert samples to bytes */ - trim *= bpf; - size *= bpf; - + /* cut out all the samples that are no longer relevant */ GST_DEBUG ("trim %" G_GSIZE_FORMAT " size %" G_GSIZE_FORMAT, trim, size); - ret = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, trim, size); - gst_buffer_unref (buffer); + ret = gst_audio_buffer_truncate (buffer, bpf, trim, size); GST_DEBUG ("timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp)); if (ret) { @@ -265,8 +238,75 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment, if (change_offset_end) GST_BUFFER_OFFSET_END (ret) = offset_end; } else { - GST_ERROR ("copy_region failed"); + GST_ERROR ("gst_audio_buffer_truncate failed"); } } return ret; } + +/** + * gst_audio_buffer_truncate: + * @buffer: (transfer full): The buffer to truncate. + * @bpf: size of one audio frame in bytes. This is the size of one sample * + * number of channels. + * @trim: the number of samples to remove from the beginning of the buffer + * @samples: the final number of samples that should exist in this buffer or -1 + * to use all the remaining samples if you are only removing samples from the + * beginning. + * + * Truncate the buffer to finally have @samples number of samples, removing + * the necessary amount of samples from the end and @trim number of samples + * from the beginning. + * + * After calling this function the caller does not own a reference to + * @buffer anymore. + * + * Returns: (transfer full): the truncated buffer or %NULL if the arguments + * were invalid + * + * Since: 1.16 + */ +GstBuffer * +gst_audio_buffer_truncate (GstBuffer * buffer, gint bpf, gsize trim, + gsize samples) +{ + GstAudioMeta *meta = NULL; + GstBuffer *ret = NULL; + gsize orig_samples; + gint i; + + g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); + + meta = gst_buffer_get_audio_meta (buffer); + orig_samples = meta ? meta->samples : gst_buffer_get_size (buffer) / bpf; + + g_return_val_if_fail (trim < orig_samples, NULL); + g_return_val_if_fail (samples == -1 || trim + samples <= orig_samples, NULL); + + if (samples == -1) + samples = orig_samples - trim; + + /* nothing to truncate */ + if (samples == orig_samples) + return buffer; + + if (!meta || meta->info.layout == GST_AUDIO_LAYOUT_INTERLEAVED) { + /* interleaved */ + ret = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, trim * bpf, + samples * bpf); + gst_buffer_unref (buffer); + + if ((meta = gst_buffer_get_audio_meta (ret))) + meta->samples = samples; + } else { + /* non-interleaved */ + ret = gst_buffer_make_writable (buffer); + meta = gst_buffer_get_audio_meta (buffer); + meta->samples = samples; + for (i = 0; i < meta->info.channels; i++) { + meta->offsets[i] += trim * bpf / meta->info.channels; + } + } + + return ret; +} diff --git a/gst-libs/gst/audio/audio.h b/gst-libs/gst/audio/audio.h index 16a985d..4120f5b 100644 --- a/gst-libs/gst/audio/audio.h +++ b/gst-libs/gst/audio/audio.h @@ -97,6 +97,9 @@ GstBuffer * gst_audio_buffer_clip (GstBuffer *buffer, const GstSegment *segment, gint rate, gint bpf); +GST_EXPORT +GstBuffer * gst_audio_buffer_truncate (GstBuffer *buffer, + gint bpf, gsize trim, gsize samples); G_END_DECLS -- 2.7.4