[FFmpeg-devel] [PATCH 2/2] avformat/mov: simplify allocating stts/ctts arrays
James Almer
jamrial at gmail.com
Tue Jan 14 00:44:03 EET 2025
On 1/13/2025 7:35 PM, Andreas Rheinhardt wrote:
> James Almer:
>> No point using av_fast_realloc() in a loop when we want to allocate all
>> entries to begin with, and any duplicate stts/ctts will just replace the
>> old arrays.
>> Furthermore, these are temporary arrays that will be merged into tts_data
>> when building the index.
>>
>> Signed-off-by: James Almer <jamrial at gmail.com>
>> ---
>> libavformat/isom.h | 2 --
>> libavformat/mov.c | 40 ++++++----------------------------------
>> 2 files changed, 6 insertions(+), 36 deletions(-)
>>
>> diff --git a/libavformat/isom.h b/libavformat/isom.h
>> index ccdead7192..16981dc918 100644
>> --- a/libavformat/isom.h
>> +++ b/libavformat/isom.h
>> @@ -183,12 +183,10 @@ typedef struct MOVStreamContext {
>> unsigned int tts_allocated_size;
>> MOVTimeToSample *tts_data;
>> unsigned int stts_count;
>> - unsigned int stts_allocated_size;
>> MOVStts *stts_data;
>> unsigned int sdtp_count;
>> uint8_t *sdtp_data;
>> unsigned int ctts_count;
>> - unsigned int ctts_allocated_size;
>> MOVCtts *ctts_data;
>> unsigned int stsc_count;
>> MOVStsc *stsc_data;
>> diff --git a/libavformat/mov.c b/libavformat/mov.c
>> index 138120488a..f310cb8d49 100644
>> --- a/libavformat/mov.c
>> +++ b/libavformat/mov.c
>> @@ -3498,22 +3498,14 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>> av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
>> av_freep(&sc->stts_data);
>> sc->stts_count = 0;
>> - if (entries >= INT_MAX / sizeof(*sc->stts_data))
>> +
>> + sc->stts_data = av_malloc_array(entries, sizeof(*sc->stts_data));
>> + if (!sc->stts_data)
>> return AVERROR(ENOMEM);
>>
>> for (i = 0; i < entries && !pb->eof_reached; i++) {
>> unsigned int sample_duration;
>> unsigned int sample_count;
>> - unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
>> - MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
>> - min_entries * sizeof(*sc->stts_data));
>> - if (!stts_data) {
>> - av_freep(&sc->stts_data);
>> - sc->stts_count = 0;
>> - return AVERROR(ENOMEM);
>> - }
>> - sc->stts_count = min_entries;
>> - sc->stts_data = stts_data;
>>
>> sample_count = avio_rb32(pb);
>> sample_duration = avio_rb32(pb);
>> @@ -3656,20 +3648,12 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>>
>> if (!entries)
>> return 0;
>> - if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
>> - return AVERROR_INVALIDDATA;
>> av_freep(&sc->ctts_data);
>> - sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
>> + sc->ctts_data = av_malloc_array(entries, sizeof(*sc->ctts_data));
>> if (!sc->ctts_data)
>> return AVERROR(ENOMEM);
>>
>> for (i = 0; i < entries && !pb->eof_reached; i++) {
>> - MOVCtts *ctts_data;
>> - const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
>> - const size_t requested_size =
>> - min_size_needed > sc->ctts_allocated_size ?
>> - FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
>> - min_size_needed;
>> int count = avio_rb32(pb);
>> int duration = avio_rb32(pb);
>>
>> @@ -3680,18 +3664,8 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>> continue;
>> }
>>
>> - if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
>> - return AVERROR(ENOMEM);
>> -
>> - ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
>> -
>> - if (!ctts_data)
>> - return AVERROR(ENOMEM);
>> -
>> - sc->ctts_data = ctts_data;
>> -
>> - ctts_data[ctts_count].count = count;
>> - ctts_data[ctts_count].offset = duration;
>> + sc->ctts_data[ctts_count].count = count;
>> + sc->ctts_data[ctts_count].offset = duration;
>> ctts_count++;
>>
>> av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
>> @@ -4585,7 +4559,6 @@ static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
>> } else
>> sc->ctts_count = 0;
>> av_freep(&sc->ctts_data);
>> - sc->ctts_allocated_size = 0;
>>
>> idx = 0;
>> if (stts) {
>> @@ -4610,7 +4583,6 @@ static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
>> } else
>> sc->stts_count = 0;
>> av_freep(&sc->stts_data);
>> - sc->stts_allocated_size = 0;
>>
>> return 0;
>> }
>
> I always thought that this pattern is used because it avoids having to
> allocate a potentially huge buffer just because a counter says that many
> elements are present even when the actual file doesn't contain that many
> entries because it is very small (this might cause timeout issues in the
> fuzzer).
That only applied to stts, because ctts had a realloc call for all
entries before the loop.
If you think this approach is better, then i can remove that call.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20250113/2397b3fd/attachment.sig>
More information about the ffmpeg-devel
mailing list