From b46718b1a041250a24dec339473e5da51a569bc8 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 22 May 2020 23:24:55 -0400 Subject: [PATCH] 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: --- gst/audiotestsrc/gstaudiotestsrc.c | 4 +- meson_options.txt | 2 + tests/check/meson.build | 9 ---- tests/meson.build | 13 ++++++ .../audiotestsrc/reverse.validatetest | 24 ++++++++++ .../flow-expectations/log-asink-sink-expected | 45 +++++++++++++++++++ tests/validate/meson.build | 33 ++++++++++++++ 7 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 tests/validate/audiotestsrc/reverse.validatetest create mode 100644 tests/validate/audiotestsrc/reverse/flow-expectations/log-asink-sink-expected create mode 100644 tests/validate/meson.build diff --git a/gst/audiotestsrc/gstaudiotestsrc.c b/gst/audiotestsrc/gstaudiotestsrc.c index b06b336ccc..00645eb209 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.c +++ b/gst/audiotestsrc/gstaudiotestsrc.c @@ -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 { diff --git a/meson_options.txt b/meson_options.txt index bb3cb3c4ed..a1bee94d68 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -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.') diff --git a/tests/check/meson.build b/tests/check/meson.build index f06bc08835..81e8b45275 100644 --- a/tests/check/meson.build +++ b/tests/check/meson.build @@ -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() diff --git a/tests/meson.build b/tests/meson.build index c53d53806e..b15dd529bf 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -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 diff --git a/tests/validate/audiotestsrc/reverse.validatetest b/tests/validate/audiotestsrc/reverse.validatetest new file mode 100644 index 0000000000..3c7438a208 --- /dev/null +++ b/tests/validate/audiotestsrc/reverse.validatetest @@ -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; \ No newline at end of file diff --git a/tests/validate/audiotestsrc/reverse/flow-expectations/log-asink-sink-expected b/tests/validate/audiotestsrc/reverse/flow-expectations/log-asink-sink-expected new file mode 100644 index 0000000000..5f0ca2ac0a --- /dev/null +++ b/tests/validate/audiotestsrc/reverse/flow-expectations/log-asink-sink-expected @@ -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) diff --git a/tests/validate/meson.build b/tests/validate/meson.build new file mode 100644 index 0000000000..9d7d065e47 --- /dev/null +++ b/tests/validate/meson.build @@ -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 \ No newline at end of file