[FFmpeg-devel] [PATCH] Wrong duration in TS container (Ticket #1836)
Heesuk Jung
heesuk.jung at lge.com
Thu Oct 25 10:30:54 CEST 2012
Hi,
Please review new patch for #1836.
Thanks!
-----Original Message-----
From: ffmpeg-devel-bounces at ffmpeg.org
[mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf Of Heesuk Jung
Sent: Wednesday, October 24, 2012 2:30 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)
Hi Michael,
Please review new patch as below.
If you can not apply patch as corrupted e-mail, please check attached patch
file.
> 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
These 2 may need a heuristic like your patch, i dont immedeatly see a better
solution
-> Understand and I updated new patch for the above 2 files.
Test result for 2 files is ok and also 3
other problematic files is ok.(New patch is not effected for 3 files.)
Could you let me know changed id for other 3 problematic files ?
Thanks!
>From 0afa8caa8927dc4a3d0a1a58b6a40bf10023f12a Mon Sep 17 00:00:00 2001
From: Heesuk Jung <heesuk.jung at lge.com>
Date: Wed, 24 Oct 2012 14:14:26 +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)
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 some hueristic vlaue(file size / average bit rate * 2).
2. check if program time diff is reasonable or not.
Duration is determined comparing program time diff with estimated duration.
(Progrma time diff is "program end time - program start time.
Actually duration is selected as bigger value in time diff and estimated
duration.)
I suggest that we don't beleive time diff if time diff is bigger than
hueristic value (file size / average bit rate * 2).
---
libavformat/utils.c | 75
++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 72 insertions(+), 3 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 cd4161f..edd005b
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2012,6 +2012,55 @@ 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 = 2;
+
+ if (bit_rate > 0 &&
+ duration > (filesize*8/bit_rate*limit_filesize_multiple*1000000)) {
+ 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);
+ 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)
+ bit_rate += st->codec->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 +2138,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 +2319,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