X-Git-Url: https://git.piment-noir.org/?p=deb_ffmpeg.git;a=blobdiff_plain;f=ffmpeg%2Flibavformat%2Futils.c;h=798c6123e0cfcf70ec4949dfea58df795972ab60;hp=e899e4d071b62a242303c4d7bf2b1188bf7794fd;hb=f6fa7814ccfe3e76514b36cf04f5cd3cb657c8cf;hpb=2ba45a602cbfa7b771effba9b11bb4245c21bc00 diff --git a/ffmpeg/libavformat/utils.c b/ffmpeg/libavformat/utils.c index e899e4d..798c612 100644 --- a/ffmpeg/libavformat/utils.c +++ b/ffmpeg/libavformat/utils.c @@ -103,6 +103,7 @@ static int64_t wrap_timestamp(AVStream *st, int64_t timestamp) } MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate) +MAKE_ACCESSORS(AVStream, stream, char *, recommended_encoder_configuration) MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec) MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec) MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec) @@ -130,6 +131,19 @@ void av_format_inject_global_side_data(AVFormatContext *s) } } +int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src) +{ + av_assert0(!dst->codec_whitelist && !dst->format_whitelist); + dst-> codec_whitelist = av_strdup(src->codec_whitelist); + dst->format_whitelist = av_strdup(src->format_whitelist); + if ( (src-> codec_whitelist && !dst-> codec_whitelist) + || (src->format_whitelist && !dst->format_whitelist)) { + av_log(dst, AV_LOG_ERROR, "Failed to duplicate whitelist\n"); + return AVERROR(ENOMEM); + } + return 0; +} + static const AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id) { if (st->codec->codec) @@ -291,6 +305,11 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, int av_demuxer_open(AVFormatContext *ic) { int err; + if (ic->format_whitelist && av_match_list(ic->iformat->name, ic->format_whitelist, ',') <= 0) { + av_log(ic, AV_LOG_ERROR, "Format not on whitelist\n"); + return AVERROR(EINVAL); + } + if (ic->iformat->read_header) { err = ic->iformat->read_header(ic); if (err < 0) @@ -402,6 +421,13 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, if ((ret = init_input(s, filename, &tmp)) < 0) goto fail; s->probe_score = ret; + + if (s->format_whitelist && av_match_list(s->iformat->name, s->format_whitelist, ',') <= 0) { + av_log(s, AV_LOG_ERROR, "Format not on whitelist\n"); + ret = AVERROR(EINVAL); + goto fail; + } + avio_skip(s->pb, s->skip_initial_bytes); /* Check filename in case an image number is expected. */ @@ -691,13 +717,6 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) } } -#if FF_API_READ_PACKET -int av_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - return ff_read_packet(s, pkt); -} -#endif - /**********************************************************/ @@ -715,9 +734,11 @@ static int determinable_frame_size(AVCodecContext *avctx) /** * Return the frame duration in seconds. Return 0 if not available. */ -void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, +void ff_compute_frame_duration(AVFormatContext *s, int *pnum, int *pden, AVStream *st, AVCodecParserContext *pc, AVPacket *pkt) { + AVRational codec_framerate = s->iformat ? st->codec->framerate : + av_mul_q(av_inv_q(st->codec->time_base), (AVRational){1, st->codec->ticks_per_frame}); int frame_size; *pnum = 0; @@ -730,14 +751,19 @@ void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, } else if (st->time_base.num * 1000LL > st->time_base.den) { *pnum = st->time_base.num; *pden = st->time_base.den; - } else if (st->codec->time_base.num * 1000LL > st->codec->time_base.den) { - *pnum = st->codec->time_base.num; - *pden = st->codec->time_base.den; + } else if (codec_framerate.den * 1000LL > codec_framerate.num) { + av_assert0(st->codec->ticks_per_frame); + av_reduce(pnum, pden, + codec_framerate.den, + codec_framerate.num * (int64_t)st->codec->ticks_per_frame, + INT_MAX); + if (pc && pc->repeat_pict) { - if (*pnum > INT_MAX / (1 + pc->repeat_pict)) - *pden /= 1 + pc->repeat_pict; - else - *pnum *= 1 + pc->repeat_pict; + av_assert0(s->iformat); // this may be wrong for interlaced encoding but its not used for that case + av_reduce(pnum, pden, + (*pnum) * (1LL + pc->repeat_pict), + (*pden), + INT_MAX); } /* If this codec can be interlaced or progressive then we need * a parser to compute duration of a packet. Thus if we have @@ -1022,7 +1048,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, duration = av_mul_q((AVRational) {pkt->duration, 1}, st->time_base); if (pkt->duration == 0) { - ff_compute_frame_duration(&num, &den, st, pc, pkt); + ff_compute_frame_duration(s, &num, &den, st, pc, pkt); if (den && num) { duration = (AVRational) {num, den}; pkt->duration = av_rescale_rnd(1, @@ -1053,9 +1079,9 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, presentation_delayed = 1; av_dlog(NULL, - "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%d\n", + "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%d delay:%d onein_oneout:%d\n", presentation_delayed, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), - pkt->stream_index, pc, pkt->duration); + pkt->stream_index, pc, pkt->duration, delay, onein_oneout); /* Interpolate PTS and DTS if they are not present. We skip H264 * currently because delay and has_b_frames are not reliably set. */ if ((delay == 0 || (delay == 1 && pc)) && @@ -1255,6 +1281,11 @@ static int read_from_packet_buffer(AVPacketList **pkt_buffer, return 0; } +static int64_t ts_to_samples(AVStream *st, int64_t ts) +{ + return av_rescale(ts, st->time_base.num * st->codec->sample_rate, st->time_base.den); +} + static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) { int ret = 0, i, got_packet = 0; @@ -1352,10 +1383,21 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) if (ret >= 0) { AVStream *st = s->streams[pkt->stream_index]; - if (st->skip_samples) { + int discard_padding = 0; + if (st->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 (st->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 + 4, discard_padding); av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d\n", st->skip_samples); } st->skip_samples = 0; @@ -2365,7 +2407,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) (st->start_time != AV_NOPTS_VALUE || st->first_dts != AV_NOPTS_VALUE)) { if (pkt->duration == 0) { - ff_compute_frame_duration(&num, &den, st, st->parser, pkt); + ff_compute_frame_duration(ic, &num, &den, st, st->parser, pkt); if (den && num) { pkt->duration = av_rescale_rnd(1, num * (int64_t) st->time_base.den, @@ -2560,6 +2602,8 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt, /* 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); + if (s->codec_whitelist) + av_dict_set(options ? options : &thread_opt, "codec_whitelist", s->codec_whitelist, 0); ret = avcodec_open2(st->codec, codec, options ? options : &thread_opt); if (!options) av_dict_free(&thread_opt); @@ -2743,10 +2787,16 @@ static void compute_chapters_end(AVFormatContext *s) static int get_std_framerate(int i) { - if (i < 60 * 12) + if (i < 30*12) return (i + 1) * 1001; - else - return ((const int[]) { 24, 30, 60, 12, 15, 48 })[i - 60 * 12] * 1000 * 12; + i -= 30*12; + + if (i < 7) + return ((const int[]) { 40, 48, 50, 60, 80, 120, 240})[i] * 1001 * 12; + + i -= 7; + + return ((const int[]) { 24, 30, 60, 12, 15, 48 })[i] * 1000 * 12; } /* Is the time base unreliable? @@ -2769,13 +2819,6 @@ static int tb_unreliable(AVCodecContext *c) return 0; } -#if FF_API_FORMAT_PARAMETERS -int av_find_stream_info(AVFormatContext *ic) -{ - return avformat_find_stream_info(ic, NULL); -} -#endif - int ff_alloc_extradata(AVCodecContext *avctx, int size) { int ret; @@ -2946,6 +2989,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) int orig_nb_streams = ic->nb_streams; int flush_codecs; int64_t max_analyze_duration = ic->max_analyze_duration2; + int64_t max_stream_analyze_duration; int64_t probesize = ic->probesize2; if (!max_analyze_duration) @@ -2956,11 +3000,12 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN); + max_stream_analyze_duration = max_analyze_duration; if (!max_analyze_duration) { - if (!strcmp(ic->iformat->name, "flv") && !(ic->ctx_flags & AVFMTCTX_NOHEADER)) { - max_analyze_duration = 10*AV_TIME_BASE; - } else - max_analyze_duration = 5*AV_TIME_BASE; + max_stream_analyze_duration = + max_analyze_duration = 5*AV_TIME_BASE; + if (!strcmp(ic->iformat->name, "flv")) + max_stream_analyze_duration = 30*AV_TIME_BASE; } if (ic->pb) @@ -3000,6 +3045,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) * SPS and PPS to extradata during multi-threaded decoding. */ av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 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->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && codec && !st->codec->codec) { @@ -3030,6 +3078,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) count = 0; read_size = 0; for (;;) { + int analyzed_all_streams; if (ff_check_interrupt(&ic->interrupt_callback)) { ret = AVERROR_EXIT; av_log(ic, AV_LOG_DEBUG, "interrupted\n"); @@ -3069,7 +3118,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) st->codec->codec_type == AVMEDIA_TYPE_AUDIO)) break; } + analyzed_all_streams = 0; if (i == ic->nb_streams) { + analyzed_all_streams = 1; /* NOTE: If the format has no header, then we need to read some * packets to get most of the streams, so we cannot stop here. */ if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) { @@ -3177,10 +3228,12 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) && 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)); - if (t >= max_analyze_duration) { + if (t >= (analyzed_all_streams ? max_analyze_duration : max_stream_analyze_duration)) { av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds\n", max_analyze_duration, t); + if (ic->flags & AVFMT_FLAG_NOBUFFER) + av_packet_unref(pkt); break; } if (pkt->duration) { @@ -3214,6 +3267,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) try_decode_frame(ic, st, pkt, (options && i < orig_nb_streams) ? &options[i] : NULL); + if (ic->flags & AVFMT_FLAG_NOBUFFER) + av_packet_unref(pkt); + st->codec_info_nb_frames++; count++; } @@ -3242,7 +3298,6 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) } } } - av_opt_set(ic, "skip_clear", "0", AV_OPT_SEARCH_CHILDREN); // close codecs which were opened in try_decode_frame() for (i = 0; i < ic->nb_streams; i++) { @@ -3303,6 +3358,11 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) st->r_frame_rate.den = st->time_base.num; } } + if (st->display_aspect_ratio.num && st->display_aspect_ratio.den) { + AVRational hw_ratio = { st->codec->height, st->codec->width }; + st->sample_aspect_ratio = av_mul_q(st->display_aspect_ratio, + hw_ratio); + } } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { if (!st->codec->bits_per_coded_sample) st->codec->bits_per_coded_sample = @@ -3331,6 +3391,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) if (probesize) estimate_timings(ic, old_offset); + av_opt_set(ic, "skip_clear", "0", AV_OPT_SEARCH_CHILDREN); + if (ret >= 0 && ic->nb_streams) /* We could not have all the codec parameters before EOF. */ ret = -1; @@ -3492,6 +3554,7 @@ void ff_free_stream(AVFormatContext *s, AVStream *st) { if (st->info) av_freep(&st->info->duration_error); av_freep(&st->info); + av_freep(&st->recommended_encoder_configuration); av_freep(&s->streams[ --s->nb_streams ]); } @@ -3530,13 +3593,6 @@ void avformat_free_context(AVFormatContext *s) av_free(s); } -#if FF_API_CLOSE_INPUT_FILE -void av_close_input_file(AVFormatContext *s) -{ - avformat_close_input(&s); -} -#endif - void avformat_close_input(AVFormatContext **ps) { AVFormatContext *s; @@ -3565,16 +3621,6 @@ void avformat_close_input(AVFormatContext **ps) avio_close(pb); } -#if FF_API_NEW_STREAM -AVStream *av_new_stream(AVFormatContext *s, int id) -{ - AVStream *st = avformat_new_stream(s, NULL); - if (st) - st->id = id; - return st; -} -#endif - AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) { AVStream *st; @@ -3902,14 +3948,6 @@ int ff_hex_to_data(uint8_t *data, const char *p) return len; } -#if FF_API_SET_PTS_INFO -void av_set_pts_info(AVStream *s, int pts_wrap_bits, - unsigned int pts_num, unsigned int pts_den) -{ - avpriv_set_pts_info(s, pts_wrap_bits, pts_num, pts_den); -} -#endif - void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den) { @@ -4115,7 +4153,7 @@ AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *strea AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame) { AVRational fr = st->r_frame_rate; - AVRational codec_fr = av_inv_q(st->codec->time_base); + AVRational codec_fr = st->codec->framerate; AVRational avg_fr = st->avg_frame_rate; if (avg_fr.num > 0 && avg_fr.den > 0 && fr.num > 0 && fr.den > 0 && @@ -4125,7 +4163,6 @@ AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *f if (st->codec->ticks_per_frame > 1) { - codec_fr.den *= st->codec->ticks_per_frame; if ( codec_fr.num > 0 && codec_fr.den > 0 && av_q2d(codec_fr) < av_q2d(fr)*0.7 && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1) fr = codec_fr; @@ -4254,6 +4291,21 @@ int ff_generate_avci_extradata(AVStream *st) 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48, 0xd0 }; + static const uint8_t avci50_1080p_extradata[] = { + // SPS + 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28, + 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18, + 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c, + 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37, + 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde, + 0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e, + 0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04, + 0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00, + // PPS + 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12, + 0x11 + }; static const uint8_t avci50_1080i_extradata[] = { // SPS 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28, @@ -4287,6 +4339,21 @@ int ff_generate_avci_extradata(AVStream *st) 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12, 0x11 }; + static const uint8_t avci50_720p_extradata[] = { + // SPS + 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20, + 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18, + 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c, + 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37, + 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde, + 0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff, + 0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40, + 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, + 0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + // PPS + 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12, + 0x11 + }; const uint8_t *data = NULL; int size = 0; @@ -4300,11 +4367,19 @@ int ff_generate_avci_extradata(AVStream *st) size = sizeof(avci100_1080i_extradata); } } else if (st->codec->width == 1440) { - data = avci50_1080i_extradata; - size = sizeof(avci50_1080i_extradata); + if (st->codec->field_order == AV_FIELD_PROGRESSIVE) { + data = avci50_1080p_extradata; + size = sizeof(avci50_1080p_extradata); + } else { + data = avci50_1080i_extradata; + size = sizeof(avci50_1080i_extradata); + } } else if (st->codec->width == 1280) { data = avci100_720p_extradata; size = sizeof(avci100_720p_extradata); + } else if (st->codec->width == 960) { + data = avci50_720p_extradata; + size = sizeof(avci50_720p_extradata); } if (!size)