[FFmpeg-devel] Audio decoding in api-example.c broken?

Martin Storsjö martin
Mon May 24 13:27:42 CEST 2010


On Mon, 24 May 2010, Michael Niedermayer wrote:

> On Mon, May 24, 2010 at 10:42:41AM +0300, Martin Storsj? wrote:
> > On Mon, 24 May 2010, Michael Niedermayer wrote:
> > 
> > > a AVParser could be used or you could implement some buffer that is refilled
> > > after each frame is decoded
> > 
> > An attempt at solving it by refilling the buffer is attached.
> > 
> > // Martin
> >  api-example.c |   12 ++++++------
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> > f62159abacf81c6c15a0a4f310284b9f6d2859e4  0001-Refill-the-input-audio-buffer-after-decoding-each-pa.patch
> > From 25f9c3322ebe7381623ddb546d61c67540267835 Mon Sep 17 00:00:00 2001
> > From: Martin Storsjo <martin at martin.st>
> > Date: Mon, 24 May 2010 10:23:25 +0300
> > Subject: [PATCH] Refill the input audio buffer after decoding each packet
> > 
> > This avoids trying to decode incomplete frames.
> > ---
> >  libavcodec/api-example.c |   12 ++++++------
> >  1 files changed, 6 insertions(+), 6 deletions(-)
> > 
> > diff --git a/libavcodec/api-example.c b/libavcodec/api-example.c
> > index fb48b1f..576826d 100644
> > --- a/libavcodec/api-example.c
> > +++ b/libavcodec/api-example.c
> > @@ -155,12 +155,8 @@ static void audio_decode_example(const char *outfilename, const char *filename)
> >  
> >      /* decode until eof */
> >      avpkt.data = inbuf;
> > -    for(;;) {
> >          avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
> > -        if (avpkt.size == 0)
> > -            break;
> >  
> > -        avpkt.data = inbuf;
> >          while (avpkt.size > 0) {
> >              out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
> >              len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
> > @@ -173,9 +169,13 @@ static void audio_decode_example(const char *outfilename, const char *filename)
> >                  fwrite(outbuf, 1, out_size, outfile);
> >              }
> >              avpkt.size -= len;
> > -            avpkt.data += len;
> > +            memmove(avpkt.data, avpkt.data + len, avpkt.size);
> > +            /* Refill the input buffer, to avoid trying to decode
> > +             * incomplete frames. */
> > +            len = fread(avpkt.data + avpkt.size, 1, INBUF_SIZE - avpkt.size, f);
> > +            if (len > 0)
> > +                avpkt.size += len;
> 
> as this is an example people will use for their applications
> it should mention parsers and demuxers as alternative solutions

Ok, I could add comments mentioning that.

> and the refill must be implemented so as to minimize memmove/cpy
> moving is only needed once we get close to the end of the buffer ...

How do we know that we're "close to the end of the buffer"? Something like 
if (avpkt.size < 2*len)? I guess one cannot assume that all compressed 
packets are equally long, so with a little extra padding like this, we 
should be relatively safe.

// Martin



More information about the ffmpeg-devel mailing list