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
4690 unsigned int stps_index = 0;4690 unsigned int stps_index = 0;
4691 unsigned int i, j;4691 unsigned int i, j;
4692 uint64_t stream_size = 0;4692 uint64_t stream_size = 0;
4693 MOVStts *stts_data_old = sc->stts_data;
4693 MOVCtts *ctts_data_old = sc->ctts_data;4694 MOVCtts *ctts_data_old = sc->ctts_data;
4695 unsigned int stts_count_old = sc->stts_count;
4694 unsigned int ctts_count_old = sc->ctts_count;4696 unsigned int ctts_count_old = sc->ctts_count;
4695 4697
4696 int ret = build_open_gop_key_points(st);4698 int ret = build_open_gop_key_points(st);
@@ -4795,6 +4797,30 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 98 unmodified lines
4795 ctts_data_old[i].offset);4797 ctts_data_old[i].offset);
4796 av_free(ctts_data_old);4798 av_free(ctts_data_old);
4797 }4799 }
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 }
4798 4824
4799 for (i = 0; i < sc->chunk_count; i++) {4825 for (i = 0; i < sc->chunk_count; i++) {
4800 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;4826 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
5260 }5286 }
5261 5287
5262 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {5288 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5289 int stts_constant = !!sc->stts_count;
5263 if (sc->h_spacing && sc->v_spacing)5290 if (sc->h_spacing && sc->v_spacing)
5264 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,5291 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
5265 sc->h_spacing, sc->v_spacing, INT_MAX);5292 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
5272 }5299 }
5273 5300
5274#if FF_API_R_FRAME_RATE5301#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)
5276 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,5308 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
5277 sc->time_scale, sc->stts_data[0].duration, INT_MAX);5309 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
5278#endif5310#endif
@@ -5303,9 +5335,14 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 24 unmodified lines
5303 5335
5304 // If the duration of the mp3 packets is not constant, then they could need a parser5336 // If the duration of the mp3 packets is not constant, then they could need a parser
5305 if (st->codecpar->codec_id == AV_CODEC_ID_MP35337 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5306 && sc->stts_count > 3
5307 && sc->stts_count*10 > st->nb_frames
5308 && sc->time_scale == st->codecpar->sample_rate) {5338 && 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)
5309 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;5346 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
5310 }5347 }
5311 /* Do not need those anymore. */5348 /* 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