History

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.

James Almer committed 1 year ago

Commit 19f7dae1 parent 0e07a703 files · +42 −5Browse files

Showing the changes to libavformat (1 of 3 files). Show all

Unified · Split

libavformat/mov.c+40−3
@@ -4690,7 +4690,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 4689 unmodified lines
46904690 unsigned int stps_index = 0;
46914691 unsigned int i, j;
46924692 uint64_t stream_size = 0;
4693+ MOVStts *stts_data_old = sc->stts_data;
46934694 MOVCtts *ctts_data_old = sc->ctts_data;
4695+ unsigned int stts_count_old = sc->stts_count;
46944696 unsigned int ctts_count_old = sc->ctts_count;
46954697
46964698 int ret = build_open_gop_key_points(st);
@@ -4795,6 +4797,30 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 98 unmodified lines
47954797 ctts_data_old[i].offset);
47964798 av_free(ctts_data_old);
47974799 }
4800+ if (stts_data_old) {
4801+ // Expand stts entries such that we have a 1-1 mapping with samples
4802+ if (sc->sample_count >= UINT_MAX / sizeof(*sc->stts_data))
4803+ return;
4804+ sc->stts_count = 0;
4805+ sc->stts_allocated_size = 0;
4806+ sc->stts_data = av_fast_realloc(NULL, &sc->stts_allocated_size,
4807+ sc->sample_count * sizeof(*sc->stts_data));
4808+ if (!sc->stts_data) {
4809+ av_free(stts_data_old);
4810+ return;
4811+ }
4812+
4813+ memset((uint8_t*)(sc->stts_data), 0, sc->stts_allocated_size);
4814+
4815+ for (i = 0; i < stts_count_old &&
4816+ sc->stts_count < sc->sample_count; i++)
4817+ for (j = 0; j < stts_data_old[i].count &&
4818+ sc->stts_count < sc->sample_count; j++)
4819+ add_stts_entry(&sc->stts_data, &sc->stts_count,
4820+ &sc->stts_allocated_size, 1,
4821+ stts_data_old[i].duration);
4822+ av_free(stts_data_old);
4823+ }
47984824
47994825 for (i = 0; i < sc->chunk_count; i++) {
48004826 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) · 459 unmodified lines
52605286 }
52615287
52625288 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5289+ int stts_constant = !!sc->stts_count;
52635290 if (sc->h_spacing && sc->v_spacing)
52645291 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
52655292 sc->h_spacing, sc->v_spacing, INT_MAX);
@@ -5272,7 +5299,12 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 6 unmodified lines
52725299 }
52735300
52745301 #if FF_API_R_FRAME_RATE
5275− if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
5302+ for (int i = 1; sc->stts_count && i < sc->stts_count - 1; i++) {
5303+ if (sc->stts_data[i].duration == sc->stts_data[0].duration)
5304+ continue;
5305+ stts_constant = 0;
5306+ }
5307+ if (stts_constant)
52765308 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
52775309 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
52785310 #endif
@@ -5303,9 +5335,14 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 24 unmodified lines
53035335
53045336 // If the duration of the mp3 packets is not constant, then they could need a parser
53055337 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5306− && sc->stts_count > 3
5307− && sc->stts_count*10 > st->nb_frames
53085338 && sc->time_scale == st->codecpar->sample_rate) {
5339+ int stts_constant = 1;
5340+ for (int i = 1; i < sc->stts_count; i++) {
5341+ if (sc->stts_data[i].duration == sc->stts_data[0].duration)
5342+ continue;
5343+ stts_constant = 0;
5344+ }
5345+ if (!stts_constant)
53095346 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
53105347 }
53115348 /* Do not need those anymore. */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t