Ticket #2144 (closed defect: fixed)
libavfilter ebur128 loudness inaccuracy, irregular time interval, LFE interference
|Reported by:||sedacca||Owned by:|
|Blocking:||Reproduced by developer:||no|
|Analyzed by developer:||no|
Summary of the bug:
(1) The time interval between logged data rows is often greater than the expected 100 milliseconds.
(2) For some channel layouts the wrong weighting factors are applied to channels, leading to incorrect reported loudness.
(3) Loudness computation is disturbed by the presence of the LFE channel, which is not supposed to affect reported loudness.
How to reproduce the problem:
% ffmpeg -nostats -i seq-3341-6-6channels-WAVEEX-16bit.wav -filter_complex ebur128 -f null dummyout.txt 2>f_ebur128_c_2013-01-15_bug.txt
The input WAV file is from http://tech.ebu.ch/docs/testmaterial/ebu-loudness-test-setv03.zip.
The results in ebur_results_before_bugfix_6ch.txt show irregular time increments, for instance from t: 9.98898 to t: 10.0955 (a difference of 106.5 msec instead of the expected 100 msec). They also show an integrated loudness level of -22.6 LUFS instead of the expected -23.0 LUFS.
% ffmpeg -v 9 -loglevel 99 -i seq-3341-6-6channels-WAVEEX-16bit.wav ffmpeg version N-48928-g918b411 Copyright (c) 2000-2013 the FFmpeg developers built on Jan 15 2013 15:34:46 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5) configuration: --enable-gpl libavutil 52. 15.100 / 52. 15.100 libavcodec 54. 89.100 / 54. 89.100 libavformat 54. 60.100 / 54. 60.100 libavdevice 54. 3.102 / 54. 3.102 libavfilter 3. 32.100 / 3. 32.100 libswscale 2. 1.103 / 2. 1.103 libswresample 0. 17.102 / 0. 17.102 libpostproc 52. 2.100 / 52. 2.100 Splitting the commandline. Reading option '-v' ... matched as option 'v' (set libav* logging level) with argument '9'. Reading option '-loglevel' ... matched as option 'loglevel' (set libav* logging level) with argument '99'. Reading option '-i' ... matched as input file with argument 'seq-3341-6-6channels-WAVEEX-16bit.wav'. Finished splitting the commandline. Parsing a group of options: global . Applying option v (set libav* logging level) with argument 9. Successfully parsed a group of options. Parsing a group of options: input file seq-3341-6-6channels-WAVEEX-16bit.wav. Successfully parsed a group of options. Opening an input file: seq-3341-6-6channels-WAVEEX-16bit.wav. [wav @ 0x2eef4c0] Format wav probed with size=2048 and score=99 [wav @ 0x2eef4c0] File position before avformat_find_stream_info() is 80 [wav @ 0x2eef4c0] parser not found for codec pcm_s16le, packets or times may be invalid. [wav @ 0x2eef4c0] probing stream 0 pp:4 [wav @ 0x2eef4c0] probing stream 0 pp:3 [wav @ 0x2eef4c0] probing stream 0 pp:2 [wav @ 0x2eef4c0] probing stream 0 pp:1 [wav @ 0x2eef4c0] probed stream 0 [wav @ 0x2eef4c0] parser not found for codec pcm_s16le, packets or times may be invalid. [wav @ 0x2eef4c0] max_analyze_duration 5000000 reached at 5001333 microseconds [wav @ 0x2eef4c0] File position after avformat_find_stream_info() is 2893124 Input #0, wav, from 'seq-3341-6-6channels-WAVEEX-16bit.wav': Duration: 00:00:20.00, bitrate: 4608 kb/s Stream #0:0, 706, 1/48000: Audio: pcm_s16le ( / 0x0001), 48000 Hz, 5.1, s16, 4608 kb/s Successfully openened the file. At least one output file must be specified Statistics: 2916352 bytes read, 0 seeks
Causes in file f_ebur128.c:
(1) For unexpected time intervals: In the function filter_samples(), the for loop encompassing lines 449 to 638 has control variable i that is incorrectly reused and altered by inner for loops at lines 537, 558, 566, and 577.
(2) For unexpected channel weightings: the examination of the bitmap for channel layout does not properly scan for bits that are set and skip over bits that are cleared.
(3) For wrong loudness indication when LFE is present: the increment operation to *samples is wrongly skipped when the channel index ch has the value for the LFE channel. This causes the LFE samples to inadvertently contribute to the loudness computation when the channel index next has the value for a non-LFE channel, and distorts the time and weighting of samples.
Suggested fixes to file f_ebur128.c (a suggested patch will be posted to the developer list):
(1) Add a new control variable idx_insample for the outermost for loop in the function filter_samples();
(2) Add new logic to scan the channel_layout bitmap for the next nonzero entry, and update the macro BACK_MASK to include all non-front and all non-LFE channels.
(3) Move the existing increment operation of *samples to precede the continue operation that skips unneeded expensive computations for the LFE channel.