New submission from Karl Blomster <thefl...@uppcon.com>:

It's not really nondeterministic, but it's pretty close. Consider the following
case: read any random packet from an mp3 stream (in any container, or
containerless; it does not seem to matter) with av_read_frame(). Now, feed this
same packet to avcodec_decode_audio3() five times in a row, flushing the codec
context buffers between each decoding run, and observe how you get a different
decoded result each time. You get data of the same _size_ each time, but it's
not quite the same data.

I'm quite possibly doing something wrong here, but none of the other decoders
I've tested behave in this way. I've attached a very dumb and simple test
program that demonstrates the issue. Run it with any test.mp3, md5 the output
files and you'll see what I mean.

----------
files: mp3decoding.c
messages: 13651
priority: normal
status: new
substatus: new
title: The mp3 decoder is highly unpredictable
topic: avcodec
type: bug

________________________________________________
FFmpeg issue tracker <iss...@roundup.ffmpeg.org>
<https://roundup.ffmpeg.org/issue2598>
________________________________________________
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/log.h>
#include <stdio.h>
#include <stdint.h>

int main (void) {
        AVCodec *codec;
        AVCodecContext *cc;
        AVFormatContext *fc;
        AVPacket p;
        int16_t *buf;
        FILE *f[5];
        const char *filenames[5] = {"1.raw", "2.raw", "3.raw", "4.raw", 
"5.raw"};
        
        av_register_all();
        av_log_set_level(AV_LOG_DEBUG);
        
        if (av_open_input_file(&fc, "test.mp3", NULL, 0, NULL))
                return 1;
        if (av_find_stream_info(fc) < 0)
                return 2;
        
        cc              = fc->streams[0]->codec;
        codec   = avcodec_find_decoder(cc->codec_id);
        if (codec == NULL || avcodec_open(cc, codec) < 0)
                return 3;
        
        int i = 0;
        while (av_read_frame(fc, &p) >= 0) {
                if (i > 500)
                        break;
                
                av_free_packet(&p);
                i++;
        }
        
        for (int j=0; j<5; j++) {
                int psz         = p.size;
                uint8_t *pd     = p.data; 
                f[j] = fopen(filenames[j], "wb");
                
                buf = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE*10);
                while (p.size > 0) {
                        int dbsize = AVCODEC_MAX_AUDIO_FRAME_SIZE*10;
                        int ret = avcodec_decode_audio3(cc, buf, &dbsize, &p);
                        if (ret < 0)
                                return 4;
                        
                        p.size -= ret;
                        p.data += ret;
                        fwrite(buf, 1, dbsize, f[j]);
                }
                p.size = psz;
                p.data = pd;
                avcodec_flush_buffers(cc);
                av_free(buf);
                fclose(f[j]);
        }
        
        return 0;
}

Reply via email to