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
@ -222,37 +222,10 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
|
|||||||
ret = gst_buffer_make_writable (ret);
|
ret = gst_buffer_make_writable (ret);
|
||||||
GST_BUFFER_DURATION (ret) = duration;
|
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 {
|
} else {
|
||||||
/* resize the buffer, effectively cutting out all
|
/* cut out all the samples that are no longer relevant */
|
||||||
* the samples that are no longer relevant */
|
|
||||||
|
|
||||||
/* convert samples to bytes */
|
|
||||||
trim *= bpf;
|
|
||||||
size *= bpf;
|
|
||||||
|
|
||||||
GST_DEBUG ("trim %" G_GSIZE_FORMAT " size %" G_GSIZE_FORMAT, trim, size);
|
GST_DEBUG ("trim %" G_GSIZE_FORMAT " size %" G_GSIZE_FORMAT, trim, size);
|
||||||
ret = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, trim, size);
|
ret = gst_audio_buffer_truncate (buffer, bpf, trim, size);
|
||||||
gst_buffer_unref (buffer);
|
|
||||||
|
|
||||||
GST_DEBUG ("timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
|
GST_DEBUG ("timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -265,8 +238,75 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
|
|||||||
if (change_offset_end)
|
if (change_offset_end)
|
||||||
GST_BUFFER_OFFSET_END (ret) = offset_end;
|
GST_BUFFER_OFFSET_END (ret) = offset_end;
|
||||||
} else {
|
} else {
|
||||||
GST_ERROR ("copy_region failed");
|
GST_ERROR ("gst_audio_buffer_truncate failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
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,
|
const GstSegment *segment,
|
||||||
gint rate, gint bpf);
|
gint rate, gint bpf);
|
||||||
|
|
||||||
|
GST_EXPORT
|
||||||
|
GstBuffer * gst_audio_buffer_truncate (GstBuffer *buffer,
|
||||||
|
gint bpf, gsize trim, gsize samples);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user