From: Clément Bœsch <clem...@stupeflix.com> In lavf we have access to st->internal->avctx so it's a better place than in ffmpeg*.c and will allow moving to codecpar.
TODO: avformat.h doxy TODO: version.h minor bump TODO: doc/APIchanges update --- ffmpeg.c | 51 +++----------------------------------------- libavformat/avformat.h | 12 +++++++++++ libavformat/utils.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 48 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index d858407..5c487c3 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2909,57 +2909,12 @@ static int transcode_init(void) enc_ctx->bits_per_coded_sample = dec_ctx->bits_per_coded_sample; enc_ctx->bits_per_raw_sample = dec_ctx->bits_per_raw_sample; - enc_ctx->time_base = ist->st->time_base; - /* - * Avi is a special case here because it supports variable fps but - * having the fps and timebase differe significantly adds quite some - * overhead - */ - if(!strcmp(oc->oformat->name, "avi")) { - if ( copy_tb<0 && ist->st->r_frame_rate.num - && av_q2d(ist->st->r_frame_rate) >= av_q2d(ist->st->avg_frame_rate) - && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(ist->st->time_base) - && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(dec_ctx->time_base) - && av_q2d(ist->st->time_base) < 1.0/500 && av_q2d(dec_ctx->time_base) < 1.0/500 - || copy_tb==2){ - enc_ctx->time_base.num = ist->st->r_frame_rate.den; - enc_ctx->time_base.den = 2*ist->st->r_frame_rate.num; - enc_ctx->ticks_per_frame = 2; - } else if ( copy_tb<0 && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > 2*av_q2d(ist->st->time_base) - && av_q2d(ist->st->time_base) < 1.0/500 - || copy_tb==0){ - enc_ctx->time_base = dec_ctx->time_base; - enc_ctx->time_base.num *= dec_ctx->ticks_per_frame; - enc_ctx->time_base.den *= 2; - enc_ctx->ticks_per_frame = 2; - } - } else if(!(oc->oformat->flags & AVFMT_VARIABLE_FPS) - && strcmp(oc->oformat->name, "mov") && strcmp(oc->oformat->name, "mp4") && strcmp(oc->oformat->name, "3gp") - && strcmp(oc->oformat->name, "3g2") && strcmp(oc->oformat->name, "psp") && strcmp(oc->oformat->name, "ipod") - && strcmp(oc->oformat->name, "f4v") - ) { - if( copy_tb<0 && dec_ctx->time_base.den - && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > av_q2d(ist->st->time_base) - && av_q2d(ist->st->time_base) < 1.0/500 - || copy_tb==0){ - enc_ctx->time_base = dec_ctx->time_base; - enc_ctx->time_base.num *= dec_ctx->ticks_per_frame; - } - } - if ( enc_ctx->codec_tag == AV_RL32("tmcd") - && dec_ctx->time_base.num < dec_ctx->time_base.den - && dec_ctx->time_base.num > 0 - && 121LL*dec_ctx->time_base.num > dec_ctx->time_base.den) { - enc_ctx->time_base = dec_ctx->time_base; - } + ret = avformat_transfer_stream_timing_info(oc->oformat, ost->st, ist->st, copy_tb); + if (ret < 0) + return ret; if (!ost->frame_rate.num) ost->frame_rate = ist->framerate; - if(ost->frame_rate.num) - enc_ctx->time_base = av_inv_q(ost->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); if (ist->st->nb_side_data) { ost->st->side_data = av_realloc_array(NULL, ist->st->nb_side_data, diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 3ee7051..766e9b3 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -2893,6 +2893,18 @@ int av_apply_bitstream_filters(AVCodecContext *codec, AVPacket *pkt, AVBitStreamFilterContext *bsfc); #endif +enum AVTimebaseCopyFrom { + AVFMT_TBCF_AUTO = -1, + AVFMT_TBCF_DECODER, + AVFMT_TBCF_DEMUXER, + AVFMT_TBCF_R_FRAMERATE, +}; + +// TODO: doc +int avformat_transfer_stream_timing_info(const AVOutputFormat *ofmt, + AVStream *ost, const AVStream *ist, + enum AVTimebaseCopyFrom copy_tb); + /** * @} */ diff --git a/libavformat/utils.c b/libavformat/utils.c index 76cbff4..e0c307f 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -5281,3 +5281,61 @@ int ff_bprint_to_codecpar_extradata(AVCodecParameters *par, struct AVBPrint *buf par->extradata_size = buf->len; return 0; } + +int avformat_transfer_stream_timing_info(const AVOutputFormat *ofmt, + AVStream *ost, const AVStream *ist, + enum AVTimebaseCopyFrom copy_tb) +{ + //TODO: use [io]st->internal->avctx + const AVCodecContext *dec_ctx = ist->codec; + AVCodecContext *enc_ctx = ost->codec; + + enc_ctx->time_base = ist->time_base; + /* + * Avi is a special case here because it supports variable fps but + * having the fps and timebase differe significantly adds quite some + * overhead + */ + if (!strcmp(ofmt->name, "avi")) { + if (copy_tb == AVFMT_TBCF_AUTO && ist->r_frame_rate.num + && av_q2d(ist->r_frame_rate) >= av_q2d(ist->avg_frame_rate) + && 0.5/av_q2d(ist->r_frame_rate) > av_q2d(ist->time_base) + && 0.5/av_q2d(ist->r_frame_rate) > av_q2d(dec_ctx->time_base) + && av_q2d(ist->time_base) < 1.0/500 && av_q2d(dec_ctx->time_base) < 1.0/500 + || copy_tb == AVFMT_TBCF_R_FRAMERATE) { + enc_ctx->time_base.num = ist->r_frame_rate.den; + enc_ctx->time_base.den = 2*ist->r_frame_rate.num; + enc_ctx->ticks_per_frame = 2; + } else if (copy_tb == AVFMT_TBCF_AUTO && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > 2*av_q2d(ist->time_base) + && av_q2d(ist->time_base) < 1.0/500 + || copy_tb == AVFMT_TBCF_DECODER) { + enc_ctx->time_base = dec_ctx->time_base; + enc_ctx->time_base.num *= dec_ctx->ticks_per_frame; + enc_ctx->time_base.den *= 2; + enc_ctx->ticks_per_frame = 2; + } + } else if (!(ofmt->flags & AVFMT_VARIABLE_FPS) + && strcmp(ofmt->name, "mov") && strcmp(ofmt->name, "mp4") && strcmp(ofmt->name, "3gp") + && strcmp(ofmt->name, "3g2") && strcmp(ofmt->name, "psp") && strcmp(ofmt->name, "ipod") + && strcmp(ofmt->name, "f4v")) { + if (copy_tb == AVFMT_TBCF_AUTO && dec_ctx->time_base.den + && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > av_q2d(ist->time_base) + && av_q2d(ist->time_base) < 1.0/500 + || copy_tb == AVFMT_TBCF_DECODER) { + enc_ctx->time_base = dec_ctx->time_base; + enc_ctx->time_base.num *= dec_ctx->ticks_per_frame; + } + } + + if (enc_ctx->codec_tag == AV_RL32("tmcd") + && dec_ctx->time_base.num < dec_ctx->time_base.den + && dec_ctx->time_base.num > 0 + && 121LL*dec_ctx->time_base.num > dec_ctx->time_base.den) { + enc_ctx->time_base = dec_ctx->time_base; + } + + av_reduce(&enc_ctx->time_base.num, &enc_ctx->time_base.den, + enc_ctx->time_base.num, enc_ctx->time_base.den, INT_MAX); + + return 0; +} -- 2.9.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel