From c0df9d75bd9a3170a793eb1651354076360998e8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 30 Apr 2005 21:43:59 +0000 Subject: [PATCH] switch to native time bases Originally committed as revision 4168 to svn://svn.ffmpeg.org/ffmpeg/trunk --- ffmpeg.c | 89 +++++++++++++++--------------- ffplay.c | 7 +-- ffserver.c | 28 +++++----- libavcodec/apiexample.c | 3 +- libavcodec/avcodec.h | 29 ++++------ libavcodec/h261.c | 4 +- libavcodec/h263.c | 83 ++++++++++++++-------------- libavcodec/h264.c | 3 +- libavcodec/mpeg12.c | 16 +++--- libavcodec/mpegvideo.c | 23 ++++---- libavcodec/mpegvideo.h | 1 - libavcodec/msmpeg4.c | 2 +- libavcodec/oggvorbis.c | 3 +- libavcodec/parser.c | 11 ++-- libavcodec/ratecontrol.c | 10 ++-- libavcodec/utils.c | 11 +++- libavcodec/vc9.c | 8 +-- libavcodec/wmv2.c | 2 +- libavcodec/x264.c | 4 +- libavcodec/xvidff.c | 20 +++---- libavformat/4xm.c | 2 - libavformat/asf-enc.c | 2 +- libavformat/asf.c | 7 +-- libavformat/avformat.h | 8 +-- libavformat/avidec.c | 4 +- libavformat/avienc.c | 12 ++-- libavformat/dc1394.c | 6 +- libavformat/dv.c | 3 +- libavformat/ffm.c | 10 ++-- libavformat/flvdec.c | 3 +- libavformat/gif.c | 4 +- libavformat/gifdec.c | 4 +- libavformat/grab.c | 10 ++-- libavformat/img.c | 18 +++--- libavformat/img2.c | 12 ++-- libavformat/mov.c | 20 +++---- libavformat/movenc.c | 8 +-- libavformat/mpegts.c | 2 +- libavformat/nsvdec.c | 9 +-- libavformat/nut.c | 7 +-- libavformat/raw.c | 11 ++-- libavformat/rm.c | 10 ++-- libavformat/rtp.c | 4 +- libavformat/swf.c | 12 ++-- libavformat/utils.c | 140 +++++++++++++++++------------------------------ libavformat/yuv4mpeg.c | 5 +- output_example.c | 4 +- vhook/watermark.c | 4 +- 48 files changed, 314 insertions(+), 384 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 31a8acb..604eb15 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -556,7 +556,7 @@ static void do_audio_out(AVFormatContext *s, pkt.data= audio_out; pkt.size= ret; if(enc->coded_frame) - pkt.pts= enc->coded_frame->pts; + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); pkt.flags |= PKT_FLAG_KEY; av_interleaved_write_frame(s, &pkt); @@ -587,7 +587,7 @@ static void do_audio_out(AVFormatContext *s, pkt.data= audio_out; pkt.size= ret; if(enc->coded_frame) - pkt.pts= enc->coded_frame->pts; + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); pkt.flags |= PKT_FLAG_KEY; av_interleaved_write_frame(s, &pkt); } @@ -708,7 +708,7 @@ static void do_video_out(AVFormatContext *s, if(video_sync_method){ double vdelta; - vdelta = ost->sync_ipts * enc->frame_rate / enc->frame_rate_base - ost->sync_opts; + vdelta = ost->sync_ipts / av_q2d(enc->time_base) - ost->sync_opts; //FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c if (vdelta < -1.1) nb_frames = 0; @@ -725,7 +725,7 @@ static void do_video_out(AVFormatContext *s, fprintf(stderr, "*** %d dup!\n", nb_frames-1); } }else - ost->sync_opts= lrintf(ost->sync_ipts * enc->frame_rate / enc->frame_rate_base); + ost->sync_opts= lrintf(ost->sync_ipts / av_q2d(enc->time_base)); nb_frames= FFMIN(nb_frames, max_frames[CODEC_TYPE_VIDEO] - ost->frame_number); if (nb_frames <= 0) @@ -875,7 +875,7 @@ static void do_video_out(AVFormatContext *s, pkt.data= (uint8_t *)final_picture; pkt.size= sizeof(AVPicture); if(dec->coded_frame) - pkt.pts= dec->coded_frame->pts; + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); if(dec->coded_frame && dec->coded_frame->key_frame) pkt.flags |= PKT_FLAG_KEY; @@ -904,7 +904,8 @@ static void do_video_out(AVFormatContext *s, if(!me_threshold) big_picture.pict_type = 0; // big_picture.pts = AV_NOPTS_VALUE; - big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->frame_rate_base, enc->frame_rate); + big_picture.pts= ost->sync_opts; +// big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->time_base.num, enc->time_base.den); //av_log(NULL, AV_LOG_DEBUG, "%lld -> encoder\n", ost->sync_opts); ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, @@ -914,10 +915,10 @@ static void do_video_out(AVFormatContext *s, pkt.data= bit_buffer; pkt.size= ret; if(enc->coded_frame) - pkt.pts= enc->coded_frame->pts; + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); /*av_log(NULL, AV_LOG_DEBUG, "encoder -> %lld/%lld\n", - pkt.pts != AV_NOPTS_VALUE ? av_rescale(pkt.pts, enc->frame_rate, AV_TIME_BASE*(int64_t)enc->frame_rate_base) : -1, - pkt.dts != AV_NOPTS_VALUE ? av_rescale(pkt.dts, enc->frame_rate, AV_TIME_BASE*(int64_t)enc->frame_rate_base) : -1);*/ + pkt.pts != AV_NOPTS_VALUE ? av_rescale(pkt.pts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1, + pkt.dts != AV_NOPTS_VALUE ? av_rescale(pkt.dts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1);*/ if(enc->coded_frame && enc->coded_frame->key_frame) pkt.flags |= PKT_FLAG_KEY; @@ -980,11 +981,11 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost, fprintf(fvstats,"f_size= %6d ", frame_size); /* compute pts value */ - ti1 = (double)ost->sync_opts *enc->frame_rate_base / enc->frame_rate; + ti1 = ost->sync_opts * av_q2d(enc->time_base); if (ti1 < 0.01) ti1 = 0.01; - bitrate = (double)(frame_size * 8) * enc->frame_rate / enc->frame_rate_base / 1000.0; + bitrate = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0; avg_bitrate = (double)(video_size * 8) / ti1 / 1000.0; fprintf(fvstats, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", (double)video_size / 1024, ti1, bitrate, avg_bitrate); @@ -1119,7 +1120,7 @@ static int output_packet(AVInputStream *ist, int ist_index, if(!pkt){ ist->pts= ist->next_pts; // needed for last packet if vsync=0 } else if (pkt->dts != AV_NOPTS_VALUE) { //FIXME seems redundant, as libavformat does this too - ist->next_pts = ist->pts = pkt->dts; + ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); } else { // assert(ist->pts == ist->next_pts); } @@ -1175,10 +1176,10 @@ static int output_packet(AVInputStream *ist, int ist_index, /* no picture yet */ goto discard_packet; } - if (ist->st->codec.frame_rate_base != 0) { + if (ist->st->codec.time_base.num != 0) { ist->next_pts += ((int64_t)AV_TIME_BASE * - ist->st->codec.frame_rate_base) / - ist->st->codec.frame_rate; + ist->st->codec.time_base.num) / + ist->st->codec.time_base.den; } len = 0; break; @@ -1192,10 +1193,10 @@ static int output_packet(AVInputStream *ist, int ist_index, (ist->st->codec.sample_rate * ist->st->codec.channels); break; case CODEC_TYPE_VIDEO: - if (ist->st->codec.frame_rate_base != 0) { + if (ist->st->codec.time_base.num != 0) { ist->next_pts += ((int64_t)AV_TIME_BASE * - ist->st->codec.frame_rate_base) / - ist->st->codec.frame_rate; + ist->st->codec.time_base.num) / + ist->st->codec.time_base.den; } break; } @@ -1227,7 +1228,7 @@ static int output_packet(AVInputStream *ist, int ist_index, /* frame rate emulation */ if (ist->st->codec.rate_emu) { - int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec.frame_rate_base, 1000000, ist->st->codec.frame_rate); + int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec.time_base.num, 1000000, ist->st->codec.time_base.den); int64_t now = av_gettime() - ist->start; if (pts > now) usleep(pts - now); @@ -1304,10 +1305,10 @@ static int output_packet(AVInputStream *ist, int ist_index, opkt.data= data_buf; opkt.size= data_size; if(pkt->pts != AV_NOPTS_VALUE) - opkt.pts= pkt->pts + input_files_ts_offset[ist->file_index]; + opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); else opkt.pts= AV_NOPTS_VALUE; - opkt.dts= pkt->dts + input_files_ts_offset[ist->file_index]; + opkt.dts= av_rescale_q(av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); opkt.flags= pkt->flags; av_interleaved_write_frame(os, &opkt); @@ -1363,7 +1364,7 @@ static int output_packet(AVInputStream *ist, int ist_index, pkt.data= bit_buffer; pkt.size= ret; if(enc->coded_frame) - pkt.pts= enc->coded_frame->pts; + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); av_interleaved_write_frame(os, &pkt); } } @@ -1549,8 +1550,7 @@ static int av_encode(AVFormatContext **output_files, codec->block_align= icodec->block_align; break; case CODEC_TYPE_VIDEO: - codec->frame_rate = icodec->frame_rate; - codec->frame_rate_base = icodec->frame_rate_base; + codec->time_base = icodec->time_base; codec->width = icodec->width; codec->height = icodec->height; codec->has_b_frames = icodec->has_b_frames; @@ -1781,7 +1781,7 @@ static int av_encode(AVFormatContext **output_files, ist = ist_table[i]; is = input_files[ist->file_index]; ist->pts = 0; - ist->next_pts = ist->st->start_time; + ist->next_pts = av_rescale_q(ist->st->start_time, ist->st->time_base, AV_TIME_BASE_Q); if(ist->next_pts == AV_NOPTS_VALUE) ist->next_pts=0; if(input_files_ts_offset[ist->file_index]) @@ -1874,9 +1874,9 @@ static int av_encode(AVFormatContext **output_files, os = output_files[ost->file_index]; ist = ist_table[ost->source_index]; if(ost->st->codec.codec_type == CODEC_TYPE_VIDEO) - opts = (double)ost->sync_opts * ost->st->codec.frame_rate_base / ost->st->codec.frame_rate; + opts = ost->sync_opts * av_q2d(ost->st->codec.time_base); else - opts = (double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den; + opts = ost->st->pts.val * av_q2d(ost->st->time_base); ipts = (double)ist->pts; if (!file_table[ist->file_index].eof_reached){ if(ipts < ipts_min) { @@ -1932,7 +1932,7 @@ static int av_encode(AVFormatContext **output_files, // fprintf(stderr, "next:%lld dts:%lld off:%lld %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec.codec_type); if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE) { - int64_t delta= pkt.dts - ist->next_pts; + int64_t delta= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q) - ist->next_pts; if(ABS(delta) > 10LL*AV_TIME_BASE && !copy_ts){ input_files_ts_offset[ist->file_index]-= delta; if (verbose > 2) @@ -2869,8 +2869,8 @@ static void opt_input_file(const char *filename) memset(ap, 0, sizeof(*ap)); ap->sample_rate = audio_sample_rate; ap->channels = audio_channels; - ap->frame_rate = frame_rate; - ap->frame_rate_base = frame_rate_base; + ap->time_base.den = frame_rate; + ap->time_base.num = frame_rate_base; ap->width = frame_width + frame_padleft + frame_padright; ap->height = frame_height + frame_padtop + frame_padbottom; ap->image_format = image_format; @@ -2935,8 +2935,8 @@ static void opt_input_file(const char *filename) frame_width = enc->width; frame_aspect_ratio = av_q2d(enc->sample_aspect_ratio) * enc->width / enc->height; frame_pix_fmt = enc->pix_fmt; - rfps = ic->streams[i]->r_frame_rate; - rfps_base = ic->streams[i]->r_frame_rate_base; + rfps = ic->streams[i]->r_frame_rate.num; + rfps_base = ic->streams[i]->r_frame_rate.den; enc->workaround_bugs = workaround_bugs; enc->error_resilience = error_resilience; enc->error_concealment = error_concealment; @@ -2949,11 +2949,11 @@ static void opt_input_file(const char *filename) if(me_threshold) enc->debug |= FF_DEBUG_MV; - if (enc->frame_rate != rfps || enc->frame_rate_base != rfps_base) { + if (enc->time_base.den != rfps || enc->time_base.num != rfps_base) { if (verbose >= 0) fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f (%d/%d) -> %2.2f (%d/%d)\n", - i, (float)enc->frame_rate / enc->frame_rate_base, enc->frame_rate, enc->frame_rate_base, + i, (float)enc->time_base.den / enc->time_base.num, enc->time_base.den, enc->time_base.num, (float)rfps / rfps_base, rfps, rfps_base); } @@ -3118,8 +3118,8 @@ static void opt_output_file(const char *filename) video_enc->bit_rate = video_bit_rate; video_enc->bit_rate_tolerance = video_bit_rate_tolerance; - video_enc->frame_rate = frame_rate; - video_enc->frame_rate_base = frame_rate_base; + video_enc->time_base.den = frame_rate; + video_enc->time_base.num = frame_rate_base; if(codec && codec->supported_framerates){ const AVRational *p= codec->supported_framerates; AVRational req= (AVRational){frame_rate, frame_rate_base}; @@ -3133,8 +3133,8 @@ static void opt_output_file(const char *filename) best= p; } } - video_enc->frame_rate = best->num; - video_enc->frame_rate_base= best->den; + video_enc->time_base.den= best->num; + video_enc->time_base.num= best->den; } video_enc->width = frame_width + frame_padright + frame_padleft; @@ -3497,7 +3497,7 @@ static void prepare_grab(void) has_audio = 0; memset(ap, 0, sizeof(*ap)); memset(vp, 0, sizeof(*vp)); - vp->frame_rate_base= 1; + vp->time_base.num= 1; for(j=0;jnb_streams;i++) { @@ -3516,9 +3516,8 @@ static void prepare_grab(void) if (enc->height > vp->height) vp->height = enc->height; - if (vp->frame_rate_base*(int64_t)enc->frame_rate > enc->frame_rate_base*(int64_t)vp->frame_rate){ - vp->frame_rate = enc->frame_rate; - vp->frame_rate_base = enc->frame_rate_base; + if (vp->time_base.num*(int64_t)enc->time_base.den > enc->time_base.num*(int64_t)vp->time_base.den){ + vp->time_base = enc->time_base; } has_video = 1; break; @@ -3550,8 +3549,8 @@ static void prepare_grab(void) exit(1); } /* by now video grab has one stream */ - ic->streams[0]->r_frame_rate = vp->frame_rate; - ic->streams[0]->r_frame_rate_base = vp->frame_rate_base; + ic->streams[0]->r_frame_rate.num = vp->time_base.den; + ic->streams[0]->r_frame_rate.den = vp->time_base.num; input_files[nb_input_files] = ic; if (verbose >= 0) @@ -3799,7 +3798,7 @@ static void opt_target(const char *arg) AVCodecContext *c = &input_files[j]->streams[i]->codec; if(c->codec_type != CODEC_TYPE_VIDEO) continue; - fr = c->frame_rate * 1000 / c->frame_rate_base; + fr = c->time_base.den * 1000 / c->time_base.num; if(fr == 25000) { norm = 0; break; diff --git a/ffplay.c b/ffplay.c index 161f34e..2df39d9 100644 --- a/ffplay.c +++ b/ffplay.c @@ -874,8 +874,7 @@ static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1) pts = is->video_clock; } /* update video clock for next frame */ - frame_delay = (double)is->video_st->codec.frame_rate_base / - (double)is->video_st->codec.frame_rate; + frame_delay = av_q2d(is->video_st->codec.time_base); /* for MPEG2, the frame can be repeated, so we update the clock accordingly */ if (src_frame->repeat_pict) { @@ -917,7 +916,7 @@ static int video_thread(void *arg) this packet, if any */ pts = 0; if (pkt->dts != AV_NOPTS_VALUE) - pts = (double)pkt->dts / AV_TIME_BASE; + pts = av_q2d(is->video_st->time_base)*pkt->dts; SDL_LockMutex(is->video_decoder_mutex); len1 = avcodec_decode_video(&is->video_st->codec, @@ -1097,7 +1096,7 @@ static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_pt /* if update the audio clock with the pts */ if (pkt->pts != AV_NOPTS_VALUE) { - is->audio_clock = (double)pkt->pts / AV_TIME_BASE; + is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts; } } } diff --git a/ffserver.c b/ffserver.c index 6f37786..f799514 100644 --- a/ffserver.c +++ b/ffserver.c @@ -1757,7 +1757,7 @@ static void compute_stats(HTTPContext *c) case CODEC_TYPE_VIDEO: type = "video"; snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec.width, st->codec.height, - st->codec.qmin, st->codec.qmax, st->codec.frame_rate / st->codec.frame_rate_base); + st->codec.qmin, st->codec.qmax, st->codec.time_base.den / st->codec.time_base.num); break; default: av_abort(); @@ -2076,7 +2076,7 @@ static int http_prepare_data(HTTPContext *c) } else { /* update first pts if needed */ if (c->first_pts == AV_NOPTS_VALUE) { - c->first_pts = pkt.dts; + c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q); c->start_time = cur_time; } /* send it to the appropriate stream */ @@ -2125,10 +2125,10 @@ static int http_prepare_data(HTTPContext *c) AVStream *st; /* compute send time and duration */ st = c->fmt_in->streams[pkt.stream_index]; - c->cur_pts = pkt.dts; + c->cur_pts = av_rescale_q(pkt.dts, st->time_base, AV_TIME_BASE_Q); if (st->start_time != AV_NOPTS_VALUE) - c->cur_pts -= st->start_time; - c->cur_frame_duration = pkt.duration; + c->cur_pts -= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q); + c->cur_frame_duration = av_rescale_q(pkt.duration, st->time_base, AV_TIME_BASE_Q); #if 0 printf("index=%d pts=%0.3f duration=%0.6f\n", pkt.stream_index, @@ -3254,8 +3254,8 @@ static int add_av_stream(FFStream *feed, AVStream *st) case CODEC_TYPE_VIDEO: if (av1->width == av->width && av1->height == av->height && - av1->frame_rate == av->frame_rate && - av1->frame_rate_base == av->frame_rate_base && + av1->time_base.den == av->time_base.den && + av1->time_base.num == av->time_base.num && av1->gop_size == av->gop_size) goto found; break; @@ -3452,8 +3452,8 @@ static void build_feed_streams(void) printf("Codec bitrates do not match for stream %d\n", i); matches = 0; } else if (ccf->codec_type == CODEC_TYPE_VIDEO) { - if (CHECK_CODEC(frame_rate) || - CHECK_CODEC(frame_rate_base) || + if (CHECK_CODEC(time_base.den) || + CHECK_CODEC(time_base.num) || CHECK_CODEC(width) || CHECK_CODEC(height)) { printf("Codec width, height and framerate do not match for stream %d\n", i); @@ -3613,9 +3613,9 @@ static void add_codec(FFStream *stream, AVCodecContext *av) case CODEC_TYPE_VIDEO: if (av->bit_rate == 0) av->bit_rate = 64000; - if (av->frame_rate == 0){ - av->frame_rate = 5; - av->frame_rate_base = 1; + if (av->time_base.num == 0){ + av->time_base.den = 5; + av->time_base.num = 1; } if (av->width == 0 || av->height == 0) { av->width = 160; @@ -4095,8 +4095,8 @@ static int parse_ffconfig(const char *filename) } else if (!strcasecmp(cmd, "VideoFrameRate")) { get_arg(arg, sizeof(arg), &p); if (stream) { - video_enc.frame_rate_base= DEFAULT_FRAME_RATE_BASE; - video_enc.frame_rate = (int)(strtod(arg, NULL) * video_enc.frame_rate_base); + video_enc.time_base.num= DEFAULT_FRAME_RATE_BASE; + video_enc.time_base.den = (int)(strtod(arg, NULL) * video_enc.time_base.num); } } else if (!strcasecmp(cmd, "VideoGopSize")) { get_arg(arg, sizeof(arg), &p); diff --git a/libavcodec/apiexample.c b/libavcodec/apiexample.c index 84a3d2c..8598538 100644 --- a/libavcodec/apiexample.c +++ b/libavcodec/apiexample.c @@ -195,8 +195,7 @@ void video_encode_example(const char *filename) c->width = 352; c->height = 288; /* frames per second */ - c->frame_rate = 25; - c->frame_rate_base= 1; + c->time_base= (AVRational){1,25}; c->gop_size = 10; /* emit one intra frame every ten frames */ c->max_b_frames=1; diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 9efb95e..83514e6 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -17,7 +17,7 @@ extern "C" { #define FFMPEG_VERSION_INT 0x000409 #define FFMPEG_VERSION "0.4.9-pre1" -#define LIBAVCODEC_BUILD 4753 +#define LIBAVCODEC_BUILD 4754 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION FFMPEG_VERSION @@ -28,6 +28,7 @@ extern "C" { #define AV_NOPTS_VALUE int64_t_C(0x8000000000000000) #define AV_TIME_BASE 1000000 +#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} enum CodecID { CODEC_ID_NONE, @@ -442,8 +443,8 @@ typedef struct AVPanScan{ int pict_type;\ \ /**\ - * presentation timestamp in AV_TIME_BASE (=micro seconds currently) (time when frame should be shown to user)\ - * if AV_NOPTS_VALUE then the frame_rate will be used as reference\ + * presentation timestamp in time_base units (time when frame should be shown to user)\ + * if AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed\ * - encoding: MUST be set by user\ * - decoding: set by lavc\ */\ @@ -721,13 +722,11 @@ typedef struct AVCodecContext { /* video only */ /** - * frames per sec multiplied by frame_rate_base. - * for variable fps this is the precission, so if the timestamps - * can be specified in msec precssion then this is 1000*frame_rate_base + * time base in which the timestamps are specified. * - encoding: MUST be set by user - * - decoding: set by lavc. 0 or the frame_rate if available + * - decoding: set by lavc. */ - int frame_rate; + AVRational time_base; /** * picture width / height. @@ -1421,15 +1420,6 @@ typedef struct AVCodecContext { int me_range; /** - * frame_rate_base. - * for variable fps this is 1 - * - encoding: set by user. - * - decoding: set by lavc. - * @todo move this after frame_rate - */ - - int frame_rate_base; - /** * intra quantizer bias. * - encoding: set by user. * - decoding: unused @@ -2244,6 +2234,11 @@ int64_t av_rescale(int64_t a, int64_t b, int64_t c); */ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding); +/** + * rescale a 64bit integer by 2 rational numbers. + */ +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq); + /* frame parsing */ typedef struct AVCodecParserContext { void *priv_data; diff --git a/libavcodec/h261.c b/libavcodec/h261.c index 630cf8f..f9e1484 100644 --- a/libavcodec/h261.c +++ b/libavcodec/h261.c @@ -103,8 +103,8 @@ void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ put_bits(&s->pb, 20, 0x10); /* PSC */ - temp_ref= s->picture_number * (int64_t)30000 * s->avctx->frame_rate_base / - (1001 * (int64_t)s->avctx->frame_rate); + temp_ref= s->picture_number * (int64_t)30000 * s->avctx->time_base.num / + (1001 * (int64_t)s->avctx->time_base.den); //FIXME maybe this should use a timestamp put_bits(&s->pb, 5, temp_ref & 0x1f); /* TemporalReference */ put_bits(&s->pb, 1, 0); /* split screen off */ diff --git a/libavcodec/h263.c b/libavcodec/h263.c index 7561c51..469cdf2 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -160,8 +160,8 @@ void ff_flv_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 17, 1); put_bits(&s->pb, 5, (s->h263_flv-1)); /* 0: h263 escape codes 1: 11-bit escape codes */ - put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * s->avctx->frame_rate_base) / - s->avctx->frame_rate) & 0xff); /* TemporalReference */ + put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * s->avctx->time_base.num) / //FIXME use timestamp + s->avctx->time_base.den) & 0xff); /* TemporalReference */ if (s->width == 352 && s->height == 288) format = 2; else if (s->width == 176 && s->height == 144) @@ -208,9 +208,9 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) if(s->h263_plus){ for(i=0; i<2; i++){ int div, error; - div= (s->avctx->frame_rate_base*1800000LL + 500LL*s->avctx->frame_rate) / ((1000LL+i)*s->avctx->frame_rate); + div= (s->avctx->time_base.num*1800000LL + 500LL*s->avctx->time_base.den) / ((1000LL+i)*s->avctx->time_base.den); div= clip(1, div, 127); - error= ABS(s->avctx->frame_rate_base*1800000LL - (1000LL+i)*s->avctx->frame_rate*div); + error= ABS(s->avctx->time_base.num*1800000LL - (1000LL+i)*s->avctx->time_base.den*div); if(error < best_error){ best_error= error; best_divisor= div; @@ -227,8 +227,8 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) /* Update the pointer to last GOB */ s->ptr_lastgob = pbBufPtr(&s->pb); put_bits(&s->pb, 22, 0x20); /* PSC */ - temp_ref= s->picture_number * (int64_t)coded_frame_rate * s->avctx->frame_rate_base / - (coded_frame_rate_base * (int64_t)s->avctx->frame_rate); + temp_ref= s->picture_number * (int64_t)coded_frame_rate * s->avctx->time_base.num / //FIXME use timestamp + (coded_frame_rate_base * (int64_t)s->avctx->time_base.den); put_bits(&s->pb, 8, temp_ref & 0xff); /* TemporalReference */ put_bits(&s->pb, 1, 1); /* marker */ @@ -2210,10 +2210,10 @@ void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){ int time_div, time_mod; assert(s->current_picture_ptr->pts != AV_NOPTS_VALUE); - s->time= (s->current_picture_ptr->pts*s->time_increment_resolution + AV_TIME_BASE/2)/AV_TIME_BASE; + s->time= s->current_picture_ptr->pts*s->avctx->time_base.num; - time_div= s->time/s->time_increment_resolution; - time_mod= s->time%s->time_increment_resolution; + time_div= s->time/s->avctx->time_base.den; + time_mod= s->time%s->avctx->time_base.den; if(s->pict_type==B_TYPE){ s->pb_time= s->pp_time - (s->last_non_b_time - s->time); @@ -2237,9 +2237,9 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){ time= s->current_picture_ptr->pts; if(s->reordered_input_picture[1]) time= FFMIN(time, s->reordered_input_picture[1]->pts); - time= (time*s->time_increment_resolution + AV_TIME_BASE/2)/AV_TIME_BASE; + time= time*s->avctx->time_base.num; - seconds= time/s->time_increment_resolution; + seconds= time/s->avctx->time_base.den; minutes= seconds/60; seconds %= 60; hours= minutes/60; minutes %= 60; hours%=24; @@ -2252,7 +2252,7 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){ put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP)); put_bits(&s->pb, 1, 0); //broken link == NO - s->last_time_base= time / s->time_increment_resolution; + s->last_time_base= time / s->avctx->time_base.den; ff_mpeg4_stuffing(&s->pb); } @@ -2349,7 +2349,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n put_bits(&s->pb, 2, RECT_SHAPE); /* vol shape= rectangle */ put_bits(&s->pb, 1, 1); /* marker bit */ - put_bits(&s->pb, 16, s->time_increment_resolution); + put_bits(&s->pb, 16, s->avctx->time_base.den); if (s->time_increment_bits < 1) s->time_increment_bits = 1; put_bits(&s->pb, 1, 1); /* marker bit */ @@ -2420,14 +2420,14 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) s->partitioned_frame= s->data_partitioning && s->pict_type!=B_TYPE; -//printf("num:%d rate:%d base:%d\n", s->picture_number, s->frame_rate, FRAME_RATE_BASE); +//printf("num:%d rate:%d base:%d\n", s->picture_number, s->time_base.den, FRAME_RATE_BASE); put_bits(&s->pb, 16, 0); /* vop header */ put_bits(&s->pb, 16, VOP_STARTCODE); /* vop header */ put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */ - time_div= s->time/s->time_increment_resolution; - time_mod= s->time%s->time_increment_resolution; + time_div= s->time/s->avctx->time_base.den; + time_mod= s->time%s->avctx->time_base.den; time_incr= time_div - s->last_time_base; assert(time_incr >= 0); while(time_incr--) @@ -5054,8 +5054,7 @@ int h263_decode_picture_header(MpegEncContext *s) s->width = width; s->height = height; s->avctx->sample_aspect_ratio= (AVRational){12,11}; - s->avctx->frame_rate = 30000; - s->avctx->frame_rate_base= 1001; + s->avctx->time_base= (AVRational){1001, 30000}; } else { int ufep; @@ -5150,20 +5149,19 @@ int h263_decode_picture_header(MpegEncContext *s) if(s->custom_pcf){ int gcd; - s->avctx->frame_rate= 1800000; - s->avctx->frame_rate_base= 1000 + get_bits1(&s->gb); - s->avctx->frame_rate_base*= get_bits(&s->gb, 7); - if(s->avctx->frame_rate_base == 0){ + s->avctx->time_base.den= 1800000; + s->avctx->time_base.num= 1000 + get_bits1(&s->gb); + s->avctx->time_base.num*= get_bits(&s->gb, 7); + if(s->avctx->time_base.num == 0){ av_log(s, AV_LOG_ERROR, "zero framerate\n"); return -1; } - gcd= ff_gcd(s->avctx->frame_rate, s->avctx->frame_rate_base); - s->avctx->frame_rate /= gcd; - s->avctx->frame_rate_base /= gcd; -// av_log(s->avctx, AV_LOG_DEBUG, "%d/%d\n", s->avctx->frame_rate, s->avctx->frame_rate_base); + gcd= ff_gcd(s->avctx->time_base.den, s->avctx->time_base.num); + s->avctx->time_base.den /= gcd; + s->avctx->time_base.num /= gcd; +// av_log(s->avctx, AV_LOG_DEBUG, "%d/%d\n", s->avctx->time_base.den, s->avctx->time_base.num); }else{ - s->avctx->frame_rate = 30000; - s->avctx->frame_rate_base= 1001; + s->avctx->time_base= (AVRational){1001, 30000}; } } @@ -5234,7 +5232,7 @@ int h263_decode_picture_header(MpegEncContext *s) s->modified_quant ? " MQ" : "", s->loop_filter ? " LOOP" : "", s->h263_slice_structured ? " SS" : "", - s->avctx->frame_rate, s->avctx->frame_rate_base + s->avctx->time_base.den, s->avctx->time_base.num ); } #if 1 @@ -5537,18 +5535,19 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ check_marker(gb, "before time_increment_resolution"); - s->time_increment_resolution = get_bits(gb, 16); + s->avctx->time_base.den = get_bits(gb, 16); - s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; + s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; if (s->time_increment_bits < 1) s->time_increment_bits = 1; check_marker(gb, "before fixed_vop_rate"); if (get_bits1(gb) != 0) { /* fixed_vop_rate */ - skip_bits(gb, s->time_increment_bits); - } - + s->avctx->time_base.num = get_bits(gb, s->time_increment_bits); + }else + s->avctx->time_base.num = 1; + s->t_frame=0; if (s->shape != BIN_ONLY_SHAPE) { @@ -5799,8 +5798,8 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ else s->decode_mb= ff_mpeg4_decode_mb; - if(s->time_increment_resolution==0){ - s->time_increment_resolution=1; + if(s->avctx->time_base.den==0){ + s->avctx->time_base.den=1; // fprintf(stderr, "time_increment_resolution is illegal\n"); } time_incr=0; @@ -5827,18 +5826,18 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ if(s->pict_type!=B_TYPE){ s->last_time_base= s->time_base; s->time_base+= time_incr; - s->time= s->time_base*s->time_increment_resolution + time_increment; + s->time= s->time_base*s->avctx->time_base.den + time_increment; if(s->workaround_bugs&FF_BUG_UMP4){ if(s->time < s->last_non_b_time){ // fprintf(stderr, "header is not mpeg4 compatible, broken encoder, trying to workaround\n"); s->time_base++; - s->time+= s->time_increment_resolution; + s->time+= s->avctx->time_base.den; } } s->pp_time= s->time - s->last_non_b_time; s->last_non_b_time= s->time; }else{ - s->time= (s->last_time_base + time_incr)*s->time_increment_resolution + time_increment; + s->time= (s->last_time_base + time_incr)*s->avctx->time_base.den + time_increment; s->pb_time= s->pp_time - (s->last_non_b_time - s->time); if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){ // printf("messed up order, maybe after seeking? skipping current b frame\n"); @@ -5854,9 +5853,9 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ } //av_log(s->avctx, AV_LOG_DEBUG, "last nonb %Ld last_base %d time %Ld pp %d pb %d t %d ppf %d pbf %d\n", s->last_non_b_time, s->last_time_base, s->time, s->pp_time, s->pb_time, s->t_frame, s->pp_field_time, s->pb_field_time); - s->current_picture_ptr->pts= s->time*(int64_t)AV_TIME_BASE / s->time_increment_resolution; + s->current_picture_ptr->pts= (s->time + s->avctx->time_base.num/2) / s->avctx->time_base.num; if(s->avctx->debug&FF_DEBUG_PTS) - av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %f\n", s->current_picture_ptr->pts/(float)AV_TIME_BASE); + av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %f\n", s->current_picture_ptr->pts); check_marker(gb, "before vop_coded"); @@ -5866,7 +5865,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n"); return FRAME_SKIPPED; } -//printf("time %d %d %d || %Ld %Ld %Ld\n", s->time_increment_bits, s->time_increment_resolution, s->time_base, +//printf("time %d %d %d || %Ld %Ld %Ld\n", s->time_increment_bits, s->avctx->time_base.den, s->time_base, //s->time, s->last_non_b_time, s->last_non_b_time - s->pp_time); if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == P_TYPE || (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) { diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 42f9b06..7fdae20 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -3838,8 +3838,7 @@ static int decode_slice_header(H264Context *h){ s->avctx->sample_aspect_ratio.den = 1; if(h->sps.timing_info_present_flag && h->sps.fixed_frame_rate_flag){ - s->avctx->frame_rate = h->sps.time_scale; - s->avctx->frame_rate_base = h->sps.num_units_in_tick; + s->avctx->time_base= (AVRational){h->sps.num_units_in_tick, h->sps.time_scale}; } } diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index b06fe51..47c7887 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -201,8 +201,8 @@ static int find_frame_rate_index(MpegEncContext *s){ int64_t d; for(i=1;i<14;i++) { - int64_t n0= 1001LL/frame_rate_tab[i].den*frame_rate_tab[i].num*s->avctx->frame_rate_base; - int64_t n1= 1001LL*s->avctx->frame_rate; + int64_t n0= 1001LL/frame_rate_tab[i].den*frame_rate_tab[i].num*s->avctx->time_base.num; + int64_t n1= 1001LL*s->avctx->time_base.den; if(s->avctx->strict_std_compliance >= 0 && i>=9) break; d = ABS(n0 - n1); @@ -226,10 +226,10 @@ static int encode_init(AVCodecContext *avctx) if(find_frame_rate_index(s) < 0){ if(s->strict_std_compliance >=0){ - av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->frame_rate, avctx->frame_rate_base); + av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->time_base.den, avctx->time_base.num); return -1; }else{ - av_log(avctx, AV_LOG_INFO, "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n", avctx->frame_rate, avctx->frame_rate_base); + av_log(avctx, AV_LOG_INFO, "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n", avctx->time_base.den, avctx->time_base.num); } } @@ -2099,8 +2099,8 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ if(avctx->sub_id==1){//s->codec_id==avctx->codec_id==CODEC_ID //mpeg1 fps - avctx->frame_rate = frame_rate_tab[s->frame_rate_index].num; - avctx->frame_rate_base= frame_rate_tab[s->frame_rate_index].den; + avctx->time_base.den = frame_rate_tab[s->frame_rate_index].num; + avctx->time_base.num= frame_rate_tab[s->frame_rate_index].den; //mpeg1 aspect avctx->sample_aspect_ratio= av_d2q( 1.0/mpeg1_aspect[s->aspect_ratio_info], 255); @@ -2108,8 +2108,8 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ }else{//mpeg2 //mpeg2 fps av_reduce( - &s->avctx->frame_rate, - &s->avctx->frame_rate_base, + &s->avctx->time_base.den, + &s->avctx->time_base.num, frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num, frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den, 1<<30); diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 697430c..cbd5cd6 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1050,7 +1050,7 @@ int MPV_encode_init(AVCodecContext *avctx) if(s->avctx->thread_count > 1) s->rtp_mode= 1; - if(!avctx->frame_rate || !avctx->frame_rate_base){ + if(!avctx->time_base.den || !avctx->time_base.num){ av_log(avctx, AV_LOG_ERROR, "framerate not set\n"); return -1; } @@ -1065,11 +1065,11 @@ int MPV_encode_init(AVCodecContext *avctx) return -1; } - i= ff_gcd(avctx->frame_rate, avctx->frame_rate_base); + i= ff_gcd(avctx->time_base.den, avctx->time_base.num); if(i > 1){ av_log(avctx, AV_LOG_INFO, "removing common factors from framerate\n"); - avctx->frame_rate /= i; - avctx->frame_rate_base /= i; + avctx->time_base.den /= i; + avctx->time_base.num /= i; // return -1; } @@ -1091,8 +1091,11 @@ int MPV_encode_init(AVCodecContext *avctx) avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift); - av_reduce(&s->time_increment_resolution, &dummy, s->avctx->frame_rate, s->avctx->frame_rate_base, (1<<16)-1); - s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; + if(s->avctx->time_base.den > (1<<16)-1){ + av_log(avctx, AV_LOG_ERROR, "timebase not supported by mpeg 4 standard\n"); + return -1; + } + s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; switch(avctx->codec->id) { case CODEC_ID_MPEG1VIDEO: @@ -2006,8 +2009,8 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){ if(pts != AV_NOPTS_VALUE){ if(s->user_specified_pts != AV_NOPTS_VALUE){ - int64_t time= av_rescale(pts, s->avctx->frame_rate, s->avctx->frame_rate_base*(int64_t)AV_TIME_BASE); - int64_t last= av_rescale(s->user_specified_pts, s->avctx->frame_rate, s->avctx->frame_rate_base*(int64_t)AV_TIME_BASE); + int64_t time= pts; + int64_t last= s->user_specified_pts; if(time <= last){ av_log(s->avctx, AV_LOG_ERROR, "Error, Invalid timestamp=%Ld, last=%Ld\n", pts, s->user_specified_pts); @@ -2018,10 +2021,10 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){ }else{ if(s->user_specified_pts != AV_NOPTS_VALUE){ s->user_specified_pts= - pts= s->user_specified_pts + AV_TIME_BASE*(int64_t)s->avctx->frame_rate_base / s->avctx->frame_rate; + pts= s->user_specified_pts + 1; av_log(s->avctx, AV_LOG_INFO, "Warning: AVFrame.pts=? trying to guess (%Ld)\n", pts); }else{ - pts= av_rescale(pic_arg->display_picture_number*(int64_t)s->avctx->frame_rate_base, AV_TIME_BASE, s->avctx->frame_rate); + pts= pic_arg->display_picture_number; } } } diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 9983718..df67a46 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -552,7 +552,6 @@ typedef struct MpegEncContext { int custom_pcf; /* mpeg4 specific */ - int time_increment_resolution; int time_increment_bits; ///< number of bits to represent the fractional part of time int last_time_base; int time_base; ///< time in seconds of last I,P,S Frame diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c index 468e07d..85b492a 100644 --- a/libavcodec/msmpeg4.c +++ b/libavcodec/msmpeg4.c @@ -438,7 +438,7 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) void msmpeg4_encode_ext_header(MpegEncContext * s) { - put_bits(&s->pb, 5, s->avctx->frame_rate / s->avctx->frame_rate_base); //yes 29.97 -> 29 + put_bits(&s->pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047)); diff --git a/libavcodec/oggvorbis.c b/libavcodec/oggvorbis.c index 8358411..e5dd106 100644 --- a/libavcodec/oggvorbis.c +++ b/libavcodec/oggvorbis.c @@ -140,7 +140,7 @@ static int oggvorbis_encode_frame(AVCodecContext *avccontext, op2->packet = context->buffer + sizeof(ogg_packet); l= op2->bytes; - avccontext->coded_frame->pts= av_rescale(op2->granulepos, AV_TIME_BASE, avccontext->sample_rate); + avccontext->coded_frame->pts= op2->granulepos; memcpy(packets, op2->packet, l); context->buffer_index -= l + sizeof(ogg_packet); @@ -203,6 +203,7 @@ static int oggvorbis_decode_init(AVCodecContext *avccontext) { } avccontext->channels = context->vi.channels; avccontext->sample_rate = context->vi.rate; + avccontext->time_base= (AVRational){1, avccontext->sample_rate}; vorbis_synthesis_init(&context->vd, &context->vi); vorbis_block_init(&context->vd, &context->vb); diff --git a/libavcodec/parser.c b/libavcodec/parser.c index 4725d56..93bbf87 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -282,6 +282,7 @@ static const int frame_rate_tab[16] = { 25025, }; +//FIXME move into mpeg12.c static void mpegvideo_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t *buf, int buf_size) @@ -311,8 +312,8 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; avcodec_set_dimensions(avctx, pc->width, pc->height); frame_rate_index = buf[3] & 0xf; - pc->frame_rate = avctx->frame_rate = frame_rate_tab[frame_rate_index]; - avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE; + pc->frame_rate = avctx->time_base.den = frame_rate_tab[frame_rate_index]; + avctx->time_base.num = MPEG1_FRAME_RATE_BASE; avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400; avctx->codec_id = CODEC_ID_MPEG1VIDEO; avctx->sub_id = 1; @@ -336,8 +337,8 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, pc->height |=( vert_size_ext << 12); avctx->bit_rate += (bit_rate_ext << 18) * 400; avcodec_set_dimensions(avctx, pc->width, pc->height); - avctx->frame_rate = pc->frame_rate * (frame_rate_ext_n + 1); - avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1); + avctx->time_base.den = pc->frame_rate * (frame_rate_ext_n + 1); + avctx->time_base.num = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1); avctx->codec_id = CODEC_ID_MPEG2VIDEO; avctx->sub_id = 2; /* forces MPEG2 */ } @@ -406,7 +407,7 @@ static int mpegvideo_parse(AVCodecParserContext *s, mpegvideo_extract_headers(s, avctx, buf, buf_size); #if 0 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", - s->pict_type, (double)avctx->frame_rate / avctx->frame_rate_base, s->repeat_pict); + s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict); #endif *poutbuf = (uint8_t *)buf; diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 94fca1e..0fc9caa 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -166,7 +166,7 @@ int ff_rate_control_init(MpegEncContext *s) bits= rce.i_tex_bits + rce.p_tex_bits; q= get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i); - rcc->pass1_wanted_bits+= s->bit_rate/(s->avctx->frame_rate / (double)s->avctx->frame_rate_base); + rcc->pass1_wanted_bits+= s->bit_rate/(1/av_q2d(s->avctx->time_base)); //FIXME missbehaves a little for variable fps } } @@ -199,7 +199,7 @@ static inline double bits2qp(RateControlEntry *rce, double bits){ int ff_vbv_update(MpegEncContext *s, int frame_size){ RateControlContext *rcc= &s->rc_context; - const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; + const double fps= 1/av_q2d(s->avctx->time_base); const int buffer_size= s->avctx->rc_buffer_size; const double min_rate= s->avctx->rc_min_rate/fps; const double max_rate= s->avctx->rc_max_rate/fps; @@ -400,7 +400,7 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q, double bits; const int pict_type= rce->new_pict_type; const double buffer_size= s->avctx->rc_buffer_size; - const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; + const double fps= 1/av_q2d(s->avctx->time_base); const double min_rate= s->avctx->rc_min_rate / fps; const double max_rate= s->avctx->rc_max_rate / fps; @@ -631,7 +631,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s) get_qminmax(&qmin, &qmax, s, pict_type); - fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; + fps= 1/av_q2d(s->avctx->time_base); //printf("input_pic_num:%d pic_num:%d frame_rate:%d\n", s->input_picture_number, s->picture_number, s->frame_rate); /* update predictors */ if(picture_number>2){ @@ -757,7 +757,7 @@ static int init_pass2(MpegEncContext *s) RateControlContext *rcc= &s->rc_context; AVCodecContext *a= s->avctx; int i; - double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; + double fps= 1/av_q2d(s->avctx->time_base); double complexity[5]={0,0,0,0,0}; // aproximate bits at quant=1 double avg_quantizer[5]; uint64_t const_bits[5]={0,0,0,0,0}; // quantizer idependant bits diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 4ef9cb2..b5bd17f 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -442,8 +442,7 @@ void avcodec_get_context_defaults(AVCodecContext *s){ s->error_concealment= 3; s->error_resilience= 1; s->workaround_bugs= FF_BUG_AUTODETECT; - s->frame_rate_base= 1; - s->frame_rate = 25; + s->time_base= (AVRational){0,1}; s->gop_size= 50; s->me_method= ME_EPZS; s->get_buffer= avcodec_default_get_buffer; @@ -734,7 +733,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %dx%d, %0.2f fps", enc->width, enc->height, - (float)enc->frame_rate / enc->frame_rate_base); + 1/av_q2d(enc->time_base)); } if (encode) { snprintf(buf + strlen(buf), buf_size - strlen(buf), @@ -930,6 +929,12 @@ int64_t av_rescale(int64_t a, int64_t b, int64_t c){ return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); } +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq){ + int64_t b= bq.num * (int64_t)cq.den; + int64_t c= cq.num * (int64_t)bq.den; + return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); +} + int64_t ff_gcd(int64_t a, int64_t b){ if(b) return ff_gcd(b, a%b); else return a; diff --git a/libavcodec/vc9.c b/libavcodec/vc9.c index 5225dde..93c3983 100644 --- a/libavcodec/vc9.c +++ b/libavcodec/vc9.c @@ -595,15 +595,15 @@ static int decode_advanced_sequence_header(AVCodecContext *avctx, GetBitContext av_log(avctx, AV_LOG_ERROR, "Reserved FRAMERATEDR %i not handled\n", dr); } - avctx->frame_rate_base = fps_nr[dr]; - avctx->frame_rate = fps_nr[nr]; + avctx->time_base.num = fps_nr[dr]; + avctx->time_base.den = fps_nr[nr]; } else { nr = get_bits(gb, 16); // 0.03125->2048Hz / 0.03125Hz - avctx->frame_rate = 1000000; - avctx->frame_rate_base = 31250*(1+nr); + avctx->time_base.den = 1000000; + avctx->time_base.num = 31250*(1+nr); } } diff --git a/libavcodec/wmv2.c b/libavcodec/wmv2.c index b3e31a4..949d7c6 100644 --- a/libavcodec/wmv2.c +++ b/libavcodec/wmv2.c @@ -68,7 +68,7 @@ static int encode_ext_header(Wmv2Context *w){ init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size); - put_bits(&pb, 5, s->avctx->frame_rate / s->avctx->frame_rate_base); //yes 29.97 -> 29 + put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047)); put_bits(&pb, 1, w->mspel_bit=1); diff --git a/libavcodec/x264.c b/libavcodec/x264.c index 79f82b8..c04a2e6 100644 --- a/libavcodec/x264.c +++ b/libavcodec/x264.c @@ -151,8 +151,8 @@ X264_init(AVCodecContext *avctx) x4->params.i_height = avctx->height; x4->params.vui.i_sar_width = avctx->sample_aspect_ratio.num; x4->params.vui.i_sar_height = avctx->sample_aspect_ratio.den; - x4->params.i_fps_num = avctx->frame_rate; - x4->params.i_fps_den = avctx->frame_rate_base; + x4->params.i_fps_num = avctx->time_base.den; + x4->params.i_fps_den = avctx->time_base.num; x4->enc = x264_encoder_open(&x4->params); if(!x4->enc) diff --git a/libavcodec/xvidff.c b/libavcodec/xvidff.c index b46b5e3..9156b2e 100644 --- a/libavcodec/xvidff.c +++ b/libavcodec/xvidff.c @@ -283,8 +283,8 @@ int ff_xvid_encode_init(AVCodecContext *avctx) { /* Frame Rate and Key Frames */ xvid_correct_framerate(avctx); - xvid_enc_create.fincr = avctx->frame_rate_base; - xvid_enc_create.fbase = avctx->frame_rate; + xvid_enc_create.fincr = avctx->time_base.num; + xvid_enc_create.fbase = avctx->time_base.den; if( avctx->gop_size > 0 ) xvid_enc_create.max_key_interval = avctx->gop_size; else @@ -551,8 +551,8 @@ void xvid_correct_framerate(AVCodecContext *avctx) { int gcd; float est_fps, fps; - frate = avctx->frame_rate; - fbase = avctx->frame_rate_base; + frate = avctx->time_base.den; + fbase = avctx->time_base.num; gcd = ff_gcd(frate, fbase); if( gcd > 1 ) { @@ -561,8 +561,8 @@ void xvid_correct_framerate(AVCodecContext *avctx) { } if( frate <= 65000 && fbase <= 65000 ) { - avctx->frame_rate = frate; - avctx->frame_rate_base = fbase; + avctx->time_base.den = frate; + avctx->time_base.num = fbase; return; } @@ -583,14 +583,14 @@ void xvid_correct_framerate(AVCodecContext *avctx) { } if( fbase > est_fbase ) { - avctx->frame_rate = est_frate; - avctx->frame_rate_base = est_fbase; + avctx->time_base.den = est_frate; + avctx->time_base.num = est_fbase; av_log(avctx, AV_LOG_DEBUG, "XviD: framerate re-estimated: %.2f, %.3f%% correction\n", est_fps, (((est_fps - fps)/fps) * 100.0)); } else { - avctx->frame_rate = frate; - avctx->frame_rate_base = fbase; + avctx->time_base.den = frate; + avctx->time_base.num = fbase; } } diff --git a/libavformat/4xm.c b/libavformat/4xm.c index 164c674..5ce1f43 100644 --- a/libavformat/4xm.c +++ b/libavformat/4xm.c @@ -166,8 +166,6 @@ static int fourxm_read_header(AVFormatContext *s, fourxm->video_stream_index = st->index; - st->codec.frame_rate = fourxm->fps; - st->codec.frame_rate_base = 1.0; st->codec.codec_type = CODEC_TYPE_VIDEO; st->codec.codec_id = CODEC_ID_4XM; st->codec.codec_tag = 0; /* no fourcc */ diff --git a/libavformat/asf-enc.c b/libavformat/asf-enc.c index 5c1bcff..4e2fd35 100644 --- a/libavformat/asf-enc.c +++ b/libavformat/asf-enc.c @@ -740,7 +740,7 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt) duration = (codec->frame_number * (int64_t)codec->frame_size * int64_t_C(10000000)) / codec->sample_rate; } else { - duration = av_rescale(codec->frame_number * (int64_t)codec->frame_rate_base, 10000000, codec->frame_rate); + duration = av_rescale(codec->frame_number * (int64_t)codec->time_base.num, 10000000, codec->time_base.den); } } else { duration = pts * 10000; diff --git a/libavformat/asf.c b/libavformat/asf.c index d88a840..4a480bf 100644 --- a/libavformat/asf.c +++ b/libavformat/asf.c @@ -196,9 +196,9 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) if (!asf_st) goto fail; st->priv_data = asf_st; - st->start_time = asf->hdr.preroll * (int64_t)AV_TIME_BASE / 1000; + st->start_time = asf->hdr.preroll; st->duration = asf->hdr.send_time / - (10000000 / AV_TIME_BASE) - st->start_time; + (10000000 / 1000) - st->start_time; get_guid(pb, &g); if (!memcmp(&g, &audio_stream, sizeof(GUID))) { type = CODEC_TYPE_AUDIO; @@ -217,9 +217,6 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) get_le32(pb); st->codec.codec_type = type; - /* 1 fps default (XXX: put 0 fps instead) */ - st->codec.frame_rate = 1000; - st->codec.frame_rate_base = 1; if (type == CODEC_TYPE_AUDIO) { get_wav_header(pb, &st->codec, type_specific_size); st->need_parsing = 1; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 892b0f8..f19ea89 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -5,7 +5,7 @@ extern "C" { #endif -#define LIBAVFORMAT_BUILD 4623 +#define LIBAVFORMAT_BUILD 4624 #define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT #define LIBAVFORMAT_VERSION FFMPEG_VERSION @@ -98,8 +98,7 @@ typedef struct AVProbeData { #define AVPROBE_SCORE_MAX 100 typedef struct AVFormatParameters { - int frame_rate; - int frame_rate_base; + AVRational time_base; int sample_rate; int channels; int width; @@ -225,8 +224,7 @@ typedef struct AVStream { int index; /* stream index in AVFormatContext */ int id; /* format specific stream id */ AVCodecContext codec; /* codec context */ - int r_frame_rate; /* real frame rate of the stream */ - int r_frame_rate_base;/* real frame rate base of the stream */ + AVRational r_frame_rate; /* real frame rate of the stream */ void *priv_data; /* internal data used in av_find_stream_info() */ int64_t codec_info_duration; diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 058c886..bf02018 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -221,7 +221,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) nb_frames = get_le32(pb); st->start_time = 0; - st->duration = av_rescale(nb_frames, ast->scale*(int64_t)AV_TIME_BASE, ast->rate); + st->duration = nb_frames; get_le32(pb); /* buffer size */ get_le32(pb); /* quality */ ast->sample_size = get_le32(pb); /* sample ssize */ @@ -232,8 +232,6 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) codec_type = CODEC_TYPE_VIDEO; ast->sample_size = 0; - st->codec.frame_rate = ast->rate; - st->codec.frame_rate_base = ast->scale; break; case MKTAG('a', 'u', 'd', 's'): codec_type = CODEC_TYPE_AUDIO; diff --git a/libavformat/avienc.c b/libavformat/avienc.c index 0919f5b..f4a7cf7 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -271,8 +271,8 @@ static void parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ *au_scale=stream->frame_size; *au_rate= stream->sample_rate; }else if(stream->codec_type == CODEC_TYPE_VIDEO){ - *au_scale= stream->frame_rate_base; - *au_rate = stream->frame_rate; + *au_scale= stream->time_base.num; + *au_rate = stream->time_base.den; }else{ *au_scale= stream->block_align ? stream->block_align*8 : 8; *au_rate = stream->bit_rate; @@ -343,7 +343,7 @@ static int avi_write_header(AVFormatContext *s) nb_frames = 0; if(video_enc){ - put_le32(pb, (uint32_t)(int64_t_C(1000000) * video_enc->frame_rate_base / video_enc->frame_rate)); + put_le32(pb, (uint32_t)(int64_t_C(1000000) * video_enc->time_base.num / video_enc->time_base.den)); } else { put_le32(pb, 0); } @@ -390,9 +390,9 @@ static int avi_write_header(AVFormatContext *s) put_le16(pb, 0); /* language */ put_le32(pb, 0); /* initial frame */ - put_le32(pb, stream->frame_rate_base); /* scale */ - put_le32(pb, stream->frame_rate); /* rate */ - av_set_pts_info(s->streams[i], 64, stream->frame_rate_base, stream->frame_rate); + put_le32(pb, stream->time_base.num); /* scale */ + put_le32(pb, stream->time_base.den); /* rate */ + av_set_pts_info(s->streams[i], 64, stream->time_base.num, stream->time_base.den); put_le32(pb, 0); /* start */ avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */ diff --git a/libavformat/dc1394.c b/libavformat/dc1394.c index 5132052..551042a 100644 --- a/libavformat/dc1394.c +++ b/libavformat/dc1394.c @@ -72,7 +72,7 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap) break; for (fps = dc1394_frame_rates; fps->frame_rate; fps++) - if (fps->frame_rate == av_rescale(1000, ap->frame_rate, ap->frame_rate_base)) + if (fps->frame_rate == av_rescale(1000, ap->time_base.den, ap->time_base.num)) break; /* create a video stream */ @@ -82,8 +82,8 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap) av_set_pts_info(vst, 64, 1, 1000); vst->codec.codec_type = CODEC_TYPE_VIDEO; vst->codec.codec_id = CODEC_ID_RAWVIDEO; - vst->codec.frame_rate = fps->frame_rate; - vst->codec.frame_rate_base = 1000; + vst->codec.time_base.den = fps->frame_rate; + vst->codec.time_base.num = 1000; vst->codec.width = fmt->width; vst->codec.height = fmt->height; vst->codec.pix_fmt = fmt->pix_fmt; diff --git a/libavformat/dv.c b/libavformat/dv.c index 2ddb6a5..ed6a740 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -591,9 +591,8 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame) if (sys) { avctx = &c->vst->codec; - avctx->frame_rate = sys->frame_rate; - avctx->frame_rate_base = sys->frame_rate_base; av_set_pts_info(c->vst, 64, sys->frame_rate_base, sys->frame_rate); + avctx->time_base= (AVRational){sys->frame_rate_base, sys->frame_rate}; avctx->width = sys->width; avctx->height = sys->height; avctx->pix_fmt = sys->pix_fmt; diff --git a/libavformat/ffm.c b/libavformat/ffm.c index 7640d65..cb53415 100644 --- a/libavformat/ffm.c +++ b/libavformat/ffm.c @@ -163,8 +163,8 @@ static int ffm_write_header(AVFormatContext *s) /* specific info */ switch(codec->codec_type) { case CODEC_TYPE_VIDEO: - put_be32(pb, codec->frame_rate_base); - put_be32(pb, codec->frame_rate); + put_be32(pb, codec->time_base.num); + put_be32(pb, codec->time_base.den); put_be16(pb, codec->width); put_be16(pb, codec->height); put_be16(pb, codec->gop_size); @@ -235,7 +235,7 @@ static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt) if (st->codec.codec_type == CODEC_TYPE_AUDIO) { duration = ((float)st->codec.frame_size / st->codec.sample_rate * 1000000.0); } else { - duration = (1000000.0 * st->codec.frame_rate_base / (float)st->codec.frame_rate); + duration = (1000000.0 * st->codec.time_base.num / (float)st->codec.time_base.den); } pts = fst->pts; @@ -480,8 +480,8 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) /* specific info */ switch(codec->codec_type) { case CODEC_TYPE_VIDEO: - codec->frame_rate_base = get_be32(pb); - codec->frame_rate = get_be32(pb); + codec->time_base.num = get_be32(pb); + codec->time_base.den = get_be32(pb); codec->width = get_be16(pb); codec->height = get_be16(pb); codec->gop_size = get_be16(pb); diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 379e909..942e188 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -102,8 +102,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR_NOMEM; av_set_pts_info(st, 24, 1, 1000); /* 24 bit pts in ms */ - st->codec.frame_rate_base= 1; - st->codec.frame_rate= 1000; + st->codec.time_base= (AVRational){1,1000}; } // av_log(NULL, AV_LOG_DEBUG, "%d %X %d \n", is_audio, flags, st->discard); if( (st->discard >= AVDISCARD_NONKEY && !((flags >> 4)==1 || is_audio)) diff --git a/libavformat/gif.c b/libavformat/gif.c index bf04e81..0cb9b9a 100644 --- a/libavformat/gif.c +++ b/libavformat/gif.c @@ -316,7 +316,7 @@ static int gif_write_header(AVFormatContext *s) } else { width = video_enc->width; height = video_enc->height; -// rate = video_enc->frame_rate; +// rate = video_enc->time_base.den; } /* XXX: is it allowed ? seems to work so far... */ @@ -349,7 +349,7 @@ static int gif_write_video(AVFormatContext *s, /* XXX: should use delay, in order to be more accurate */ /* instead of using the same rounded value each time */ /* XXX: don't even remember if I really use it for now */ - jiffies = (70*enc->frame_rate_base/enc->frame_rate) - 1; + jiffies = (70*enc->time_base.num/enc->time_base.den) - 1; put_le16(pb, jiffies); diff --git a/libavformat/gifdec.c b/libavformat/gifdec.c index 4ee295d..90c6fc6 100644 --- a/libavformat/gifdec.c +++ b/libavformat/gifdec.c @@ -557,8 +557,8 @@ static int gif_read_header(AVFormatContext * s1, st->codec.codec_type = CODEC_TYPE_VIDEO; st->codec.codec_id = CODEC_ID_RAWVIDEO; - st->codec.frame_rate = 5; - st->codec.frame_rate_base = 1; + st->codec.time_base.den = 5; + st->codec.time_base.num = 1; /* XXX: check if screen size is always valid */ st->codec.width = s->screen_width; st->codec.height = s->screen_height; diff --git a/libavformat/grab.c b/libavformat/grab.c index 84284c1..e7c4262 100644 --- a/libavformat/grab.c +++ b/libavformat/grab.c @@ -68,13 +68,13 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) const char *video_device; int j; - if (!ap || ap->width <= 0 || ap->height <= 0 || ap->frame_rate <= 0) + if (!ap || ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0) return -1; width = ap->width; height = ap->height; - frame_rate = ap->frame_rate; - frame_rate_base = ap->frame_rate_base; + frame_rate = ap->time_base.den; + frame_rate_base = ap->time_base.num; if((unsigned)width > 32767 || (unsigned)height > 32767) return -1; @@ -265,8 +265,8 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) st->codec.codec_id = CODEC_ID_RAWVIDEO; st->codec.width = width; st->codec.height = height; - st->codec.frame_rate = frame_rate; - st->codec.frame_rate_base = frame_rate_base; + st->codec.time_base.den = frame_rate; + st->codec.time_base.num = frame_rate_base; return 0; fail: diff --git a/libavformat/img.c b/libavformat/img.c index d52e1a0..c30d455 100644 --- a/libavformat/img.c +++ b/libavformat/img.c @@ -132,15 +132,13 @@ static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) s->is_pipe = 0; else s->is_pipe = 1; - - if (!ap || !ap->frame_rate) { - st->codec.frame_rate = 25; - st->codec.frame_rate_base = 1; + + if (!ap || !ap->time_base.num) { + st->codec.time_base= (AVRational){1,25}; } else { - st->codec.frame_rate = ap->frame_rate; - st->codec.frame_rate_base = ap->frame_rate_base; + st->codec.time_base= ap->time_base; } - + if (!s->is_pipe) { if (find_image_range(&first_index, &last_index, s->path) < 0) goto fail; @@ -149,9 +147,7 @@ static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) s->img_number = first_index; /* compute duration */ st->start_time = 0; - st->duration = ((int64_t)AV_TIME_BASE * - (last_index - first_index + 1) * - st->codec.frame_rate_base) / st->codec.frame_rate; + st->duration = last_index - first_index + 1; if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0) goto fail; if (url_fopen(f, buf, URL_RDONLY) < 0) @@ -236,7 +232,7 @@ static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) } else { /* XXX: computing this pts is not necessary as it is done in the generic code too */ - pkt->pts = av_rescale((int64_t)s->img_count * s1->streams[0]->codec.frame_rate_base, s1->streams[0]->time_base.den, s1->streams[0]->codec.frame_rate) / s1->streams[0]->time_base.num; + pkt->pts = av_rescale((int64_t)s->img_count * s1->streams[0]->codec.time_base.num, s1->streams[0]->time_base.den, s1->streams[0]->codec.time_base.den) / s1->streams[0]->time_base.num; s->img_count++; s->img_number++; return 0; diff --git a/libavformat/img2.c b/libavformat/img2.c index 0d58604..fe225e9 100644 --- a/libavformat/img2.c +++ b/libavformat/img2.c @@ -186,12 +186,10 @@ static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) st->need_parsing= 1; } - if (!ap || !ap->frame_rate) { - st->codec.frame_rate = 25; - st->codec.frame_rate_base = 1; + if (!ap || !ap->time_base.num) { + av_set_pts_info(st, 60, 1, 25); } else { - st->codec.frame_rate = ap->frame_rate; - st->codec.frame_rate_base = ap->frame_rate_base; + av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den); } if(ap && ap->width && ap->height){ @@ -207,9 +205,7 @@ static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) s->img_number = first_index; /* compute duration */ st->start_time = 0; - st->duration = ((int64_t)AV_TIME_BASE * - (last_index - first_index + 1) * - st->codec.frame_rate_base) / st->codec.frame_rate; + st->duration = last_index - first_index + 1; } if(ap->video_codec_id){ diff --git a/libavformat/mov.c b/libavformat/mov.c index 6bba5ba..ca82a03 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -867,8 +867,8 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) st->codec.color_table_id = get_be16(pb); /* colortable id */ /* These are set in mov_read_stts and might already be set! - st->codec.frame_rate = 25; - st->codec.frame_rate_base = 1; + st->codec.time_base.den = 25; + st->codec.time_base.num = 1; */ size -= (16+8*4+2+32+2*2); #if 0 @@ -1342,10 +1342,10 @@ av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, #if 0 //We calculate an average instead, needed by .mp4-files created with nec e606 3g phone if (!i && st->codec.codec_type==CODEC_TYPE_VIDEO) { - st->codec.frame_rate_base = sample_duration ? sample_duration : 1; - st->codec.frame_rate = c->streams[c->fc->nb_streams-1]->time_scale; + st->codec.time_base.num = sample_duration ? sample_duration : 1; + st->codec.time_base.den = c->streams[c->fc->nb_streams-1]->time_scale; #ifdef DEBUG - av_log(NULL, AV_LOG_DEBUG, "VIDEO FRAME RATE= %i (sd= %i)\n", st->codec.frame_rate, sample_duration); + av_log(NULL, AV_LOG_DEBUG, "VIDEO FRAME RATE= %i (sd= %i)\n", st->codec.time_base.den, sample_duration); #endif } #endif @@ -1355,21 +1355,21 @@ av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, if(duration>0) { av_reduce( - &st->codec.frame_rate, - &st->codec.frame_rate_base, + &st->codec.time_base.den, + &st->codec.time_base.num, c->streams[c->fc->nb_streams-1]->time_scale * total_sample_count, duration, INT_MAX ); #ifdef DEBUG - av_log(NULL, AV_LOG_DEBUG, "FRAME RATE average (video or audio)= %f (tot sample count= %i ,tot dur= %i timescale=%d)\n", (float)st->codec.frame_rate/st->codec.frame_rate_base,total_sample_count,duration,c->streams[c->fc->nb_streams-1]->time_scale); + av_log(NULL, AV_LOG_DEBUG, "FRAME RATE average (video or audio)= %f (tot sample count= %i ,tot dur= %i timescale=%d)\n", (float)st->codec.time_base.den/st->codec.time_base.num,total_sample_count,duration,c->streams[c->fc->nb_streams-1]->time_scale); #endif } else { - st->codec.frame_rate_base = 1; - st->codec.frame_rate = c->streams[c->fc->nb_streams-1]->time_scale; + st->codec.time_base.num = 1; + st->codec.time_base.den = c->streams[c->fc->nb_streams-1]->time_scale; } return 0; } diff --git a/libavformat/movenc.c b/libavformat/movenc.c index f45c1c1..9df793e 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1181,8 +1181,8 @@ static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov, if(mov->tracks[i].entry <= 0) continue; if(mov->tracks[i].enc->codec_type == CODEC_TYPE_VIDEO) { - mov->tracks[i].timescale = mov->tracks[i].enc->frame_rate; - mov->tracks[i].sampleDuration = mov->tracks[i].enc->frame_rate_base; + mov->tracks[i].timescale = mov->tracks[i].enc->time_base.den; + mov->tracks[i].sampleDuration = mov->tracks[i].enc->time_base.num; } else if(mov->tracks[i].enc->codec_type == CODEC_TYPE_AUDIO) { /* If AMR, track timescale = 8000, AMR_WB = 16000 */ @@ -1257,10 +1257,10 @@ int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s) static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s) { int AudioRate = s->streams[1]->codec.sample_rate; - int FrameRate = ((s->streams[0]->codec.frame_rate) * (0x10000))/ (s->streams[0]->codec.frame_rate_base); + int FrameRate = ((s->streams[0]->codec.time_base.den) * (0x10000))/ (s->streams[0]->codec.time_base.num); //printf("audiorate = %d\n",AudioRate); - //printf("framerate = %d / %d = 0x%x\n",s->streams[0]->codec.frame_rate,s->streams[0]->codec.frame_rate_base,FrameRate); + //printf("framerate = %d / %d = 0x%x\n",s->streams[0]->codec.time_base.den,s->streams[0]->codec.time_base.num,FrameRate); put_be32(pb, 0x94 ); /* size */ put_tag(pb, "uuid"); diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index d89258c..ec38423 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -1208,7 +1208,7 @@ static int mpegts_read_header(AVFormatContext *s, ts->cur_pcr = pcrs[0] - ts->pcr_incr * packet_count[0]; s->bit_rate = (TS_PACKET_SIZE * 8) * 27e6 / ts->pcr_incr; st->codec.bit_rate = s->bit_rate; - st->start_time = ts->cur_pcr * 1000000.0 / 27.0e6; + st->start_time = ts->cur_pcr; #if 0 printf("start=%0.3f pcr=%0.3f incr=%d\n", st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr); diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 7157eb7..fa8adf0 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -300,8 +300,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) PRINT(("NSV NSVf chunk_size %ld\n", size)); PRINT(("NSV NSVf file_size %Ld\n", file_size)); - duration = get_le32(pb); /* in ms */ - nsv->duration = duration * AV_TIME_BASE / 1000; /* convert */ + nsv->duration = duration = get_le32(pb); /* in ms */ PRINT(("NSV NSVf duration %Ld ms\n", duration)); // XXX: store it in AVStreams @@ -448,10 +447,8 @@ static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap) st->codec.bits_per_sample = 24; /* depth XXX */ av_set_pts_info(st, 64, framerate.den, framerate.num); - st->codec.frame_rate = framerate.num; - st->codec.frame_rate_base = framerate.den; st->start_time = 0; - st->duration = nsv->duration; + st->duration = av_rescale(nsv->duration, framerate.num, 1000*framerate.den); } if (atag != T_NONE) { #ifndef DISABLE_AUDIO @@ -467,7 +464,7 @@ static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap) st->codec.codec_tag = atag; st->codec.codec_id = codec_get_id(nsv_codec_audio_tags, atag); st->start_time = 0; - st->duration = nsv->duration; +// st->duration = nsv->duration; //FIXME st->need_parsing = 1; /* for PCM we will read a chunk later and put correct info */ /* XXX:FIXME */ diff --git a/libavformat/nut.c b/libavformat/nut.c index 89a6aa7..7c1557f 100644 --- a/libavformat/nut.c +++ b/libavformat/nut.c @@ -599,8 +599,8 @@ static int nut_write_header(AVFormatContext *s) if (codec->codec_type == CODEC_TYPE_VIDEO) { - nom = codec->frame_rate; - denom = codec->frame_rate_base; + nom = codec->time_base.den; + denom = codec->time_base.num; } else { @@ -1001,9 +1001,6 @@ static int decode_stream_header(NUTContext *nut){ st->codec.sample_aspect_ratio.num= get_v(bc); st->codec.sample_aspect_ratio.den= get_v(bc); get_v(bc); /* csp type */ - - st->codec.frame_rate = nom; - st->codec.frame_rate_base = denom; } if (class == 32) /* AUDIO */ { diff --git a/libavformat/raw.c b/libavformat/raw.c index a0bbbce..b33cdf9 100644 --- a/libavformat/raw.c +++ b/libavformat/raw.c @@ -63,8 +63,7 @@ static int raw_read_header(AVFormatContext *s, AVFormatParameters *ap) av_set_pts_info(st, 64, 1, st->codec.sample_rate); break; case CODEC_TYPE_VIDEO: - st->codec.frame_rate = ap->frame_rate; - st->codec.frame_rate_base = ap->frame_rate_base; + av_set_pts_info(st, 64, ap->time_base.num, ap->time_base.den); st->codec.width = ap->width; st->codec.height = ap->height; st->codec.pix_fmt = ap->pix_fmt; @@ -238,12 +237,10 @@ static int video_read_header(AVFormatContext *s, /* for mpeg4 specify it too (most mpeg4 streams dont have the fixed_vop_rate set ...)*/ if (st->codec.codec_id == CODEC_ID_MJPEG || st->codec.codec_id == CODEC_ID_MPEG4) { - if (ap && ap->frame_rate) { - st->codec.frame_rate = ap->frame_rate; - st->codec.frame_rate_base = ap->frame_rate_base; + if (ap && ap->time_base.num) { + av_set_pts_info(st, 64, ap->time_base.num, ap->time_base.den); } else { - st->codec.frame_rate = 25; - st->codec.frame_rate_base = 1; + av_set_pts_info(st, 64, 1, 25); } } return 0; diff --git a/libavformat/rm.c b/libavformat/rm.c index f4babe4..58a3cab 100644 --- a/libavformat/rm.c +++ b/libavformat/rm.c @@ -316,7 +316,7 @@ static int rm_write_header(AVFormatContext *s) break; case CODEC_TYPE_VIDEO: rm->video_stream = stream; - stream->frame_rate = (float)codec->frame_rate / (float)codec->frame_rate_base; + stream->frame_rate = (float)codec->time_base.den / (float)codec->time_base.num; /* XXX: dummy values */ stream->packet_max_size = 4096; stream->nb_packets = 0; @@ -641,8 +641,8 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) start_time = get_be32(pb); /* start time */ get_be32(pb); /* preroll */ duration = get_be32(pb); /* duration */ - st->start_time = start_time * (AV_TIME_BASE / 1000); - st->duration = duration * (AV_TIME_BASE / 1000); + st->start_time = start_time; + st->duration = duration; get_str8(pb, buf, sizeof(buf)); /* desc */ get_str8(pb, buf, sizeof(buf)); /* mimetype */ codec_data_size = get_be32(pb); @@ -670,7 +670,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) goto fail1; st->codec.width = get_be16(pb); st->codec.height = get_be16(pb); - st->codec.frame_rate_base= 1; + st->codec.time_base.num= 1; fps= get_be16(pb); st->codec.codec_type = CODEC_TYPE_VIDEO; get_be32(pb); @@ -682,7 +682,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) get_buffer(pb, st->codec.extradata, st->codec.extradata_size); // av_log(NULL, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2); - st->codec.frame_rate = fps * st->codec.frame_rate_base; + st->codec.time_base.den = fps * st->codec.time_base.num; /* modification of h263 codec version (!) */ #ifdef WORDS_BIGENDIAN h263_hack_version = ((uint32_t*)st->codec.extradata)[1]; diff --git a/libavformat/rtp.c b/libavformat/rtp.c index 31e4a21..32711af 100644 --- a/libavformat/rtp.c +++ b/libavformat/rtp.c @@ -610,7 +610,7 @@ static void rtp_send_mpegvideo(AVFormatContext *s1, /* 90 KHz time stamp */ s->timestamp = s->base_timestamp + - av_rescale((int64_t)s->cur_timestamp * st->codec.frame_rate_base, 90000, st->codec.frame_rate); + av_rescale((int64_t)s->cur_timestamp * st->codec.time_base.num, 90000, st->codec.time_base.den); //FIXME pass timestamps rtp_send_data(s1, s->buf, q - s->buf); buf1 += len; @@ -635,7 +635,7 @@ static void rtp_send_raw(AVFormatContext *s1, /* 90 KHz time stamp */ s->timestamp = s->base_timestamp + - av_rescale((int64_t)s->cur_timestamp * st->codec.frame_rate_base, 90000, st->codec.frame_rate); + av_rescale((int64_t)s->cur_timestamp * st->codec.time_base.num, 90000, st->codec.time_base.den); //FIXME pass timestamps rtp_send_data(s1, buf1, len); buf1 += len; diff --git a/libavformat/swf.c b/libavformat/swf.c index 9538dc2..5f86899 100644 --- a/libavformat/swf.c +++ b/libavformat/swf.c @@ -348,8 +348,8 @@ static int swf_write_header(AVFormatContext *s) swf->video_type = video_enc->codec_id; width = video_enc->width; height = video_enc->height; - rate = video_enc->frame_rate; - rate_base = video_enc->frame_rate_base; + rate = video_enc->time_base.den; + rate_base = video_enc->time_base.num; } if (!audio_enc ) { @@ -767,8 +767,8 @@ static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) if (tag < 0) { if ( ast || vst ) { if ( vst && ast ) { - vst->codec.frame_rate = ast->codec.sample_rate / swf->samples_per_frame; - vst->codec.frame_rate_base = 1; + vst->codec.time_base.den = ast->codec.sample_rate / swf->samples_per_frame; + vst->codec.time_base.num = 1; } break; } @@ -789,8 +789,8 @@ static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) vst->codec.codec_type = CODEC_TYPE_VIDEO; vst->codec.codec_id = CODEC_ID_FLV1; if ( swf->samples_per_frame ) { - vst->codec.frame_rate = 1000. / swf->ms_per_frame; - vst->codec.frame_rate_base = 1; + vst->codec.time_base.den = 1000. / swf->ms_per_frame; + vst->codec.time_base.num = 1; } } } else if ( ( tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2 ) && !ast) { diff --git a/libavformat/utils.c b/libavformat/utils.c index cb43df4..50cde39 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -632,8 +632,13 @@ static void compute_frame_duration(int *pnum, int *pden, AVStream *st, *pden = 0; switch(st->codec.codec_type) { case CODEC_TYPE_VIDEO: - *pnum = st->codec.frame_rate_base; - *pden = st->codec.frame_rate; + if(st->codec.time_base.num*1000 <= st->codec.time_base.den){ + *pnum = st->time_base.num; + *pden = st->time_base.den; + }else{ + *pnum = st->codec.time_base.num; + *pden = st->codec.time_base.den; + } if (pc && pc->repeat_pict) { *pden *= 2; *pnum = (*pnum) * (2 + pc->repeat_pict); @@ -683,7 +688,6 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, AVCodecParserContext *pc, AVPacket *pkt) { int num, den, presentation_delayed; - /* handle wrapping */ if(st->cur_dts != AV_NOPTS_VALUE){ if(pkt->pts != AV_NOPTS_VALUE) @@ -789,15 +793,6 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, break; } } - - /* convert the packet time stamp units */ - if(pkt->pts != AV_NOPTS_VALUE) - pkt->pts = av_rescale(pkt->pts, AV_TIME_BASE * (int64_t)st->time_base.num, st->time_base.den); - if(pkt->dts != AV_NOPTS_VALUE) - pkt->dts = av_rescale(pkt->dts, AV_TIME_BASE * (int64_t)st->time_base.num, st->time_base.den); - - /* duration field */ - pkt->duration = av_rescale(pkt->duration, AV_TIME_BASE * (int64_t)st->time_base.num, st->time_base.den); } void av_destruct_packet_nofree(AVPacket *pkt) @@ -1066,8 +1061,7 @@ static void av_build_index_raw(AVFormatContext *s) break; if (pkt->stream_index == 0 && st->parser && (pkt->flags & PKT_FLAG_KEY)) { - int64_t dts= av_rescale(pkt->dts, st->time_base.den, AV_TIME_BASE*(int64_t)st->time_base.num); - av_add_index_entry(st, st->parser->frame_offset, dts, + av_add_index_entry(st, st->parser->frame_offset, pkt->dts, 0, AVINDEX_KEYFRAME); } av_free_packet(pkt); @@ -1406,7 +1400,7 @@ static int av_has_timings(AVFormatContext *ic) compute the global bitrate if possible */ static void av_update_stream_timings(AVFormatContext *ic) { - int64_t start_time, end_time, end_time1; + int64_t start_time, start_time1, end_time, end_time1; int i; AVStream *st; @@ -1415,10 +1409,12 @@ static void av_update_stream_timings(AVFormatContext *ic) for(i = 0;i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->start_time != AV_NOPTS_VALUE) { - if (st->start_time < start_time) - start_time = st->start_time; + start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q); + if (start_time1 < start_time) + start_time = start_time1; if (st->duration != AV_NOPTS_VALUE) { - end_time1 = st->start_time + st->duration; + end_time1 = start_time1 + + av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q); if (end_time1 > end_time) end_time = end_time1; } @@ -1447,8 +1443,10 @@ static void fill_all_stream_timings(AVFormatContext *ic) for(i = 0;i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->start_time == AV_NOPTS_VALUE) { - st->start_time = ic->start_time; - st->duration = ic->duration; + if(ic->start_time != AV_NOPTS_VALUE) + st->start_time = av_rescale_q(ic->start_time, AV_TIME_BASE_Q, st->time_base); + if(ic->duration != AV_NOPTS_VALUE) + st->duration = av_rescale_q(ic->duration, AV_TIME_BASE_Q, st->time_base); } } } @@ -1475,9 +1473,9 @@ static void av_estimate_timings_from_bit_rate(AVFormatContext *ic) ic->file_size != 0) { filesize = ic->file_size; if (filesize > 0) { - duration = (int64_t)((8 * AV_TIME_BASE * (double)filesize) / (double)ic->bit_rate); for(i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; + duration= av_rescale(8*filesize, st->time_base.den, ic->bit_rate*(int64_t)st->time_base.num); if (st->start_time == AV_NOPTS_VALUE || st->duration == AV_NOPTS_VALUE) { st->start_time = 0; @@ -1538,22 +1536,11 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic) st = ic->streams[pkt->stream_index]; if (pkt->pts != AV_NOPTS_VALUE) { if (st->start_time == AV_NOPTS_VALUE) - st->start_time = av_rescale(pkt->pts, st->time_base.num * (int64_t)AV_TIME_BASE, st->time_base.den); + st->start_time = pkt->pts; } av_free_packet(pkt); } - /* we compute the minimum start_time and use it as default */ - start_time = MAXINT64; - for(i = 0; i < ic->nb_streams; i++) { - st = ic->streams[i]; - if (st->start_time != AV_NOPTS_VALUE && - st->start_time < start_time) - start_time = st->start_time; - } - if (start_time != MAXINT64) - ic->start_time = start_time; - /* estimate the end time (duration) */ /* XXX: may need to support wrapping */ filesize = ic->file_size; @@ -1581,7 +1568,7 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic) read_size += pkt->size; st = ic->streams[pkt->stream_index]; if (pkt->pts != AV_NOPTS_VALUE) { - end_time = av_rescale(pkt->pts, st->time_base.num * (int64_t)AV_TIME_BASE, st->time_base.den); + end_time = pkt->pts; duration = end_time - st->start_time; if (duration > 0) { if (st->duration == AV_NOPTS_VALUE || @@ -1592,37 +1579,7 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic) av_free_packet(pkt); } - /* estimate total duration */ - end_time = MININT64; - for(i = 0;i < ic->nb_streams; i++) { - st = ic->streams[i]; - if (st->duration != AV_NOPTS_VALUE) { - end_time1 = st->start_time + st->duration; - if (end_time1 > end_time) - end_time = end_time1; - } - } - - /* update start_time (new stream may have been created, so we do - it at the end */ - if (ic->start_time != AV_NOPTS_VALUE) { - for(i = 0; i < ic->nb_streams; i++) { - st = ic->streams[i]; - if (st->start_time == AV_NOPTS_VALUE) - st->start_time = ic->start_time; - } - } - - if (end_time != MININT64) { - /* put dummy values for duration if needed */ - for(i = 0;i < ic->nb_streams; i++) { - st = ic->streams[i]; - if (st->duration == AV_NOPTS_VALUE && - st->start_time != AV_NOPTS_VALUE) - st->duration = end_time - st->start_time; - } - ic->duration = end_time - ic->start_time; - } + fill_all_stream_timings(ic); url_fseek(&ic->pb, 0, SEEK_SET); } @@ -1753,6 +1710,16 @@ int av_find_stream_info(AVFormatContext *ic) int64_t last_dts[MAX_STREAMS]; int64_t best_duration[MAX_STREAMS]; + for(i=0;inb_streams;i++) { + st = ic->streams[i]; + if(st->codec.codec_type == CODEC_TYPE_VIDEO){ +/* if(!st->time_base.num) + st->time_base= */ + if(!st->codec.time_base.num) + st->codec.time_base= st->time_base; + } + } + for(i=0;icodec)) break; /* variable fps and no guess at the real fps */ - if( st->codec.frame_rate >= 1000LL*st->codec.frame_rate_base - && best_duration[i]== INT64_MAX) + if( st->codec.time_base.den >= 1000LL*st->codec.time_base.num + && best_duration[i]== INT64_MAX && st->codec.codec_type == CODEC_TYPE_VIDEO) break; } if (i == ic->nb_streams) { @@ -1874,18 +1841,18 @@ int av_find_stream_info(AVFormatContext *ic) if(st->codec.codec_id == CODEC_ID_RAWVIDEO && !st->codec.codec_tag && !st->codec.bits_per_sample) st->codec.codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec.pix_fmt); - if(best_duration[i] < INT64_MAX && st->codec.frame_rate_base*1000 <= st->codec.frame_rate){ + if(best_duration[i] < INT64_MAX && st->codec.time_base.num*1000 <= st->codec.time_base.den){ int int_fps; - st->r_frame_rate= st->codec.frame_rate; - st->r_frame_rate_base= av_rescale(best_duration[i], st->codec.frame_rate, AV_TIME_BASE); - av_reduce(&st->r_frame_rate, &st->r_frame_rate_base, st->r_frame_rate, st->r_frame_rate_base, 1<<15); + st->r_frame_rate.num= st->time_base.den; + st->r_frame_rate.den= st->time_base.num*best_duration[i]; + av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->r_frame_rate.num, st->r_frame_rate.den, 1<<15); - int_fps= av_rescale(st->r_frame_rate, 1, st->r_frame_rate_base); + int_fps= av_rescale(st->r_frame_rate.num, 1, st->r_frame_rate.den); // 1/0 - if(int_fps>0 && av_rescale(st->r_frame_rate, 1, int_fps) == st->r_frame_rate_base){ - st->r_frame_rate= int_fps; - st->r_frame_rate_base= 1; + if(int_fps>0 && av_rescale(st->r_frame_rate.num, 1, int_fps) == st->r_frame_rate.den){ + st->r_frame_rate.num= int_fps; + st->r_frame_rate.den= 1; } } @@ -1898,8 +1865,7 @@ int av_find_stream_info(AVFormatContext *ic) float coded_frame_rate, est_frame_rate; est_frame_rate = ((double)st->codec_info_nb_frames * AV_TIME_BASE) / (double)st->codec_info_duration ; - coded_frame_rate = (double)st->codec.frame_rate / - (double)st->codec.frame_rate_base; + coded_frame_rate = 1.0/av_q2d(st->codec.time_base); #if 0 printf("telecine: coded_frame_rate=%0.3f est_frame_rate=%0.3f\n", coded_frame_rate, est_frame_rate); @@ -1909,15 +1875,14 @@ int av_find_stream_info(AVFormatContext *ic) higher level as it can change in a film */ if (coded_frame_rate >= 24.97 && (est_frame_rate >= 23.5 && est_frame_rate < 24.5)) { - st->r_frame_rate = 24000; - st->r_frame_rate_base = 1001; + st->r_frame_rate = (AVRational){24000, 1001}; } } } /* if no real frame rate, use the codec one */ - if (!st->r_frame_rate){ - st->r_frame_rate = st->codec.frame_rate; - st->r_frame_rate_base = st->codec.frame_rate_base; + if (!st->r_frame_rate.num){ + st->r_frame_rate.num = st->codec.time_base.den; + st->r_frame_rate.den = st->codec.time_base.num; } } } @@ -2098,7 +2063,7 @@ int av_write_header(AVFormatContext *s) break; case CODEC_TYPE_VIDEO: av_frac_init(&st->pts, 0, 0, - (int64_t)st->time_base.num * st->codec.frame_rate); + (int64_t)st->time_base.num * st->codec.time_base.den); break; default: break; @@ -2117,13 +2082,7 @@ static int compute_pkt_fields2(AVStream *st, AVPacket *pkt){ /* if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE) return -1;*/ - if(pkt->pts != AV_NOPTS_VALUE) - pkt->pts = av_rescale(pkt->pts, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num); - if(pkt->dts != AV_NOPTS_VALUE) - pkt->dts = av_rescale(pkt->dts, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num); - /* duration field */ - pkt->duration = av_rescale(pkt->duration, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num); if (pkt->duration == 0) { compute_frame_duration(&num, &den, st, NULL, pkt); if (den && num) { @@ -2178,7 +2137,7 @@ static int compute_pkt_fields2(AVStream *st, AVPacket *pkt){ } break; case CODEC_TYPE_VIDEO: - av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec.frame_rate_base); + av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec.time_base.num); break; default: break; @@ -2776,6 +2735,7 @@ void av_hex_dump(FILE *f, uint8_t *buf, int size) * @param pkt packet to dump * @param dump_payload true if the payload must be displayed too */ + //FIXME needs to know the time_base void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload) { fprintf(f, "stream #%d:\n", pkt->stream_index); diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c index 01f841c..7aead7b 100644 --- a/libavformat/yuv4mpeg.c +++ b/libavformat/yuv4mpeg.c @@ -36,7 +36,7 @@ static int yuv4_generate_header(AVFormatContext *s, char* buf) width = st->codec.width; height = st->codec.height; - av_reduce(&raten, &rated, st->codec.frame_rate, st->codec.frame_rate_base, (1UL<<31)-1); + av_reduce(&raten, &rated, st->codec.time_base.den, st->codec.time_base.num, (1UL<<31)-1); aspectn = st->codec.sample_aspect_ratio.num; aspectd = st->codec.sample_aspect_ratio.den; @@ -323,8 +323,7 @@ static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap) st->codec.width = width; st->codec.height = height; av_reduce(&raten, &rated, raten, rated, (1UL<<31)-1); - st->codec.frame_rate = raten; - st->codec.frame_rate_base = rated; + av_set_pts_info(st, 64, rated, raten); st->codec.pix_fmt = pix_fmt; st->codec.codec_type = CODEC_TYPE_VIDEO; st->codec.codec_id = CODEC_ID_RAWVIDEO; diff --git a/output_example.c b/output_example.c index 214ee9f..37368ff 100644 --- a/output_example.c +++ b/output_example.c @@ -199,8 +199,8 @@ AVStream *add_video_stream(AVFormatContext *oc, int codec_id) c->width = 352; c->height = 288; /* frames per second */ - c->frame_rate = STREAM_FRAME_RATE; - c->frame_rate_base = 1; + c->time_base.den = STREAM_FRAME_RATE; + c->time_base.num = 1; c->gop_size = 12; /* emit one intra frame every twelve frames at most */ if (c->codec_id == CODEC_ID_MPEG2VIDEO) { /* just for testing, we also add B frames */ diff --git a/vhook/watermark.c b/vhook/watermark.c index e176427..e8562fb 100644 --- a/vhook/watermark.c +++ b/vhook/watermark.c @@ -343,8 +343,8 @@ int get_watermark_picture(ContextInfo *ci, int cleanup) // Hack to correct wrong frame rates that seem to be generated by some // codecs - if (ci->pCodecCtx->frame_rate>1000 && ci->pCodecCtx->frame_rate_base==1) - ci->pCodecCtx->frame_rate_base=1000; + if (ci->pCodecCtx->time_base.den>1000 && ci->pCodecCtx->time_base.num==1) + ci->pCodecCtx->time_base.num=1000; /* * Allocate a video frame to store the decoded images in. -- 2.7.4