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) {
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;
+}