af_loudnorm: FINAL_FRAME handling does not update loudness anymore
|Reported by:||Sebastian Dröge||Owned by:|
|Blocking:||Reproduced by developer:||no|
|Analyzed by developer:||no|
At the last frame there will be up to 3s of samples left in the buffer. These are currently copied out into a new AVFrame and then handled specially. While they were all already passed to the input EBUR128 context and the corresponding gain adjustments for them were stored in the deltas array in the previous INNER_FRAME processing, the whole last frame in the FINAL_FRAME handling is using the same index into that array.
Currently the last 30 gain adjustments stored in the deltas array are not used at all
In theory every 100ms (i.e. up to 30 times) the index into the deltas array would have to be incremented in the FINAL_FRAME handling, and like in the INNER_FRAME handling it would make sense to do linear interpolation between the current/next gain.
I've found this while porting the filter to Rust for a GStreamer plugin, the code of which can be found here: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/blob/master/audio/audiofx/src/audioloudnorm.rs . This also contains lots of code comments for all the steps, which might be helpful to take over to the ffmpeg code too.
My solution for this might not be the best or most simple approach, but during my testing they worked so feel free to adapt them for the ffmpeg code.
You can find the solution for this issue here: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/blob/1730de6cea10cb73ff1ab882a8235d540bfa5061/audio/audiofx/src/audioloudnorm.rs#L735
If you agree that the above approach (incrementing the index every 100ms and linear interpolation as for INNER_FRAME) is the right thing to do here, I can also prepare a patch for the C code in ffmpeg.