[FFmpeg-devel] [PATCH 1/5] avformat/smacker: Read extradata directly into extradata

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Tue Apr 7 16:37:13 EEST 2020


Andreas Rheinhardt:
> The Smacker demuxer reads four consecutive 32bit values from the file
> header into its demux context (as four uint32_t), converting it to
> native endianness in the process and then writing these four values
> later (after extradata has been allocated) to extradata as four 32bit
> values (converting to little endian in the process).
> 
> This commit changes this: The stream and the extradata are allocated
> earlier, so that the data destined for extradata can be read directly
> into extradata.
> 
> Furthermore, given that these values are not needed for demuxing itself
> they are now no longer kept as part of the demuxing context.
> 
> Finally, a check regarding the number of frames has been moved up,
> too, in order to exit early before unnecessarily allocating the
> stream and the extradata.
> 
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
> ---
>  libavformat/smacker.c | 47 +++++++++++++++++--------------------------
>  1 file changed, 18 insertions(+), 29 deletions(-)
> 
> diff --git a/libavformat/smacker.c b/libavformat/smacker.c
> index 6de0e7a0f1..4db3ec326f 100644
> --- a/libavformat/smacker.c
> +++ b/libavformat/smacker.c
> @@ -25,10 +25,10 @@
>  
>  #include <inttypes.h>
>  
> -#include "libavutil/bswap.h"
>  #include "libavutil/channel_layout.h"
>  #include "libavutil/intreadwrite.h"
>  #include "avformat.h"
> +#include "avio_internal.h"
>  #include "internal.h"
>  
>  #define SMACKER_PAL 0x01
> @@ -51,7 +51,6 @@ typedef struct SmackerContext {
>      uint32_t flags;
>      uint32_t audio[7];
>      uint32_t treesize;
> -    uint32_t mmap_size, mclr_size, full_size, type_size;
>      uint8_t  aflags[7];
>      uint32_t rates[7];
>      uint32_t pad;
> @@ -128,6 +127,10 @@ static int smacker_read_header(AVFormatContext *s)
>      smk->flags = avio_rl32(pb);
>      if(smk->flags & SMACKER_FLAG_RING_FRAME)
>          smk->frames++;
> +    if (smk->frames > 0xFFFFFF) {
> +        av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n", smk->frames);
> +        return AVERROR_INVALIDDATA;
> +    }
>      for(i = 0; i < 7; i++)
>          smk->audio[i] = avio_rl32(pb);
>      smk->treesize = avio_rl32(pb);
> @@ -137,21 +140,25 @@ static int smacker_read_header(AVFormatContext *s)
>          return AVERROR_INVALIDDATA;
>      }
>  
> -//FIXME remove extradata "rebuilding"
> -    smk->mmap_size = avio_rl32(pb);
> -    smk->mclr_size = avio_rl32(pb);
> -    smk->full_size = avio_rl32(pb);
> -    smk->type_size = avio_rl32(pb);
> +    st = avformat_new_stream(s, NULL);
> +    if (!st)
> +        return AVERROR(ENOMEM);
> +
> +    if ((ret = ff_alloc_extradata(st->codecpar, smk->treesize + 16)) < 0) {
> +        av_log(s, AV_LOG_ERROR,
> +               "Cannot allocate %"PRIu32" bytes of extradata\n",
> +               smk->treesize + 16);
> +        return ret;
> +    }
> +    if ((ret = ffio_read_size(pb, st->codecpar->extradata, 16)) < 0)
> +        return ret;
> +
>      for(i = 0; i < 7; i++) {
>          smk->rates[i]  = avio_rl24(pb);
>          smk->aflags[i] = avio_r8(pb);
>      }
>      smk->pad = avio_rl32(pb);
>      /* setup data */
> -    if(smk->frames > 0xFFFFFF) {
> -        av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n", smk->frames);
> -        return AVERROR_INVALIDDATA;
> -    }
>      smk->frm_size = av_malloc_array(smk->frames, sizeof(*smk->frm_size));
>      smk->frm_flags = av_malloc(smk->frames);
>      if (!smk->frm_size || !smk->frm_flags) {
> @@ -171,12 +178,6 @@ static int smacker_read_header(AVFormatContext *s)
>      }
>  
>      /* init video codec */
> -    st = avformat_new_stream(s, NULL);
> -    if (!st) {
> -        av_freep(&smk->frm_size);
> -        av_freep(&smk->frm_flags);
> -        return AVERROR(ENOMEM);
> -    }
>      smk->videoindex = st->index;
>      st->codecpar->width = smk->width;
>      st->codecpar->height = smk->height;
> @@ -233,24 +234,12 @@ static int smacker_read_header(AVFormatContext *s)
>  
>  
>      /* load trees to extradata, they will be unpacked by decoder */
> -    if ((ret = ff_alloc_extradata(st->codecpar, smk->treesize + 16)) < 0) {
> -        av_log(s, AV_LOG_ERROR,
> -               "Cannot allocate %"PRIu32" bytes of extradata\n",
> -               smk->treesize + 16);
> -        av_freep(&smk->frm_size);
> -        av_freep(&smk->frm_flags);
> -        return ret;
> -    }
>      ret = avio_read(pb, st->codecpar->extradata + 16, st->codecpar->extradata_size - 16);
>      if(ret != st->codecpar->extradata_size - 16){
>          av_freep(&smk->frm_size);
>          av_freep(&smk->frm_flags);
>          return AVERROR(EIO);
>      }
> -    ((int32_t*)st->codecpar->extradata)[0] = av_le2ne32(smk->mmap_size);
> -    ((int32_t*)st->codecpar->extradata)[1] = av_le2ne32(smk->mclr_size);
> -    ((int32_t*)st->codecpar->extradata)[2] = av_le2ne32(smk->full_size);
> -    ((int32_t*)st->codecpar->extradata)[3] = av_le2ne32(smk->type_size);
>  
>      smk->curstream = -1;
>      smk->nextpos = avio_tell(pb);
> 
Any comments on this patchset? If not, I'll apply it tomorrow.

- Andreas


More information about the ffmpeg-devel mailing list