mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 19:55:32 +00:00
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
This commit is contained in:
parent
adf48c9d3b
commit
b33d70e97f
2 changed files with 73 additions and 30 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue