X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Futils.c;h=26fb0b9da84771483a0ef72c95c33e694234103b;hb=6ea1196673b769d65b378822566e639d0d5497b7;hp=25736f9ab4b73313b8c27a837a70f23e053effc6;hpb=b6c1e80bf4a931bd05d799684842fb3503fff93e;p=ffmpeg diff --git a/libavformat/utils.c b/libavformat/utils.c index 25736f9ab4b..26fb0b9da84 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -110,6 +110,16 @@ 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) +void av_format_inject_global_side_data(AVFormatContext *s) +{ + int i; + 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; + } +} + static AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id) { if (st->codec->codec) @@ -564,7 +574,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */ if (s->pb) - ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); + ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, 0); if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header) if ((ret = s->iformat->read_header(s)) < 0) @@ -1350,12 +1360,6 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) st->time_base, AV_ROUND_DOWN); } - } else if (st->codec->time_base.num != 0 && - st->codec->time_base.den != 0) { - out_pkt.duration = av_rescale_q_rnd(st->parser->duration, - st->codec->time_base, - st->time_base, - AV_ROUND_DOWN); } out_pkt.stream_index = st->index; @@ -1526,10 +1530,29 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) } st->skip_samples = 0; } - } - if (ret >= 0 && !(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA)) - av_packet_merge_side_data(pkt); + if (st->inject_global_side_data) { + for (i = 0; i < st->nb_side_data; i++) { + AVPacketSideData *src_sd = &st->side_data[i]; + uint8_t *dst_data; + + if (av_packet_get_side_data(pkt, src_sd->type, NULL)) + continue; + + dst_data = av_packet_new_side_data(pkt, src_sd->type, src_sd->size); + if (!dst_data) { + av_log(s, AV_LOG_WARNING, "Could not inject global side data\n"); + continue; + } + + memcpy(dst_data, src_sd->data, src_sd->size); + } + st->inject_global_side_data = 0; + } + + if (!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA)) + av_packet_merge_side_data(pkt); + } if (s->debug & FF_FDEBUG_TS) av_log(s, AV_LOG_DEBUG, @@ -1697,6 +1720,9 @@ void ff_read_frame_flush(AVFormatContext *s) for (j = 0; j < MAX_REORDER_DELAY + 1; j++) st->pts_buffer[j] = AV_NOPTS_VALUE; + + if (s->internal->inject_global_side_data) + st->inject_global_side_data = 1; } } @@ -2623,13 +2649,15 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt, if (!frame) return AVERROR(ENOMEM); - if (!avcodec_is_open(st->codec) && !st->info->found_decoder) { + if (!avcodec_is_open(st->codec) && + st->info->found_decoder <= 0 && + (st->codec->codec_id != -st->info->found_decoder || !st->codec->codec_id)) { AVDictionary *thread_opt = NULL; codec = find_decoder(s, st, st->codec->codec_id); if (!codec) { - st->info->found_decoder = -1; + st->info->found_decoder = -st->codec->codec_id; ret = -1; goto fail; } @@ -2641,7 +2669,7 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt, if (!options) av_dict_free(&thread_opt); if (ret < 0) { - st->info->found_decoder = -1; + st->info->found_decoder = -st->codec->codec_id; goto fail; } st->info->found_decoder = 1; @@ -2840,6 +2868,7 @@ static int tb_unreliable(AVCodecContext *c) // c->codec_tag == AV_RL32("XVID") || c->codec_tag == AV_RL32("mp4v") || c->codec_id == AV_CODEC_ID_MPEG2VIDEO || + c->codec_id == AV_CODEC_ID_GIF || c->codec_id == AV_CODEC_ID_H264) return 1; return 0; @@ -2964,6 +2993,7 @@ void ff_rfps_calculate(AVFormatContext *ic) && tb_unreliable(st->codec)) { int num = 0; double best_error= 0.01; + AVRational ref_rate = st->r_frame_rate.num ? st->r_frame_rate : av_inv_q(st->time_base); for (j= 0; jr_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate))) + if (num && (!ref_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(ref_rate))) 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 + ) { + 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; @@ -3097,13 +3136,14 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) * the correct fps. */ if (av_q2d(st->time_base) > 0.0005) fps_analyze_framecount *= 2; + if (!tb_unreliable(st->codec)) + fps_analyze_framecount = 0; if (ic->fps_probe_size >= 0) fps_analyze_framecount = ic->fps_probe_size; if (st->disposition & AV_DISPOSITION_ATTACHED_PIC) fps_analyze_framecount = 0; /* variable fps and no guess at the real fps */ - if (tb_unreliable(st->codec) && - !(st->r_frame_rate.num && st->avg_frame_rate.num) && + if (!(st->r_frame_rate.num && st->avg_frame_rate.num) && st->info->duration_count < fps_analyze_framecount && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) break; @@ -3669,6 +3709,8 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) st->info->fps_first_dts = AV_NOPTS_VALUE; st->info->fps_last_dts = AV_NOPTS_VALUE; + st->inject_global_side_data = s->internal->inject_global_side_data; + s->streams[s->nb_streams++] = st; return st; }