[FFmpeg-devel] [PATCH] avformat/matroskaenc: always reserve max aac private data

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Fri May 1 20:35:15 EEST 2020


James Almer:
> On 5/1/2020 2:09 PM, John Stebbins wrote:
>> When extra data is updated using AV_PKT_DATA_NEW_EXTRADATA, the data is
>> written plus extra space is reserved for the max possible size extradata.
>> But when extradata is written during mkv_write_header, no extra space is
>> reserved. So the side data update overwrites whatever follows the
>> extradata in the track header and results in an invalid file.
> 
> In what scenario there's extradata during init() and then new extradata
> propagated in a packet side data for AAC? And should the side data one
> take priority over the original one?
> 
> With FLAC we know it must have priority because the encoder sends it at
> the end of the encoding process with information that was not available
> during init(), but afaik that's not the case with AAC.
> 
>> ---
>>  libavformat/matroskaenc.c | 14 ++++++++------
>>  1 file changed, 8 insertions(+), 6 deletions(-)
>>
>> diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
>> index 784973a951..e6917002c4 100644
>> --- a/libavformat/matroskaenc.c
>> +++ b/libavformat/matroskaenc.c
>> @@ -728,8 +728,6 @@ static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb,
>>      case AV_CODEC_ID_AAC:
>>          if (par->extradata_size)
>>              avio_write(dyn_cp, par->extradata, par->extradata_size);
>> -        else
>> -            put_ebml_void(pb, MAX_PCE_SIZE + 2 + 4);
>>          break;
>>      default:
>>          if (par->codec_id == AV_CODEC_ID_PRORES &&
>> @@ -749,6 +747,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
>>      AVIOContext *dyn_cp;
>>      uint8_t *codecpriv;
>>      int ret, codecpriv_size;
>> +    int64_t offset;
>>  
>>      ret = avio_open_dyn_buf(&dyn_cp);
>>      if (ret < 0)
>> @@ -802,9 +801,15 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
>>      }
>>  
>>      codecpriv_size = avio_get_dyn_buf(dyn_cp, &codecpriv);
>> +    offset = avio_tell(pb);
>>      if (codecpriv_size)
>>          put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codecpriv,
>>                          codecpriv_size);
>> +    if (par->codec_id == AV_CODEC_ID_AAC) {
>> +        int filler = MAX_PCE_SIZE + 2 + 4 - (avio_tell(pb) - offset);
>> +        if (filler)
>> +            put_ebml_void(pb, filler);
>> +    }
> 
> Why are you adding this here instead of adapting the code in
> mkv_write_native_codecprivate()?
> 
> Can't you just do something like
> 
> case AV_CODEC_ID_AAC:
>     if (par->extradata_size)
>         avio_write(dyn_cp, par->extradata, par->extradata_size);
>     put_ebml_void(pb, MAX_PCE_SIZE + 2 + 4 - avio_tell(dyn_cp));
>     break;
> 
Then mkv_write_codecprivate() would overwrite the beginning of the void
element when it writes the CodecPrivate, creating an invalid file.
Instead one could do something like

if (par->extradata_size)
    put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, par->extradata,
par->extradata_size);
put_ebml_void(pb, MAX_PCE_SIZE + 2 + 4 - what was just written (not only
par->extradata);

- Andreas


More information about the ffmpeg-devel mailing list