Ticket #1836: 0001-Wrong-duration-in-TS-container-Ticket-1836.3.patch

File 0001-Wrong-duration-in-TS-container-Ticket-1836.3.patch, 5.5 KB (added by Heesuk Jung, 4 years ago)

Resolving Patch

  • libavformat/utils.c

    From 8beba62059f0139d85a9142d8ec99958685323fb Mon Sep 17 00:00:00 2001
    From: Heesuk Jung <heesuk.jung@lge.com>
    Date: Tue, 30 Oct 2012 05:42:36 -0700
    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 file 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..9f88076
    a b int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int 
    20122012    // try some generic seek like seek_frame_generic() but with new ts semantics 
    20132013} 
    20142014 
     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 */ 
     2023static 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 > (limit_filesize_multiple*filesize*8/bit_rate*1000000)) { 
     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 */ 
     2042static 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 (ic->bit_rate > 0 && 
     2065        bit_rate > ic->bit_rate*limit_bitrate_multiple) { 
     2066        bit_rate = ic->bit_rate; 
     2067    } 
     2068 
     2069        if (duration == AV_NOPTS_VALUE || 
     2070            !check_duration_using_bit_rate(duration, filesize, bit_rate)) { 
     2071            ic->bit_rate = bit_rate; 
     2072            return 0; 
     2073    } 
     2074        return 1; 
     2075} 
     2076 
    20152077/*******************************************************/ 
    20162078 
    20172079/** 
    static void update_stream_timings(AVFormatContext *ic) 
    20892151            if (ic->nb_programs) { 
    20902152                for (i=0; i<ic->nb_programs; i++) { 
    20912153                    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); 
     2154                    if(p->start_time != AV_NOPTS_VALUE && p->end_time > p->start_time) { 
     2155                        if (check_duration_using_bit_rate(p->end_time - p->start_time, 
     2156                                                          avio_size(ic->pb), ic->bit_rate)) { 
     2157                            duration = FFMAX(duration, p->end_time - p->start_time); 
     2158                        } 
     2159                    } 
    20942160                } 
    2095             } else 
     2161            } else { 
    20962162                duration = FFMAX(duration, end_time - start_time); 
     2163            } 
    20972164        } 
    20982165    } 
    20992166    if (duration != INT64_MIN && duration > 0 && ic->duration == AV_NOPTS_VALUE) { 
    static void estimate_timings(AVFormatContext *ic, int64_t old_offset) 
    22652332        estimate_timings_from_bit_rate(ic); 
    22662333        ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE; 
    22672334    } 
     2335    if ((ic->duration_estimation_method != AVFMT_DURATION_FROM_BITRATE) && 
     2336        !valid_duration_estimation(ic)) { 
     2337        uint8_t i = 0; 
     2338        AVStream *st; 
     2339        ic->duration = AV_NOPTS_VALUE; 
     2340        for (i=0; i<ic->nb_streams; i++) { 
     2341            st = ic->streams[i]; 
     2342            st->duration = AV_NOPTS_VALUE; 
     2343        } 
     2344        av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n"); 
     2345        /* less precise: use bitrate info */ 
     2346        estimate_timings_from_bit_rate(ic); 
     2347        ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE; 
     2348    } 
    22682349    update_stream_timings(ic); 
    22692350 
    22702351    {