diff options
author | James Almer <jamrial@gmail.com> | 2024-11-24 23:38:50 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2024-11-25 14:40:15 -0300 |
commit | 19f7dae81ab2c19643b97da7556383ee3f721e78 (patch) | |
tree | 46fdec1e7b043c9747b143f35044f8d088200979 | |
parent | 0e07a70611dc109f4e84895ffc79827a91edc045 (diff) | |
download | ffmpeg-19f7dae81ab2c19643b97da7556383ee3f721e78.tar.gz |
avformat/mov: add missing stts array syncing in mov_build_index
Also fix checks for sc->stts_count that assume it may not be in sync with
sample count.
Missed in 865c73c86f9d9d167be7e41ad6cef71eba92dadd. Fixes parsing durations in
some cases.
Signed-off-by: James Almer <jamrial@gmail.com>
-rw-r--r-- | libavformat/mov.c | 43 | ||||
-rw-r--r-- | tests/ref/fate/enhanced-flv-hevc | 2 | ||||
-rw-r--r-- | tests/ref/fate/matroska-dovi-write-config8 | 2 |
3 files changed, 42 insertions, 5 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index ce7a2f69c4..24feadb95b 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4690,7 +4690,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st) unsigned int stps_index = 0; unsigned int i, j; uint64_t stream_size = 0; + MOVStts *stts_data_old = sc->stts_data; MOVCtts *ctts_data_old = sc->ctts_data; + unsigned int stts_count_old = sc->stts_count; unsigned int ctts_count_old = sc->ctts_count; int ret = build_open_gop_key_points(st); @@ -4795,6 +4797,30 @@ static void mov_build_index(MOVContext *mov, AVStream *st) ctts_data_old[i].offset); av_free(ctts_data_old); } + if (stts_data_old) { + // Expand stts entries such that we have a 1-1 mapping with samples + if (sc->sample_count >= UINT_MAX / sizeof(*sc->stts_data)) + return; + sc->stts_count = 0; + sc->stts_allocated_size = 0; + sc->stts_data = av_fast_realloc(NULL, &sc->stts_allocated_size, + sc->sample_count * sizeof(*sc->stts_data)); + if (!sc->stts_data) { + av_free(stts_data_old); + return; + } + + memset((uint8_t*)(sc->stts_data), 0, sc->stts_allocated_size); + + for (i = 0; i < stts_count_old && + sc->stts_count < sc->sample_count; i++) + for (j = 0; j < stts_data_old[i].count && + sc->stts_count < sc->sample_count; j++) + add_stts_entry(&sc->stts_data, &sc->stts_count, + &sc->stts_allocated_size, 1, + stts_data_old[i].duration); + av_free(stts_data_old); + } for (i = 0; i < sc->chunk_count; i++) { int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX; @@ -5260,6 +5286,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) } if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + int stts_constant = !!sc->stts_count; if (sc->h_spacing && sc->v_spacing) av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den, sc->h_spacing, sc->v_spacing, INT_MAX); @@ -5272,7 +5299,12 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) } #if FF_API_R_FRAME_RATE - if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1)) + for (int i = 1; sc->stts_count && i < sc->stts_count - 1; i++) { + if (sc->stts_data[i].duration == sc->stts_data[0].duration) + continue; + stts_constant = 0; + } + if (stts_constant) av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, sc->time_scale, sc->stts_data[0].duration, INT_MAX); #endif @@ -5303,9 +5335,14 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) // If the duration of the mp3 packets is not constant, then they could need a parser if (st->codecpar->codec_id == AV_CODEC_ID_MP3 - && sc->stts_count > 3 - && sc->stts_count*10 > st->nb_frames && sc->time_scale == st->codecpar->sample_rate) { + int stts_constant = 1; + for (int i = 1; i < sc->stts_count; i++) { + if (sc->stts_data[i].duration == sc->stts_data[0].duration) + continue; + stts_constant = 0; + } + if (!stts_constant) ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL; } /* Do not need those anymore. */ diff --git a/tests/ref/fate/enhanced-flv-hevc b/tests/ref/fate/enhanced-flv-hevc index f04905d06b..9e0af51b2a 100644 --- a/tests/ref/fate/enhanced-flv-hevc +++ b/tests/ref/fate/enhanced-flv-hevc @@ -1,4 +1,4 @@ -565cf155790db391137f81f619448477 *tests/data/fate/enhanced-flv-hevc.flv +81199f98b1210eada2e7ff7ba11afd8c *tests/data/fate/enhanced-flv-hevc.flv 3603038 tests/data/fate/enhanced-flv-hevc.flv #extradata 0: 551, 0xb1ddcd66 #extradata 1: 2, 0x00340022 diff --git a/tests/ref/fate/matroska-dovi-write-config8 b/tests/ref/fate/matroska-dovi-write-config8 index d5704c7684..ca21892686 100644 --- a/tests/ref/fate/matroska-dovi-write-config8 +++ b/tests/ref/fate/matroska-dovi-write-config8 @@ -1,4 +1,4 @@ -593bb650a937b25b87de3079ee7d1517 *tests/data/fate/matroska-dovi-write-config8.matroska +2f28699111ea95a7d2937a23e92dfd77 *tests/data/fate/matroska-dovi-write-config8.matroska 3600617 tests/data/fate/matroska-dovi-write-config8.matroska #extradata 0: 551, 0xb1ddcd66 #extradata 1: 2, 0x00340022 |