forked from FFmpeg/FFmpeg
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 865c73c86f
. Fixes parsing durations in
some cases.
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
parent
0e07a70611
commit
19f7dae81a
3 changed files with 42 additions and 5 deletions
|
@ -4690,7 +4690,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
|
||||||
unsigned int stps_index = 0;
|
unsigned int stps_index = 0;
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
uint64_t stream_size = 0;
|
uint64_t stream_size = 0;
|
||||||
|
MOVStts *stts_data_old = sc->stts_data;
|
||||||
MOVCtts *ctts_data_old = sc->ctts_data;
|
MOVCtts *ctts_data_old = sc->ctts_data;
|
||||||
|
unsigned int stts_count_old = sc->stts_count;
|
||||||
unsigned int ctts_count_old = sc->ctts_count;
|
unsigned int ctts_count_old = sc->ctts_count;
|
||||||
|
|
||||||
int ret = build_open_gop_key_points(st);
|
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);
|
ctts_data_old[i].offset);
|
||||||
av_free(ctts_data_old);
|
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++) {
|
for (i = 0; i < sc->chunk_count; i++) {
|
||||||
int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
|
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) {
|
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
|
int stts_constant = !!sc->stts_count;
|
||||||
if (sc->h_spacing && sc->v_spacing)
|
if (sc->h_spacing && sc->v_spacing)
|
||||||
av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
|
av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
|
||||||
sc->h_spacing, sc->v_spacing, INT_MAX);
|
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 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,
|
av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
|
||||||
sc->time_scale, sc->stts_data[0].duration, INT_MAX);
|
sc->time_scale, sc->stts_data[0].duration, INT_MAX);
|
||||||
#endif
|
#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 the duration of the mp3 packets is not constant, then they could need a parser
|
||||||
if (st->codecpar->codec_id == AV_CODEC_ID_MP3
|
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) {
|
&& 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;
|
ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
|
||||||
}
|
}
|
||||||
/* Do not need those anymore. */
|
/* Do not need those anymore. */
|
||||||
|
|
|
@ -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
|
3603038 tests/data/fate/enhanced-flv-hevc.flv
|
||||||
#extradata 0: 551, 0xb1ddcd66
|
#extradata 0: 551, 0xb1ddcd66
|
||||||
#extradata 1: 2, 0x00340022
|
#extradata 1: 2, 0x00340022
|
||||||
|
|
|
@ -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
|
3600617 tests/data/fate/matroska-dovi-write-config8.matroska
|
||||||
#extradata 0: 551, 0xb1ddcd66
|
#extradata 0: 551, 0xb1ddcd66
|
||||||
#extradata 1: 2, 0x00340022
|
#extradata 1: 2, 0x00340022
|
||||||
|
|
Loading…
Add table
Reference in a new issue