[FFmpeg-devel] [PATCH] make analyze_duration work for streams with incomplete timestamps (mp3)

Reimar Döffinger Reimar.Doeffinger
Sun Sep 13 12:41:09 CEST 2009


Hello,
currently max_analyze_duration does not work for e.g.
http://208.80.52.108:80/KDLDFM because the mpeg audio parser is very
thorough in making a mess of timestamps.
Basically, only every 4th packet has a timestamp and thus none at all
have any duration.
Attached patch handles this case by using the difference between the
minimum and current dts for comparing against max_analyze_duration when
we have no other duration info.
-------------- next part --------------
Index: libavformat/utils.c
===================================================================
--- libavformat/utils.c	(revision 19824)
+++ libavformat/utils.c	(working copy)
@@ -2015,6 +2015,7 @@
     AVStream *st;
     AVPacket pkt1, *pkt;
     int64_t last_dts[MAX_STREAMS];
+    int64_t min_dts[MAX_STREAMS];
     int64_t duration_gcd[MAX_STREAMS]={0};
     int duration_count[MAX_STREAMS]={0};
     double (*duration_error)[MAX_STD_TIMEBASES];
@@ -2043,12 +2044,14 @@
     }
 
     for(i=0;i<MAX_STREAMS;i++){
+        min_dts[i] =
         last_dts[i]= AV_NOPTS_VALUE;
     }
 
     count = 0;
     read_size = 0;
     for(;;) {
+        int64_t analyze_duration = AV_NOPTS_VALUE;
         if(url_interrupt_cb()){
             ret= AVERROR(EINTR);
             av_log(ic, AV_LOG_DEBUG, "interrupted\n");
@@ -2117,12 +2120,20 @@
         read_size += pkt->size;
 
         st = ic->streams[pkt->stream_index];
+
+        if (min_dts[st->index] == AV_NOPTS_VALUE || (pkt->dts != AV_NOPTS_VALUE && pkt->dts < min_dts[st->index]))
+            min_dts[st->index] = pkt->dts;
         if(codec_info_nb_frames[st->index]>1) {
-            if (st->time_base.den > 0 && av_rescale_q(codec_info_duration[st->index], st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration){
+            analyze_duration = codec_info_duration[st->index];
+            codec_info_duration[st->index] += pkt->duration;
+        } else if (min_dts[st->index] != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE)
+            analyze_duration = pkt->dts - min_dts[st->index];
+
+        if (analyze_duration != AV_NOPTS_VALUE) {
+            if (st->time_base.den > 0 && av_rescale_q(analyze_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration){
                 av_log(ic, AV_LOG_DEBUG, "max_analyze_duration reached\n");
                 break;
             }
-            codec_info_duration[st->index] += pkt->duration;
         }
         if (pkt->duration != 0)
             codec_info_nb_frames[st->index]++;



More information about the ffmpeg-devel mailing list