[FFmpeg-devel] [PATCH] Wrong duration in TS container (Ticket #1836)

Heesuk Jung heesuk.jung at lge.com
Tue Oct 30 10:43:54 CET 2012


Hi,

Michael wrote:
> Ive tested the patch a bit and it breaks finding the correct duration of:
> https://ffmpeg.org/trac/ffmpeg/raw-attachment/ticket/1186/sync1.ogg

I update patches and did regression test for 472 files include "sync1.ogg".
(I compared extracted duration value with master version and patch applied
master.)

Test result is ok and duration of 4 files with patch is more improved than
original duration.

Thanks !

>From 6af199fbd89ecc9441ce84789e4f1a6800128670 Mon Sep 17 00:00:00 2001
From: Heesuk Jung <heesuk.jung at lge.com>
Date: Tue, 30 Oct 2012 18:29:47 +0900
Subject: [PATCH] Wrong duration in TS container (Ticket #1836)

Libavformat somtimes get wrong duration in some TS conatiner.
Please refer the problem description and file link in Ticket #1836.
(http://ffmpeg.org/trac/ffmpeg/ticket/1836)

I have just modified 2 points as below.

1. check if duration estimation is reasonable or not.

examine if estimated duration is valid based on bit rate information.
The duration is regarded as abnormal value if it is unreasonably bigger
than file size / average bit rate.

2. check if PTS time diff is reasonable or not.

Duration is determined comparing PTS time diff with estimated duration.
(Actually final duration is selected as bigger value in PTS time diff and
estimated duration) I suggest that don't beleive duration based on PTS time
diff if time diff is bigger than hueristic value (file size / average bit
rate * 2).
---
 libavformat/utils.c |   87
+++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 84 insertions(+), 3 deletions(-)
 mode change 100644 => 100755 ffprobe.c
 mode change 100644 => 100755 libavformat/utils.c

diff --git a/ffprobe.c b/ffprobe.c
old mode 100644
new mode 100755
diff --git a/libavformat/utils.c b/libavformat/utils.c
old mode 100644
new mode 100755
index fb5742b..cf76cc1
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2012,6 +2012,68 @@ int avformat_seek_file(AVFormatContext *s, int
stream_index, int64_t min_ts, int
     // try some generic seek like seek_frame_generic() but with new ts
semantics
 }
 
+/**
+ * examine if duration is valid based on bit rate information or not.
+ * Duration is regarded as invlaid value
+ * if duration is unreasonably bigger than file size/average bit rate.
+ * hueristically suggest  limit_filesize_multiple that means double file
size
+ * @return 1 if duration is valid.
+ *         0 if duration is not valid.
+ */
+static int check_duration_using_bit_rate(const int64_t duration,
+                                         const int64_t filesize, int const
bit_rate)
+{
+    const uint8_t limit_filesize_multiple = 3;
+
+    if (bit_rate > 0 &&
+        duration >
(filesize*8/(bit_rate/1000)*limit_filesize_multiple*1000)) {
+        return 0;
+    }
+    return 1;
+}
+
+/**
+ * examine if estimated duration is valid or not.
+ * Estimated duration is regarded as invalid value
+ * if duration is unreasonably bigger than file size/average bit rate.
+ * @return 1 if duration estimeation is valid.
+ *         0 if duration estimation is not valid.
+ */
+static int valid_duration_estimation(AVFormatContext *ic)
+{
+    const int64_t duration = ic->duration;
+    const int64_t filesize = avio_size(ic->pb);
+    const uint8_t limit_bitrate_multiple = 10;
+    uint8_t i = 0;
+    int bit_rate = 0;
+    AVStream *st;
+
+    for (i=0; i<ic->nb_streams; i++) {
+        st = ic->streams[i];
+        if (st->codec->bit_rate > 0) {
+            switch (st->codec->codec_type) {
+            case AVMEDIA_TYPE_VIDEO:
+                bit_rate += st->codec->bit_rate;
+                break;
+            case AVMEDIA_TYPE_AUDIO:
+                bit_rate += st->codec->bit_rate;
+                break;
+            }
+	    }
+    }
+    if (ic->bit_rate > 0 &&
+        bit_rate > ic->bit_rate*limit_bitrate_multiple) {
+        bit_rate = ic->bit_rate;
+    }
+
+	if (duration == AV_NOPTS_VALUE ||
+	    !check_duration_using_bit_rate(duration, filesize, bit_rate)) {
+	    ic->bit_rate = bit_rate;
+	    return 0;
+    }
+	return 1;
+}
+
 /*******************************************************/
 
 /**
@@ -2089,11 +2151,16 @@ static void update_stream_timings(AVFormatContext
*ic)
             if (ic->nb_programs) {
                 for (i=0; i<ic->nb_programs; i++) {
                     p = ic->programs[i];
-                    if(p->start_time != AV_NOPTS_VALUE && p->end_time >
p->start_time)
-                        duration = FFMAX(duration, p->end_time -
p->start_time);
+                    if(p->start_time != AV_NOPTS_VALUE && p->end_time >
p->start_time) {
+                        if (check_duration_using_bit_rate(p->end_time -
p->start_time,
+
avio_size(ic->pb), ic->bit_rate)) {
+                            duration = FFMAX(duration, p->end_time -
p->start_time);
+                        }
+                    }
                 }
-            } else
+            } else {
                 duration = FFMAX(duration, end_time - start_time);
+            }
         }
     }
     if (duration != INT64_MIN && duration > 0 && ic->duration ==
AV_NOPTS_VALUE) {
@@ -2265,6 +2332,20 @@ static void estimate_timings(AVFormatContext *ic,
int64_t old_offset)
         estimate_timings_from_bit_rate(ic);
         ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE;
     }
+    if ((ic->duration_estimation_method != AVFMT_DURATION_FROM_BITRATE) &&
+        !valid_duration_estimation(ic)) {
+        uint8_t i = 0;
+        AVStream *st;
+        ic->duration = AV_NOPTS_VALUE;
+        for (i=0; i<ic->nb_streams; i++) {
+            st = ic->streams[i];
+            st->duration = AV_NOPTS_VALUE;
+        }
+        av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this
may be inaccurate\n");
+        /* less precise: use bitrate info */
+        estimate_timings_from_bit_rate(ic);
+        ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE;
+    }
     update_stream_timings(ic);
 
     {
-- 
1.7.0.4

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Wrong-duration-in-TS-container-Ticket-1836.patch
Type: application/octet-stream
Size: 5619 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20121030/688105e6/attachment.obj>


More information about the ffmpeg-devel mailing list