audiotestsrc: Fix the way we compute EOS in reverse playback

In reverse playback we were not taking into account the current buffer
samples to check if we had reached EOS which was leading to a buffer
with PTS = CLOCK_TIME_NONE containing too many frames followed by a
useless buffer with pts=0 duration=0, and a g_critical issue in
gst_object_sync_values.

Also add a validate based test case.
Without that patch this is how the expectation fails:

``` diff
--- log-asink-sink-expected       2020-05-22 23:22:42.654384579 -0400
+++ log-asink-sink-actual  2020-05-22 23:29:35.671586380 -0400
@@ -27,5 +27,6 @@
 buffer: pts=0:00:00.058820861, due=0:00:00.023219955, flags=discont
 buffer: pts=0:00:00.035600907, due=0:00:00.023219954, flags=discont
 buffer: pts=0:00:00.012380952, due=0:00:00.023219955, flags=discont
-buffer: pts=0:00:00.000000000, due=0:00:00.012380952, flags=discont
+buffer: due=0:00:00.012380953, flags=discont
+buffer: pts=0:00:00.000000000, flags=discont
 event eos: (no structure)
 ```

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/667>
This commit is contained in:
Thibault Saunier 2020-05-22 23:24:55 -04:00 committed by GStreamer Merge Bot
parent eed54928c8
commit b46718b1a0
7 changed files with 119 additions and 11 deletions

View file

@ -1489,10 +1489,10 @@ gst_audio_test_src_fill (GstBaseSrc * basesrc, guint64 offset,
next_sample = src->sample_stop;
src->eos_reached = TRUE;
} else if (src->check_seek_stop && src->reverse &&
(src->sample_stop > src->next_sample)
(src->sample_stop >= (src->next_sample - samples))
) {
/* calculate only partial buffer */
src->generate_samples_per_buffer = src->sample_stop - src->next_sample;
src->generate_samples_per_buffer = src->next_sample - src->sample_stop;
next_sample = src->sample_stop;
src->eos_reached = TRUE;
} else {

View file

@ -87,3 +87,5 @@ option('package-origin', type : 'string', value : 'Unknown package origin', yiel
description : 'package origin URL to use in plugins')
option('doc', type : 'feature', value : 'auto', yield: true,
description: 'Enable documentation.')
option('validate', type : 'feature', value : 'auto', yield: true,
description: 'Enable validate tests.')

View file

@ -131,15 +131,6 @@ test_deps = [gst_dep, gst_base_dep, gst_net_dep, gst_check_dep, audio_dep,
video_dep, pbutils_dep, rtp_dep, rtsp_dep, tag_dep, allocators_dep, app_dep,
fft_dep, riff_dep, sdp_dep, gio_dep, valgrind_dep] + glib_deps
pluginsdirs = []
if gst_dep.type_name() == 'pkgconfig'
pluginsdirs = [gst_dep.get_pkgconfig_variable('pluginsdir')]
gst_plugin_scanner_dir = gst_dep.get_pkgconfig_variable('pluginscannerdir')
else
gst_plugin_scanner_dir = gst_proj.get_variable('gst_scanner_dir')
endif
gst_plugin_scanner_path = join_paths(gst_plugin_scanner_dir, 'gst-plugin-scanner')
foreach t : base_tests
fname = t.get(0)
test_name = fname.split('.').get(0).underscorify()

View file

@ -1,3 +1,12 @@
pluginsdirs = []
if gst_dep.type_name() == 'pkgconfig'
pluginsdirs = [gst_dep.get_pkgconfig_variable('pluginsdir')]
gst_plugin_scanner_dir = gst_dep.get_pkgconfig_variable('pluginscannerdir')
else
gst_plugin_scanner_dir = gst_proj.get_variable('gst_scanner_dir')
endif
gst_plugin_scanner_path = join_paths(gst_plugin_scanner_dir, 'gst-plugin-scanner')
if not get_option('tests').disabled() and gst_check_dep.found()
subdir('check')
subdir('icles')
@ -5,3 +14,7 @@ endif
if not get_option('examples').disabled()
subdir('examples')
endif
if not get_option('validate').disabled()
subdir('validate')
endif

View file

@ -0,0 +1,24 @@
meta,
args = {
"audiotestsrc name=src samplesperbuffer=1024 ! audio/x-raw,format=S16LE,rate=44100 ! fakesink name=asink sync=true",
},
configs = {
"$(validateflow), pad=asink:sink, record-buffers=true",
},
handles-states=true,
ignore-eos=true
play;
seek, start=0.0, stop=0.5, rate=-1.0, flags=accurate+flush
crank-clock, expected-time=0.0
# roundup((44100 / 2 / 1024) - 1 (already cranked) + 1 (for eos)) = 22
crank-clock, repeat=22
set-property, target-element-name="src", property-name="samplesperbuffer", property-value=4410, on-message=eos
seek, start=0.0, stop=1.0, rate=-1.0, flags=accurate+flush
crank-clock, expected-elapsed-time=0.0
crank-clock, repeat=10, expected-elapsed-time=0.1
stop, on-message=eos;

View file

@ -0,0 +1,45 @@
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
event caps: audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)1;
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
event tag: GstTagList-stream, taglist=(taglist)"taglist\,\ description\=\(string\)\"audiotest\\\ wave\"\;";
buffer: pts=0:00:00.000000000, dur=0:00:00.023219954, flags=discont
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:00.500000000, rate=-1.000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.500000000
buffer: pts=0:00:00.476780045, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.453560090, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.430340136, dur=0:00:00.023219954, flags=discont
buffer: pts=0:00:00.407120181, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.383900226, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.360680272, dur=0:00:00.023219954, flags=discont
buffer: pts=0:00:00.337460317, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.314240362, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.291020408, dur=0:00:00.023219954, flags=discont
buffer: pts=0:00:00.267800453, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.244580498, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.221360544, dur=0:00:00.023219954, flags=discont
buffer: pts=0:00:00.198140589, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.174920634, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.151700680, dur=0:00:00.023219954, flags=discont
buffer: pts=0:00:00.128480725, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.105260770, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.082040816, dur=0:00:00.023219954, flags=discont
buffer: pts=0:00:00.058820861, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.035600907, dur=0:00:00.023219954, flags=discont
buffer: pts=0:00:00.012380952, dur=0:00:00.023219955, flags=discont
buffer: pts=0:00:00.000000000, dur=0:00:00.012380952, flags=discont
event eos: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:01.000000000, rate=-1.000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:01.000000000
buffer: pts=0:00:00.900000000, dur=0:00:00.100000000, flags=discont
buffer: pts=0:00:00.800000000, dur=0:00:00.100000000, flags=discont
buffer: pts=0:00:00.700000000, dur=0:00:00.100000000, flags=discont
buffer: pts=0:00:00.600000000, dur=0:00:00.100000000, flags=discont
buffer: pts=0:00:00.500000000, dur=0:00:00.100000000, flags=discont
buffer: pts=0:00:00.400000000, dur=0:00:00.100000000, flags=discont
buffer: pts=0:00:00.300000000, dur=0:00:00.100000000, flags=discont
buffer: pts=0:00:00.200000000, dur=0:00:00.100000000, flags=discont
buffer: pts=0:00:00.100000000, dur=0:00:00.100000000, flags=discont
buffer: pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont
event eos: (no structure)

