Ticket #1836: 0001-PATCH-Wrong-duration-in-TS-container-Ticket-1836.patch
| File 0001-PATCH-Wrong-duration-in-TS-container-Ticket-1836.patch, 5.4 KB (added by Heesuk Jung, 7 months ago) |
|---|
-
libavformat/utils.c
From 90cd184d1c45c8586c9f58115fc88a7b0e913839 Mon Sep 17 00:00:00 2001 From: Heesuk Jung <heesuk.jung@lge.com> Date: Mon, 29 Oct 2012 07:28:11 -0700 Subject: [PATCH] [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 | 86 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 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 fb5742b..a8f6779
a b int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int 2012 2012 // try some generic seek like seek_frame_generic() but with new ts semantics 2013 2013 } 2014 2014 2015 /** 2016 * examine if duration is valid based on bit rate information or not. 2017 * Duration is regarded as invlaid value 2018 * if duration is unreasonably bigger than file size/average bit rate. 2019 * hueristically suggest limit_filesize_multiple that means double file size 2020 * @return 1 if duration is valid. 2021 * 0 if duration is not valid. 2022 */ 2023 static int check_duration_using_bit_rate(const int64_t duration, 2024 const int64_t filesize, int const bit_rate) 2025 { 2026 const uint8_t limit_filesize_multiple = 3; 2027 2028 if (bit_rate > 0 && 2029 duration > (filesize*8/(bit_rate/1000)*limit_filesize_multiple*1000)) { 2030 return 0; 2031 } 2032 return 1; 2033 } 2034 2035 /** 2036 * examine if estimated duration is valid or not. 2037 * Estimated duration is regarded as invalid value 2038 * if duration is unreasonably bigger than file size/average bit rate. 2039 * @return 1 if duration estimeation is valid. 2040 * 0 if duration estimation is not valid. 2041 */ 2042 static int valid_duration_estimation(AVFormatContext *ic) 2043 { 2044 const int64_t duration = ic->duration; 2045 const int64_t filesize = avio_size(ic->pb); 2046 const uint8_t limit_bitrate_multiple = 10; 2047 uint8_t i = 0; 2048 int bit_rate = 0; 2049 AVStream *st; 2050 2051 for (i=0; i<ic->nb_streams; i++) { 2052 st = ic->streams[i]; 2053 if (st->codec->bit_rate > 0) { 2054 switch (st->codec->codec_type) { 2055 case AVMEDIA_TYPE_VIDEO: 2056 bit_rate += st->codec->bit_rate; 2057 break; 2058 case AVMEDIA_TYPE_AUDIO: 2059 bit_rate += st->codec->bit_rate; 2060 break; 2061 } 2062 } 2063 } 2064 if (bit_rate > ic->bit_rate*limit_bitrate_multiple) { 2065 bit_rate = ic->bit_rate; 2066 } 2067 2068 if (duration == AV_NOPTS_VALUE || 2069 !check_duration_using_bit_rate(duration, filesize, bit_rate)) { 2070 ic->bit_rate = bit_rate; 2071 return 0; 2072 } 2073 return 1; 2074 } 2075 2015 2076 /*******************************************************/ 2016 2077 2017 2078 /** … … static void update_stream_timings(AVFormatContext *ic) 2089 2150 if (ic->nb_programs) { 2090 2151 for (i=0; i<ic->nb_programs; i++) { 2091 2152 p = ic->programs[i]; 2092 if(p->start_time != AV_NOPTS_VALUE && p->end_time > p->start_time) 2093 duration = FFMAX(duration, p->end_time - p->start_time); 2153 if(p->start_time != AV_NOPTS_VALUE && p->end_time > p->start_time) { 2154 if (check_duration_using_bit_rate(p->end_time - p->start_time, 2155 avio_size(ic->pb), ic->bit_rate)) { 2156 duration = FFMAX(duration, p->end_time - p->start_time); 2157 } 2158 } 2094 2159 } 2095 } else 2160 } else { 2096 2161 duration = FFMAX(duration, end_time - start_time); 2162 } 2097 2163 } 2098 2164 } 2099 2165 if (duration != INT64_MIN && duration > 0 && ic->duration == AV_NOPTS_VALUE) { … … static void estimate_timings(AVFormatContext *ic, int64_t old_offset) 2265 2331 estimate_timings_from_bit_rate(ic); 2266 2332 ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE; 2267 2333 } 2334 if ((ic->duration_estimation_method != AVFMT_DURATION_FROM_BITRATE) && 2335 !valid_duration_estimation(ic)) { 2336 uint8_t i = 0; 2337 AVStream *st; 2338 ic->duration = AV_NOPTS_VALUE; 2339 for (i=0; i<ic->nb_streams; i++) { 2340 st = ic->streams[i]; 2341 st->duration = AV_NOPTS_VALUE; 2342 } 2343 av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n"); 2344 /* less precise: use bitrate info */ 2345 estimate_timings_from_bit_rate(ic); 2346 ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE; 2347 } 2268 2348 update_stream_timings(ic); 2269 2349 2270 2350 {
