diff mbox series

[FFmpeg-devel] avcodec/dolby_e: Add error recovery when parse_mantissas run out of bits

Message ID 20220913213127.1756-1-nicolas.gaullier@cji.paris
State New
Headers show
Series [FFmpeg-devel] avcodec/dolby_e: Add error recovery when parse_mantissas run out of bits | expand

Checks

Context Check Description
andriy/commit_msg_x86 warning Please wrap lines in the body of the commit message between 60 and 72 characters.
yinshiyou/commit_msg_loongarch64 warning Please wrap lines in the body of the commit message between 60 and 72 characters.
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Nicolas Gaullier Sept. 13, 2022, 9:31 p.m. UTC
Mantissas are the last data in the channel subsegment and it appears it is
sometimes missing a very few bits for the parsing to complete.
This should not be confused with data corruption.
For 5.1+2@25fps, the occurence of this issue is pretty steady and about once every 2 hours.
The truncation is at about 950 out of the 1024 values (never seen below 923 so far).
The current code raises a severe 'Read past end' error and all data is lost resulting in
20ms(@25fps) of silence for the affected channel.
This patch introduces a tolerance: if 800 out of the 1024 mantissas have been parsed,
a simple warning is raised and the data is preserved.

Signed-off-by: Nicolas Gaullier <nicolas.gaullier@cji.paris>
---
 libavcodec/dolby_e.c | 8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Nicolas Gaullier Sept. 16, 2022, 8:28 a.m. UTC | #1
>Envoyé : mardi 13 septembre 2022 23:31
>Mantissas are the last data in the channel subsegment and it appears it is sometimes missing a very few bits for the parsing to complete.
>This should not be confused with data corruption.

Here is a very short sample set with an audacity screen grab which shows the effect of the fix:
http://0x0.st/oOvv.zip

I don't know how to make this patch acceptable... and especially I understand that setting an arbitrary limit with a #define does not look to be the best practice in the world.
The fact is that the reference implementation (checked against dp600 and a certified broadcast encoder) does handle that (maybe with no limit at all, hard to tell).
Do you have any suggestion ?
If it can help, I can post a message to ffmpeg-user to gain more users support ?

Nicolas
Nicolas Gaullier Oct. 14, 2022, 8:03 a.m. UTC | #2
>Envoyé : mardi 13 septembre 2022 23:31

>Mantissas are the last data in the channel subsegment and it appears it is sometimes missing a very few bits for the parsing to complete.
>This should not be confused with data corruption.
>For 5.1+2@25fps, the occurence of this issue is pretty steady and about once every 2 hours.
>The truncation is at about 950 out of the 1024 values (never seen below 923 so far).
>The current code raises a severe 'Read past end' error and all data is lost resulting in
>20ms(@25fps) of silence for the affected channel.
>This patch introduces a tolerance: if 800 out of the 1024 mantissas have been parsed, a simple warning is raised and the data is preserved.

I did not received any feedback yet (except trivial wrap-lines warning from patchwork).
I tried to contact foobaz86@gmail.com > 2 weeks ago, but with no answer, I fear there is nobody behind the screen.
And no activity in https://github.com/foo86 for 5 years.

Maybe MAINTAINERS should be updated ?

There are a lot of things to come as DolbyED2 support (rawly already decodable with current code) and broader avformats support,
so this is not only about this single interoperability point issue.

Thank you for your support
Nicolas
diff mbox series

Patch

diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c
index 06f4fdd44f..0ec7b5e318 100644
--- a/libavcodec/dolby_e.c
+++ b/libavcodec/dolby_e.c
@@ -844,6 +844,7 @@  static int parse_indices(DBEContext *s, DBEChannel *c)
     return 0;
 }
 
+#define MIN_MANTISSAS 800
 static int parse_mantissas(DBEContext *s, DBEChannel *c)
 {
     DBEGroup *g;
@@ -884,6 +885,13 @@  static int parse_mantissas(DBEContext *s, DBEChannel *c)
                     }
                 }
             } else {
+                if (i == c->nb_groups - 1
+                    && count * size1 > get_bits_left(&s->gb)
+                    && get_bits_left(&s->gb) >= 0
+                    && (int)(mnt - c->mantissas) >= MIN_MANTISSAS) {
+                    av_log(s->avctx, AV_LOG_WARNING, "Truncated mantissas @%d, highest frequencies not recoverable\n", (int)(mnt - c->mantissas));
+                    break;
+                }
                 for (k = 0; k < count; k++)
                     mnt[k] = get_sbits(&s->gb, size1) * scale;
             }