changeset 2637:ef44d24680d1 libavcodec

switch to native time bases
author michael
date Sat, 30 Apr 2005 21:43:59 +0000
parents 2344c6713011
children 00393c294d4d
files apiexample.c avcodec.h h261.c h263.c h264.c mpeg12.c mpegvideo.c mpegvideo.h msmpeg4.c oggvorbis.c parser.c ratecontrol.c utils.c vc9.c wmv2.c x264.c xvidff.c
diffstat 17 files changed, 119 insertions(+), 118 deletions(-) [+]
line wrap: on
line diff
--- a/apiexample.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/apiexample.c	Sat Apr 30 21:43:59 2005 +0000
@@ -195,8 +195,7 @@
     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;
 
--- a/avcodec.h	Mon Apr 25 18:41:38 2005 +0000
+++ b/avcodec.h	Sat Apr 30 21:43:59 2005 +0000
@@ -17,7 +17,7 @@
 
 #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 @@
 
 #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 @@
     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 @@
     
     /* 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 @@
     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_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;
--- a/h261.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/h261.c	Sat Apr 30 21:43:59 2005 +0000
@@ -103,8 +103,8 @@
 
     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 */
--- a/h263.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/h263.c	Sat Apr 30 21:43:59 2005 +0000
@@ -160,8 +160,8 @@
 
       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 @@
     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 @@
     /* 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 @@
     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;
-
-    time_div= s->time/s->time_increment_resolution;
-    time_mod= s->time%s->time_increment_resolution;
+    s->time= s->current_picture_ptr->pts*s->avctx->time_base.num;
+
+    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 @@
     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;
-
-    seconds= time/s->time_increment_resolution;
+    time= time*s->avctx->time_base.num;
+
+    seconds= time/s->avctx->time_base.den;
     minutes= seconds/60; seconds %= 60;
     hours= minutes/60; minutes %= 60;
     hours%=24;
@@ -2252,7 +2252,7 @@
     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 @@
     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 @@
     
     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 @@
         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 @@
 
             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 @@
          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 @@
 
     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 @@
     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 @@
     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 @@
     }
 //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 @@
             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))) {
--- a/h264.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/h264.c	Sat Apr 30 21:43:59 2005 +0000
@@ -3838,8 +3838,7 @@
             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};
         }
     }
 
--- a/mpeg12.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/mpeg12.c	Sat Apr 30 21:43:59 2005 +0000
@@ -201,8 +201,8 @@
     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 @@
 
     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 @@
 
         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 @@
         }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);
--- a/mpegvideo.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/mpegvideo.c	Sat Apr 30 21:43:59 2005 +0000
@@ -1050,7 +1050,7 @@
     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 @@
         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 @@
         
     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 @@
 
         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 @@
         }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;
             }
         }
     }
--- a/mpegvideo.h	Mon Apr 25 18:41:38 2005 +0000
+++ b/mpegvideo.h	Sat Apr 30 21:43:59 2005 +0000
@@ -552,7 +552,6 @@
     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 
--- a/msmpeg4.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/msmpeg4.c	Sat Apr 30 21:43:59 2005 +0000
@@ -438,7 +438,7 @@
 
 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));
 
--- a/oggvorbis.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/oggvorbis.c	Sat Apr 30 21:43:59 2005 +0000
@@ -140,7 +140,7 @@
         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 @@
     }
     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); 
--- a/parser.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/parser.c	Sat Apr 30 21:43:59 2005 +0000
@@ -282,6 +282,7 @@
     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 @@
                 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 @@
                         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 @@
     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;
--- a/ratecontrol.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/ratecontrol.c	Sat Apr 30 21:43:59 2005 +0000
@@ -166,7 +166,7 @@
                 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 @@
     
 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 @@
     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 @@
 
     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 @@
     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
--- a/utils.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/utils.c	Sat Apr 30 21:43:59 2005 +0000
@@ -442,8 +442,7 @@
     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 @@
             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 @@
     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;
--- a/vc9.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/vc9.c	Sat Apr 30 21:43:59 2005 +0000
@@ -595,15 +595,15 @@
                 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);
         }
     }
 
--- a/wmv2.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/wmv2.c	Sat Apr 30 21:43:59 2005 +0000
@@ -68,7 +68,7 @@
         
     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);
--- a/x264.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/x264.c	Sat Apr 30 21:43:59 2005 +0000
@@ -151,8 +151,8 @@
     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)
--- a/xvidff.c	Mon Apr 25 18:41:38 2005 +0000
+++ b/xvidff.c	Sat Apr 30 21:43:59 2005 +0000
@@ -283,8 +283,8 @@
 
     /* 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 @@
     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 @@
     }
     
     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 @@
     }    
     
     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;
     }
 }