mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 16:08:51 +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
|
* the necessary amount of samples from the end and @trim number of samples
|
||||||
* from the beginning.
|
* 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
|
* After calling this function the caller does not own a reference to
|
||||||
* @buffer anymore.
|
* @buffer anymore.
|
||||||
*
|
*
|
||||||
|
@ -274,11 +280,14 @@ gst_audio_buffer_truncate (GstBuffer * buffer, gint bpf, gsize trim,
|
||||||
GstBuffer *ret = NULL;
|
GstBuffer *ret = NULL;
|
||||||
gsize orig_samples;
|
gsize orig_samples;
|
||||||
gint i;
|
gint i;
|
||||||
|
GstClockTime orig_ts, orig_offset;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
|
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
|
||||||
|
|
||||||
meta = gst_buffer_get_audio_meta (buffer);
|
meta = gst_buffer_get_audio_meta (buffer);
|
||||||
orig_samples = meta ? meta->samples : gst_buffer_get_size (buffer) / bpf;
|
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 (trim < orig_samples, NULL);
|
||||||
g_return_val_if_fail (samples == -1 || trim + samples <= 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;
|
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_TIMESTAMP (ret), 4 * GST_SECOND);
|
||||||
fail_unless_equals_int64 (GST_BUFFER_DURATION (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), 400);
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
|
||||||
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret),
|
fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 800);
|
||||||
GST_BUFFER_OFFSET_NONE);
|
|
||||||
gst_buffer_map (ret, &map, GST_MAP_READ);
|
gst_buffer_map (ret, &map, GST_MAP_READ);
|
||||||
fail_unless (map.data == data + 200);
|
fail_unless (map.data == data + 200);
|
||||||
fail_unless (map.size == 400);
|
fail_unless (map.size == 400);
|
||||||
|
@ -664,7 +663,7 @@ GST_START_TEST (test_buffer_clip_samples_no_timestamp)
|
||||||
GstSegment s;
|
GstSegment s;
|
||||||
GstBuffer *buf;
|
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.
|
* FIXME: check if return value is the same as the input buffer.
|
||||||
* probably can't be done because the assert() does a SIGABRT.
|
* 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_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)
|
GST_START_TEST (test_multichannel_checks)
|
||||||
{
|
{
|
||||||
GstAudioChannelPosition pos_2_mixed[2] = {
|
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_outside);
|
||||||
tcase_add_test (tc_chain, test_buffer_clip_samples_start_and_stop_no_meta);
|
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_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_checks);
|
||||||
tcase_add_test (tc_chain, test_multichannel_reorder);
|
tcase_add_test (tc_chain, test_multichannel_reorder);
|
||||||
tcase_add_test (tc_chain, test_audio_format_s8);
|
tcase_add_test (tc_chain, test_audio_format_s8);
|
||||||
|
|
Loading…
Reference in a new issue