[FFmpeg-devel] [PATCH 1/9] avformat/smacker: Don't increase packet counter prematurely

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Fri Jul 3 03:14:27 EEST 2020


Andreas Rheinhardt:
> The Smacker demuxer buffers audio packets before it outputs them, but it
> increments the counter of buffered packets prematurely: If allocating
> the audio buffer fails, an error (most likely AVERROR(ENOMEM)) is returned.
> If the caller decides to call av_read_frame() again, the next call will
> take the codepath for returning already buffered audio packets and it
> will fail (because the buffer that ought to be allocated isn't) without
> decrementing the number of supposedly buffered audio packets (it doesn't
> matter whether there would be enough memory available in subsequent calls).
> Depending on the caller's behaviour this is potentially an infinite loop.
> 
> This commit fixes this by only incrementing the number of buffered audio
> packets after having successfully read them and unconditionally reducing
> said number when outputting one of them. It also changes the semantics
> of the curstream variable: It is now the number of currently buffered
> audio packets whereas it used to be the index of the last audio stream
> to be read. (Index refers to the index in the array of buffers, not to
> the stream index.)
> 
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
> ---
>  libavformat/smacker.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/libavformat/smacker.c b/libavformat/smacker.c
> index 8b1e185817..14dc4ef406 100644
> --- a/libavformat/smacker.c
> +++ b/libavformat/smacker.c
> @@ -229,7 +229,6 @@ static int smacker_read_header(AVFormatContext *s)
>          return AVERROR(EIO);
>      }
>  
> -    smk->curstream = -1;
>      smk->nextpos = avio_tell(pb);
>  
>      return 0;
> @@ -249,7 +248,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
>          return AVERROR_EOF;
>  
>      /* if we demuxed all streams, pass another frame */
> -    if(smk->curstream < 0) {
> +    if (smk->curstream <= 0) {
>          avio_seek(s->pb, smk->nextpos, 0);
>          frame_size = smk->frm_size[smk->cur_frame] & (~3);
>          flags = smk->frm_flags[smk->cur_frame];
> @@ -301,7 +300,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
>              palchange |= 1;
>          }
>          flags >>= 1;
> -        smk->curstream = -1;
> +        smk->curstream = 0;
>          /* if audio chunks are present, put them to stack and retrieve later */
>          for(i = 0; i < 7; i++) {
>              if(flags & 1) {
> @@ -315,7 +314,6 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
>                  }
>                  frame_size -= size;
>                  frame_size -= 4;
> -                smk->curstream++;
>                  if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) {
>                      smk->buf_sizes[smk->curstream] = 0;
>                      return err;
> @@ -325,6 +323,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
>                  if(ret != size)
>                      return AVERROR(EIO);
>                  smk->stream_id[smk->curstream] = smk->indexes[i];
> +                smk->curstream++;
>              }
>              flags >>= 1;
>          }
> @@ -345,6 +344,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
>          smk->cur_frame++;
>          smk->nextpos = avio_tell(s->pb);
>      } else {
> +        smk->curstream--;
>          if (smk->stream_id[smk->curstream] < 0 || !smk->bufs[smk->curstream])
>              return AVERROR_INVALIDDATA;
>          if ((ret = av_new_packet(pkt, smk->buf_sizes[smk->curstream])) < 0)
> @@ -354,7 +354,6 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
>          pkt->stream_index = smk->stream_id[smk->curstream];
>          pkt->pts = smk->aud_pts[smk->curstream];
>          smk->aud_pts[smk->curstream] += AV_RL32(pkt->data);
> -        smk->curstream--;
>      }
>  
>      return 0;
> 
Will apply the patchset tomorrow unless there are objections.

- Andreas


More information about the ffmpeg-devel mailing list