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, 4 years ago)

Resolving Patch

  • 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 
    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 > (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 */ 
     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 (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 
    20152076/*******************************************************/ 
    20162077 
    20172078/** 
    static void update_stream_timings(AVFormatContext *ic) 
    20892150            if (ic->nb_programs) { 
    20902151                for (i=0; i<ic->nb_programs; i++) { 
    20912152                    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                    } 
    20942159                } 
    2095             } else 
     2160            } else { 
    20962161                duration = FFMAX(duration, end_time - start_time); 
     2162            } 
    20972163        } 
    20982164    } 
    20992165    if (duration != INT64_MIN && duration > 0 && ic->duration == AV_NOPTS_VALUE) { 
    static void estimate_timings(AVFormatContext *ic, int64_t old_offset) 
    22652331        estimate_timings_from_bit_rate(ic); 
    22662332        ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE; 
    22672333    } 
     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    } 
    22682348    update_stream_timings(ic); 
    22692349 
    22702350    {