diff utils.c @ 743:af4e24d6310c libavformat

switch to native time bases
author michael
date Sat, 30 Apr 2005 21:43:59 +0000
parents 119ac74d1c49
children 95c9cef3c3db
line wrap: on
line diff
--- a/utils.c	Tue Apr 26 21:46:46 2005 +0000
+++ b/utils.c	Sat Apr 30 21:43:59 2005 +0000
@@ -632,8 +632,13 @@
     *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 @@
                                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 @@
             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 @@
             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 @@
    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 @@
     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 @@
     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 @@
         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 @@
         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 @@
         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 @@
         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 @@
     int64_t last_dts[MAX_STREAMS];
     int64_t best_duration[MAX_STREAMS];
 
+    for(i=0;i<ic->nb_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;i<MAX_STREAMS;i++){
         last_dts[i]= AV_NOPTS_VALUE;
         best_duration[i]= INT64_MAX;
@@ -1768,8 +1735,8 @@
             if (!has_codec_parameters(&st->codec))
                 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 @@
             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 @@
                     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 @@
                        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 @@
             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 @@
 /*    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 @@
         }
         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 @@
  * @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);