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.
Showing the changes to libavformat (1 of 3 files). Show all
Unified · Split
| @@ -4690,7 +4690,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 4689 unmodified lines | ||
| 4690 | 4690 | unsigned int stps_index = 0; |
| 4691 | 4691 | unsigned int i, j; |
| 4692 | 4692 | uint64_t stream_size = 0; |
| 4693 | + MOVStts *stts_data_old = sc->stts_data; | |
| 4693 | 4694 | MOVCtts *ctts_data_old = sc->ctts_data; |
| 4695 | + unsigned int stts_count_old = sc->stts_count; | |
| 4694 | 4696 | unsigned int ctts_count_old = sc->ctts_count; |
| 4695 | 4697 | |
| 4696 | 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 | 4797 | ctts_data_old[i].offset); |
| 4796 | 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 | 4825 | for (i = 0; i < sc->chunk_count; i++) { |
| 4800 | 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 | 5288 | if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { |
| 5289 | + int stts_constant = !!sc->stts_count; | |
| 5263 | 5290 | if (sc->h_spacing && sc->v_spacing) |
| 5264 | 5291 | av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den, |
| 5265 | 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 | 5301 | #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 | 5308 | av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, |
| 5277 | 5309 | sc->time_scale, sc->stts_data[0].duration, INT_MAX); |
| 5278 | 5310 | #endif |
| @@ -5303,9 +5335,14 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 24 unmodified lines | ||
| 5303 | 5335 | |
| 5304 | 5336 | // If the duration of the mp3 packets is not constant, then they could need a parser |
| 5305 | 5337 | if (st->codecpar->codec_id == AV_CODEC_ID_MP3 |
| 5306 | − && sc->stts_count > 3 | |
| 5307 | − && sc->stts_count*10 > st->nb_frames | |
| 5308 | 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 | 5346 | ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL; |
| 5310 | 5347 | } |
| 5311 | 5348 | /* Do not need those anymore. */ |