Panic when calling loudness_range
overdrivenpotato opened this issue · 10 comments
Hello, thanks for making this library :-)
There seems to be a bug when calling loudness_range
that occasionally triggers a panic. I've attached a stack trace with the relevant calls below. I've tried unsuccessfully to build a repro case but in my application the error is somewhat rare. Even with the same input data every time, it will fail spuriously about 1% of the time. For some context, I'm testing with a ~40 second 96kHz stereo clip buffered in as f32
samples.
panicked at 'called `Option::unwrap()` on a `None` value', /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/history.rs:433:67
stack backtrace:
0: 0x1001d1d44 - std::backtrace_rs::backtrace::libunwind::trace::h3440e89bdeed3ddf
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
1: 0x1001d1d44 - std::backtrace_rs::backtrace::trace_unsynchronized::hfa68bcc7baf06ad7
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x1001d1d44 - std::sys_common::backtrace::_print_fmt::h483e161a2ffbfba4
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:67:5
3: 0x1001d1d44 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h34f76b2ca42fab41
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:46:22
4: 0x1001ef37d - core::fmt::write::h8f13d857463c51c1
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/fmt/mod.rs:1078:17
5: 0x1001ce326 - std::io::Write::write_fmt::h013bead77842bdd6
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/io/mod.rs:1517:15
6: 0x1001d3db9 - std::sys_common::backtrace::_print::h7f3525175df798e8
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:49:5
7: 0x1001d3db9 - std::sys_common::backtrace::print::hf68eec1a3c535c32
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:36:9
8: 0x1001d3db9 - std::panicking::default_hook::{{closure}}::hb14d90e928578cc7
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:208:50
9: 0x1001d3976 - std::panicking::default_hook::h460969f1dc8f738d
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:222:9
10: 0x1001d443b - std::panicking::rust_panic_with_hook::h28bf9d6c3916221e
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:591:17
11: 0x1001d3f39 - std::panicking::begin_panic_handler::{{closure}}::h99569328be4adae9
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:495:13
12: 0x1001d21e8 - std::sys_common::backtrace::__rust_end_short_backtrace::h9a7e5cc6475b496b
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:141:18
13: 0x1001d3eca - rust_begin_unwind
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:493:5
14: 0x1001fb3af - core::panicking::panic_fmt::h65997884a2662b8c
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/panicking.rs:92:14
15: 0x1001fb307 - core::panicking::panic::h2ca2e9d2b0a1f2bf
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/panicking.rs:50:5
16: 0x100189cad - core::option::Option<T>::unwrap::hdeee087517023990
at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:386:21
17: 0x100189cad - ebur128::history::History::loudness_range_multiple::{{closure}}::h1a0ff08728c0cb3b
at /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/history.rs:433:50
18: 0x100189cad - core::slice::<impl [T]>::sort_unstable_by::{{closure}}::hc07c59363457d04f
at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/mod.rs:2066:38
19: 0x100189cad - core::slice::sort::shift_tail::h7ec07b4e8c340c30
at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/sort.rs:100:24
20: 0x100189dae - core::slice::sort::insertion_sort::h74c03aa25773ab0d
at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/sort.rs:177:9
21: 0x100189dae - core::slice::sort::recurse::h16dae32c7768ff6f
at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/sort.rs:687:13
22: 0x10018b5f4 - core::slice::sort::quicksort::h89c7abc843bf1a67
at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/sort.rs:768:5
23: 0x10018b5f4 - core::slice::<impl [T]>::sort_unstable_by::hd97a30f3bafd244c
at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/mod.rs:2066:9
24: 0x10018b5f4 - ebur128::history::History::loudness_range_multiple::hc7e4bb112053e86c
at /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/history.rs:433:17
25: 0x10018698d - ebur128::history::History::loudness_range::h10766b0a6c5a0aa1
at /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/history.rs:377:9
26: 0x10018698d - ebur128::ebur128::EbuR128::loudness_range::h4efb27ac08702281
at /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/ebur128.rs:831:12
...[snip]...
Thanks for reporting this. The problem is in
combined.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
Apparently the history contains NaNs sometimes? Can you provide a testcase for this, even if it only triggers rarely?
@overdrivenpotato Any updates here?
I've shifted off that particular project but for some added context:
This was triggered by feeding a simple non-NaN 96kHz FLAC input into FFMPEG, which was then decoded, resampled to 96kHz (same rate, no-op?), and then fed into ebur128. I would imagine the data coming out of the FFMPEG FLAC decoder/resampler is constant as the FLAC input was always identical, and the sample rate was always the same between I/O. The spurious nature of the panic is puzzling.
Indeed. If you can somehow produce a testcase for this, even if it only triggers the problem sometimes, that would be really great. I don't see how any of these values can end up as NaN so without a testcase there's not much I can do.
Would that be possible for you? Otherwise I guess we can close this issue until someone can reproduce it :)
Hello, think i've run into same or a simliar problem and can reproduce it with:
#[test]
fn loudness_range_panic() {
// at least this many samples are needed to trigger panic
let mut data = vec![0.0f32; 44_100*80];
for out in data.chunks_exact_mut(2) {
out[0] = f32::INFINITY;
out[1] = f32::NEG_INFINITY;
}
let mut ebu = EbuR128::new(2, 44_100, Mode::I | Mode::TRUE_PEAK | Mode::LRA,).unwrap();
ebu.add_frames_f32(&data).unwrap();
assert_float_eq!(
ebu.loudness_range().unwrap(),
0.0,
abs <= 0.000001
);
}
Panic:
---- ebur128::tests::loudness_range_panic stdout ----
thread 'ebur128::tests::loudness_range_panic' panicked at src/history.rs:413:67:
called `Option::unwrap()` on a `None` value
stack backtrace:
0: rust_begin_unwind
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:645:5
1: core::panicking::panic_fmt
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panicking.rs:72:14
2: core::panicking::panic
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panicking.rs:144:5
3: core::slice::sort::recurse
4: core::slice::sort::quicksort
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/slice/sort.rs:904:5
5: core::slice::<impl [T]>::sort_unstable_by
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/slice/mod.rs:3008:9
6: ebur128::history::History::loudness_range_multiple
at ./src/history.rs:413:17
7: ebur128::history::History::loudness_range
at ./src/history.rs:357:9
8: ebur128::ebur128::EbuR128::loudness_range
at ./src/ebur128.rs:864:12
9: ebur128::ebur128::tests::loudness_range_panic
at ./src/ebur128.rs:1517:13
10: ebur128::ebur128::tests::loudness_range_panic::{{closure}}
at ./src/ebur128.rs:1506:30
11: core::ops::function::FnOnce::call_once
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/ops/function.rs:250:5
12: core::ops::function::FnOnce::call_once
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
The file that triggers this for me is a wav file with fmt audio format 3 (32 bit little endian float PCM) filled with only left / right samples that are the bytes 00 00 80 7f
/ 00 00 80 ff
which seems to be Inf / -Inf.
Thanks for the testcase, I'll look into this :)
🥳
This is fixed in 0.1.9. Sorry for the delay!
No worries at all and btw thanks for a creating and maintaining this create!