X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Futils.c;h=bb0351d7f57d2fe727bd3e1c533456b51aac0ad2;hb=119ebd642a6ceeeb506f46aa229870aefa97794b;hp=a36d6738cd712a93af62ab9b264546adfc07b480;hpb=7afb161bc100247b66f2bd5afc7d547faf37a1f9;p=ffmpeg diff --git a/libavformat/utils.c b/libavformat/utils.c index a36d6738cd7..bb0351d7f57 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -37,6 +37,7 @@ #include "libavcodec/bytestream.h" #include "libavcodec/internal.h" +#include "libavcodec/packet_internal.h" #include "libavcodec/raw.h" #include "avformat.h" @@ -100,13 +101,13 @@ static int is_relative(int64_t ts) { */ static int64_t wrap_timestamp(const AVStream *st, int64_t timestamp) { - if (st->pts_wrap_behavior != AV_PTS_WRAP_IGNORE && - st->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) { - if (st->pts_wrap_behavior == AV_PTS_WRAP_ADD_OFFSET && - timestamp < st->pts_wrap_reference) + 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) return timestamp + (1ULL << st->pts_wrap_bits); - else if (st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET && - timestamp >= st->pts_wrap_reference) + else if (st->internal->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET && + timestamp >= st->internal->pts_wrap_reference) return timestamp - (1ULL << st->pts_wrap_bits); } return timestamp; @@ -114,11 +115,6 @@ static int64_t wrap_timestamp(const AVStream *st, int64_t timestamp) #if FF_API_FORMAT_GET_SET MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate) -#if FF_API_LAVF_FFSERVER -FF_DISABLE_DEPRECATION_WARNINGS -MAKE_ACCESSORS(AVStream, stream, char *, recommended_encoder_configuration) -FF_ENABLE_DEPRECATION_WARNINGS -#endif MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec) MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec) MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec) @@ -126,11 +122,6 @@ MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, data_codec) MAKE_ACCESSORS(AVFormatContext, format, int, metadata_header_padding) MAKE_ACCESSORS(AVFormatContext, format, void *, opaque) MAKE_ACCESSORS(AVFormatContext, format, av_format_control_message, control_message_cb) -#if FF_API_OLD_OPEN_CALLBACKS -FF_DISABLE_DEPRECATION_WARNINGS -MAKE_ACCESSORS(AVFormatContext, format, AVOpenCallback, open_cb) -FF_ENABLE_DEPRECATION_WARNINGS -#endif #endif int64_t av_stream_get_end_pts(const AVStream *st) @@ -152,7 +143,7 @@ void av_format_inject_global_side_data(AVFormatContext *s) s->internal->inject_global_side_data = 1; for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - st->inject_global_side_data = 1; + st->internal->inject_global_side_data = 1; } } @@ -219,7 +210,7 @@ static const AVCodec *find_probe_decoder(AVFormatContext *s, const AVStream *st, const AVCodec *probe_codec = NULL; void *iter = NULL; while ((probe_codec = av_codec_iterate(&iter))) { - if (probe_codec->id == codec_id && + if (probe_codec->id == codec->id && av_codec_is_decoder(probe_codec) && !(probe_codec->capabilities & (AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_EXPERIMENTAL))) { return probe_codec; @@ -243,18 +234,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; @@ -303,9 +299,15 @@ static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size) int av_get_packet(AVIOContext *s, AVPacket *pkt, int size) { +#if FF_API_INIT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS av_init_packet(pkt); pkt->data = NULL; pkt->size = 0; +FF_ENABLE_DEPRECATION_WARNINGS +#else + av_packet_unref(pkt); +#endif pkt->pos = avio_tell(s); return append_packet_chunked(s, pkt, size); @@ -364,7 +366,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; @@ -386,6 +388,7 @@ FF_ENABLE_DEPRECATION_WARNINGS /************************************************************/ /* input media file */ +#if FF_API_DEMUXER_OPEN int av_demuxer_open(AVFormatContext *ic) { int err; @@ -405,7 +408,7 @@ int av_demuxer_open(AVFormatContext *ic) { return 0; } - +#endif /* Open input file and probe the format if necessary. */ static int init_input(AVFormatContext *s, const char *filename, AVDictionary **options) @@ -438,40 +441,6 @@ static int init_input(AVFormatContext *s, const char *filename, s, 0, s->format_probesize); } -int ff_packet_list_put(AVPacketList **packet_buffer, - AVPacketList **plast_pktl, - AVPacket *pkt, int flags) -{ - AVPacketList *pktl = av_mallocz(sizeof(AVPacketList)); - int ret; - - if (!pktl) - return AVERROR(ENOMEM); - - if (flags & FF_PACKETLIST_FLAG_REF_PACKET) { - if ((ret = av_packet_ref(&pktl->pkt, pkt)) < 0) { - av_free(pktl); - return ret; - } - } else { - ret = av_packet_make_refcounted(pkt); - if (ret < 0) { - av_free(pktl); - return ret; - } - av_packet_move_ref(&pktl->pkt, pkt); - } - - if (*packet_buffer) - (*plast_pktl)->next = pktl; - else - *packet_buffer = pktl; - - /* Add the packet in the buffered packet list. */ - *plast_pktl = pktl; - return 0; -} - int avformat_queue_attached_pictures(AVFormatContext *s) { int i, ret; @@ -485,16 +454,51 @@ int avformat_queue_attached_pictures(AVFormatContext *s) continue; } - ret = ff_packet_list_put(&s->internal->raw_packet_buffer, + ret = avpriv_packet_list_put(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end, &s->streams[i]->attached_pic, - FF_PACKETLIST_FLAG_REF_PACKET); + av_packet_ref, 0); if (ret < 0) return ret; } return 0; } +int ff_add_attached_pic(AVFormatContext *s, AVStream *st0, AVIOContext *pb, + AVBufferRef **buf, int size) +{ + AVStream *st = st0; + AVPacket *pkt; + int ret; + + if (!st && !(st = avformat_new_stream(s, NULL))) + return AVERROR(ENOMEM); + pkt = &st->attached_pic; + if (buf) { + av_assert1(*buf); + av_packet_unref(pkt); + pkt->buf = *buf; + pkt->data = (*buf)->data; + pkt->size = (*buf)->size - AV_INPUT_BUFFER_PADDING_SIZE; + *buf = NULL; + } else { + ret = av_get_packet(pb, pkt, size); + if (ret < 0) + goto fail; + } + st->disposition |= AV_DISPOSITION_ATTACHED_PIC; + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + + pkt->stream_index = st->index; + pkt->flags |= AV_PKT_FLAG_KEY; + + return 0; +fail: + if (!st0) + ff_free_stream(s, st); + return ret; +} + static int update_stream_avctx(AVFormatContext *s) { int i, ret; @@ -531,7 +535,7 @@ FF_ENABLE_DEPRECATION_WARNINGS int avformat_open_input(AVFormatContext **ps, const char *filename, - ff_const59 AVInputFormat *fmt, AVDictionary **options) + const AVInputFormat *fmt, AVDictionary **options) { AVFormatContext *s = *ps; int i, ret = 0; @@ -622,8 +626,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if (s->pb) ff_id3v2_read_dict(s->pb, &s->internal->id3v2_meta, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); - +#if FF_API_DEMUXER_OPEN if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header) +#else + if (s->iformat->read_header) +#endif if ((ret = s->iformat->read_header(s)) < 0) goto fail; @@ -638,11 +645,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if (id3v2_extra_meta) { if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac") || !strcmp(s->iformat->name, "tta") || !strcmp(s->iformat->name, "wav")) { - if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) + if ((ret = ff_id3v2_parse_apic(s, id3v2_extra_meta)) < 0) goto close; - if ((ret = ff_id3v2_parse_chapters(s, &id3v2_extra_meta)) < 0) + if ((ret = ff_id3v2_parse_chapters(s, id3v2_extra_meta)) < 0) goto close; - if ((ret = ff_id3v2_parse_priv(s, &id3v2_extra_meta)) < 0) + if ((ret = ff_id3v2_parse_priv(s, id3v2_extra_meta)) < 0) goto close; } else av_log(s, AV_LOG_DEBUG, "demuxer does not support additional id3 data, skipping\n"); @@ -652,7 +659,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if ((ret = avformat_queue_attached_pictures(s)) < 0) goto close; +#if FF_API_DEMUXER_OPEN if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->internal->data_offset) +#else + if (s->pb && !s->internal->data_offset) +#endif s->internal->data_offset = avio_tell(s->pb); s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; @@ -708,8 +719,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; @@ -744,7 +755,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 @@ -765,7 +776,7 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in if (ref == AV_NOPTS_VALUE) ref = pkt->pts; - if (st->pts_wrap_reference != AV_NOPTS_VALUE || st->pts_wrap_bits >= 63 || ref == AV_NOPTS_VALUE || !s->correct_ts_overflow) + if (st->internal->pts_wrap_reference != AV_NOPTS_VALUE || st->pts_wrap_bits >= 63 || ref == AV_NOPTS_VALUE || !s->correct_ts_overflow) return 0; ref &= (1LL << st->pts_wrap_bits)-1; @@ -780,17 +791,17 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in if (!first_program) { int default_stream_index = av_find_default_stream_index(s); - if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) { + if (s->streams[default_stream_index]->internal->pts_wrap_reference == AV_NOPTS_VALUE) { for (i = 0; i < s->nb_streams; i++) { if (av_find_program_from_stream(s, NULL, i)) continue; - s->streams[i]->pts_wrap_reference = pts_wrap_reference; - s->streams[i]->pts_wrap_behavior = pts_wrap_behavior; + s->streams[i]->internal->pts_wrap_reference = pts_wrap_reference; + s->streams[i]->internal->pts_wrap_behavior = pts_wrap_behavior; } } else { - st->pts_wrap_reference = s->streams[default_stream_index]->pts_wrap_reference; - st->pts_wrap_behavior = s->streams[default_stream_index]->pts_wrap_behavior; + st->internal->pts_wrap_reference = s->streams[default_stream_index]->internal->pts_wrap_reference; + st->internal->pts_wrap_behavior = s->streams[default_stream_index]->internal->pts_wrap_behavior; } } else { @@ -809,8 +820,8 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in while (program) { if (program->pts_wrap_reference != pts_wrap_reference) { for (i = 0; inb_stream_indexes; i++) { - s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; - s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; + s->streams[program->stream_index[i]]->internal->pts_wrap_reference = pts_wrap_reference; + s->streams[program->stream_index[i]]->internal->pts_wrap_behavior = pts_wrap_behavior; } program->pts_wrap_reference = pts_wrap_reference; @@ -824,15 +835,21 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in int ff_read_packet(AVFormatContext *s, AVPacket *pkt) { - int ret, i, err; + int err, i; AVStream *st; +#if FF_API_INIT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS pkt->data = NULL; pkt->size = 0; av_init_packet(pkt); +FF_ENABLE_DEPRECATION_WARNINGS +#else + av_packet_unref(pkt); +#endif for (;;) { - AVPacketList *pktl = s->internal->raw_packet_buffer; + PacketList *pktl = s->internal->raw_packet_buffer; const AVPacket *pkt1; if (pktl) { @@ -840,31 +857,31 @@ 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) { - ff_packet_list_get(&s->internal->raw_packet_buffer, + 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; return 0; } } - ret = s->iformat->read_packet(s, pkt); - if (ret < 0) { + err = s->iformat->read_packet(s, pkt); + if (err < 0) { av_packet_unref(pkt); /* Some demuxers return FFERROR_REDO when they consume data and discard it (ignored streams, junk, extradata). We must re-call the demuxer to get the real packet. */ - if (ret == FFERROR_REDO) + if (err == FFERROR_REDO) continue; - if (!pktl || ret == AVERROR(EAGAIN)) - return ret; + if (!pktl || err == AVERROR(EAGAIN)) + return err; 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; } @@ -892,7 +909,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) st = s->streams[pkt->stream_index]; - if (update_wrap_reference(s, st, pkt->stream_index, pkt) && st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) { + if (update_wrap_reference(s, st, pkt->stream_index, pkt) && st->internal->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) { // correct first time stamps to negative values if (!is_relative(st->first_dts)) st->first_dts = wrap_timestamp(st, st->first_dts); @@ -911,12 +928,12 @@ 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) - return ret; + if (!pktl && st->internal->request_probe <= 0) + return 0; - err = ff_packet_list_put(&s->internal->raw_packet_buffer, + err = avpriv_packet_list_put(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end, - pkt, 0); + pkt, NULL, 0); if (err < 0) { av_packet_unref(pkt); return err; @@ -1011,7 +1028,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } } -static int is_intra_only(enum AVCodecID id) +int ff_is_intra_only(enum AVCodecID id) { const AVCodecDescriptor *d = avcodec_descriptor_get(id); if (!d) @@ -1025,7 +1042,7 @@ static int is_intra_only(enum AVCodecID id) static int has_decode_delay_been_guessed(AVStream *st) { if (st->codecpar->codec_id != AV_CODEC_ID_H264) return 1; - if (!st->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy + if (!st->internal->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy return 1; #if CONFIG_H264_DECODER if (st->internal->avctx->has_b_frames && @@ -1033,14 +1050,14 @@ static int has_decode_delay_been_guessed(AVStream *st) return 1; #endif if (st->internal->avctx->has_b_frames<3) - return st->nb_decoded_frames >= 7; + return st->internal->nb_decoded_frames >= 7; else if (st->internal->avctx->has_b_frames<4) - return st->nb_decoded_frames >= 18; + return st->internal->nb_decoded_frames >= 18; else - return st->nb_decoded_frames >= 20; + return st->internal->nb_decoded_frames >= 20; } -static AVPacketList *get_next_pkt(AVFormatContext *s, AVStream *st, AVPacketList *pktl) +static PacketList *get_next_pkt(AVFormatContext *s, AVStream *st, PacketList *pktl) { if (pktl->next) return pktl->next; @@ -1060,8 +1077,8 @@ static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t if (dts == AV_NOPTS_VALUE) { int64_t best_score = INT64_MAX; for (i = 0; ipts_reorder_error_count[i]) { - int64_t score = st->pts_reorder_error[i] / st->pts_reorder_error_count[i]; + if (st->internal->pts_reorder_error_count[i]) { + int64_t score = st->internal->pts_reorder_error[i] / st->internal->pts_reorder_error_count[i]; if (score < best_score) { best_score = score; dts = pts_buffer[i]; @@ -1072,13 +1089,13 @@ static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t for (i = 0; ipts_reorder_error[i]; - diff = FFMAX(diff, st->pts_reorder_error[i]); - st->pts_reorder_error[i] = diff; - st->pts_reorder_error_count[i]++; - if (st->pts_reorder_error_count[i] > 250) { - st->pts_reorder_error[i] >>= 1; - st->pts_reorder_error_count[i] >>= 1; + + (uint64_t)st->internal->pts_reorder_error[i]; + diff = FFMAX(diff, st->internal->pts_reorder_error[i]); + st->internal->pts_reorder_error[i] = diff; + st->internal->pts_reorder_error_count[i]++; + if (st->internal->pts_reorder_error_count[i] > 250) { + st->internal->pts_reorder_error[i] >>= 1; + st->internal->pts_reorder_error_count[i] >>= 1; } } } @@ -1096,7 +1113,7 @@ static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t * of the packets in a window. */ static void update_dts_from_pts(AVFormatContext *s, int stream_index, - AVPacketList *pkt_buffer) + PacketList *pkt_buffer) { AVStream *st = s->streams[stream_index]; int delay = st->internal->avctx->has_b_frames; @@ -1125,8 +1142,8 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, int64_t dts, int64_t pts, AVPacket *pkt) { AVStream *st = s->streams[stream_index]; - AVPacketList *pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue; - AVPacketList *pktl_it; + PacketList *pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue; + PacketList *pktl_it; uint64_t shift; @@ -1134,6 +1151,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; @@ -1156,7 +1174,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_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)); } } @@ -1169,20 +1187,20 @@ 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_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)); } } static void update_initial_durations(AVFormatContext *s, AVStream *st, - int stream_index, int duration) + int stream_index, int64_t duration) { - AVPacketList *pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue; + PacketList *pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue; int64_t cur_dts = RELATIVE_TS_BASE; if (st->first_dts != AV_NOPTS_VALUE) { - if (st->update_initial_durations_done) + if (st->internal->update_initial_durations_done) return; - st->update_initial_durations_done = 1; + st->internal->update_initial_durations_done = 1; cur_dts = st->first_dts; for (; pktl; pktl = get_next_pkt(s, st, pktl)) { if (pktl->pkt.stream_index == stream_index) { @@ -1219,8 +1237,7 @@ static void update_initial_durations(AVFormatContext *s, AVStream *st, pktl->pkt.dts = cur_dts; if (!st->internal->avctx->has_b_frames) pktl->pkt.pts = cur_dts; -// if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) - pktl->pkt.duration = duration; + pktl->pkt.duration = duration; } else break; cur_dts = pktl->pkt.dts + pktl->pkt.duration; @@ -1243,24 +1260,24 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, return; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && pkt->dts != AV_NOPTS_VALUE) { - if (pkt->dts == pkt->pts && st->last_dts_for_order_check != AV_NOPTS_VALUE) { - if (st->last_dts_for_order_check <= pkt->dts) { - st->dts_ordered++; + if (pkt->dts == pkt->pts && st->internal->last_dts_for_order_check != AV_NOPTS_VALUE) { + if (st->internal->last_dts_for_order_check <= pkt->dts) { + st->internal->dts_ordered++; } else { - av_log(s, st->dts_misordered ? AV_LOG_DEBUG : AV_LOG_WARNING, + av_log(s, st->internal->dts_misordered ? AV_LOG_DEBUG : AV_LOG_WARNING, "DTS %"PRIi64" < %"PRIi64" out of order\n", pkt->dts, - st->last_dts_for_order_check); - st->dts_misordered++; + st->internal->last_dts_for_order_check); + st->internal->dts_misordered++; } - if (st->dts_ordered + st->dts_misordered > 250) { - st->dts_ordered >>= 1; - st->dts_misordered >>= 1; + if (st->internal->dts_ordered + st->internal->dts_misordered > 250) { + st->internal->dts_ordered >>= 1; + st->internal->dts_misordered >>= 1; } } - st->last_dts_for_order_check = pkt->dts; - if (st->dts_ordered < 8*st->dts_misordered && pkt->dts == pkt->pts) + st->internal->last_dts_for_order_check = pkt->dts; + if (st->internal->dts_ordered < 8*st->internal->dts_misordered && pkt->dts == pkt->pts) pkt->dts = AV_NOPTS_VALUE; } @@ -1283,7 +1300,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) && 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; @@ -1359,7 +1376,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, if (st->last_IP_duration == 0 && (uint64_t)pkt->duration <= INT32_MAX) st->last_IP_duration = pkt->duration; if (pkt->dts != AV_NOPTS_VALUE) - st->cur_dts = pkt->dts + st->last_IP_duration; + st->cur_dts = av_sat_add64(pkt->dts, st->last_IP_duration); if (pkt->dts != AV_NOPTS_VALUE && pkt->pts == AV_NOPTS_VALUE && st->last_IP_duration > 0 && @@ -1391,12 +1408,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) @@ -1410,28 +1427,8 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, presentation_delayed, delay, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), st->index, st->id); /* update flags */ - if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA || is_intra_only(st->codecpar->codec_id)) + if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA || ff_is_intra_only(st->codecpar->codec_id)) pkt->flags |= AV_PKT_FLAG_KEY; -#if FF_API_CONVERGENCE_DURATION -FF_DISABLE_DEPRECATION_WARNINGS - if (pc) - pkt->convergence_duration = pc->convergence_duration; -FF_ENABLE_DEPRECATION_WARNINGS -#endif -} - -void ff_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end) -{ - AVPacketList *tmp = *pkt_buf; - - while (tmp) { - AVPacketList *pktl = tmp; - tmp = pktl->next; - av_packet_unref(&pktl->pkt); - av_freep(&pktl); - } - *pkt_buf = NULL; - *pkt_buf_end = NULL; } /** @@ -1443,15 +1440,13 @@ void ff_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end) static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index, int flush) { - AVPacket out_pkt; + AVPacket *out_pkt = s->internal->parse_pkt; AVStream *st = s->streams[stream_index]; uint8_t *data = pkt->data; int size = pkt->size; int ret = 0, got_output = flush; - if (size || flush) { - av_init_packet(&out_pkt); - } else if (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) { + if (!size && !flush && st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) { // preserve 0-size sync packets compute_pkt_fields(s, st, st->parser, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE); } @@ -1462,48 +1457,49 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int64_t next_dts = pkt->dts; len = av_parser_parse2(st->parser, st->internal->avctx, - &out_pkt.data, &out_pkt.size, data, size, + &out_pkt->data, &out_pkt->size, data, size, pkt->pts, pkt->dts, pkt->pos); 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; + got_output = !!out_pkt->size; - if (!out_pkt.size) + if (!out_pkt->size) continue; - if (pkt->buf && out_pkt.data == pkt->data) { - /* reference pkt->buf only when out_pkt.data is guaranteed to point + if (pkt->buf && out_pkt->data == pkt->data) { + /* reference pkt->buf only when out_pkt->data is guaranteed to point * to data in it and not in the parser's internal buffer. */ /* XXX: Ensure this is the case with all parsers when st->parser->flags * is PARSER_FLAG_COMPLETE_FRAMES and check for that instead? */ - out_pkt.buf = av_buffer_ref(pkt->buf); - if (!out_pkt.buf) { + out_pkt->buf = av_buffer_ref(pkt->buf); + if (!out_pkt->buf) { ret = AVERROR(ENOMEM); goto fail; } } else { - ret = av_packet_make_refcounted(&out_pkt); + ret = av_packet_make_refcounted(out_pkt); if (ret < 0) goto fail; } if (pkt->side_data) { - out_pkt.side_data = pkt->side_data; - out_pkt.side_data_elems = pkt->side_data_elems; + out_pkt->side_data = pkt->side_data; + out_pkt->side_data_elems = pkt->side_data_elems; pkt->side_data = NULL; pkt->side_data_elems = 0; } /* set the duration */ - out_pkt.duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0; + out_pkt->duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0; if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { if (st->internal->avctx->sample_rate > 0) { - out_pkt.duration = + out_pkt->duration = av_rescale_q_rnd(st->parser->duration, (AVRational) { 1, st->internal->avctx->sample_rate }, st->time_base, @@ -1511,32 +1507,30 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, } } - out_pkt.stream_index = st->index; - out_pkt.pts = st->parser->pts; - out_pkt.dts = st->parser->dts; - out_pkt.pos = st->parser->pos; - out_pkt.flags |= pkt->flags & AV_PKT_FLAG_DISCARD; + out_pkt->stream_index = st->index; + out_pkt->pts = st->parser->pts; + out_pkt->dts = st->parser->dts; + out_pkt->pos = st->parser->pos; + out_pkt->flags |= pkt->flags & AV_PKT_FLAG_DISCARD; if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) - out_pkt.pos = st->parser->frame_offset; + out_pkt->pos = st->parser->frame_offset; if (st->parser->key_frame == 1 || (st->parser->key_frame == -1 && st->parser->pict_type == AV_PICTURE_TYPE_I)) - out_pkt.flags |= AV_PKT_FLAG_KEY; + out_pkt->flags |= AV_PKT_FLAG_KEY; if (st->parser->key_frame == -1 && st->parser->pict_type ==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY)) - out_pkt.flags |= AV_PKT_FLAG_KEY; + out_pkt->flags |= AV_PKT_FLAG_KEY; - compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts); + compute_pkt_fields(s, st, st->parser, out_pkt, next_dts, next_pts); - ret = ff_packet_list_put(&s->internal->parse_queue, + ret = avpriv_packet_list_put(&s->internal->parse_queue, &s->internal->parse_queue_end, - &out_pkt, 0); - if (ret < 0) { - av_packet_unref(&out_pkt); + out_pkt, NULL, 0); + if (ret < 0) goto fail; - } } /* end of the stream => close and free the parser */ @@ -1546,25 +1540,12 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, } fail: + if (ret < 0) + av_packet_unref(out_pkt); av_packet_unref(pkt); return ret; } -int ff_packet_list_get(AVPacketList **pkt_buffer, - AVPacketList **pkt_buffer_end, - AVPacket *pkt) -{ - AVPacketList *pktl; - av_assert0(*pkt_buffer); - pktl = *pkt_buffer; - *pkt = pktl->pkt; - *pkt_buffer = pktl->next; - if (!pktl->next) - *pkt_buffer_end = NULL; - av_freep(&pktl); - return 0; -} - static int64_t ts_to_samples(AVStream *st, int64_t ts) { return av_rescale(ts, st->time_base.num * st->codecpar->sample_rate, st->time_base.den); @@ -1596,12 +1577,14 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) ret = 0; st = s->streams[pkt->stream_index]; + st->event_flags |= AVSTREAM_EVENT_FLAG_NEW_PACKETS; + /* update context if required */ if (st->internal->need_context_update) { if (avcodec_is_open(st->internal->avctx)) { av_log(s, AV_LOG_DEBUG, "Demuxer context update while decoder is open, closing and trying to re-open\n"); avcodec_close(st->internal->avctx); - st->info->found_decoder = 0; + st->internal->info->found_decoder = 0; } /* close parser, because it depends on the codec */ @@ -1687,41 +1670,41 @@ 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; } } if (!got_packet && s->internal->parse_queue) - ret = ff_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt); + ret = avpriv_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt); 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->inject_global_side_data) { + if (st->internal->inject_global_side_data) { for (i = 0; i < st->nb_side_data; i++) { AVPacketSideData *src_sd = &st->side_data[i]; uint8_t *dst_data; @@ -1737,7 +1720,7 @@ FF_ENABLE_DEPRECATION_WARNINGS memcpy(dst_data, src_sd->data, src_sd->size); } - st->inject_global_side_data = 0; + st->internal->inject_global_side_data = 0; } } @@ -1779,7 +1762,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) if (!genpts) { ret = s->internal->packet_buffer - ? ff_packet_list_get(&s->internal->packet_buffer, + ? avpriv_packet_list_get(&s->internal->packet_buffer, &s->internal->packet_buffer_end, pkt) : read_frame_internal(s, pkt); if (ret < 0) @@ -1788,7 +1771,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) } for (;;) { - AVPacketList *pktl = s->internal->packet_buffer; + PacketList *pktl = s->internal->packet_buffer; if (pktl) { AVPacket *next_pkt = &pktl->pkt; @@ -1828,7 +1811,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) st = s->streams[next_pkt->stream_index]; if (!(next_pkt->pts == AV_NOPTS_VALUE && st->discard < AVDISCARD_ALL && next_pkt->dts != AV_NOPTS_VALUE && !eof)) { - ret = ff_packet_list_get(&s->internal->packet_buffer, + ret = avpriv_packet_list_get(&s->internal->packet_buffer, &s->internal->packet_buffer_end, pkt); goto return_packet; } @@ -1843,9 +1826,9 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) return ret; } - ret = ff_packet_list_put(&s->internal->packet_buffer, + ret = avpriv_packet_list_put(&s->internal->packet_buffer, &s->internal->packet_buffer_end, - pkt, 0); + pkt, NULL, 0); if (ret < 0) { av_packet_unref(pkt); return ret; @@ -1873,9 +1856,9 @@ static void flush_packet_queue(AVFormatContext *s) { if (!s->internal) return; - ff_packet_list_free(&s->internal->parse_queue, &s->internal->parse_queue_end); - ff_packet_list_free(&s->internal->packet_buffer, &s->internal->packet_buffer_end); - ff_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end); + avpriv_packet_list_free(&s->internal->parse_queue, &s->internal->parse_queue_end); + avpriv_packet_list_free(&s->internal->packet_buffer, &s->internal->packet_buffer_end); + avpriv_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end); s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; } @@ -1937,7 +1920,7 @@ void ff_read_frame_flush(AVFormatContext *s) st->parser = NULL; } st->last_IP_pts = AV_NOPTS_VALUE; - st->last_dts_for_order_check = AV_NOPTS_VALUE; + st->internal->last_dts_for_order_check = AV_NOPTS_VALUE; if (st->first_dts == AV_NOPTS_VALUE) st->cur_dts = RELATIVE_TS_BASE; else @@ -1947,12 +1930,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->inject_global_side_data = 1; + st->internal->inject_global_side_data = 1; - st->skip_samples = 0; + st->internal->skip_samples = 0; } } @@ -1975,11 +1958,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; } } @@ -2046,8 +2029,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); } @@ -2123,13 +2106,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; @@ -2161,10 +2144,37 @@ 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); } +int avformat_index_get_entries_count(const AVStream *st) +{ + return st->internal->nb_index_entries; +} + +const AVIndexEntry *avformat_index_get_entry(const AVStream *st, int idx) +{ + if (idx < 0 || idx >= st->internal->nb_index_entries) + return NULL; + + return &st->internal->index_entries[idx]; +} + +const AVIndexEntry *avformat_index_get_entry_from_timestamp(const AVStream *st, + int64_t wanted_timestamp, + int flags) +{ + int idx = ff_index_search_timestamp(st->internal->index_entries, + st->internal->nb_index_entries, + wanted_timestamp, flags); + + if (idx < 0) + return NULL; + + return &st->internal->index_entries[idx]; +} + static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )) { @@ -2194,7 +2204,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 @@ -2202,7 +2212,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; @@ -2215,9 +2225,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; @@ -2418,17 +2428,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) { - AVPacket pkt; + if (index < 0 || index == st->internal->nb_index_entries - 1) { + AVPacket *pkt = s->internal->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); @@ -2436,25 +2446,26 @@ static int seek_frame_generic(AVFormatContext *s, int stream_index, if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0) return ret; } + av_packet_unref(pkt); for (;;) { int read_status; do { - read_status = av_read_frame(s, &pkt); + read_status = av_read_frame(s, pkt); } while (read_status == AVERROR(EAGAIN)); if (read_status < 0) break; - if (stream_index == pkt.stream_index && pkt.dts > timestamp) { - if (pkt.flags & AV_PKT_FLAG_KEY) { - av_packet_unref(&pkt); + if (stream_index == pkt->stream_index && pkt->dts > timestamp) { + if (pkt->flags & AV_PKT_FLAG_KEY) { + av_packet_unref(pkt); break; } if (nonkey++ > 1000 && st->codecpar->codec_id != AV_CODEC_ID_CDGRAPHICS) { av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey); - av_packet_unref(&pkt); + av_packet_unref(pkt); break; } } - av_packet_unref(&pkt); + av_packet_unref(pkt); } index = av_index_search_timestamp(st, timestamp, flags); } @@ -2465,7 +2476,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); @@ -2782,7 +2793,7 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) st = ic->streams[i]; if ( st->time_base.num <= INT64_MAX / ic->bit_rate && st->duration == AV_NOPTS_VALUE) { - duration = av_rescale(8 * filesize, st->time_base.den, + duration = av_rescale(filesize, 8LL * st->time_base.den, ic->bit_rate * (int64_t) st->time_base.num); st->duration = duration; @@ -2802,7 +2813,7 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) /* only usable for MPEG-PS streams */ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) { - AVPacket pkt1, *pkt = &pkt1; + AVPacket *pkt = ic->internal->pkt; AVStream *st; int num, den, read_size, i, ret; int found_duration = 0; @@ -2874,10 +2885,10 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) else duration -= st->first_dts; if (duration > 0) { - if (st->duration == AV_NOPTS_VALUE || st->info->last_duration<= 0 || - (st->duration < duration && FFABS(duration - st->info->last_duration) < 60LL*st->time_base.den / st->time_base.num)) + if (st->duration == AV_NOPTS_VALUE || st->internal->info->last_duration<= 0 || + (st->duration < duration && FFABS(duration - st->internal->info->last_duration) < 60LL*st->time_base.den / st->time_base.num)) st->duration = duration; - st->info->last_duration = duration; + st->internal->info->last_duration = duration; } } av_packet_unref(pkt); @@ -2926,14 +2937,14 @@ skip_duration_calc: st = ic->streams[i]; st->cur_dts = st->first_dts; st->last_IP_pts = AV_NOPTS_VALUE; - st->last_dts_for_order_check = 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", @@ -2978,23 +2989,19 @@ static void estimate_timings(AVFormatContext *ic, int64_t old_offset) } update_stream_timings(ic); - { - int i; - AVStream av_unused *st; - for (i = 0; i < ic->nb_streams; i++) { - st = ic->streams[i]; - if (st->time_base.den) - av_log(ic, AV_LOG_TRACE, "stream %d: start_time: %0.3f duration: %0.3f\n", i, - (double) st->start_time * av_q2d(st->time_base), - (double) st->duration * av_q2d(st->time_base)); - } - av_log(ic, AV_LOG_TRACE, - "format: start_time: %0.3f duration: %0.3f (estimate from %s) bitrate=%"PRId64" kb/s\n", - (double) ic->start_time / AV_TIME_BASE, - (double) ic->duration / AV_TIME_BASE, - duration_estimate_name(ic->duration_estimation_method), - (int64_t)ic->bit_rate / 1000); + for (unsigned i = 0; i < ic->nb_streams; i++) { + AVStream *st = ic->streams[i]; + if (st->time_base.den) + av_log(ic, AV_LOG_TRACE, "stream %u: start_time: %s duration: %s\n", i, + av_ts2timestr(st->start_time, &st->time_base), + av_ts2timestr(st->duration, &st->time_base)); } + av_log(ic, AV_LOG_TRACE, + "format: start_time: %s duration: %s (estimate from %s) bitrate=%"PRId64" kb/s\n", + av_ts2timestr(ic->start_time, &AV_TIME_BASE_Q), + av_ts2timestr(ic->duration, &AV_TIME_BASE_Q), + duration_estimate_name(ic->duration_estimation_method), + (int64_t)ic->bit_rate / 1000); } static int has_codec_parameters(AVStream *st, const char **errmsg_ptr) @@ -3014,20 +3021,20 @@ static int has_codec_parameters(AVStream *st, const char **errmsg_ptr) case AVMEDIA_TYPE_AUDIO: if (!avctx->frame_size && determinable_frame_size(avctx)) FAIL("unspecified frame size"); - if (st->info->found_decoder >= 0 && + if (st->internal->info->found_decoder >= 0 && avctx->sample_fmt == AV_SAMPLE_FMT_NONE) FAIL("unspecified sample format"); if (!avctx->sample_rate) FAIL("unspecified sample rate"); if (!avctx->channels) FAIL("unspecified number of channels"); - if (st->info->found_decoder >= 0 && !st->nb_decoded_frames && avctx->codec_id == AV_CODEC_ID_DTS) + if (st->internal->info->found_decoder >= 0 && !st->internal->nb_decoded_frames && avctx->codec_id == AV_CODEC_ID_DTS) FAIL("no decodable DTS frames"); break; case AVMEDIA_TYPE_VIDEO: if (!avctx->width) FAIL("unspecified size"); - if (st->info->found_decoder >= 0 && avctx->pix_fmt == AV_PIX_FMT_NONE) + if (st->internal->info->found_decoder >= 0 && avctx->pix_fmt == AV_PIX_FMT_NONE) FAIL("unspecified pixel format"); if (st->codecpar->codec_id == AV_CODEC_ID_RV30 || st->codecpar->codec_id == AV_CODEC_ID_RV40) if (!st->sample_aspect_ratio.num && !st->codecpar->sample_aspect_ratio.num && !st->codec_info_nb_frames) @@ -3061,14 +3068,14 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, return AVERROR(ENOMEM); if (!avcodec_is_open(avctx) && - st->info->found_decoder <= 0 && - (st->codecpar->codec_id != -st->info->found_decoder || !st->codecpar->codec_id)) { + st->internal->info->found_decoder <= 0 && + (st->codecpar->codec_id != -st->internal->info->found_decoder || !st->codecpar->codec_id)) { AVDictionary *thread_opt = NULL; codec = find_probe_decoder(s, st, st->codecpar->codec_id); if (!codec) { - st->info->found_decoder = -st->codecpar->codec_id; + st->internal->info->found_decoder = -st->codecpar->codec_id; ret = -1; goto fail; } @@ -3076,20 +3083,24 @@ 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); if (!options) av_dict_free(&thread_opt); if (ret < 0) { - st->info->found_decoder = -avctx->codec_id; + st->internal->info->found_decoder = -avctx->codec_id; goto fail; } - st->info->found_decoder = 1; - } else if (!st->info->found_decoder) - st->info->found_decoder = 1; + st->internal->info->found_decoder = 1; + } else if (!st->internal->info->found_decoder) + st->internal->info->found_decoder = 1; - if (st->info->found_decoder < 0) { + if (st->internal->info->found_decoder < 0) { ret = -1; goto fail; } @@ -3128,7 +3139,7 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, } if (ret >= 0) { if (got_picture) - st->nb_decoded_frames++; + st->internal->nb_decoded_frames++; ret = got_picture; } } @@ -3252,31 +3263,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) +{ + 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, j; + 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) @@ -3355,59 +3386,59 @@ int ff_get_extradata(AVFormatContext *s, AVCodecParameters *par, AVIOContext *pb int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts) { int i, j; - int64_t last = st->info->last_dts; + int64_t last = st->internal->info->last_dts; if ( ts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && ts > last && ts - (uint64_t)last < INT64_MAX) { double dts = (is_relative(ts) ? ts - RELATIVE_TS_BASE : ts) * av_q2d(st->time_base); int64_t duration = ts - last; - if (!st->info->duration_error) - st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2); - if (!st->info->duration_error) + if (!st->internal->info->duration_error) + st->internal->info->duration_error = av_mallocz(sizeof(st->internal->info->duration_error[0])*2); + if (!st->internal->info->duration_error) return AVERROR(ENOMEM); // if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) // av_log(NULL, AV_LOG_ERROR, "%f\n", dts); for (i = 0; iinfo->duration_error[0][1][i] < 1e10) { + if (st->internal->info->duration_error[0][1][i] < 1e10) { int framerate = get_std_framerate(i); double sdts = dts*framerate/(1001*12); for (j= 0; j<2; j++) { int64_t ticks = llrint(sdts+j*0.5); double error= sdts - ticks + j*0.5; - st->info->duration_error[j][0][i] += error; - st->info->duration_error[j][1][i] += error*error; + st->internal->info->duration_error[j][0][i] += error; + st->internal->info->duration_error[j][1][i] += error*error; } } } - if (st->info->rfps_duration_sum <= INT64_MAX - duration) { - st->info->duration_count++; - st->info->rfps_duration_sum += duration; + if (st->internal->info->rfps_duration_sum <= INT64_MAX - duration) { + st->internal->info->duration_count++; + st->internal->info->rfps_duration_sum += duration; } - if (st->info->duration_count % 10 == 0) { - int n = st->info->duration_count; + if (st->internal->info->duration_count % 10 == 0) { + int n = st->internal->info->duration_count; for (i = 0; iinfo->duration_error[0][1][i] < 1e10) { - double a0 = st->info->duration_error[0][0][i] / n; - double error0 = st->info->duration_error[0][1][i] / n - a0*a0; - double a1 = st->info->duration_error[1][0][i] / n; - double error1 = st->info->duration_error[1][1][i] / n - a1*a1; + if (st->internal->info->duration_error[0][1][i] < 1e10) { + double a0 = st->internal->info->duration_error[0][0][i] / n; + double error0 = st->internal->info->duration_error[0][1][i] / n - a0*a0; + double a1 = st->internal->info->duration_error[1][0][i] / n; + double error1 = st->internal->info->duration_error[1][1][i] / n - a1*a1; if (error0 > 0.04 && error1 > 0.04) { - st->info->duration_error[0][1][i] = 2e10; - st->info->duration_error[1][1][i] = 2e10; + st->internal->info->duration_error[0][1][i] = 2e10; + st->internal->info->duration_error[1][1][i] = 2e10; } } } } // ignore the first 4 values, they might have some random jitter - if (st->info->duration_count > 3 && is_relative(ts) == is_relative(last)) - st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration); + if (st->internal->info->duration_count > 3 && is_relative(ts) == is_relative(last)) + st->internal->info->duration_gcd = av_gcd(st->internal->info->duration_gcd, duration); } if (ts != AV_NOPTS_VALUE) - st->info->last_dts = ts; + st->internal->info->last_dts = ts; return 0; } @@ -3424,9 +3455,10 @@ void ff_rfps_calculate(AVFormatContext *ic) // the check for tb_unreliable() is not completely correct, since this is not about handling // an unreliable/inexact time base, but a time base that is finer than necessary, as e.g. // ipmovie.c produces. - if (tb_unreliable(st->internal->avctx) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num) - av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX); - if (st->info->duration_count>1 && !st->r_frame_rate.num + if (tb_unreliable(st->internal->avctx) && st->internal->info->duration_count > 15 && st->internal->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num && + st->internal->info->duration_gcd < INT64_MAX / st->time_base.num) + av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->internal->info->duration_gcd, INT_MAX); + if (st->internal->info->duration_count>1 && !st->r_frame_rate.num && tb_unreliable(st->internal->avctx)) { int num = 0; double best_error= 0.01; @@ -3435,19 +3467,19 @@ void ff_rfps_calculate(AVFormatContext *ic) for (j= 0; jinfo->codec_info_duration && - st->info->codec_info_duration*av_q2d(st->time_base) < (1001*11.5)/get_std_framerate(j)) + if (st->internal->info->codec_info_duration && + st->internal->info->codec_info_duration*av_q2d(st->time_base) < (1001*11.5)/get_std_framerate(j)) continue; - if (!st->info->codec_info_duration && get_std_framerate(j) < 1001*12) + if (!st->internal->info->codec_info_duration && get_std_framerate(j) < 1001*12) continue; - if (av_q2d(st->time_base) * st->info->rfps_duration_sum / st->info->duration_count < (1001*12.0 * 0.8)/get_std_framerate(j)) + if (av_q2d(st->time_base) * st->internal->info->rfps_duration_sum / st->internal->info->duration_count < (1001*12.0 * 0.8)/get_std_framerate(j)) continue; for (k= 0; k<2; k++) { - int n = st->info->duration_count; - double a= st->info->duration_error[k][0][j] / n; - double error= st->info->duration_error[k][1][j]/n - a*a; + int n = st->internal->info->duration_count; + double a= st->internal->info->duration_error[k][0][j] / n; + double error= st->internal->info->duration_error[k][1][j]/n - a*a; if (error < best_error && best_error> 0.000000001) { best_error= error; @@ -3462,19 +3494,19 @@ void ff_rfps_calculate(AVFormatContext *ic) av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX); } if ( !st->avg_frame_rate.num - && st->r_frame_rate.num && st->info->rfps_duration_sum - && st->info->codec_info_duration <= 0 - && st->info->duration_count > 2 - && fabs(1.0 / (av_q2d(st->r_frame_rate) * av_q2d(st->time_base)) - st->info->rfps_duration_sum / (double)st->info->duration_count) <= 1.0 + && st->r_frame_rate.num && st->internal->info->rfps_duration_sum + && st->internal->info->codec_info_duration <= 0 + && st->internal->info->duration_count > 2 + && fabs(1.0 / (av_q2d(st->r_frame_rate) * av_q2d(st->time_base)) - st->internal->info->rfps_duration_sum / (double)st->internal->info->duration_count) <= 1.0 ) { av_log(ic, AV_LOG_DEBUG, "Setting avg frame rate based on r frame rate\n"); st->avg_frame_rate = st->r_frame_rate; } - av_freep(&st->info->duration_error); - st->info->last_dts = AV_NOPTS_VALUE; - st->info->duration_count = 0; - st->info->rfps_duration_sum = 0; + av_freep(&st->internal->info->duration_error); + st->internal->info->last_dts = AV_NOPTS_VALUE; + st->internal->info->duration_count = 0; + st->internal->info->rfps_duration_sum = 0; } } @@ -3511,13 +3543,9 @@ static int extract_extradata_init(AVStream *st) if (!ret) goto finish; - sti->extract_extradata.pkt = av_packet_alloc(); - if (!sti->extract_extradata.pkt) - return AVERROR(ENOMEM); - ret = av_bsf_alloc(f, &sti->extract_extradata.bsf); if (ret < 0) - goto fail; + return ret; ret = avcodec_parameters_copy(sti->extract_extradata.bsf->par_in, st->codecpar); @@ -3536,14 +3564,13 @@ finish: return 0; fail: av_bsf_free(&sti->extract_extradata.bsf); - av_packet_free(&sti->extract_extradata.pkt); return ret; } -static int extract_extradata(AVStream *st, const AVPacket *pkt) +static int extract_extradata(AVFormatContext *s, AVStream *st, const AVPacket *pkt) { AVStreamInternal *sti = st->internal; - AVPacket *pkt_ref; + AVPacket *pkt_ref = s->internal->parse_pkt; int ret; if (!sti->extract_extradata.inited) { @@ -3555,7 +3582,6 @@ static int extract_extradata(AVStream *st, const AVPacket *pkt) if (sti->extract_extradata.inited && !sti->extract_extradata.bsf) return 0; - pkt_ref = sti->extract_extradata.pkt; ret = av_packet_ref(pkt_ref, pkt); if (ret < 0) return ret; @@ -3567,9 +3593,6 @@ static int extract_extradata(AVStream *st, const AVPacket *pkt) } while (ret >= 0 && !sti->avctx->extradata) { - int extradata_size; - uint8_t *extradata; - ret = av_bsf_receive_packet(sti->extract_extradata.bsf, pkt_ref); if (ret < 0) { if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) @@ -3577,19 +3600,15 @@ static int extract_extradata(AVStream *st, const AVPacket *pkt) continue; } - extradata = av_packet_get_side_data(pkt_ref, AV_PKT_DATA_NEW_EXTRADATA, - &extradata_size); - - if (extradata) { - av_assert0(!sti->avctx->extradata); - if ((unsigned)extradata_size < FF_MAX_EXTRADATA_SIZE) - sti->avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!sti->avctx->extradata) { - av_packet_unref(pkt_ref); - return AVERROR(ENOMEM); + for (int i = 0; i < pkt_ref->side_data_elems; i++) { + AVPacketSideData *side_data = &pkt_ref->side_data[i]; + if (side_data->type == AV_PKT_DATA_NEW_EXTRADATA) { + sti->avctx->extradata = side_data->data; + sti->avctx->extradata_size = side_data->size; + side_data->data = NULL; + side_data->size = 0; + break; } - memcpy(sti->avctx->extradata, extradata, extradata_size); - sti->avctx->extradata_size = extradata_size; } av_packet_unref(pkt_ref); } @@ -3618,7 +3637,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) int64_t read_size; AVStream *st; AVCodecContext *avctx; - AVPacket pkt1; + AVPacket *pkt1 = ic->internal->pkt; int64_t old_offset = avio_tell(ic->pb); // new streams might appear, no options for those int orig_nb_streams = ic->nb_streams; @@ -3675,7 +3694,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) { @@ -3696,7 +3715,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); @@ -3704,20 +3723,18 @@ 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); - /* Ensure that subtitle_header is properly set. */ - if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE - && codec && !avctx->codec) { - if (avcodec_open2(avctx, codec, options ? &options[i] : &thread_opt) < 0) - av_log(ic, AV_LOG_WARNING, - "Failed to open codec in %s\n",__FUNCTION__); - } - // Try to just open decoders, in case this is enough to get parameters. - if (!has_codec_parameters(st, NULL) && st->request_probe <= 0) { + // Also ensure that subtitle_header is properly set. + if (!has_codec_parameters(st, NULL) && st->internal->request_probe <= 0 || + st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) { if (codec && !avctx->codec) if (avcodec_open2(avctx, codec, options ? &options[i] : &thread_opt) < 0) av_log(ic, AV_LOG_WARNING, @@ -3729,10 +3746,10 @@ FF_ENABLE_DEPRECATION_WARNINGS for (i = 0; i < ic->nb_streams; i++) { #if FF_API_R_FRAME_RATE - ic->streams[i]->info->last_dts = AV_NOPTS_VALUE; + ic->streams[i]->internal->info->last_dts = AV_NOPTS_VALUE; #endif - ic->streams[i]->info->fps_first_dts = AV_NOPTS_VALUE; - ic->streams[i]->info->fps_last_dts = AV_NOPTS_VALUE; + ic->streams[i]->internal->info->fps_first_dts = AV_NOPTS_VALUE; + ic->streams[i]->internal->info->fps_last_dts = AV_NOPTS_VALUE; } read_size = 0; @@ -3766,8 +3783,8 @@ FF_ENABLE_DEPRECATION_WARNINGS fps_analyze_framecount = 0; /* variable fps and no guess at the real fps */ count = (ic->iformat->flags & AVFMT_NOTIMESTAMPS) ? - st->info->codec_info_duration_fields/2 : - st->info->duration_count; + st->internal->info->codec_info_duration_fields/2 : + st->internal->info->duration_count; if (!(st->r_frame_rate.num && st->avg_frame_rate.num) && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (count < fps_analyze_framecount) @@ -3775,7 +3792,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } // Look at the first 3 frames if there is evidence of frame delay // but the decoder delay is not set. - if (st->info->frame_delay_evidence && count < 2 && st->internal->avctx->has_b_frames == 0) + if (st->internal->info->frame_delay_evidence && count < 2 && st->internal->avctx->has_b_frames == 0) break; if (!st->internal->avctx->extradata && (!st->internal->extract_extradata.inited || @@ -3810,7 +3827,7 @@ FF_ENABLE_DEPRECATION_WARNINGS "Probe buffer size limit of %"PRId64" bytes reached\n", probesize); for (i = 0; i < ic->nb_streams; i++) if (!ic->streams[i]->r_frame_rate.num && - ic->streams[i]->info->duration_count <= 1 && + ic->streams[i]->internal->info->duration_count <= 1 && ic->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && strcmp(ic->iformat->name, "image2")) av_log(ic, AV_LOG_WARNING, @@ -3821,7 +3838,7 @@ FF_ENABLE_DEPRECATION_WARNINGS /* NOTE: A new stream can be added there if no header in file * (AVFMTCTX_NOHEADER). */ - ret = read_frame_internal(ic, &pkt1); + ret = read_frame_internal(ic, pkt1); if (ret == AVERROR(EAGAIN)) continue; @@ -3832,15 +3849,15 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) { - ret = ff_packet_list_put(&ic->internal->packet_buffer, + ret = avpriv_packet_list_put(&ic->internal->packet_buffer, &ic->internal->packet_buffer_end, - &pkt1, 0); + pkt1, NULL, 0); if (ret < 0) goto unref_then_goto_end; pkt = &ic->internal->packet_buffer_end->pkt; } else { - pkt = &pkt1; + pkt = pkt1; } st = ic->streams[pkt->stream_index]; @@ -3857,57 +3874,59 @@ FF_ENABLE_DEPRECATION_WARNINGS if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) { /* check for non-increasing dts */ - if (st->info->fps_last_dts != AV_NOPTS_VALUE && - st->info->fps_last_dts >= pkt->dts) { + if (st->internal->info->fps_last_dts != AV_NOPTS_VALUE && + st->internal->info->fps_last_dts >= pkt->dts) { av_log(ic, AV_LOG_DEBUG, "Non-increasing DTS in stream %d: packet %d with DTS " "%"PRId64", packet %d with DTS %"PRId64"\n", - st->index, st->info->fps_last_dts_idx, - st->info->fps_last_dts, st->codec_info_nb_frames, + st->index, st->internal->info->fps_last_dts_idx, + st->internal->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts); - st->info->fps_first_dts = - st->info->fps_last_dts = AV_NOPTS_VALUE; + st->internal->info->fps_first_dts = + st->internal->info->fps_last_dts = AV_NOPTS_VALUE; } /* Check for a discontinuity in dts. If the difference in dts * is more than 1000 times the average packet duration in the * sequence, we treat it as a discontinuity. */ - if (st->info->fps_last_dts != AV_NOPTS_VALUE && - st->info->fps_last_dts_idx > st->info->fps_first_dts_idx && - (pkt->dts - (uint64_t)st->info->fps_last_dts) / 1000 > - (st->info->fps_last_dts - (uint64_t)st->info->fps_first_dts) / - (st->info->fps_last_dts_idx - st->info->fps_first_dts_idx)) { + if (st->internal->info->fps_last_dts != AV_NOPTS_VALUE && + st->internal->info->fps_last_dts_idx > st->internal->info->fps_first_dts_idx && + (pkt->dts - (uint64_t)st->internal->info->fps_last_dts) / 1000 > + (st->internal->info->fps_last_dts - (uint64_t)st->internal->info->fps_first_dts) / + (st->internal->info->fps_last_dts_idx - st->internal->info->fps_first_dts_idx)) { av_log(ic, AV_LOG_WARNING, "DTS discontinuity in stream %d: packet %d with DTS " "%"PRId64", packet %d with DTS %"PRId64"\n", - st->index, st->info->fps_last_dts_idx, - st->info->fps_last_dts, st->codec_info_nb_frames, + st->index, st->internal->info->fps_last_dts_idx, + st->internal->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts); - st->info->fps_first_dts = - st->info->fps_last_dts = AV_NOPTS_VALUE; + st->internal->info->fps_first_dts = + st->internal->info->fps_last_dts = AV_NOPTS_VALUE; } /* update stored dts values */ - if (st->info->fps_first_dts == AV_NOPTS_VALUE) { - st->info->fps_first_dts = pkt->dts; - st->info->fps_first_dts_idx = st->codec_info_nb_frames; + if (st->internal->info->fps_first_dts == AV_NOPTS_VALUE) { + st->internal->info->fps_first_dts = pkt->dts; + st->internal->info->fps_first_dts_idx = st->codec_info_nb_frames; } - st->info->fps_last_dts = pkt->dts; - st->info->fps_last_dts_idx = st->codec_info_nb_frames; + st->internal->info->fps_last_dts = pkt->dts; + st->internal->info->fps_last_dts_idx = st->codec_info_nb_frames; } if (st->codec_info_nb_frames>1) { int64_t t = 0; int64_t limit; if (st->time_base.den > 0) - t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q); + t = av_rescale_q(st->internal->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q); if (st->avg_frame_rate.num > 0) t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, av_inv_q(st->avg_frame_rate), AV_TIME_BASE_Q)); if ( t == 0 && st->codec_info_nb_frames>30 - && st->info->fps_first_dts != AV_NOPTS_VALUE - && st->info->fps_last_dts != AV_NOPTS_VALUE) - t = FFMAX(t, av_rescale_q(st->info->fps_last_dts - st->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q)); + && st->internal->info->fps_first_dts != AV_NOPTS_VALUE + && 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; @@ -3918,15 +3937,15 @@ FF_ENABLE_DEPRECATION_WARNINGS limit, t, pkt->stream_index); if (ic->flags & AVFMT_FLAG_NOBUFFER) - av_packet_unref(&pkt1); + av_packet_unref(pkt1); break; } if (pkt->duration) { if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && st->start_time != AV_NOPTS_VALUE && pkt->pts >= st->start_time) { - st->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->info->codec_info_duration + pkt->duration); + st->internal->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->internal->info->codec_info_duration + pkt->duration); } else - st->info->codec_info_duration += pkt->duration; - st->info->codec_info_duration_fields += st->parser && st->need_parsing && avctx->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2; + st->internal->info->codec_info_duration += pkt->duration; + st->internal->info->codec_info_duration_fields += st->parser && st->need_parsing && avctx->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2; } } if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { @@ -3934,10 +3953,10 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_rfps_add_frame(ic, st, pkt->dts); #endif if (pkt->dts != pkt->pts && pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE) - st->info->frame_delay_evidence = 1; + st->internal->info->frame_delay_evidence = 1; } if (!st->internal->avctx->extradata) { - ret = extract_extradata(st, pkt); + ret = extract_extradata(ic, st, pkt); if (ret < 0) goto unref_then_goto_end; } @@ -3955,7 +3974,7 @@ FF_ENABLE_DEPRECATION_WARNINGS (options && i < orig_nb_streams) ? &options[i] : NULL); if (ic->flags & AVFMT_FLAG_NOBUFFER) - av_packet_unref(&pkt1); + av_packet_unref(pkt1); st->codec_info_nb_frames++; count++; @@ -3988,18 +4007,18 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (flush_codecs) { - AVPacket empty_pkt = { 0 }; + AVPacket *empty_pkt = ic->internal->pkt; int err = 0; - av_init_packet(&empty_pkt); + av_packet_unref(empty_pkt); for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; /* flush the decoders */ - if (st->info->found_decoder == 1) { + if (st->internal->info->found_decoder == 1) { do { - err = try_decode_frame(ic, st, &empty_pkt, + err = try_decode_frame(ic, st, empty_pkt, (options && i < orig_nb_streams) ? &options[i] : NULL); } while (err > 0 && !has_codec_parameters(st, NULL)); @@ -4025,20 +4044,20 @@ FF_ENABLE_DEPRECATION_WARNINGS } /* estimate average framerate if not set by demuxer */ - if (st->info->codec_info_duration_fields && + if (st->internal->info->codec_info_duration_fields && !st->avg_frame_rate.num && - st->info->codec_info_duration) { + st->internal->info->codec_info_duration) { int best_fps = 0; double best_error = 0.01; AVRational codec_frame_rate = avctx->framerate; - if (st->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| - st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den || - st->info->codec_info_duration < 0) + if (st->internal->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| + st->internal->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den || + st->internal->info->codec_info_duration < 0) continue; av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - st->info->codec_info_duration_fields * (int64_t) st->time_base.den, - st->info->codec_info_duration * 2 * (int64_t) st->time_base.num, 60000); + st->internal->info->codec_info_duration_fields * (int64_t) st->time_base.den, + st->internal->info->codec_info_duration * 2 * (int64_t) st->time_base.num, 60000); /* Round guessed framerate to a "standard" framerate if it's * within 1% of the original estimate. */ @@ -4076,9 +4095,9 @@ FF_ENABLE_DEPRECATION_WARNINGS st->r_frame_rate.den = st->time_base.num; } } - if (st->display_aspect_ratio.num && st->display_aspect_ratio.den) { + if (st->internal->display_aspect_ratio.num && st->internal->display_aspect_ratio.den) { AVRational hw_ratio = { avctx->height, avctx->width }; - st->sample_aspect_ratio = av_mul_q(st->display_aspect_ratio, + st->sample_aspect_ratio = av_mul_q(st->internal->display_aspect_ratio, hw_ratio); } } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -4132,35 +4151,28 @@ FF_ENABLE_DEPRECATION_WARNINGS avcodec_string(buf, sizeof(buf), st->internal->avctx, 0); av_log(ic, AV_LOG_WARNING, "Could not find codec parameters for stream %d (%s): %s\n" - "Consider increasing the value for the 'analyzeduration' and 'probesize' options\n", - i, buf, errmsg); + "Consider increasing the value for the 'analyzeduration' (%"PRId64") and 'probesize' (%"PRId64") options\n", + i, buf, errmsg, ic->max_analyze_duration, ic->probesize); } else { ret = 0; } } - 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 @@ -4169,7 +4181,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) { @@ -4177,7 +4188,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; @@ -4207,12 +4217,11 @@ FF_ENABLE_DEPRECATION_WARNINGS find_stream_info_err: for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; - if (st->info) - av_freep(&st->info->duration_error); + if (st->internal->info) + av_freep(&st->internal->info->duration_error); avcodec_close(ic->streams[i]->internal->avctx); - av_freep(&ic->streams[i]->info); + av_freep(&ic->streams[i]->internal->info); av_bsf_free(&ic->streams[i]->internal->extract_extradata.bsf); - av_packet_free(&ic->streams[i]->internal->extract_extradata.pkt); } if (ic->pb) av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n", @@ -4220,7 +4229,7 @@ find_stream_info_err: return ret; unref_then_goto_end: - av_packet_unref(&pkt1); + av_packet_unref(pkt1); goto find_stream_info_err; } @@ -4373,18 +4382,6 @@ int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src) } } -#if FF_API_LAVF_FFSERVER -FF_DISABLE_DEPRECATION_WARNINGS - av_freep(&dst->recommended_encoder_configuration); - if (src->recommended_encoder_configuration) { - const char *conf_str = src->recommended_encoder_configuration; - dst->recommended_encoder_configuration = av_strdup(conf_str); - if (!dst->recommended_encoder_configuration) - return AVERROR(ENOMEM); - } -FF_ENABLE_DEPRECATION_WARNINGS -#endif - return 0; } @@ -4408,34 +4405,27 @@ static void free_stream(AVStream **pst) if (st->internal) { avcodec_free_context(&st->internal->avctx); - for (i = 0; i < st->internal->nb_bsfcs; i++) { - av_bsf_free(&st->internal->bsfcs[i]); - av_freep(&st->internal->bsfcs); - } + 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); + + if (st->internal->info) + av_freep(&st->internal->info->duration_error); + av_freep(&st->internal->info); } av_freep(&st->internal); 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); FF_ENABLE_DEPRECATION_WARNINGS #endif av_freep(&st->priv_data); - if (st->info) - av_freep(&st->info->duration_error); - av_freep(&st->info); -#if FF_API_LAVF_FFSERVER -FF_DISABLE_DEPRECATION_WARNINGS - av_freep(&st->recommended_encoder_configuration); -FF_ENABLE_DEPRECATION_WARNINGS -#endif av_freep(pst); } @@ -4484,6 +4474,8 @@ void avformat_free_context(AVFormatContext *s) av_freep(&s->chapters); av_dict_free(&s->metadata); av_dict_free(&s->internal->id3v2_meta); + av_packet_free(&s->internal->pkt); + av_packet_free(&s->internal->parse_pkt); av_freep(&s->streams); flush_packet_queue(s); av_freep(&s->internal); @@ -4525,9 +4517,10 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) int i; AVStream **streams; - if (s->nb_streams >= FFMIN(s->max_streams, INT_MAX/sizeof(*streams))) { - if (s->max_streams < INT_MAX/sizeof(*streams)) - av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter (%d), see the documentation if you wish to increase it\n", s->max_streams); + if (s->nb_streams >= s->max_streams) { + av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter" + " (%d), see the documentation if you wish to increase it\n", + s->max_streams); return NULL; } streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams)); @@ -4538,17 +4531,11 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) st = av_mallocz(sizeof(AVStream)); if (!st) return NULL; - if (!(st->info = av_mallocz(sizeof(*st->info)))) { - av_free(st); - return NULL; - } - st->info->last_dts = AV_NOPTS_VALUE; #if FF_API_LAVF_AVCTX FF_DISABLE_DEPRECATION_WARNINGS st->codec = avcodec_alloc_context3(c); if (!st->codec) { - av_free(st->info); av_free(st); return NULL; } @@ -4559,6 +4546,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!st->internal) goto fail; + st->internal->info = av_mallocz(sizeof(*st->internal->info)); + if (!st->internal->info) + goto fail; + st->internal->info->last_dts = AV_NOPTS_VALUE; + st->codecpar = avcodec_parameters_alloc(); if (!st->codecpar) goto fail; @@ -4591,23 +4583,23 @@ FF_ENABLE_DEPRECATION_WARNINGS st->duration = AV_NOPTS_VALUE; st->first_dts = AV_NOPTS_VALUE; st->probe_packets = s->max_probe_packets; - st->pts_wrap_reference = AV_NOPTS_VALUE; - st->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; + st->internal->pts_wrap_reference = AV_NOPTS_VALUE; + st->internal->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; st->last_IP_pts = AV_NOPTS_VALUE; - st->last_dts_for_order_check = 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 }; #if FF_API_R_FRAME_RATE - st->info->last_dts = AV_NOPTS_VALUE; + st->internal->info->last_dts = AV_NOPTS_VALUE; #endif - st->info->fps_first_dts = AV_NOPTS_VALUE; - st->info->fps_last_dts = AV_NOPTS_VALUE; + st->internal->info->fps_first_dts = AV_NOPTS_VALUE; + st->internal->info->fps_last_dts = AV_NOPTS_VALUE; - st->inject_global_side_data = s->internal->inject_global_side_data; + st->internal->inject_global_side_data = s->internal->inject_global_side_data; st->internal->need_context_update = 1; @@ -4621,7 +4613,7 @@ fail: AVProgram *av_new_program(AVFormatContext *ac, int id) { AVProgram *program = NULL; - int i; + int i, ret; av_log(ac, AV_LOG_TRACE, "new_program: id=0x%04x\n", id); @@ -4633,40 +4625,55 @@ AVProgram *av_new_program(AVFormatContext *ac, int id) program = av_mallocz(sizeof(AVProgram)); if (!program) return NULL; - dynarray_add(&ac->programs, &ac->nb_programs, program); + ret = av_dynarray_add_nofree(&ac->programs, &ac->nb_programs, program); + if (ret < 0) { + av_free(program); + return NULL; + } 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; } +#if FF_API_CHAPTER_ID_INT AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, +#else +AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, +#endif int64_t start, int64_t end, const char *title) { AVChapter *chapter = NULL; - int i; + int i, ret; if (end != AV_NOPTS_VALUE && start > end) { av_log(s, AV_LOG_ERROR, "Chapter end time %"PRId64" before start %"PRId64"\n", end, start); 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)); if (!chapter) return NULL; - dynarray_add(&s->chapters, &s->nb_chapters, chapter); + ret = av_dynarray_add_nofree(&s->chapters, &s->nb_chapters, chapter); + if (ret < 0) { + av_free(chapter); + return NULL; + } } av_dict_set(&chapter->metadata, "title", title, 0); chapter->id = id; @@ -4732,6 +4739,15 @@ uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us) return ntp_ts; } +uint64_t ff_parse_ntp_time(uint64_t ntp_ts) +{ + uint64_t sec = ntp_ts >> 32; + uint64_t frac_part = ntp_ts & 0xFFFFFFFFULL; + uint64_t usec = (frac_part * 1000000) / 0xFFFFFFFFULL; + + return (sec * 1000000) + usec; +} + int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags) { const char *p; @@ -4748,8 +4764,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)); @@ -5499,7 +5518,7 @@ int ff_generate_avci_extradata(AVStream *st) } uint8_t *av_stream_get_side_data(const AVStream *st, - enum AVPacketSideDataType type, int *size) + enum AVPacketSideDataType type, buffer_size_t *size) { int i; @@ -5510,6 +5529,8 @@ uint8_t *av_stream_get_side_data(const AVStream *st, return st->side_data[i].data; } } + if (size) + *size = 0; return NULL; } @@ -5550,7 +5571,7 @@ int av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type, } uint8_t *av_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type, - int size) + buffer_size_t size) { int ret; uint8_t *data = av_malloc(size); @@ -5572,7 +5593,8 @@ int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *a int ret; const AVBitStreamFilter *bsf; AVBSFContext *bsfc; - AVCodecParameters *in_par; + + av_assert0(!st->internal->bsfc); if (!(bsf = av_bsf_get_by_name(name))) { av_log(NULL, AV_LOG_ERROR, "Unknown bitstream filter '%s'\n", name); @@ -5582,15 +5604,8 @@ int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *a if ((ret = av_bsf_alloc(bsf, &bsfc)) < 0) return ret; - if (st->internal->nb_bsfcs) { - in_par = st->internal->bsfcs[st->internal->nb_bsfcs - 1]->par_out; - bsfc->time_base_in = st->internal->bsfcs[st->internal->nb_bsfcs - 1]->time_base_out; - } else { - in_par = st->codecpar; - bsfc->time_base_in = st->time_base; - } - - if ((ret = avcodec_parameters_copy(bsfc->par_in, in_par)) < 0) { + bsfc->time_base_in = st->time_base; + if ((ret = avcodec_parameters_copy(bsfc->par_in, st->codecpar)) < 0) { av_bsf_free(&bsfc); return ret; } @@ -5613,10 +5628,7 @@ int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *a return ret; } - if ((ret = av_dynarray_add_nofree(&st->internal->bsfcs, &st->internal->nb_bsfcs, bsfc))) { - av_bsf_free(&bsfc); - return ret; - } + st->internal->bsfc = bsfc; av_log(NULL, AV_LOG_VERBOSE, "Automatically inserted bitstream filter '%s'; args='%s'\n", @@ -5624,64 +5636,6 @@ int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *a return 1; } -#if FF_API_OLD_BSF -FF_DISABLE_DEPRECATION_WARNINGS -int av_apply_bitstream_filters(AVCodecContext *codec, AVPacket *pkt, - AVBitStreamFilterContext *bsfc) -{ - int ret = 0; - while (bsfc) { - AVPacket new_pkt = *pkt; - int a = av_bitstream_filter_filter(bsfc, codec, NULL, - &new_pkt.data, &new_pkt.size, - pkt->data, pkt->size, - pkt->flags & AV_PKT_FLAG_KEY); - if (a == 0 && new_pkt.size == 0 && new_pkt.side_data_elems == 0) { - av_packet_unref(pkt); - memset(pkt, 0, sizeof(*pkt)); - return 0; - } - if(a == 0 && new_pkt.data != pkt->data) { - uint8_t *t = av_malloc(new_pkt.size + AV_INPUT_BUFFER_PADDING_SIZE); //the new should be a subset of the old so cannot overflow - if (t) { - memcpy(t, new_pkt.data, new_pkt.size); - memset(t + new_pkt.size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - new_pkt.data = t; - new_pkt.buf = NULL; - a = 1; - } else { - a = AVERROR(ENOMEM); - } - } - if (a > 0) { - new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size, - av_buffer_default_free, NULL, 0); - if (new_pkt.buf) { - pkt->side_data = NULL; - pkt->side_data_elems = 0; - av_packet_unref(pkt); - } else { - av_freep(&new_pkt.data); - a = AVERROR(ENOMEM); - } - } - if (a < 0) { - av_log(codec, AV_LOG_ERROR, - "Failed to open bitstream filter %s for stream %d with codec %s", - bsfc->filter->name, pkt->stream_index, - codec->codec ? codec->codec->name : "copy"); - ret = a; - break; - } - *pkt = new_pkt; - - bsfc = bsfc->next; - } - return ret; -} -FF_ENABLE_DEPRECATION_WARNINGS -#endif - int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options) { if (!s->oformat) @@ -5733,7 +5687,7 @@ int ff_standardize_creation_time(AVFormatContext *s) int ff_get_packet_palette(AVFormatContext *s, AVPacket *pkt, int ret, uint32_t *palette) { uint8_t *side_data; - int size; + buffer_size_t size; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_PALETTE, &size); if (side_data) { @@ -5783,8 +5737,18 @@ int avformat_transfer_internal_stream_timing_info(const AVOutputFormat *ofmt, enum AVTimebaseSource copy_tb) { //TODO: use [io]st->internal->avctx - const AVCodecContext *dec_ctx = ist->codec; - AVCodecContext *enc_ctx = ost->codec; + const AVCodecContext *dec_ctx; + AVCodecContext *enc_ctx; + +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS + dec_ctx = ist->codec; + enc_ctx = ost->codec; +FF_ENABLE_DEPRECATION_WARNINGS +#else + dec_ctx = ist->internal->avctx; + enc_ctx = ost->internal->avctx; +#endif enc_ctx->time_base = ist->time_base; /* @@ -5831,9 +5795,6 @@ int avformat_transfer_internal_stream_timing_info(const AVOutputFormat *ofmt, enc_ctx->time_base = dec_ctx->time_base; } - if (ost->avg_frame_rate.num) - enc_ctx->time_base = av_inv_q(ost->avg_frame_rate); - av_reduce(&enc_ctx->time_base.num, &enc_ctx->time_base.den, enc_ctx->time_base.num, enc_ctx->time_base.den, INT_MAX);