X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Futils.c;h=6e92bd777a1d96e02d8ae49ce663498a9b2c2897;hb=963d4b76debd3b7577a8e35fb40662974d52fe28;hp=d1e77d7b2484f0bcc8f4d02000efe7454e8404e9;hpb=cb46a6bcbcb85b3910cc0cce78399686ab8efff6;p=ffmpeg diff --git a/libavformat/utils.c b/libavformat/utils.c index d1e77d7b248..6e92bd777a1 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -101,7 +101,7 @@ static int is_relative(int64_t ts) { */ static int64_t wrap_timestamp(const AVStream *st, int64_t timestamp) { - if (st->internal->pts_wrap_behavior != AV_PTS_WRAP_IGNORE && + if (st->internal->pts_wrap_behavior != AV_PTS_WRAP_IGNORE && st->pts_wrap_bits < 64 && st->internal->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) { if (st->internal->pts_wrap_behavior == AV_PTS_WRAP_ADD_OFFSET && timestamp < st->internal->pts_wrap_reference) @@ -244,18 +244,23 @@ int av_format_get_probe_score(const AVFormatContext *s) int ffio_limit(AVIOContext *s, int size) { if (s->maxsize>= 0) { - int64_t remaining= s->maxsize - avio_tell(s); + int64_t pos = avio_tell(s); + int64_t remaining= s->maxsize - pos; if (remaining < size) { int64_t newsize = avio_size(s); if (!s->maxsize || s->maxsizemaxsize = newsize - !newsize; - remaining= s->maxsize - avio_tell(s); - remaining= FFMAX(remaining, 0); + if (pos > s->maxsize && s->maxsize >= 0) + s->maxsize = AVERROR(EIO); + if (s->maxsize >= 0) + remaining = s->maxsize - pos; } - if (s->maxsize>= 0 && remaining+1 < size) { - av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG, "Truncating packet of size %d to %"PRId64"\n", size, remaining+1); - size = remaining+1; + if (s->maxsize >= 0 && remaining < size && size > 1) { + av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG, + "Truncating packet of size %d to %"PRId64"\n", + size, remaining + !remaining); + size = remaining + !remaining; } } return size; @@ -365,7 +370,7 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, if (fmt_id_type[i].type != AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate) continue; - if (st->request_probe > score && + if (st->internal->request_probe > score && st->codecpar->codec_id != fmt_id_type[i].id) continue; st->codecpar->codec_id = fmt_id_type[i].id; @@ -675,8 +680,8 @@ static void force_codec_ids(AVFormatContext *s, AVStream *st) static int probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt) { - if (st->request_probe>0) { - AVProbeData *pd = &st->probe_data; + if (st->internal->request_probe>0) { + AVProbeData *pd = &st->internal->probe_data; int end; av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets); --st->probe_packets; @@ -711,7 +716,7 @@ no_packet: || end) { pd->buf_size = 0; av_freep(&pd->buf); - st->request_probe = -1; + st->internal->request_probe = -1; if (st->codecpar->codec_id != AV_CODEC_ID_NONE) { av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index); } else @@ -807,7 +812,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) if (s->internal->raw_packet_buffer_remaining_size <= 0) if ((err = probe_codec(s, st, NULL)) < 0) return err; - if (st->request_probe <= 0) { + if (st->internal->request_probe <= 0) { avpriv_packet_list_get(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end, pkt); s->internal->raw_packet_buffer_remaining_size += pkt->size; @@ -828,10 +833,10 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) return ret; for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; - if (st->probe_packets || st->request_probe > 0) + if (st->probe_packets || st->internal->request_probe > 0) if ((err = probe_codec(s, st, NULL)) < 0) return err; - av_assert0(st->request_probe <= 0); + av_assert0(st->internal->request_probe <= 0); } continue; } @@ -878,7 +883,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) if (s->use_wallclock_as_timestamps) pkt->dts = pkt->pts = av_rescale_q(av_gettime(), AV_TIME_BASE_Q, st->time_base); - if (!pktl && st->request_probe <= 0) + if (!pktl && st->internal->request_probe <= 0) return ret; err = avpriv_packet_list_put(&s->internal->raw_packet_buffer, @@ -1101,6 +1106,7 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, dts == AV_NOPTS_VALUE || st->cur_dts == AV_NOPTS_VALUE || st->cur_dts < INT_MIN + RELATIVE_TS_BASE || + dts < INT_MIN + (st->cur_dts - RELATIVE_TS_BASE) || is_relative(dts)) return; @@ -1123,7 +1129,7 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, if (st->start_time == AV_NOPTS_VALUE && pktl_it->pkt.pts != AV_NOPTS_VALUE) { st->start_time = pktl_it->pkt.pts; if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate) - st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base)); + st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->internal->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base)); } } @@ -1136,7 +1142,7 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, st->start_time = pts; } if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate) - st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base)); + st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->internal->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base)); } } @@ -1249,7 +1255,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, presentation_delayed = 1; if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && - st->pts_wrap_bits < 63 && + st->pts_wrap_bits < 63 && pkt->dts > INT64_MIN + (1LL << (st->pts_wrap_bits - 1)) && pkt->dts - (1LL << (st->pts_wrap_bits - 1)) > pkt->pts) { if (is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits - 1)) > st->cur_dts) { pkt->dts -= 1LL << st->pts_wrap_bits; @@ -1357,12 +1363,12 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, } if (pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY) { - st->pts_buffer[0] = pkt->pts; - for (i = 0; ipts_buffer[i] > st->pts_buffer[i + 1]; i++) - FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]); + st->internal->pts_buffer[0] = pkt->pts; + for (i = 0; iinternal->pts_buffer[i] > st->internal->pts_buffer[i + 1]; i++) + FFSWAP(int64_t, st->internal->pts_buffer[i], st->internal->pts_buffer[i + 1]); if(has_decode_delay_been_guessed(st)) - pkt->dts = select_from_pts_buffer(st, st->pts_buffer, pkt->dts); + pkt->dts = select_from_pts_buffer(st, st->internal->pts_buffer, pkt->dts); } // We skipped it above so we try here. if (!onein_oneout) @@ -1420,7 +1426,8 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, pkt->pts = pkt->dts = AV_NOPTS_VALUE; pkt->pos = -1; /* increment read pointer */ - data += len; + av_assert1(data || !len); + data = len ? data + len : data; size -= len; got_output = !!out_pkt.size; @@ -1626,8 +1633,8 @@ FF_ENABLE_DEPRECATION_WARNINGS av_packet_unref(pkt); } if (pkt->flags & AV_PKT_FLAG_KEY) - st->skip_to_keyframe = 0; - if (st->skip_to_keyframe) { + st->internal->skip_to_keyframe = 0; + if (st->internal->skip_to_keyframe) { av_packet_unref(pkt); got_packet = 0; } @@ -1639,25 +1646,25 @@ FF_ENABLE_DEPRECATION_WARNINGS if (ret >= 0) { AVStream *st = s->streams[pkt->stream_index]; int discard_padding = 0; - if (st->first_discard_sample && pkt->pts != AV_NOPTS_VALUE) { + if (st->internal->first_discard_sample && pkt->pts != AV_NOPTS_VALUE) { int64_t pts = pkt->pts - (is_relative(pkt->pts) ? RELATIVE_TS_BASE : 0); int64_t sample = ts_to_samples(st, pts); int duration = ts_to_samples(st, pkt->duration); int64_t end_sample = sample + duration; - if (duration > 0 && end_sample >= st->first_discard_sample && - sample < st->last_discard_sample) - discard_padding = FFMIN(end_sample - st->first_discard_sample, duration); + if (duration > 0 && end_sample >= st->internal->first_discard_sample && + sample < st->internal->last_discard_sample) + discard_padding = FFMIN(end_sample - st->internal->first_discard_sample, duration); } - if (st->start_skip_samples && (pkt->pts == 0 || pkt->pts == RELATIVE_TS_BASE)) - st->skip_samples = st->start_skip_samples; - if (st->skip_samples || discard_padding) { + if (st->internal->start_skip_samples && (pkt->pts == 0 || pkt->pts == RELATIVE_TS_BASE)) + st->internal->skip_samples = st->internal->start_skip_samples; + if (st->internal->skip_samples || discard_padding) { uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10); if (p) { - AV_WL32(p, st->skip_samples); + AV_WL32(p, st->internal->skip_samples); AV_WL32(p + 4, discard_padding); - av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d / discard %d\n", st->skip_samples, discard_padding); + av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d / discard %d\n", st->internal->skip_samples, discard_padding); } - st->skip_samples = 0; + st->internal->skip_samples = 0; } if (st->internal->inject_global_side_data) { @@ -1886,12 +1893,12 @@ void ff_read_frame_flush(AVFormatContext *s) st->probe_packets = s->max_probe_packets; for (j = 0; j < MAX_REORDER_DELAY + 1; j++) - st->pts_buffer[j] = AV_NOPTS_VALUE; + st->internal->pts_buffer[j] = AV_NOPTS_VALUE; if (s->internal->inject_global_side_data) st->internal->inject_global_side_data = 1; - st->skip_samples = 0; + st->internal->skip_samples = 0; } } @@ -1914,11 +1921,11 @@ void ff_reduce_index(AVFormatContext *s, int stream_index) AVStream *st = s->streams[stream_index]; unsigned int max_entries = s->max_index_size / sizeof(AVIndexEntry); - if ((unsigned) st->nb_index_entries >= max_entries) { + if ((unsigned) st->internal->nb_index_entries >= max_entries) { int i; - for (i = 0; 2 * i < st->nb_index_entries; i++) - st->index_entries[i] = st->index_entries[2 * i]; - st->nb_index_entries = i; + for (i = 0; 2 * i < st->internal->nb_index_entries; i++) + st->internal->index_entries[i] = st->internal->index_entries[2 * i]; + st->internal->nb_index_entries = i; } } @@ -1985,8 +1992,8 @@ int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags) { timestamp = wrap_timestamp(st, timestamp); - return ff_add_index_entry(&st->index_entries, &st->nb_index_entries, - &st->index_entries_allocated_size, pos, + return ff_add_index_entry(&st->internal->index_entries, &st->internal->nb_index_entries, + &st->internal->index_entries_allocated_size, pos, timestamp, size, distance, flags); } @@ -2062,13 +2069,13 @@ void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance) if (ist1 == ist2) continue; - for (i1 = i2 = 0; i1 < st1->nb_index_entries; i1++) { - AVIndexEntry *e1 = &st1->index_entries[i1]; + for (i1 = i2 = 0; i1 < st1->internal->nb_index_entries; i1++) { + AVIndexEntry *e1 = &st1->internal->index_entries[i1]; int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q); skip = FFMAX(skip, e1->size); - for (; i2 < st2->nb_index_entries; i2++) { - AVIndexEntry *e2 = &st2->index_entries[i2]; + for (; i2 < st2->internal->nb_index_entries; i2++) { + AVIndexEntry *e2 = &st2->internal->index_entries[i2]; int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q); if (e2_pts < e1_pts || e2_pts - (uint64_t)e1_pts < time_tolerance) continue; @@ -2100,7 +2107,7 @@ void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance) int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags) { - return ff_index_search_timestamp(st->index_entries, st->nb_index_entries, + return ff_index_search_timestamp(st->internal->index_entries, st->internal->nb_index_entries, wanted_timestamp, flags); } @@ -2133,7 +2140,7 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, pos_limit = -1; // GCC falsely says it may be uninitialized. st = s->streams[stream_index]; - if (st->index_entries) { + if (st->internal->index_entries) { AVIndexEntry *e; /* FIXME: Whole function must be checked for non-keyframe entries in @@ -2141,7 +2148,7 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, index = av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); index = FFMAX(index, 0); - e = &st->index_entries[index]; + e = &st->internal->index_entries[index]; if (e->timestamp <= target_ts || e->pos == e->min_distance) { pos_min = e->pos; @@ -2154,9 +2161,9 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, index = av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD); - av_assert0(index < st->nb_index_entries); + av_assert0(index < st->internal->nb_index_entries); if (index >= 0) { - e = &st->index_entries[index]; + e = &st->internal->index_entries[index]; av_assert1(e->timestamp >= target_ts); pos_max = e->pos; ts_max = e->timestamp; @@ -2357,17 +2364,17 @@ static int seek_frame_generic(AVFormatContext *s, int stream_index, index = av_index_search_timestamp(st, timestamp, flags); - if (index < 0 && st->nb_index_entries && - timestamp < st->index_entries[0].timestamp) + if (index < 0 && st->internal->nb_index_entries && + timestamp < st->internal->index_entries[0].timestamp) return -1; - if (index < 0 || index == st->nb_index_entries - 1) { + if (index < 0 || index == st->internal->nb_index_entries - 1) { AVPacket pkt; int nonkey = 0; - if (st->nb_index_entries) { - av_assert0(st->index_entries); - ie = &st->index_entries[st->nb_index_entries - 1]; + if (st->internal->nb_index_entries) { + av_assert0(st->internal->index_entries); + ie = &st->internal->index_entries[st->internal->nb_index_entries - 1]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; ff_update_cur_dts(s, st, ie->timestamp); @@ -2404,7 +2411,7 @@ static int seek_frame_generic(AVFormatContext *s, int stream_index, if (s->iformat->read_seek) if (s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0) return 0; - ie = &st->index_entries[index]; + ie = &st->internal->index_entries[index]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; ff_update_cur_dts(s, st, ie->timestamp); @@ -2867,12 +2874,12 @@ skip_duration_calc: st->last_IP_pts = AV_NOPTS_VALUE; st->internal->last_dts_for_order_check = AV_NOPTS_VALUE; for (j = 0; j < MAX_REORDER_DELAY + 1; j++) - st->pts_buffer[j] = AV_NOPTS_VALUE; + st->internal->pts_buffer[j] = AV_NOPTS_VALUE; } } /* 1:1 map to AVDurationEstimationMethod */ -static const char *duration_name[] = { +static const char *const duration_name[] = { [AVFMT_DURATION_FROM_PTS] = "pts", [AVFMT_DURATION_FROM_STREAM] = "stream", [AVFMT_DURATION_FROM_BITRATE] = "bit rate", @@ -3015,6 +3022,10 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, /* Force thread count to 1 since the H.264 decoder will not extract * SPS and PPS to extradata during multi-threaded decoding. */ av_dict_set(options ? options : &thread_opt, "threads", "1", 0); + /* Force lowres to 0. The decoder might reduce the video size by the + * lowres factor, and we don't want that propagated to the stream's + * codecpar */ + av_dict_set(options ? options : &thread_opt, "lowres", "0", 0); if (s->codec_whitelist) av_dict_set(options ? options : &thread_opt, "codec_whitelist", s->codec_whitelist, 0); ret = avcodec_open2(avctx, codec, options ? options : &thread_opt); @@ -3191,31 +3202,51 @@ enum AVCodecID av_codec_get_id(const AVCodecTag *const *tags, unsigned int tag) return AV_CODEC_ID_NONE; } -static void compute_chapters_end(AVFormatContext *s) +static int chapter_start_cmp(const void *p1, const void *p2) { - unsigned int i, j; + AVChapter *ch1 = *(AVChapter**)p1; + AVChapter *ch2 = *(AVChapter**)p2; + int delta = av_compare_ts(ch1->start, ch1->time_base, ch2->start, ch2->time_base); + if (delta) + return delta; + return (ch1 > ch2) - (ch1 < ch2); +} + +static int compute_chapters_end(AVFormatContext *s) +{ + unsigned int i; int64_t max_time = 0; + AVChapter **timetable = av_malloc(s->nb_chapters * sizeof(*timetable)); + + if (!timetable) + return AVERROR(ENOMEM); if (s->duration > 0 && s->start_time < INT64_MAX - s->duration) max_time = s->duration + ((s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time); for (i = 0; i < s->nb_chapters; i++) - if (s->chapters[i]->end == AV_NOPTS_VALUE) { - AVChapter *ch = s->chapters[i]; + timetable[i] = s->chapters[i]; + qsort(timetable, s->nb_chapters, sizeof(*timetable), chapter_start_cmp); + + for (i = 0; i < s->nb_chapters; i++) + if (timetable[i]->end == AV_NOPTS_VALUE) { + AVChapter *ch = timetable[i]; int64_t end = max_time ? av_rescale_q(max_time, AV_TIME_BASE_Q, - ch->time_base) - : INT64_MAX; + ch->time_base) + : INT64_MAX; - for (j = 0; j < s->nb_chapters; j++) { - AVChapter *ch1 = s->chapters[j]; + if (i + 1 < s->nb_chapters) { + AVChapter *ch1 = timetable[i + 1]; int64_t next_start = av_rescale_q(ch1->start, ch1->time_base, - ch->time_base); - if (j != i && next_start > ch->start && next_start < end) + ch->time_base); + if (next_start > ch->start && next_start < end) end = next_start; } ch->end = (end == INT64_MAX || end < ch->start) ? ch->start : end; } + av_free(timetable); + return 0; } static int get_std_framerate(int i) @@ -3607,7 +3638,7 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif // only for the split stuff - if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->request_probe <= 0) { + if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->internal->request_probe <= 0) { st->parser = av_parser_init(st->codecpar->codec_id); if (st->parser) { if (st->need_parsing == AVSTREAM_PARSE_HEADERS) { @@ -3628,7 +3659,7 @@ FF_ENABLE_DEPRECATION_WARNINGS ret = avcodec_parameters_to_context(avctx, st->codecpar); if (ret < 0) goto find_stream_info_err; - if (st->request_probe <= 0) + if (st->internal->request_probe <= 0) st->internal->avctx_inited = 1; codec = find_probe_decoder(ic, st, st->codecpar->codec_id); @@ -3636,6 +3667,10 @@ FF_ENABLE_DEPRECATION_WARNINGS /* Force thread count to 1 since the H.264 decoder will not extract * SPS and PPS to extradata during multi-threaded decoding. */ av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 0); + /* Force lowres to 0. The decoder might reduce the video size by the + * lowres factor, and we don't want that propagated to the stream's + * codecpar */ + av_dict_set(options ? &options[i] : &thread_opt, "lowres", "0", 0); if (ic->codec_whitelist) av_dict_set(options ? &options[i] : &thread_opt, "codec_whitelist", ic->codec_whitelist, 0); @@ -3649,7 +3684,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } // Try to just open decoders, in case this is enough to get parameters. - if (!has_codec_parameters(st, NULL) && st->request_probe <= 0) { + if (!has_codec_parameters(st, NULL) && st->internal->request_probe <= 0) { if (codec && !avctx->codec) if (avcodec_open2(avctx, codec, options ? &options[i] : &thread_opt) < 0) av_log(ic, AV_LOG_WARNING, @@ -3838,8 +3873,10 @@ FF_ENABLE_DEPRECATION_WARNINGS if ( t == 0 && st->codec_info_nb_frames>30 && st->internal->info->fps_first_dts != AV_NOPTS_VALUE - && st->internal->info->fps_last_dts != AV_NOPTS_VALUE) - t = FFMAX(t, av_rescale_q(st->internal->info->fps_last_dts - st->internal->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q)); + && st->internal->info->fps_last_dts != AV_NOPTS_VALUE) { + int64_t dur = av_sat_sub64(st->internal->info->fps_last_dts, st->internal->info->fps_first_dts); + t = FFMAX(t, av_rescale_q(dur, st->time_base, AV_TIME_BASE_Q)); + } if (analyzed_all_streams) limit = max_analyze_duration; else if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) limit = max_subtitle_analyze_duration; @@ -4071,28 +4108,21 @@ FF_ENABLE_DEPRECATION_WARNINGS } } - compute_chapters_end(ic); + ret = compute_chapters_end(ic); + if (ret < 0) + goto find_stream_info_err; /* update the stream parameters from the internal codec contexts */ for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->internal->avctx_inited) { - int orig_w = st->codecpar->width; - int orig_h = st->codecpar->height; ret = avcodec_parameters_from_context(st->codecpar, st->internal->avctx); if (ret < 0) goto find_stream_info_err; ret = add_coded_side_data(st, st->internal->avctx); if (ret < 0) goto find_stream_info_err; -#if FF_API_LOWRES - // The decoder might reduce the video size by the lowres factor. - if (st->internal->avctx->lowres && orig_w) { - st->codecpar->width = orig_w; - st->codecpar->height = orig_h; - } -#endif } #if FF_API_LAVF_AVCTX @@ -4101,7 +4131,6 @@ FF_DISABLE_DEPRECATION_WARNINGS if (ret < 0) goto find_stream_info_err; -#if FF_API_LOWRES // The old API (AVStream.codec) "requires" the resolution to be adjusted // by the lowres factor. if (st->internal->avctx->lowres && st->internal->avctx->width) { @@ -4109,7 +4138,6 @@ FF_DISABLE_DEPRECATION_WARNINGS st->codec->width = st->internal->avctx->width; st->codec->height = st->internal->avctx->height; } -#endif if (st->codec->codec_tag != MKTAG('t','m','c','d')) { st->codec->time_base = st->internal->avctx->time_base; @@ -4342,6 +4370,9 @@ static void free_stream(AVStream **pst) avcodec_free_context(&st->internal->avctx); av_bsf_free(&st->internal->bsfc); av_freep(&st->internal->priv_pts); + av_freep(&st->internal->index_entries); + av_freep(&st->internal->probe_data.buf); + av_bsf_free(&st->internal->extract_extradata.bsf); av_packet_free(&st->internal->extract_extradata.pkt); @@ -4353,8 +4384,6 @@ static void free_stream(AVStream **pst) av_dict_free(&st->metadata); avcodec_parameters_free(&st->codecpar); - av_freep(&st->probe_data.buf); - av_freep(&st->index_entries); #if FF_API_LAVF_AVCTX FF_DISABLE_DEPRECATION_WARNINGS avcodec_free_context(&st->codec); @@ -4526,7 +4555,7 @@ FF_ENABLE_DEPRECATION_WARNINGS st->last_IP_pts = AV_NOPTS_VALUE; st->internal->last_dts_for_order_check = AV_NOPTS_VALUE; for (i = 0; i < MAX_REORDER_DELAY + 1; i++) - st->pts_buffer[i] = AV_NOPTS_VALUE; + st->internal->pts_buffer[i] = AV_NOPTS_VALUE; st->sample_aspect_ratio = (AVRational) { 0, 1 }; @@ -4565,14 +4594,12 @@ AVProgram *av_new_program(AVFormatContext *ac, int id) dynarray_add(&ac->programs, &ac->nb_programs, program); program->discard = AVDISCARD_NONE; program->pmt_version = -1; + program->id = id; + program->pts_wrap_reference = AV_NOPTS_VALUE; + program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; + program->start_time = + program->end_time = AV_NOPTS_VALUE; } - program->id = id; - program->pts_wrap_reference = AV_NOPTS_VALUE; - program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; - - program->start_time = - program->end_time = AV_NOPTS_VALUE; - return program; } @@ -4587,9 +4614,14 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, return NULL; } - for (i = 0; i < s->nb_chapters; i++) - if (s->chapters[i]->id == id) - chapter = s->chapters[i]; + if (!s->nb_chapters) { + s->internal->chapter_ids_monotonic = 1; + } else if (!s->internal->chapter_ids_monotonic || s->chapters[s->nb_chapters-1]->id >= id) { + s->internal->chapter_ids_monotonic = 0; + for (i = 0; i < s->nb_chapters; i++) + if (s->chapters[i]->id == id) + chapter = s->chapters[i]; + } if (!chapter) { chapter = av_mallocz(sizeof(AVChapter)); @@ -4677,8 +4709,11 @@ int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number if (c == '%') { do { nd = 0; - while (av_isdigit(*p)) + while (av_isdigit(*p)) { + if (nd >= INT_MAX / 10 - 255) + goto fail; nd = nd * 10 + *p++ - '0'; + } c = *p++; } while (av_isdigit(c));