mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
libs: audio: Handle meta changes in gst_audio_buffer_truncate
Set timestamp and duration to GST_CLOCK_TIME_NONE unless trim==0, because that function doesn't know the rate and therefore can't calculate them. Set offset and offset_end to appropriate values. Make it clear in the documentation that the caller is responsible for setting the timestamp and duration. Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/issues/869 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1039>
This commit is contained in:
parent
c7f1fd8320
commit
2527c8f9f8
2 changed files with 81 additions and 3 deletions
|
@ -258,6 +258,12 @@ gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
|
|||
* the necessary amount of samples from the end and @trim number of samples
|
||||
* from the beginning.
|
||||
*
|
||||
* This function does not know the audio rate, therefore the caller is
|
||||
* responsible for re-setting the correct timestamp and duration to the
|
||||
* buffer. However, timestamp will be preserved if trim == 0, and duration
|
||||
* will also be preserved if there is no trimming to be done. Offset and
|
||||
* offset end will be preserved / updated.
|
||||
*
|
||||
* After calling this function the caller does not own a reference to
|
||||
* @buffer anymore.
|
||||
*
|
||||
|
@ -274,11 +280,14 @@ gst_audio_buffer_truncate (GstBuffer * buffer, gint bpf, gsize trim,
|
|||
GstBuffer *ret = NULL;
|
||||
gsize orig_samples;
|
||||
gint i;
|
||||
GstClockTime orig_ts, orig_offset;
|
||||
|
||||
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;
|
||||
orig_ts = GST_BUFFER_PTS (buffer);
|
||||
orig_offset = GST_BUFFER_OFFSET (buffer);
|
||||
|
||||
g_return_val_if_fail (trim < orig_samples, NULL);
|
||||
g_return_val_if_fail (samples == -1 || trim + samples <= orig_samples, NULL);
|
||||
|
@ -312,5 +321,22 @@ gst_audio_buffer_truncate (GstBuffer * buffer, gint bpf, gsize trim,
|
|||
}
|
||||
}
|
||||
|
||||
GST_BUFFER_DTS (ret) = GST_CLOCK_TIME_NONE;
|
||||
if (GST_CLOCK_TIME_IS_VALID (orig_ts) && trim == 0) {
|
||||
GST_BUFFER_PTS (ret) = orig_ts;
|
||||
} else {
|
||||
GST_BUFFER_PTS (ret) = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
/* If duration was the same, it would have meant there's no trimming to be
|
||||
* done, so we have an early return further up */
|
||||
GST_BUFFER_DURATION (ret) = GST_CLOCK_TIME_NONE;
|
||||
if (orig_offset != GST_BUFFER_OFFSET_NONE) {
|
||||
GST_BUFFER_OFFSET (ret) = orig_offset + trim;
|
||||
GST_BUFFER_OFFSET_END (ret) = GST_BUFFER_OFFSET (ret) + samples;
|
||||
} else {
|
||||
GST_BUFFER_OFFSET (ret) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (ret) = GST_BUFFER_OFFSET_NONE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -647,8 +647,7 @@ GST_START_TEST (test_buffer_clip_samples_start_and_stop_no_meta)
|
|||
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
|
||||
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), GST_CLOCK_TIME_NONE);
|
||||
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
||||
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret),
|
||||
GST_BUFFER_OFFSET_NONE);
|
||||
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 800);
|
||||
gst_buffer_map (ret, &map, GST_MAP_READ);
|
||||
fail_unless (map.data == data + 200);
|
||||
fail_unless (map.size == 400);
|
||||
|
@ -664,7 +663,7 @@ GST_START_TEST (test_buffer_clip_samples_no_timestamp)
|
|||
GstSegment s;
|
||||
GstBuffer *buf;
|
||||
|
||||
/* If the buffer has no offset it should assert()
|
||||
/* If the buffer has no offset it should assert() in DEFAULT format
|
||||
* FIXME: check if return value is the same as the input buffer.
|
||||
* probably can't be done because the assert() does a SIGABRT.
|
||||
*/
|
||||
|
@ -683,6 +682,57 @@ GST_START_TEST (test_buffer_clip_samples_no_timestamp)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_buffer_truncate_samples_offset_end)
|
||||
{
|
||||
GstBuffer *buf;
|
||||
GstBuffer *ret;
|
||||
guint8 *data;
|
||||
|
||||
buf = make_buffer (&data);
|
||||
GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
|
||||
GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
|
||||
GST_BUFFER_OFFSET (buf) = 200;
|
||||
GST_BUFFER_OFFSET_END (buf) = 1200;
|
||||
|
||||
ret = gst_audio_buffer_truncate (buf, 4, 100, 100);
|
||||
fail_unless (ret != NULL);
|
||||
|
||||
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), GST_CLOCK_TIME_NONE);
|
||||
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), GST_CLOCK_TIME_NONE);
|
||||
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 300);
|
||||
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 400);
|
||||
|
||||
gst_buffer_unref (ret);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_buffer_truncate_samples_no_timestamp)
|
||||
{
|
||||
GstBuffer *buf;
|
||||
GstBuffer *ret;
|
||||
guint8 *data;
|
||||
|
||||
buf = make_buffer (&data);
|
||||
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
|
||||
|
||||
ret = gst_audio_buffer_truncate (buf, 4, 100, 1);
|
||||
fail_unless (ret != NULL);
|
||||
|
||||
fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), GST_CLOCK_TIME_NONE);
|
||||
fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), GST_CLOCK_TIME_NONE);
|
||||
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), GST_BUFFER_OFFSET_NONE);
|
||||
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret),
|
||||
GST_BUFFER_OFFSET_NONE);
|
||||
|
||||
gst_buffer_unref (ret);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_multichannel_checks)
|
||||
{
|
||||
GstAudioChannelPosition pos_2_mixed[2] = {
|
||||
|
@ -1554,6 +1604,8 @@ audio_suite (void)
|
|||
tcase_add_test (tc_chain, test_buffer_clip_samples_outside);
|
||||
tcase_add_test (tc_chain, test_buffer_clip_samples_start_and_stop_no_meta);
|
||||
tcase_add_test (tc_chain, test_buffer_clip_samples_no_timestamp);
|
||||
tcase_add_test (tc_chain, test_buffer_truncate_samples_offset_end);
|
||||
tcase_add_test (tc_chain, test_buffer_truncate_samples_no_timestamp);
|
||||
tcase_add_test (tc_chain, test_multichannel_checks);
|
||||
tcase_add_test (tc_chain, test_multichannel_reorder);
|
||||
tcase_add_test (tc_chain, test_audio_format_s8);
|
||||
|
|
Loading…
Reference in a new issue