View file

@ -0,0 +1,33 @@
if gst_dep.type_name() == 'internal'
gst_tester = gst_proj.get_variable('gst_tester')
else
gst_tester = find_program('gst-tester-@0@'.format(api_version), required: get_option('validate'))
if not gst_tester.found()
subdir_done()
endif
endif
tests = [
'audiotestsrc/reverse',
]
env = environment()
env.set('GST_PLUGIN_PATH_1_0', meson.build_root(), pluginsdirs)
env.set('GST_PLUGIN_SYSTEM_PATH_1_0', '')
env.set('GST_REGISTRY', '@0@/@1@.registry'.format(meson.current_build_dir(), 'validate'))
env.set('GST_PLUGIN_SCANNER_1_0', gst_plugin_scanner_path)
env.set('GST_PLUGIN_LOADING_WHITELIST', 'gstreamer',
'gst-plugins-base@' + meson.build_root())
foreach t: tests
test_dir_name = t.split('/')
test_name = 'validate'
foreach c: test_dir_name
test_name += '.' + c
endforeach
test_env = env
test_env.set('GST_VALIDATE_LOGSDIR', join_paths(meson.current_build_dir(), test_name))
test_file = join_paths(meson.current_source_dir(), t + '.validatetest')
test(test_name, gst_tester, args: [test_file, '--use-fakesinks'],
env: test_env, timeout : 3 * 60, protocol: 'tap')
endforeach