From 3797c74ba5350692122a81db62a7bf2ce152f7fc Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 26 Feb 2009 23:47:32 +0000 Subject: Add ticks_per_frame, this should hopefully fix the regressions caused by the time_base change. Originally committed as revision 17630 to svn://svn.ffmpeg.org/ffmpeg/trunk --- ffmpeg.c | 9 +++++---- libavcodec/avcodec.h | 11 ++++++++++- libavcodec/h264.c | 1 + libavcodec/mpeg12.c | 3 ++- libavcodec/options.c | 1 + libavformat/utils.c | 6 +++--- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index f757eb5019..1e31570fd0 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -1261,7 +1261,7 @@ static int output_packet(AVInputStream *ist, int ist_index, goto discard_packet; } if (ist->st->codec->time_base.num != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : 1; + int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->time_base.num * ticks) / ist->st->codec->time_base.den; @@ -1290,7 +1290,7 @@ static int output_packet(AVInputStream *ist, int ist_index, break; case CODEC_TYPE_VIDEO: if (ist->st->codec->time_base.num != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : 1; + int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->time_base.num * ticks) / ist->st->codec->time_base.den; @@ -1750,9 +1750,10 @@ static int av_encode(AVFormatContext **output_files, codec->bit_rate = icodec->bit_rate; codec->extradata= icodec->extradata; codec->extradata_size= icodec->extradata_size; - if(av_q2d(icodec->time_base) > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/1000) + if(av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/1000){ codec->time_base = icodec->time_base; - else + codec->time_base.num *= icodec->ticks_per_frame; + }else codec->time_base = ist->st->time_base; switch(codec->codec_type) { case CODEC_TYPE_AUDIO: diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index a3bfcbc431..b078bc98c2 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -30,7 +30,7 @@ #include "libavutil/avutil.h" #define LIBAVCODEC_VERSION_MAJOR 52 -#define LIBAVCODEC_VERSION_MINOR 19 +#define LIBAVCODEC_VERSION_MINOR 20 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ @@ -2323,6 +2323,15 @@ typedef struct AVCodecContext { * - decoding: Set by libavcodec */ struct AVHWAccel *hwaccel; + + /** + * For some codecs, the time base is closer to the field rate than the frame rate. + * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration + * if no telecine is used ... + * + * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. + */ + int ticks_per_frame; } AVCodecContext; /** diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 64ca5b7e66..24dc201e9f 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2201,6 +2201,7 @@ static av_cold int decode_init(AVCodecContext *avctx){ h->sei_dpb_output_delay = 0; h->sei_cpb_removal_delay = -1; h->sei_buffering_period_present = 0; + avctx->ticks_per_frame = 2; return 0; } diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 46d7946aaa..6988da22f6 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1269,7 +1269,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ //MPEG-1 aspect avctx->sample_aspect_ratio= av_d2q( 1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255); - + avctx->ticks_per_frame=1; }else{//MPEG-2 //MPEG-2 fps av_reduce( @@ -1278,6 +1278,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ ff_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2, ff_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den, 1<<30); + avctx->ticks_per_frame=2; //MPEG-2 aspect if(s->aspect_ratio_info > 1){ //we ignore the spec here as reality does not match the spec, see for example diff --git a/libavcodec/options.c b/libavcodec/options.c index 1a3c1efd5d..e5a67a4893 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -393,6 +393,7 @@ static const AVOption options[]={ {"request_channel_layout", NULL, OFFSET(request_channel_layout), FF_OPT_TYPE_INT64, DEFAULT, 0, INT64_MAX, A|D, "request_channel_layout"}, {"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), FF_OPT_TYPE_FLOAT, 1.0/3, 0.0, FLT_MAX, V|E}, {"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), FF_OPT_TYPE_FLOAT, 3, 0.0, FLT_MAX, V|E}, +{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), FF_OPT_TYPE_INT, 1, 1, INT_MAX, A|V|E|D}, {NULL}, }; diff --git a/libavformat/utils.c b/libavformat/utils.c index 073e6dacdc..4d6cb705f9 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2201,9 +2201,9 @@ int av_find_stream_info(AVFormatContext *ic) if (!st->r_frame_rate.num){ if( st->codec->time_base.den * (int64_t)st->time_base.num - <= st->codec->time_base.num * (int64_t)st->time_base.den){ + <= st->codec->time_base.num * st->codec->ticks_per_frame * (int64_t)st->time_base.den){ st->r_frame_rate.num = st->codec->time_base.den; - st->r_frame_rate.den = st->codec->time_base.num; + st->r_frame_rate.den = st->codec->time_base.num * st->codec->ticks_per_frame; }else{ st->r_frame_rate.num = st->time_base.den; st->r_frame_rate.den = st->time_base.num; @@ -2537,7 +2537,7 @@ static int compute_pkt_fields2(AVStream *st, AVPacket *pkt){ if (pkt->duration == 0) { compute_frame_duration(&num, &den, st, NULL, pkt); if (den && num) { - pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num); + pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num); } } -- cgit v1.2.3