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

Heesuk Jung heesuk.jung at lge.com
Tue Oct 23 01:59:07 CEST 2012


Hi Michael,

Please review the latest patch as below.

I understood your comment and so I don't change "MPEGTS" condition.
I improved 5 problematic files after applying patch.

* Test Result for 5 problematic files
                                    Correct Duration    After Patch
Before Patch
472_tp_mpeg2_mp3.tp              00:00:13             00:00:21           N/A
C049_flv.flv                       00:00:27             00:00:26
00:03:44
473_tp_mpeg2_ac3.tp              00:00:19             00:00:21
00:03:15
[2]_TRP_MPEG2_MP2.tp             00:01:12            00:01:12
24:08:38
[1]_WMV_WVC1_NONE.wmv           00:08:20             00:08:17
01:29:14

-> After applying, libavformat does not get exact duration but more better
duration.

File link :
472_tp_mpeg2_mp3.tp :
https://docs.google.com/open?id=0B6r7ZfWFIypCdllqQW1KTjlibXM
C049_flv.flv : https://docs.google.com/open?id=0B6r7ZfWFIypCUi15X3NoQmk4YXM
473_tp_mpeg2_ac3.tp :
https://docs.google.com/open?id=0B6r7ZfWFIypCNFVuWHowMFBBN0E
[2]_TRP_MPEG2_MP2.tp :
https://docs.google.com/open?id=0B6r7ZfWFIypCN0Q2VmZiUHdsQW8
[1]_WMV_WVC1_NONE.wmv :
https://docs.google.com/open?id=0B6r7ZfWFIypCU0VaX2cyakFhSzg

Thanks

-----Original Message-----
From: ffmpeg-devel-bounces at ffmpeg.org [mailto:ffmpeg-devel-
bounces at ffmpeg.org] On Behalf Of Heesuk Jung
Sent: Monday, October 22, 2012 7:58 PM
To: 'FFmpeg development discussions and patches'
Cc: donggul.kim at lge.com; wonsik at google.com; chungshik at google.com;
dwkang at google.com
Subject: Re: [FFmpeg-devel] [PATCH] Wrong duration in TS container (Ticket
#1836)

>From cdac9ec5ec8a3e66f7f818d1a27fefee4e2e611b Mon Sep 17 00:00:00 2001
From: Heesuk Jung <heesuk.jung at lge.com>
Date: Mon, 22 Oct 2012 19:33:27 +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 |   74
+++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 72 insertions(+), 2 deletions(-)  mode change 100644 =>
100755 libavformat/utils.c

diff --git a/libavformat/utils.c b/libavformat/utils.c old mode 100644 new
mode 100755 index f27104e..7cdcddc
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2012,6 +2012,57 @@ 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 considered 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 = 2;
+
+    if (bit_rate > 0) {
+        if (duration >
(filesize*8/bit_rate*limit_filesize_multiple*1000000)) {
+            return 0;
+        }
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+/**
+ * examine if estimated duration is valid based on bit rate information 
+or
not.
+ * Estimated duration is considered if duration is unreasonably bigger 
+ than
file size/average bit rate.
+ * @return 1 if duration is valid.
+ *         0 if duration is not valid.
+ */
+static int valid_duration_estimation(AVFormatContext *ic) {
+    const int64_t duration = ic->duration;
+    const int64_t filesize = avio_size(ic->pb);
+    int bit_rate = 0;
+    int i = 0;
+    AVStream *st;
+
+    for (i=0; i<ic->nb_streams; i++) {
+        st = ic->streams[i];
+        if (st->codec->bit_rate > 0)
+            bit_rate += st->codec->bit_rate;
+    }
+
+    if (bit_rate != 0) {
+        if ((duration == AV_NOPTS_VALUE) ||
+            !check_duration_using_bit_rate(duration, filesize, bit_rate)) {
+            ic->bit_rate = bit_rate;
+            return 0;
+        }
+    }
+    return 1;
+}
+
 /*******************************************************/
 
 /**
@@ -2077,8 +2128,12 @@ static void update_stream_timings(AVFormatContext
*ic)
 
     if (start_time != INT64_MAX) {
         ic->start_time = start_time;
-        if (end_time != INT64_MIN)
-            duration = FFMAX(duration, end_time - start_time);
+        if (end_time != INT64_MIN) {
+            int64_t duration_time_diff = end_time - start_time;
+            if (check_duration_using_bit_rate(duration_time_diff,
avio_size(ic->pb), ic->bit_rate)) {
+                duration = FFMAX(duration, duration_time_diff);
+            }
+        }
     }
     if (duration != INT64_MIN && duration > 0 && ic->duration ==
AV_NOPTS_VALUE) {
         ic->duration = duration;
@@ -2249,6 +2304,21 @@ 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




More information about the ffmpeg-devel mailing list