changeset 2300:9c8cfadff191 libavformat

correct initial timestamps which have AV_NOPTS_VALUE
author michael
date Sat, 04 Aug 2007 22:46:13 +0000
parents fe59c768ecf7
children 45a6610e6a4f
files avformat.h utils.c
diffstat 2 files changed, 34 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/avformat.h	Sat Aug 04 12:33:34 2007 +0000
+++ b/avformat.h	Sat Aug 04 22:46:13 2007 +0000
@@ -280,9 +280,10 @@
      */
     AVRational r_frame_rate;
     void *priv_data;
-#if LIBAVFORMAT_VERSION_INT < (52<<16)
+
     /* internal data used in av_find_stream_info() */
-    int64_t codec_info_duration;
+    int64_t first_dts;
+#if LIBAVFORMAT_VERSION_INT < (52<<16)
     int codec_info_nb_frames;
 #endif
     /** encoding: PTS generation when outputing stream */
--- a/utils.c	Sat Aug 04 12:33:34 2007 +0000
+++ b/utils.c	Sat Aug 04 22:46:13 2007 +0000
@@ -589,6 +589,28 @@
     return 0;
 }
 
+static void update_initial_timestamps(AVFormatContext *s, int stream_index, int64_t dts){
+    AVStream *st= s->streams[stream_index];
+    AVPacketList *pktl= s->packet_buffer;
+
+    if(st->first_dts != AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE)
+        return;
+
+    st->first_dts= dts - st->cur_dts;
+    st->cur_dts= dts;
+
+    for(; pktl; pktl= pktl->next){
+        if(pktl->pkt.stream_index != stream_index)
+            continue;
+        //FIXME think more about this check
+        if(pktl->pkt.pts != AV_NOPTS_VALUE && pktl->pkt.pts == pktl->pkt.dts)
+            pktl->pkt.pts += st->first_dts;
+
+        if(pktl->pkt.dts != AV_NOPTS_VALUE)
+            pktl->pkt.dts += st->first_dts;
+    }
+}
+
 static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
                                AVCodecParserContext *pc, AVPacket *pkt)
 {
@@ -633,7 +655,7 @@
         presentation_delayed = 1;
 
     if(st->cur_dts == AV_NOPTS_VALUE){
-        st->cur_dts = -delay * pkt->duration;
+        st->cur_dts = 0; //FIXME maybe set it to 0 during init
     }
 
 //    av_log(NULL, AV_LOG_DEBUG, "IN delayed:%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64" st:%d pc:%p\n", presentation_delayed, pkt->pts, pkt->dts, st->cur_dts, pkt->stream_index, pc);
@@ -644,6 +666,7 @@
             /* PTS = presentation time stamp */
             if (pkt->dts == AV_NOPTS_VALUE)
                 pkt->dts = st->last_IP_pts;
+            update_initial_timestamps(s, pkt->stream_index, pkt->dts);
             if (pkt->dts == AV_NOPTS_VALUE)
                 pkt->dts = st->cur_dts;
 
@@ -669,6 +692,7 @@
             /* presentation is not delayed : PTS and DTS are the same */
             if(pkt->pts == AV_NOPTS_VALUE)
                 pkt->pts = pkt->dts;
+            update_initial_timestamps(s, pkt->stream_index, pkt->pts);
             if(pkt->pts == AV_NOPTS_VALUE)
                 pkt->pts = st->cur_dts;
             pkt->dts = pkt->pts;
@@ -684,6 +708,9 @@
             FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
         if(pkt->dts == AV_NOPTS_VALUE)
             pkt->dts= st->pts_buffer[0];
+        if(delay>1){
+            update_initial_timestamps(s, pkt->stream_index, pkt->dts); // this should happen on the first packet
+        }
         if(pkt->dts > st->cur_dts)
             st->cur_dts = pkt->dts;
     }
@@ -1767,6 +1794,8 @@
             if (st->codec->codec_type == CODEC_TYPE_AUDIO &&
                 st->codec->codec_id == CODEC_ID_NONE)
                 break;
+            if(st->first_dts == AV_NOPTS_VALUE)
+                break;
         }
         if (i == ic->nb_streams) {
             /* NOTE: if the format has no header, then we need to read
@@ -2050,6 +2079,7 @@
     st->start_time = AV_NOPTS_VALUE;
     st->duration = AV_NOPTS_VALUE;
     st->cur_dts = AV_NOPTS_VALUE;
+    st->first_dts = AV_NOPTS_VALUE;
 
     /* default pts settings is MPEG like */
     av_set_pts_info(st, 33, 1, 90000);