Ticket #2086: ffmpeg-72ff8ee-wg.diff

File ffmpeg-72ff8ee-wg.diff, 56.3 KB (added by cehoyos, 4 years ago)
  • configure

    diff --git a/configure b/configure
    index faea887..f933fd8 100755
    a b External library support: 
    232232                           native MPEG-4/Xvid encoder exists [no] 
    233233  --enable-openal          enable OpenAL 1.1 capture support [no] 
    234234  --enable-openssl         enable openssl [no] 
     235  --enable-teletext-zvbi   enable teletext support via libzvbi [no] 
    235236  --enable-zlib            enable zlib [autodetect] 
    236237 
    237238Advanced options (experts only): 
    CONFIG_LIST=" 
    12061207    sram 
    12071208    static 
    12081209    swscale_alpha 
     1210    teletext_zvbi 
    12091211    thumb 
    12101212    vaapi 
    12111213    vda 
    zlib_decoder_select="zlib" 
    17751777zlib_encoder_select="zlib" 
    17761778zmbv_decoder_select="zlib" 
    17771779zmbv_encoder_select="zlib" 
     1780#teletext_decoder_select="teletext_zvbi" 
    17781781 
    17791782# hardware accelerators 
    17801783crystalhd_deps="libcrystalhd_libcrystalhd_if_h" 
    libxavs_encoder_deps="libxavs" 
    18581861libxvid_encoder_deps="libxvid" 
    18591862libutvideo_decoder_deps="libutvideo" 
    18601863libutvideo_encoder_deps="libutvideo" 
     1864teletext_decoder_deps="teletext_zvbi" 
    18611865 
    18621866# demuxers / muxers 
    18631867ac3_demuxer_select="ac3_parser" 
    enabled openssl && { check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto 
    38723876                        check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 || 
    38733877                        check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || 
    38743878                        die "ERROR: openssl not found"; } 
     3879enabled teletext_zvbi && require libzvbi libzvbi.h vbi_decoder_new -lzvbi 
    38753880 
    38763881if enabled gnutls; then 
    38773882    { check_lib nettle/bignum.h nettle_mpz_get_str_256 -lnettle -lhogweed -lgmp && enable nettle; } || 
    echo "libxavs enabled ${libxavs-no}" 
    42734278echo "libxvid enabled           ${libxvid-no}" 
    42744279echo "openal enabled            ${openal-no}" 
    42754280echo "openssl enabled           ${openssl-no}" 
     4281echo "teletext_zvbi enabled     ${teletext_zvbi-no}" 
    42764282echo "zlib enabled              ${zlib-no}" 
    42774283echo "bzlib enabled             ${bzlib-no}" 
    42784284echo "texi2html enabled         ${texi2html-no}" 
  • ffmpeg.c

    diff --git a/ffmpeg.c b/ffmpeg.c
    index 977218f..5b05549 100644
    a b static int64_t video_size = 0; 
    117117static int64_t audio_size = 0; 
    118118static int64_t subtitle_size = 0; 
    119119static int64_t extra_size = 0; 
     120static int64_t video_iframe_count = 0; 
     121static int64_t video_iframe_last; 
     122static int64_t video_iframe_delta_sum = 0; 
    120123static int nb_frames_dup = 0; 
    121124static int nb_frames_drop = 0; 
    122125 
    int nb_output_files = 0; 
    145148FilterGraph **filtergraphs; 
    146149int        nb_filtergraphs; 
    147150 
     151static double vdelta_sum; 
     152static long   vdelta_n; 
     153 
    148154#if HAVE_TERMIOS_H 
    149155 
    150156/* init terminal so that we can grab keys */ 
    static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) 
    573579    } 
    574580 
    575581    pkt->stream_index = ost->index; 
     582    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && 
     583        pkt->flags & AV_PKT_FLAG_KEY && pkt->pts != AV_NOPTS_VALUE) { 
     584        int64_t pts = av_rescale_q(pkt->pts, 
     585                                   s->streams[pkt->stream_index]->time_base, 
     586                                   AV_TIME_BASE_Q); 
     587        if (video_iframe_count++ > 0) 
     588            video_iframe_delta_sum += pts - video_iframe_last; 
     589        video_iframe_last = pts; 
     590    } 
    576591 
    577592    if (debug_ts) { 
    578593        av_log(NULL, AV_LOG_INFO, "muxer <- type:%s " 
    static void do_video_out(AVFormatContext *s, 
    796811 
    797812    sync_ipts = in_picture->pts; 
    798813    delta = sync_ipts - ost->sync_opts + duration; 
     814    vdelta_sum += delta; 
     815    ++vdelta_n; 
    799816 
    800817    /* by default, we output a single frame */ 
    801818    nb_frames = 1; 
    static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti 
    12451262        if(video_size + audio_size + subtitle_size + extra_size == 0){ 
    12461263            av_log(NULL, AV_LOG_WARNING, "Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)\n"); 
    12471264        } 
     1265        if (vdelta_n > 0) 
     1266            av_log(NULL, AV_LOG_VERBOSE, "vdelta_avg:%f\n", vdelta_sum/(double)vdelta_n); 
     1267        if (video_iframe_count > 0) 
     1268            av_log(NULL, AV_LOG_VERBOSE, "iframes_delta_avg:%f sec\n", (double)video_iframe_delta_sum/(video_iframe_count*AV_TIME_BASE)); 
    12481269    } 
    12491270} 
    12501271 
    static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p 
    13531374    av_init_packet(&opkt); 
    13541375 
    13551376    if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && 
    1356         !ost->copy_initial_nonkeyframes) 
     1377        !ost->copy_initial_nonkeyframes) { 
     1378        int64_t d = ist->next_pts - of->start_time; 
     1379        fprintf(stderr, "ist:%d dropping non-keyframe %"PRId64"\n", 
     1380                ist->st->index, d); 
     1381        av_interleaved_discard(of->ctx, d); 
     1382        // input context start_time is effectively increased by d 
     1383        if (!copy_ts) 
     1384            input_files[ist->file_index]->ts_offset -= d; 
    13571385        return; 
     1386    } 
    13581387 
    13591388    if (!ost->frame_number && ist->pts < of->start_time && 
    13601389        !ost->copy_prior_start) 
    static int process_input(int file_index) 
    27882817               av_ts2timestr(input_files[ist->file_index]->ts_offset, &AV_TIME_BASE_Q)); 
    27892818    } 
    27902819 
     2820    // Teletext streams are often shared between programs 
     2821    // and their absolute timestamps are meaningless 
     2822    if (ist->st->codec->codec_id == CODEC_ID_DVB_TELETEXT && !copy_ts) { 
     2823        pkt.dts = pkt.pts = av_rescale_q(av_get_cur_dts(is, -1), AV_TIME_BASE_Q, ist->st->time_base); 
     2824        //fprintf(stderr, "teletext %d ts set to %f -> %"PRId64"\n", ist_index, ipts_min, pkt.dts/90); 
     2825    } 
     2826 
    27912827    if(!ist->wrap_correction_done && is->start_time != AV_NOPTS_VALUE && ist->st->pts_wrap_bits < 64){ 
    27922828        int64_t stime, stime2; 
    27932829        // Correcting starttime based on the enabled streams 
    static int process_input(int file_index) 
    28442880            pkt_dts+1<ist->pts){ 
    28452881            ifile->ts_offset -= delta; 
    28462882            av_log(NULL, AV_LOG_DEBUG, 
    2847                    "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", 
    2848                    delta, ifile->ts_offset); 
     2883                   "ist_index:%d timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", 
     2884                   ifile->ist_index + pkt.stream_index, delta, ifile->ts_offset); 
    28492885            pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); 
    28502886            if (pkt.pts != AV_NOPTS_VALUE) 
    28512887                pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); 
  • ffmpeg_opt.c

    diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
    index fcd6048..e2b63da 100644
    a b static void add_input_streams(OptionsContext *o, AVFormatContext *ic) 
    628628        case AVMEDIA_TYPE_SUBTITLE: 
    629629            if(!ist->dec) 
    630630                ist->dec = avcodec_find_decoder(dec->codec_id); 
     631            if (dec->codec_id == CODEC_ID_DVB_SUBTITLE || 
     632                dec->codec_id == CODEC_ID_DVB_TELETEXT) 
     633                ist->fix_sub_duration = 1; 
    631634            MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st); 
    632635            break; 
    633636        case AVMEDIA_TYPE_ATTACHMENT: 
    static int open_input_file(OptionsContext *o, const char *filename) 
    810813            av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n", 
    811814                   filename, (double)timestamp / AV_TIME_BASE); 
    812815        } 
     816        if (av_get_cur_dts(ic, -1) != AV_NOPTS_VALUE) { 
     817            av_log(NULL, AV_LOG_INFO, "*** seek timestamp=%"PRId64"\n", timestamp); 
     818            timestamp = av_get_cur_dts(ic, -1); 
     819            av_log(NULL, AV_LOG_INFO, "*** after seek timestamp=%"PRId64"\n", timestamp); 
     820        } 
     821        /* reload stream parameters */ 
     822        if (ic->nb_streams > orig_nb_streams) 
     823            opts = grow_array(opts, sizeof *opts, &orig_nb_streams, ic->nb_streams); 
     824        ret = avformat_find_stream_info(ic, opts); 
     825        if (ret < 0) { 
     826            av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename); 
     827            avformat_close_input(&ic); 
     828            exit(1); 
     829        } 
    813830    } 
    814831 
    815832    /* update the current parameters so that they match the one of the input stream */ 
  • libavcodec/Makefile

    diff --git a/libavcodec/Makefile b/libavcodec/Makefile
    index 27c9a11..9bd17d9 100644
    a b OBJS-$(CONFIG_LIBVPX_ENCODER) += libvpxenc.o 
    702702OBJS-$(CONFIG_LIBX264_ENCODER)            += libx264.o 
    703703OBJS-$(CONFIG_LIBXAVS_ENCODER)            += libxavs.o 
    704704OBJS-$(CONFIG_LIBXVID_ENCODER)            += libxvid.o 
     705OBJS-$(CONFIG_TELETEXT_DECODER)           += teletextdec.o pes_parser.o 
    705706 
    706707# parsers 
    707708OBJS-$(CONFIG_AAC_PARSER)              += aac_parser.o aac_ac3_parser.o \ 
    OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o \ 
    738739                                          mpegaudiodecheader.o mpegaudiodata.o 
    739740OBJS-$(CONFIG_MPEGVIDEO_PARSER)        += mpegvideo_parser.o    \ 
    740741                                          mpeg12.o mpeg12data.o 
     742OBJS-$(CONFIG_PES_PARSER)              += pes_parser.o 
    741743OBJS-$(CONFIG_PNM_PARSER)              += pnm_parser.o pnm.o 
    742744OBJS-$(CONFIG_RV30_PARSER)             += rv34_parser.o 
    743745OBJS-$(CONFIG_RV40_PARSER)             += rv34_parser.o 
  • libavcodec/allcodecs.c

    diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
    index 987b877..91ccc5e 100644
    a b void avcodec_register_all(void) 
    457457    REGISTER_ENCDEC (SUBRIP,            subrip); 
    458458    REGISTER_DECODER(SUBVIEWER,         subviewer); 
    459459    REGISTER_DECODER(SUBVIEWER1,        subviewer1); 
     460    REGISTER_DECODER(TELETEXT,          teletext); 
    460461    REGISTER_DECODER(TEXT,              text); 
    461462    REGISTER_DECODER(VPLAYER,           vplayer); 
    462463    REGISTER_DECODER(WEBVTT,            webvtt); 
    void avcodec_register_all(void) 
    518519    REGISTER_PARSER(MPEG4VIDEO,         mpeg4video); 
    519520    REGISTER_PARSER(MPEGAUDIO,          mpegaudio); 
    520521    REGISTER_PARSER(MPEGVIDEO,          mpegvideo); 
     522    REGISTER_PARSER(PES,                pes); 
    521523    REGISTER_PARSER(PNG,                png); 
    522524    REGISTER_PARSER(PNM,                pnm); 
    523525    REGISTER_PARSER(RV30,               rv30); 
  • libavcodec/dvbsub_parser.c

    diff --git a/libavcodec/dvbsub_parser.c b/libavcodec/dvbsub_parser.c
    index 5274fd6..478e897 100644
    a b  
    3030/* parser definition */ 
    3131typedef struct DVBSubParseContext { 
    3232    uint8_t *packet_buf; 
    33     int packet_start; 
     33    int cursor; 
    3434    int packet_index; 
    3535    int in_packet; 
    3636} DVBSubParseContext; 
    static int dvbsub_parse(AVCodecParserContext *s, 
    4949                        const uint8_t *buf, int buf_size) 
    5050{ 
    5151    DVBSubParseContext *pc = s->priv_data; 
    52     uint8_t *p, *p_end; 
    53     int i, len, buf_pos = 0; 
     52    int i; 
    5453 
    5554    av_dlog(avctx, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n", 
    5655            s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]); 
    static int dvbsub_parse(AVCodecParserContext *s, 
    6867    *poutbuf = NULL; 
    6968    *poutbuf_size = 0; 
    7069 
    71     s->fetch_timestamp = 1; 
    72  
    73     if (s->last_pts != s->pts && s->pts != AV_NOPTS_VALUE) /* Start of a new packet */ 
    74     { 
    75         if (pc->packet_index != pc->packet_start) 
    76         { 
    77             av_dlog(avctx, "Discarding %d bytes\n", 
    78                     pc->packet_index - pc->packet_start); 
    79         } 
    80  
    81         pc->packet_start = 0; 
    82         pc->packet_index = 0; 
    83  
     70    if (!pc->in_packet) { 
    8471        if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) { 
    8572            av_dlog(avctx, "Bad packet header\n"); 
    86             return -1; 
     73            return buf_size; /* discard data */ 
    8774        } 
    88  
    89         buf_pos = 2; 
    90  
     75        if (buf_size-2 > PARSE_BUF_SIZE) 
     76            return -1; 
     77        memcpy(pc->packet_buf, buf+2, buf_size-2); 
     78        pc->cursor = 0; 
     79        pc->packet_index = buf_size-2; 
    9180        pc->in_packet = 1; 
    9281    } else { 
    93         if (pc->packet_start != 0) 
    94         { 
    95             if (pc->packet_index != pc->packet_start) 
    96             { 
    97                 memmove(pc->packet_buf, pc->packet_buf + pc->packet_start, 
    98                             pc->packet_index - pc->packet_start); 
    99  
    100                 pc->packet_index -= pc->packet_start; 
    101                 pc->packet_start = 0; 
    102             } else { 
    103                 pc->packet_start = 0; 
    104                 pc->packet_index = 0; 
    105             } 
    106         } 
     82        if (buf_size + pc->packet_index > PARSE_BUF_SIZE) 
     83            return -1; 
     84        memcpy(pc->packet_buf + pc->packet_index, buf, buf_size); 
     85        pc->packet_index += buf_size; 
    10786    } 
    10887 
    109     if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE) 
    110         return -1; 
    111  
    112 /* if not currently in a packet, discard data */ 
    113     if (pc->in_packet == 0) 
    114         return buf_size; 
    115  
    116     memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos); 
    117     pc->packet_index += buf_size - buf_pos; 
    118  
    119     p = pc->packet_buf; 
    120     p_end = pc->packet_buf + pc->packet_index; 
    121  
    122     while (p < p_end) 
    123     { 
    124         if (*p == 0x0f) 
    125         { 
    126             if (p + 6 <= p_end) 
    127             { 
    128                 len = AV_RB16(p + 4); 
     88    /* parse newly obtained segments */ 
     89    while (pc->cursor < pc->packet_index) { 
     90        if (pc->packet_buf[pc->cursor] == 0x0f) { 
     91            if (pc->cursor + 6 <= pc->packet_index) { 
     92                int len = AV_RB16(pc->packet_buf + pc->cursor + 4); 
    12993 
    130                 if (p + len + 6 <= p_end) 
    131                 { 
    132                     *poutbuf_size += len + 6; 
    133  
    134                     p += len + 6; 
     94                if (pc->cursor + len + 6 <= pc->packet_index) { 
     95                    pc->cursor += len + 6; 
    13596                } else 
    13697                    break; 
    13798            } else 
    13899                break; 
    139         } else if (*p == 0xff) { 
    140             if (p + 1 < p_end) 
    141             { 
     100        } else if (pc->packet_buf[pc->cursor] == 0xff) { 
     101            if (pc->cursor + 1 < pc->packet_index) { 
    142102                av_dlog(avctx, "Junk at end of packet\n"); 
    143103            } 
    144             pc->packet_index = p - pc->packet_buf; 
     104            *poutbuf = pc->packet_buf; 
     105            *poutbuf_size = pc->cursor; 
     106            pc->packet_index = 0; 
    145107            pc->in_packet = 0; 
     108            av_dlog(avctx, "parse packet sz:%d\n", *poutbuf_size); 
    146109            break; 
    147110        } else { 
    148111            av_log(avctx, AV_LOG_ERROR, "Junk in packet\n"); 
    149112 
    150             pc->packet_index = p - pc->packet_buf; 
    151113            pc->in_packet = 0; 
    152114            break; 
    153115        } 
    154116    } 
    155117 
    156     if (*poutbuf_size > 0) 
    157     { 
    158         *poutbuf = pc->packet_buf; 
    159         pc->packet_start = *poutbuf_size; 
    160     } 
    161  
    162     if (s->pts == AV_NOPTS_VALUE) 
    163         s->pts = s->last_pts; 
    164  
    165118    return buf_size; 
    166119} 
    167120 
  • new file libavcodec/pes_parser.c

    diff --git a/libavcodec/pes_parser.c b/libavcodec/pes_parser.c
    new file mode 100644
    index 0000000..074b3ad
    - +  
     1/* 
     2 * PES parsing for ffmpeg 
     3 * Copyright (c) 2008, 2011 Wolfram Gloger. 
     4 * 
     5 * This file is part of FFmpeg. 
     6 * 
     7 * FFmpeg is free software; you can redistribute it and/or 
     8 * modify it under the terms of the GNU Lesser General Public 
     9 * License as published by the Free Software Foundation; either 
     10 * version 2.1 of the License, or (at your option) any later version. 
     11 * 
     12 * FFmpeg is distributed in the hope that it will be useful, 
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     15 * Lesser General Public License for more details. 
     16 * 
     17 * You should have received a copy of the GNU Lesser General Public 
     18 * License along with FFmpeg; if not, write to the Free Software 
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
     20 */ 
     21#include "avcodec.h" 
     22#include "get_bits.h" 
     23 
     24/* parser definition */ 
     25typedef struct PESParseContext { 
     26    uint8_t *packet; 
     27    int packet_len; 
     28    int packet_index; 
     29} PESParseContext; 
     30 
     31static int pes_parse_init(AVCodecParserContext *s) 
     32{ 
     33    return 0; 
     34} 
     35 
     36static int pes_parse(AVCodecParserContext *s, 
     37                     AVCodecContext *avctx, 
     38                     const uint8_t **poutbuf, int *poutbuf_size, 
     39                     const uint8_t *buf, int buf_size) 
     40{ 
     41    int old_len; 
     42    PESParseContext *pc = s->priv_data; 
     43 
     44    if (pc->packet_index == 0) { 
     45        if (buf_size < 6 || buf[0]!=0x00 || buf[1]!=0x00 || buf[2]!=0x01) { 
     46            av_log(avctx, AV_LOG_DEBUG, "PES wrong header\n"); 
     47            *poutbuf = NULL; 
     48            *poutbuf_size = 0; 
     49            return buf_size; 
     50        } 
     51        old_len = pc->packet_len; 
     52        pc->packet_len = AV_RB16(buf + 4); 
     53        if (pc->packet_len == 0) /* unbounded */ 
     54            pc->packet_len = buf_size; 
     55        else 
     56            pc->packet_len += 6; 
     57        //av_log(avctx, AV_LOG_DEBUG, "PES len:%d\n", pc->packet_len); 
     58        if (pc->packet_len > old_len) { 
     59            av_freep(&pc->packet); 
     60            pc->packet = av_malloc(pc->packet_len); 
     61        } 
     62    } 
     63    if (pc->packet) { 
     64        if (pc->packet_index + buf_size <= pc->packet_len) { 
     65            memcpy(pc->packet + pc->packet_index, buf, buf_size); 
     66            pc->packet_index += buf_size; 
     67            if (pc->packet_index >= pc->packet_len) { 
     68                *poutbuf = pc->packet; 
     69                *poutbuf_size = pc->packet_len; 
     70                pc->packet_index = 0; 
     71                return buf_size; 
     72            } 
     73        } else { 
     74            /* erroneous size */ 
     75            pc->packet_index = 0; 
     76        } 
     77    } 
     78    *poutbuf = NULL; 
     79    *poutbuf_size = 0; 
     80    return buf_size; 
     81} 
     82 
     83static void pes_parse_close(AVCodecParserContext *s) 
     84{ 
     85    PESParseContext *pc = s->priv_data; 
     86    av_freep(&pc->packet); 
     87} 
     88 
     89AVCodecParser ff_pes_parser = { 
     90    { CODEC_ID_DVB_TELETEXT }, 
     91    sizeof(PESParseContext), 
     92    pes_parse_init, 
     93    pes_parse, 
     94    pes_parse_close, 
     95}; 
  • libavcodec/srtenc.c

    diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c
    index 3036a7f..33e9d8d 100644
    a b static av_cold int srt_encode_init(AVCodecContext *avctx) 
    137137{ 
    138138    SRTContext *s = avctx->priv_data; 
    139139    s->avctx = avctx; 
     140    if (!avctx->subtitle_header) 
     141        return 0; 
    140142    s->ass_ctx = ff_ass_split(avctx->subtitle_header); 
    141143    return s->ass_ctx ? 0 : AVERROR_INVALIDDATA; 
    142144} 
    static void srt_end_cb(void *priv) 
    225227        srt_print(priv, "\r\n\r\n"); 
    226228} 
    227229 
     230static void srt_print_timing(SRTContext *s, int sc, int ec) 
     231{ 
     232    int sh, sm, ss; 
     233    int eh, em, es; 
     234 
     235    sh = sc/3600000;  sc -= 3600000*sh; 
     236    sm = sc/  60000;  sc -=   60000*sm; 
     237    ss = sc/   1000;  sc -=    1000*ss; 
     238    eh = ec/3600000;  ec -= 3600000*eh; 
     239    em = ec/  60000;  ec -=   60000*em; 
     240    es = ec/   1000;  ec -=    1000*es; 
     241    srt_print(s,"%d\r\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n", 
     242              ++s->count, sh, sm, ss, sc, eh, em, es, ec); 
     243} 
     244 
    228245static const ASSCodesCallbacks srt_callbacks = { 
    229246    .text             = srt_text_cb, 
    230247    .new_line         = srt_new_line_cb, 
    static int srt_encode_frame(AVCodecContext *avctx, 
    250267 
    251268    for (i=0; i<sub->num_rects; i++) { 
    252269 
    253         if (sub->rects[i]->type != SUBTITLE_ASS) { 
    254             av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); 
    255             return AVERROR(ENOSYS); 
    256         } 
     270        switch (sub->rects[i]->type) { 
     271        case SUBTITLE_TEXT: { 
     272            int sc0 = av_rescale(sub->pts, 1000, AV_TIME_BASE); 
    257273 
     274            if (avctx->codec->id == CODEC_ID_SRT) 
     275                srt_print_timing(s, 
     276                                 sc0 + sub->start_display_time, 
     277                                 sc0 + sub->end_display_time); 
     278            srt_print(s, sub->rects[i]->text); 
     279            break; 
     280        } 
     281        case SUBTITLE_ASS: 
     282            if (!s->ass_ctx) { 
     283                av_log(avctx, AV_LOG_ERROR, "Got SUBTITLE_ASS but no header.\n"); 
     284                return AVERROR_INVALIDDATA; 
     285            } 
    258286        dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num); 
    259287        for (; dialog && num--; dialog++) { 
    260288            if (avctx->codec->id == AV_CODEC_ID_SRT) { 
    261                 int sh, sm, ss, sc = 10 * dialog->start; 
    262                 int eh, em, es, ec = 10 * dialog->end; 
    263                 sh = sc/3600000;  sc -= 3600000*sh; 
    264                 sm = sc/  60000;  sc -=   60000*sm; 
    265                 ss = sc/   1000;  sc -=    1000*ss; 
    266                 eh = ec/3600000;  ec -= 3600000*eh; 
    267                 em = ec/  60000;  ec -=   60000*em; 
    268                 es = ec/   1000;  ec -=    1000*es; 
    269                 srt_print(s,"%d\r\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n", 
    270                           ++s->count, sh, sm, ss, sc, eh, em, es, ec); 
     289                srt_print_timing(s, 10 * dialog->start, 10 * dialog->end); 
    271290                s->dialog_start = s->ptr - 2; 
    272291            } 
    273292            s->alignment_applied = 0; 
    274293            srt_style_apply(s, dialog->style); 
    275294            ff_ass_split_override_codes(&srt_callbacks, s, dialog->text); 
    276295        } 
    277     } 
     296        break; 
     297        default: 
     298            av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_TEXT, SUBTITLE_ASS types supported.\n"); 
     299            return AVERROR(ENOSYS); 
     300        } 
     301 
     302     } 
    278303 
    279304    if (s->ptr == s->buffer) 
    280305        return 0; 
  • new file libavcodec/teletextdec.c

    diff --git a/libavcodec/teletextdec.c b/libavcodec/teletextdec.c
    new file mode 100644
    index 0000000..a415a1d
    - +  
     1/* 
     2 * Teletext decoding for ffmpeg 
     3 * Copyright (c) 2005-2010, 2012 Wolfram Gloger. 
     4 * 
     5 * This library is free software; you can redistribute it and/or 
     6 * modify it under the terms of the GNU Lesser General Public 
     7 * License as published by the Free Software Foundation; either 
     8 * version 2 of the License, or (at your option) any later version. 
     9 * 
     10 * This library is distributed in the hope that it will be useful, 
     11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     13 * Lesser General Public License for more details. 
     14 * 
     15 * You should have received a copy of the GNU Lesser General Public 
     16 * License along with this library; if not, write to the Free Software 
     17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
     18 */ 
     19 
     20#include "avcodec.h" 
     21#include "libavutil/opt.h" 
     22 
     23#include <libzvbi.h> 
     24 
     25//#define DEBUG         1 
     26 
     27#define TEXT_MAXSZ    2044 
     28#define BINARIZE      0 
     29#define PALETTE_MAX   40 
     30#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) 
     31#define VBI_R(rgba)   (((rgba) >> 0) & 0xFF) 
     32#define VBI_G(rgba)   (((rgba) >> 8) & 0xFF) 
     33#define VBI_B(rgba)   (((rgba) >> 16) & 0xFF) 
     34#define VBI_A(rgba)   (((rgba) >> 24) & 0xFF) 
     35 
     36/* main data structure */ 
     37typedef struct TeletextContext 
     38{ 
     39    AVClass        *class; 
     40    char           *pgno; 
     41    int             y_offset; 
     42    int             ci_clip; 
     43    int             gen_bitmap; 
     44    int             force_chop_top; 
     45    int             sub_display_time; /* in msec */ 
     46 
     47    int             lines_processed; 
     48    int             last_rows, last_cols; 
     49    AVSubtitleRect *sub_rect; 
     50 
     51    vbi_decoder *   vbi; 
     52    vbi_dvb_demux * dx; 
     53#ifdef DEBUG 
     54    vbi_export *    ex; 
     55#endif 
     56    /* Don't even _think_ about making sliced stack-local! */ 
     57    vbi_sliced      sliced[64]; 
     58} TeletextContext; 
     59 
     60/************************************************************************/ 
     61 
     62static int 
     63teletext_decode_frame(AVCodecContext *avctx, 
     64                      void *data, int *data_size, 
     65                      AVPacket *pkt) 
     66{ 
     67    TeletextContext *ctx = avctx->priv_data; 
     68    AVSubtitle      *sub = data; 
     69    const uint8_t   *buf = pkt->data; 
     70    unsigned int    left = pkt->size; 
     71 
     72    while (left > 0) { 
     73        int64_t pts = 0; 
     74        unsigned int lines = vbi_dvb_demux_cor(ctx->dx, ctx->sliced, 64, &pts, &buf, &left); 
     75#ifdef DEBUG 
     76        av_log(avctx, AV_LOG_INFO, 
     77               " Teletext: ctx=%p buf_size=%d left=%u lines=%u pts=%f\n", 
     78               ctx, pkt->size, left, lines, (double)pts/90000.0); 
     79#endif 
     80        if (lines > 0) { 
     81#ifdef DEBUGx 
     82            int i; 
     83            for(i=0; i<lines; ++i) 
     84                if (ctx->sliced[i].id >= 0) 
     85                    av_log(avctx, AV_LOG_INFO, 
     86                           " Teletext: lines=%d id=%x\n", i, ctx->sliced[i].id); 
     87#endif 
     88            vbi_decode(ctx->vbi, ctx->sliced, lines, (double)pts/90000.0); 
     89            ctx->lines_processed += lines; 
     90        } 
     91    } 
     92 
     93    // is there a subtitle to pass? 
     94    if (ctx->sub_rect) { 
     95        sub->format = 0; 
     96        sub->start_display_time = 0; 
     97        sub->end_display_time = ctx->sub_display_time; 
     98        sub->num_rects = 0; 
     99 
     100        if (ctx->sub_rect->type != SUBTITLE_NONE) { 
     101            sub->rects = av_malloc(sizeof(*sub->rects) * 1); 
     102            if (sub->rects) { 
     103                sub->num_rects = 1; 
     104                sub->rects[0] = ctx->sub_rect; 
     105            } 
     106        } else { 
     107            av_log(avctx, AV_LOG_DEBUG, " Teletext: sending empty sub\n"); 
     108            sub->rects = 0; 
     109        } 
     110        if (!sub->rects) // no rect was passed 
     111            av_free(ctx->sub_rect); 
     112        ctx->sub_rect = 0; 
     113 
     114        *data_size = 1; 
     115    } else 
     116        *data_size = 0; 
     117 
     118    return pkt->size; 
     119} 
     120 
     121static int 
     122chop_spaces_utf8(const unsigned char* t, int len) 
     123{ 
     124    t += len; 
     125    while (len > 0) { 
     126        if (*--t != ' ' || (len-1 > 0 && *(t-1) & 0x80)) 
     127            break; 
     128        --len; 
     129    } 
     130    return len; 
     131} 
     132 
     133// draw a page as text 
     134static int 
     135gen_sub_text(TeletextContext *ctx, vbi_page *page, int chop_top) 
     136{ 
     137    AVSubtitleRect *sub_rect = ctx->sub_rect; 
     138    char *text; 
     139    const char *in; 
     140    char *out; 
     141    char *vbi_text = av_malloc(TEXT_MAXSZ); 
     142    int sz = vbi_print_page_region(page, vbi_text, TEXT_MAXSZ-1, "UTF-8", 
     143                                   /*table mode*/ TRUE, FALSE, 
     144                                   0,             chop_top, 
     145                                   page->columns, page->rows-chop_top); 
     146    if (sz <= 0) { 
     147        av_log(0, AV_LOG_ERROR, "vbi_print error\n"); 
     148        av_free(vbi_text); 
     149        return -1; 
     150    } 
     151    vbi_text[sz] = '\0'; 
     152    in  = vbi_text; 
     153    out = text = av_malloc(TEXT_MAXSZ); 
     154    for (;;) { 
     155        int nl, sz; 
     156 
     157        // skip leading spaces and newlines 
     158        in += strspn(in, " \n"); 
     159        // compute end of row 
     160        for (nl = 0; in[nl]; ++nl) 
     161            if (in[nl] == '\n' && (nl==0 || !(in[nl-1] & 0x80))) 
     162                break; 
     163        if (!in[nl]) 
     164            break; 
     165        // skip trailing spaces 
     166        sz = chop_spaces_utf8(in, nl); 
     167        memcpy(out, in, sz); 
     168        out += sz; 
     169        *out++ = '\n'; 
     170        in  += nl; 
     171    } 
     172    av_free(vbi_text); 
     173    *out = '\0'; 
     174    if (out > text) { 
     175        sub_rect->type = SUBTITLE_TEXT; 
     176        sub_rect->text = text; 
     177        av_log(0, AV_LOG_DEBUG, "subtext:%s:txetbus\n", text); 
     178    } else { 
     179        sub_rect->type = SUBTITLE_NONE; 
     180        av_free(text); 
     181    } 
     182    return 0; 
     183} 
     184 
     185static int 
     186find_ci_in_page(const vbi_rgba *pix, const vbi_page *page) 
     187{ 
     188    static int last_i = 0; // cache for performance 
     189 
     190    if (*pix == page->color_map[last_i]) 
     191        return last_i; 
     192    for (last_i=0; 
     193         last_i<(sizeof page->color_map)/(sizeof page->color_map[0]); 
     194         ++last_i) { 
     195        if (*pix == page->color_map[last_i]) 
     196            return last_i; 
     197    } 
     198    return -1; 
     199} 
     200 
     201// draw a page as bitmap 
     202static int 
     203gen_sub_bitmap(TeletextContext *ctx, vbi_page *page, int chop_top) 
     204{ 
     205    AVSubtitleRect *sub_rect = ctx->sub_rect; 
     206    int resx = page->columns*12, resy = page->rows*10; 
     207    int ix, iy, ci, ci_max = 0, ci_max_count = 0; 
     208    const vbi_rgba* vptr; 
     209    uint8_t *bptr; 
     210    char *canvas = av_malloc(resx*resy*sizeof(vbi_rgba)); 
     211 
     212    if (!canvas) 
     213        return -1; 
     214 
     215    /* only VBI_PIXFMT_RGBA32_LE is supported in libzvbi */ 
     216    vbi_draw_vt_page(page, VBI_PIXFMT_RGBA32_LE, canvas, 
     217                     /*reveal*/ 1, /*flash*/ 1); 
     218 
     219    if (chop_top) { 
     220        resy -= 10; 
     221        av_log(0, AV_LOG_DEBUG, " Teletext: chopping top line\n"); 
     222    } 
     223    //avpicture_alloc(&sub_rect->pict, PIX_FMT_PAL8, resx, resy); 
     224    sub_rect->pict.data[0] = av_mallocz(resx*resy); 
     225 
     226    vptr = (const vbi_rgba *)canvas + (chop_top*10*resx); 
     227    bptr = sub_rect->pict.data[0]; 
     228 
     229    for (iy=0; iy<resy; ++iy) { 
     230        for (ix=0; ix<resx; ++ix, ++vptr, ++bptr) { 
     231            ci = find_ci_in_page(vptr, page); 
     232            if (ci < 0) 
     233                av_log(0, AV_LOG_ERROR, 
     234                       " Teletext: can't find pixel in LUT!\n"); 
     235            else { 
     236                if (ci >= ctx->ci_clip) 
     237                    ci = ci % ctx->ci_clip; 
     238                if (ci > ci_max) 
     239                    ci_max = ci; 
     240                if (ci == ci_max) 
     241                    ++ci_max_count; 
     242                *bptr = BINARIZE ? (!!ci) : (uint8_t)ci; 
     243            } 
     244        } 
     245    } 
     246    av_free(canvas); 
     247 
     248    if (ci_max_count == resx*resy) { 
     249        av_log(0, AV_LOG_DEBUG, " Teletext: dropping empty page\n"); 
     250        // send empty subtitle 
     251        //avpicture_free(&sub_rect->pict); 
     252        av_freep(&sub_rect->pict.data[0]); 
     253        sub_rect->type = SUBTITLE_NONE; 
     254    } else { 
     255        sub_rect->x = resx<720 ? (720 - resx)/2 : 0; 
     256        sub_rect->y = resy<576 ? (576 - resy) : 0; 
     257        if (sub_rect->y > ctx->y_offset) 
     258            sub_rect->y -= ctx->y_offset; 
     259        sub_rect->w = resx; 
     260        sub_rect->h = resy; 
     261        sub_rect->nb_colors = ci_max+1; 
     262        sub_rect->pict.linesize[0] = resx; 
     263        sub_rect->pict.data[1] = av_malloc(sub_rect->nb_colors * sizeof(uint32_t)); 
     264        //sub_rect->rgba_palette = 
     265        //    av_malloc(sizeof(*sub_rect->rgba_palette)* 
     266        //              sub_rect->nb_colors); 
     267        for (ci=0; ci<sub_rect->nb_colors; ++ci) { 
     268            int r, g, b, a; 
     269 
     270            r = VBI_R(page->color_map[ci]); 
     271            g = VBI_G(page->color_map[ci]); 
     272            b = VBI_B(page->color_map[ci]); 
     273            a = (r+g+b == 0) ? 0 : VBI_A(page->color_map[ci]); 
     274            ((uint32_t *)sub_rect->pict.data[1])[ci] = 
     275                RGBA(r, g, b, a); 
     276#ifdef DEBUG 
     277            av_log(0, AV_LOG_DEBUG, " Teletext: palette %0x\n", 
     278                   ((uint32_t *)sub_rect->pict.data[1])[ci]); 
     279#endif 
     280        } 
     281        sub_rect->type = SUBTITLE_BITMAP; 
     282    } 
     283#ifdef DEBUG 
     284    fprintf(stderr, "ci_max=%d...\n", ci_max); 
     285#endif 
     286    return 0; 
     287} 
     288 
     289static void 
     290handler(vbi_event *ev, void *user_data) 
     291{ 
     292    TeletextContext *ctx = user_data; 
     293    vbi_page page; 
     294    int res; 
     295    char pgno_str[12]; 
     296 
     297    snprintf(pgno_str, sizeof pgno_str, "%03x", ev->ev.ttx_page.pgno); 
     298    av_log(0, AV_LOG_DEBUG, "Page %s.%02x %s\n", 
     299           pgno_str, ev->ev.ttx_page.subno & 0xFF, ctx->pgno); 
     300 
     301    if (strcmp(ctx->pgno, "*") && !strstr(ctx->pgno, pgno_str)) { 
     302        return; 
     303    } 
     304 
     305    /* Fetch the page.  */ 
     306    res = vbi_fetch_vt_page(ctx->vbi, &page, 
     307                            ev->ev.ttx_page.pgno, 
     308                            ev->ev.ttx_page.subno, 
     309                            VBI_WST_LEVEL_3p5, 25, TRUE); 
     310 
     311#ifdef DEBUG 
     312    fprintf(stderr, "\nSaving res=%d dy0=%d dy1=%d...\n", 
     313            res, page.dirty.y0, page.dirty.y1); 
     314    fflush(stderr); 
     315 
     316    if (!vbi_export_stdio(ctx->ex, stderr, &page)) { 
     317        fprintf(stderr, "failed: %s\n", vbi_export_errstr(ctx->ex)); 
     318        //exit(EXIT_FAILURE); 
     319    } 
     320#endif 
     321 
     322    // TODO: check if page changed 
     323    if (page.columns!=ctx->last_cols || page.rows!=ctx->last_rows || 1) { 
     324        vbi_subno subno; 
     325        char *lang; 
     326        vbi_page_type vpt = vbi_classify_page(ctx->vbi, 
     327                                              ev->ev.ttx_page.pgno, 
     328                                              &subno, &lang); 
     329        int chop_top = ctx->force_chop_top || 
     330            ((page.rows > 1) && (vpt == VBI_SUBTITLE_PAGE)); 
     331 
     332        av_log(0, AV_LOG_DEBUG, "%d x %d page chop:%d\n", 
     333               page.columns, page.rows, chop_top); 
     334 
     335        ctx->sub_rect = av_mallocz(sizeof(*ctx->sub_rect)); 
     336        res = ctx->gen_bitmap ? 
     337            gen_sub_bitmap(ctx, &page, chop_top) : 
     338            gen_sub_text  (ctx, &page, chop_top); 
     339        if (res) 
     340            av_freep(&ctx->sub_rect); 
     341 
     342        ctx->last_cols = page.columns; 
     343        ctx->last_rows = page.rows; 
     344    } 
     345    vbi_unref_page(&page); 
     346} 
     347 
     348static int teletext_init_decoder(AVCodecContext *avctx) 
     349{ 
     350    TeletextContext *ctx = avctx->priv_data; 
     351    const char* p_env; 
     352 
     353    ctx->sub_rect = 0; 
     354 
     355    ctx->vbi = vbi_decoder_new(); 
     356    assert(NULL != ctx->vbi); 
     357    vbi_event_handler_add(ctx->vbi, VBI_EVENT_TTX_PAGE, handler, ctx); 
     358    ctx->dx = vbi_dvb_pes_demux_new (/* callback */ NULL, NULL); 
     359    assert(NULL != ctx->dx); 
     360#ifdef DEBUG 
     361    { 
     362        char *t; 
     363        ctx->ex = vbi_export_new("text", &t); 
     364    } 
     365#endif 
     366    av_log(avctx, AV_LOG_INFO, "teletext pgno:%s\n", ctx->pgno); 
     367    p_env = getenv("TELETEXT_Y_OFFSET"); 
     368    if (p_env) 
     369        ctx->y_offset = strtol(p_env, 0, 10); 
     370    ctx->sub_display_time = 10000; 
     371    ctx->ci_clip = 256; /* dvdsub encoder cannot take more than 16.. */ 
     372    return 0; 
     373} 
     374 
     375static int teletext_close_decoder(AVCodecContext *avctx) 
     376{ 
     377    TeletextContext *ctx = avctx->priv_data; 
     378 
     379#ifdef DEBUG 
     380    av_log(avctx, AV_LOG_INFO, 
     381           " Teletext: lines_total=%u\n", ctx->lines_processed); 
     382#endif 
     383    av_free(ctx->sub_rect); 
     384 
     385    vbi_dvb_demux_delete(ctx->dx); 
     386    vbi_decoder_delete(ctx->vbi); 
     387    return 0; 
     388} 
     389 
     390#define OFFSET(x) offsetof(TeletextContext, x) 
     391#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM 
     392static const AVOption options[] = { 
     393    {"teletext_page", "Number(s) of teletext page(s) to decode", OFFSET(pgno), AV_OPT_TYPE_STRING, {.str = "100"}, 0, 0, SD}, 
     394    {"teletext_chop_top", "Force discarding the top teletext line", OFFSET(force_chop_top), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, SD}, 
     395    {"teletext_bitmap", "Generate bitmap rather than text subtitles", OFFSET(gen_bitmap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD}, 
     396    {"teletext_y_offset", "y offset of generated bitmaps", OFFSET(y_offset), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1080, SD}, 
     397    { NULL }, 
     398}; 
     399 
     400static const AVClass teletext_class = { 
     401    .class_name = "teletext", 
     402    .item_name  = av_default_item_name, 
     403    .option     = options, 
     404    .version    = LIBAVUTIL_VERSION_INT, 
     405}; 
     406 
     407AVCodec ff_teletext_decoder = { 
     408    .name      = "teletext", 
     409    .type      = AVMEDIA_TYPE_SUBTITLE, 
     410    .id        = CODEC_ID_DVB_TELETEXT, 
     411    .priv_data_size = sizeof(TeletextContext), 
     412    .init      = teletext_init_decoder, 
     413    .close     = teletext_close_decoder, 
     414    .decode    = teletext_decode_frame, 
     415    .long_name = NULL_IF_CONFIG_SMALL("Teletext subtitles"), 
     416    .priv_class= &teletext_class, 
     417}; 
     418 
     419/* Local Variables: */ 
     420/* indent-tabs-mode:nil */ 
     421/* tab-width:4 */ 
     422/* c-basic-offset:4 */ 
     423/* End: */ 
  • libavformat/avformat.h

    diff --git a/libavformat/avformat.h b/libavformat/avformat.h
    index c907d4e..fd5f504 100644
    a b AVFormatContext *avformat_alloc_output_context(const char *format, 
    13821382                                               const char *filename); 
    13831383#endif 
    13841384 
     1385void av_interleaved_discard(AVFormatContext *s, int64_t dts_min); 
     1386 
    13851387/** 
    13861388 * Allocate an AVFormatContext for an output format. 
    13871389 * avformat_free_context() can be used to free the context and 
    AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score 
    14411443 */ 
    14421444AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret); 
    14431445 
     1446/* current dts in AV_TIME_BASE units */ 
     1447int64_t av_get_cur_dts(AVFormatContext *s, int stream_index); 
     1448 
    14441449/** 
    14451450 * Probe a bytestream to determine the input format. Each time a probe returns 
    14461451 * with a score that is too low, the probe buffer size is increased and another 
  • libavformat/avidec.c

    diff --git a/libavformat/avidec.c b/libavformat/avidec.c
    index 7436b63..68b60d0 100644
    a b static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp 
    15341534            index=0; 
    15351535        while(!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min) 
    15361536            index--; 
    1537         ast2->frame_offset = st2->index_entries[index].timestamp; 
     1537        st2->cur_dts = ast2->frame_offset = st2->index_entries[index].timestamp; 
    15381538    } 
    15391539 
    15401540    /* do the seek */ 
  • libavformat/mpegenc.c

    diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
    index e2a96bc..1a1d6a5 100644
    a b typedef struct PacketDesc { 
    3838    int64_t dts; 
    3939    int size; 
    4040    int unwritten_size; 
    41     int flags; 
     41  //int flags; 
    4242    struct PacketDesc *next; 
    4343} PacketDesc; 
    4444 
    typedef struct { 
    5555    int lpcm_align; 
    5656    int bytes_to_iframe; 
    5757    int align_iframe; 
    58     int64_t vobu_start_pts; 
    5958} StreamInfo; 
    6059 
    6160typedef struct { 
    typedef struct { 
    8079    int64_t vcd_padding_bytes_written; 
    8180 
    8281    int preload; 
     82    int64_t vobu_start_pts; 
    8383} MpegMuxContext; 
    8484 
    8585extern AVOutputFormat ff_mpeg1vcd_muxer; 
    static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str 
    267267    buf[4] = (size - 6) >> 8; 
    268268    buf[5] = (size - 6) & 0xff; 
    269269 
     270    //av_log(ctx, AV_LOG_DEBUG, "system header size:%d\n", size); 
    270271    return size; 
    271272} 
    272273 
    static int mpeg_mux_init(AVFormatContext *ctx) 
    425426        bitrate += 10000; 
    426427        s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); 
    427428    } 
     429    av_log(ctx, AV_LOG_DEBUG, "mux_rate=%d bytes/sec\n", s->mux_rate*50); 
    428430 
    429431    if (s->is_vcd) { 
    430432        double overhead_rate; 
    static int mpeg_mux_init(AVFormatContext *ctx) 
    483485    } 
    484486    s->system_header_size = get_system_header_size(ctx); 
    485487    s->last_scr = 0; 
     488    s->vobu_start_pts = AV_NOPTS_VALUE; 
    486489    return 0; 
    487490 fail: 
    488491    for(i=0;i<ctx->nb_streams;i++) { 
    static int flush_packet(AVFormatContext *ctx, int stream_index, 
    607610                } 
    608611 
    609612                if (stream->bytes_to_iframe == 0 || s->packet_number == 0) { 
     613                    //av_log(ctx, AV_LOG_DEBUG, "DVD ALIGN2 pack_num:%d pts:%f\n", s->packet_number, pts/90000.0); 
    610614                    size = put_system_header(ctx, buf_ptr, 0); 
    611615                    buf_ptr += size; 
    612616                    size = buf_ptr - buffer; 
    static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) 
    10521056    AVStream *st = ctx->streams[stream_index]; 
    10531057    StreamInfo *stream = st->priv_data; 
    10541058    int64_t pts, dts; 
    1055     PacketDesc *pkt_desc; 
    1056     int preload; 
     1059    PacketDesc *pkt_desc, *dec_next; 
     1060    int preload, requeue = 0; 
    10571061    const int is_iframe = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY); 
    10581062 
    10591063    preload = av_rescale(s->preload, 90000, AV_TIME_BASE); 
    static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) 
    10711075    av_dlog(ctx, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n", 
    10721076            dts / 90000.0, pts / 90000.0, pkt->flags, 
    10731077            pkt->stream_index, pts != AV_NOPTS_VALUE); 
    1074     if (!stream->premux_packet) 
     1078    if (!stream->premux_packet) { 
    10751079        stream->next_packet = &stream->premux_packet; 
     1080        requeue = 1; 
     1081    } 
    10761082    *stream->next_packet= 
    1077     pkt_desc= av_mallocz(sizeof(PacketDesc)); 
     1083    pkt_desc= av_malloc(sizeof(PacketDesc)); 
    10781084    pkt_desc->pts= pts; 
    10791085    pkt_desc->dts= dts; 
    10801086    pkt_desc->unwritten_size= 
    10811087    pkt_desc->size= size; 
     1088    pkt_desc->next= NULL; 
    10821089    if(!stream->predecode_packet) 
    10831090        stream->predecode_packet= pkt_desc; 
     1091    else if (requeue) { 
     1092        for (dec_next= stream->predecode_packet; dec_next->next; dec_next= dec_next->next); 
     1093        dec_next->next = pkt_desc; 
     1094    } 
     1095 
    10841096    stream->next_packet= &pkt_desc->next; 
    10851097 
    10861098    if (av_fifo_realloc2(stream->fifo, av_fifo_size(stream->fifo) + size) < 0) 
    10871099        return -1; 
    10881100 
    10891101    if (s->is_dvd){ 
    1090         if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder) 
     1102        if (is_iframe && s->packet_number>0 && pts != AV_NOPTS_VALUE && 
     1103            s->vobu_start_pts != AV_NOPTS_VALUE && pts - s->vobu_start_pts >= 36000) { // min VOBU length 0.4 seconds (mpucoder) 
    10911104            stream->bytes_to_iframe = av_fifo_size(stream->fifo); 
    10921105            stream->align_iframe = 1; 
    1093             stream->vobu_start_pts = pts; 
     1106            s->vobu_start_pts = pts; 
     1107        } else { 
     1108            if (s->vobu_start_pts == AV_NOPTS_VALUE) 
     1109                s->vobu_start_pts = pts; 
    10941110        } 
    10951111    } 
    10961112 
  • libavformat/mpegts.c

    diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
    index a6e07fa..b5780c4 100644
    a b static int mpegts_set_stream_info(AVStream *st, PESContext *pes, 
    699699 
    700700static void new_pes_packet(PESContext *pes, AVPacket *pkt) 
    701701{ 
     702    /* For a teletext stream, output the complete packet, 
     703       including header. */ 
     704    if (pes->st->codec->codec_id == CODEC_ID_DVB_TELETEXT) { 
     705      if (av_new_packet(pkt, pes->pes_header_size+pes->data_index) == 0) { 
     706        memcpy(pkt->data, pes->header, pes->pes_header_size); 
     707        memcpy(pkt->data+pes->pes_header_size, pes->buffer, pes->data_index); 
     708        av_freep(&pes->buffer); 
     709      } else 
     710        av_init_packet(pkt); 
     711    } else { 
     712 
    702713    av_init_packet(pkt); 
    703714 
    704715    pkt->destruct = av_destruct_packet; 
    static void new_pes_packet(PESContext *pes, AVPacket *pkt) 
    712723    } 
    713724    memset(pkt->data+pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); 
    714725 
     726    } 
     727 
    715728    // Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID 
    716729    if (pes->sub_st && pes->stream_type == 0x83 && pes->extended_stream_id == 0x76) 
    717730        pkt->stream_index = pes->sub_st->index; 
  • libavformat/mpegts.h

    diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
    index 98c4b93..98c89a3 100644
    a b  
    5757 
    5858#define STREAM_TYPE_AUDIO_AC3       0x81 
    5959#define STREAM_TYPE_AUDIO_DTS       0x8a 
     60//#define STREAM_TYPE_TELETEXT        0x101 
    6061 
    6162typedef struct MpegTSContext MpegTSContext; 
    6263 
  • libavformat/mux.c

    diff --git a/libavformat/mux.c b/libavformat/mux.c
    index c7e176a..470ccf5 100644
    a b int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) 
    763763    } 
    764764} 
    765765 
     766void av_interleaved_discard(AVFormatContext *s, int64_t dts_min) 
     767{ 
     768    AVPacketList *pktl= s->packet_buffer, **prev= &s->packet_buffer, *next; 
     769    int i; 
     770 
     771    av_log(s, AV_LOG_DEBUG, "av_interleaved_discard dts_min:%"PRId64"\n", dts_min); 
     772    while(pktl) { 
     773        const AVStream *st= s->streams[pktl->pkt.stream_index]; 
     774        next = pktl->next; 
     775        if(dts_min == AV_NOPTS_VALUE || 
     776           pktl->pkt.dts*st->time_base.num*AV_TIME_BASE < dts_min*st->time_base.den) { 
     777av_log(s, AV_LOG_DEBUG, "av_interleaved_discard %"PRId64"\n", pktl->pkt.dts); 
     778            if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl) 
     779                s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL; 
     780            av_free_packet(&pktl->pkt); 
     781            *prev = next; 
     782            av_freep(&pktl); 
     783        } else { 
     784          int64_t ts_diff= av_rescale_q(dts_min, AV_TIME_BASE_Q, st->time_base); 
     785          if (pktl->pkt.pts != AV_NOPTS_VALUE) 
     786            pktl->pkt.pts -= ts_diff; 
     787          if (pktl->pkt.dts != AV_NOPTS_VALUE) 
     788            pktl->pkt.dts -= ts_diff; 
     789          prev = &pktl->next; 
     790        } 
     791        pktl= next; 
     792    } 
     793    for(i = 0; i < s->nb_streams; i++) { 
     794      AVStream *st = s->streams[i]; 
     795 
     796      if (st->cur_dts != AV_NOPTS_VALUE) { 
     797        if (!st->last_in_packet_buffer) // all packets have been deleted 
     798          st->cur_dts = 0; 
     799        else // some packets remain 
     800          st->cur_dts -= av_rescale_q(dts_min, AV_TIME_BASE_Q, st->time_base); 
     801      } 
     802    } 
     803} 
     804 
    766805int av_write_trailer(AVFormatContext *s) 
    767806{ 
    768807    int ret, i; 
  • libavformat/seek.c

    diff --git a/libavformat/seek.c b/libavformat/seek.c
    index 0ae99eb..3e655f2 100644
    a b typedef struct { 
    6060 * @param tb_lo low timestamp time base 
    6161 * @return representation of distance between high and low timestamps 
    6262 */ 
     63#if 0 
    6364static int64_t ts_distance(int64_t ts_hi, 
    6465                           AVRational tb_hi, 
    6566                           int64_t ts_lo, 
    static int64_t ts_distance(int64_t ts_hi, 
    7273 
    7374    return hi - lo; 
    7475} 
     76#endif 
    7577 
    7678/** 
    7779 * Partial search for keyframes in multiple streams. 
    static int64_t ts_distance(int64_t ts_hi, 
    9496 * @param found_hi          ptr to the count of already found high timestamp keyframes 
    9597 * @param first_iter        flag for first iteration 
    9698 */ 
    97 static void search_hi_lo_keyframes(AVFormatContext *s, 
     99static int search_hi_lo_keyframes(AVFormatContext *s, 
    98100                                   int64_t timestamp, 
    99101                                   AVRational timebase, 
    100102                                   int flags, 
    static void search_hi_lo_keyframes(AVFormatContext *s, 
    102104                                   int keyframes_to_find, 
    103105                                   int *found_lo, 
    104106                                   int *found_hi, 
    105                                    int first_iter) 
     107                                   int first_iter, 
     108                                  int64_t delta_max) 
    106109{ 
    107110    AVPacket pkt; 
    108111    AVSyncPoint *sp; 
    static void search_hi_lo_keyframes(AVFormatContext *s, 
    114117    int64_t pts, dts;   // PTS/DTS from stream 
    115118    int64_t ts;         // PTS in stream-local time base or position for byte seeking 
    116119    AVRational ts_tb;   // Time base of the stream or 1:1 for byte seeking 
     120    int ret = 0; 
    117121 
    118122    for (;;) { 
    119123        if (av_read_frame(s, &pkt) < 0) { 
    static void search_hi_lo_keyframes(AVFormatContext *s, 
    171175                ts_tb.den = 1; 
    172176            } else { 
    173177                // otherwise, get stream time_base 
     178                int64_t delta; 
    174179                ts    = pts; 
    175180                ts_tb = st->time_base; 
     181                delta = timestamp - av_rescale_q(ts, ts_tb, timebase); 
     182                if (FFABS(delta) > delta_max) { 
     183                    ret = -1; 
     184                    break; 
     185                } 
    176186            } 
    177187 
    178188            if (sp->first_ts == AV_NOPTS_VALUE) { 
    static void search_hi_lo_keyframes(AVFormatContext *s, 
    239249 
    240250    // Clean up the parser. 
    241251    ff_read_frame_flush(s); 
     252    return ret; 
    242253} 
    243254 
    244255int64_t ff_gen_syncpoint_search(AVFormatContext *s, 
    int64_t ff_gen_syncpoint_search(AVFormatContext *s, 
    257268    int64_t step; 
    258269    int found_lo = 0, found_hi = 0; 
    259270    int64_t min_distance, distance; 
    260     int64_t min_pos = 0; 
     271    int64_t min_distance2; 
    261272    int first_iter = 1; 
    262273    AVRational time_base; 
     274    int64_t delta_max = INT64_MAX; 
    263275 
    264276    if (flags & AVSEEK_FLAG_BYTE) { 
    265277        // for byte seeking, we have exact 1:1 "timestamps" - positions 
    int64_t ff_gen_syncpoint_search(AVFormatContext *s, 
    275287            time_base.num = 1; 
    276288            time_base.den = AV_TIME_BASE; 
    277289        } 
     290        delta_max = av_rescale_q(20*AV_TIME_BASE, AV_TIME_BASE_Q, time_base); 
    278291    } 
    279292 
    280293    // Initialize syncpoint structures for each stream. 
    int64_t ff_gen_syncpoint_search(AVFormatContext *s, 
    315328    curpos = FFMAX(pos - step / 2, 0); 
    316329    for (;;) { 
    317330        avio_seek(s->pb, curpos, SEEK_SET); 
    318         search_hi_lo_keyframes(s, 
    319                                ts, time_base, 
    320                                flags, 
    321                                sync, 
    322                                keyframes_to_find, 
    323                                &found_lo, &found_hi, 
    324                                first_iter); 
     331        i = search_hi_lo_keyframes(s, 
     332                                   ts, time_base, 
     333                                   flags, 
     334                                   sync, 
     335                                   keyframes_to_find, 
     336                                   &found_lo, &found_hi, 
     337                                   first_iter, 
     338                                   delta_max); 
     339        av_log(s, AV_LOG_ERROR, "search_hi_lo=%d flo:%d fhi:%d ktf:%d delta_max=%lld\n", 
     340               i, found_lo, found_hi, keyframes_to_find, delta_max); 
    325341        if (found_lo == keyframes_to_find && found_hi == keyframes_to_find) 
    326342            break;  // have all keyframes we wanted 
    327343        if (!curpos) 
    int64_t ff_gen_syncpoint_search(AVFormatContext *s, 
    351367 
    352368    // Find actual position to start decoding so that decoder synchronizes 
    353369    // closest to ts and between ts_min and ts_max. 
    354     pos = INT64_MAX; 
     370    min_distance2 = INT64_MAX; 
    355371 
    356372    for (i = 0; i < s->nb_streams; ++i) { 
    357373        st = s->streams[i]; 
    358374        if (st->discard < AVDISCARD_ALL) { 
     375            int64_t cur_dts; 
     376            int64_t min_pos = 0; 
     377            int64_t ts_num = st->time_base.num*time_base.den; 
     378            int64_t ts_den = st->time_base.den*time_base.num; 
     379 
    359380            sp = &sync[i]; 
    360381            min_distance = INT64_MAX; 
    361382            // Find timestamp closest to requested timestamp within min/max limits. 
    int64_t ff_gen_syncpoint_search(AVFormatContext *s, 
    363384                && av_compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0 
    364385                && av_compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) { 
    365386                // low timestamp is in range 
    366                 min_distance = ts_distance(ts, time_base, sp->ts_lo, st->time_base); 
     387                min_distance = ts - av_rescale(sp->ts_lo, ts_num, ts_den); //ts_distance(ts, time_base, sp->ts_lo, st->time_base); 
    367388                min_pos = sp->pos_lo; 
     389                cur_dts = sp->ts_lo; 
    368390            } 
    369391            if (sp->pos_hi != INT64_MAX 
    370392                && av_compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0 
    371393                && av_compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) { 
    372394                // high timestamp is in range, check distance 
    373                 distance = ts_distance(sp->ts_hi, st->time_base, ts, time_base); 
     395                distance = av_rescale(sp->ts_hi, ts_num, ts_den) - ts; 
    374396                if (distance < min_distance) { 
    375397                    min_distance = distance; 
    376398                    min_pos = sp->pos_hi; 
     399                    cur_dts = sp->ts_hi; 
    377400                } 
    378401            } 
     402            av_log(s, AV_LOG_DEBUG, "seek2 st:%d dist=%lld pos=%lld dts=%lld\n", i, min_distance, min_pos, cur_dts); 
    379403            if (min_distance == INT64_MAX) { 
    380404                // no timestamp is in range, cannot seek 
    381405                av_free(sync); 
    382406                return -1; 
    383407            } 
    384             if (min_pos < pos) 
     408            if (min_distance < min_distance2) { 
     409                min_distance2 = min_distance; 
    385410                pos = min_pos; 
     411                st->cur_dts = cur_dts; 
     412            } 
    386413        } 
    387414    } 
    388415 
    389416    avio_seek(s->pb, pos, SEEK_SET); 
    390417    av_free(sync); 
     418    av_log(s, AV_LOG_DEBUG, "seek2 pos=%lld\n", pos); 
    391419    return pos; 
    392420} 
    393421 
  • libavformat/utils.c

    diff --git a/libavformat/utils.c b/libavformat/utils.c
    index a78da36..2d8ff75 100644
    a b static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) 
    14091409                   cur_pkt.duration, 
    14101410                   cur_pkt.flags); 
    14111411 
    1412         if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) { 
     1412        if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)&& st->codec->codec_id != CODEC_ID_PROBE) { 
    14131413            st->parser = av_parser_init(st->codec->codec_id); 
    14141414            if (!st->parser) { 
    14151415                av_log(s, AV_LOG_VERBOSE, "parser not found for codec " 
    int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, 
    18461846    } 
    18471847 
    18481848    if(ts_max == AV_NOPTS_VALUE){ 
    1849         int step= 1024; 
     1849        int64_t step= 1024; 
    18501850        filesize = avio_size(s->pb); 
    18511851        pos_max = filesize - 1; 
    18521852        do{ 
    18531853            pos_max -= step; 
    18541854            ts_max = ff_read_timestamp(s, stream_index, &pos_max, pos_max + step, read_timestamp); 
    1855             step += step; 
    1856         }while(ts_max == AV_NOPTS_VALUE && pos_max >= step); 
     1855#ifdef DEBUG_SEEK 
     1856            av_log(s, AV_LOG_DEBUG, "ts_min=0x%llx ts_max=0x%llx\n", 
     1857                   ts_min, ts_max); 
     1858#endif 
     1859 
     1860            if (ts_max == AV_NOPTS_VALUE || ts_max < target_ts) 
     1861                step += step; 
     1862            else { 
     1863                if (ts_max < ts_min) { /* wraparound */ 
     1864#ifdef DEBUG_SEEK 
     1865                    av_log(s, AV_LOG_DEBUG, "wraparound: target=%lld ts_min=%lld ts_max=%lld\n", 
     1866                           target_ts, ts_min, ts_max); 
     1867#endif 
     1868                    /* try to adjust pos_min until ts_min<=target_ts */ 
     1869                    step = pos_max - pos_min; 
     1870                    while (step > 0) { 
     1871                        step >>= 1; 
     1872                        pos= pos_min + step; 
     1873                        ts= ff_read_timestamp(s, stream_index, &pos, pos_max, read_timestamp); 
     1874#ifdef DEBUG_SEEK 
     1875                        av_log(s, AV_LOG_DEBUG, "wraparound2: pos=%lld step=%lld ts=%lld\n", pos, step, ts); 
     1876#endif 
     1877                        if (ts != AV_NOPTS_VALUE) { 
     1878                            if (ts <= target_ts ) { 
     1879                                pos_min = pos; 
     1880                                ts_min = ts; 
     1881                                break; 
     1882                            } else if (ts_max < ts) { 
     1883                                pos_min = pos; 
     1884                                step = pos_max - pos_min; 
     1885                            } 
     1886                        } 
     1887                    } 
     1888                } 
     1889                break; 
     1890            } 
     1891        } while (pos_max >= step); 
    18571892        if (ts_max == AV_NOPTS_VALUE) 
    18581893            return -1; 
    18591894 
    18601895        for(;;){ 
    18611896            int64_t tmp_pos= pos_max + 1; 
    18621897            int64_t tmp_ts= ff_read_timestamp(s, stream_index, &tmp_pos, INT64_MAX, read_timestamp); 
    1863             if(tmp_ts == AV_NOPTS_VALUE) 
     1898            if(tmp_ts == AV_NOPTS_VALUE || tmp_ts < ts_max) 
    18641899                break; 
    18651900            ts_max= tmp_ts; 
    18661901            pos_max= tmp_pos; 
    int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, 
    18811916        pos_limit= pos_min; 
    18821917    } 
    18831918 
     1919#ifdef DEBUG_SEEK 
     1920    av_log(s, AV_LOG_DEBUG, "ts_min=0x%llx ts_max=0x%llx pos_limit=%lld\n", 
     1921           ts_min, ts_max, pos_limit); 
     1922#endif 
     1923 
    18841924    no_change=0; 
    18851925    while (pos_min < pos_limit) { 
    18861926        av_dlog(s, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%s dts_max=%s\n", 
    static int seek_frame_generic(AVFormatContext *s, 
    20262066static int seek_frame_internal(AVFormatContext *s, int stream_index, 
    20272067                               int64_t timestamp, int flags) 
    20282068{ 
    2029     int ret; 
     2069    int i, ret; 
    20302070    AVStream *st; 
    20312071 
    20322072    if (flags & AVSEEK_FLAG_BYTE) { 
    static int seek_frame_internal(AVFormatContext *s, int stream_index, 
    20522092        ret = s->iformat->read_seek(s, stream_index, timestamp, flags); 
    20532093    } else 
    20542094        ret = -1; 
    2055     if (ret >= 0) { 
    2056         return 0; 
    2057     } 
    2058  
    2059     if (s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH)) { 
     2095    if (ret >= 0) 
     2096        ; 
     2097    else if (s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH)) { 
    20602098        ff_read_frame_flush(s); 
    2061         return ff_seek_frame_binary(s, stream_index, timestamp, flags); 
     2099        ret = ff_seek_frame_binary(s, stream_index, timestamp, flags); 
    20622100    } else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) { 
    20632101        ff_read_frame_flush(s); 
    2064         return seek_frame_generic(s, stream_index, timestamp, flags); 
     2102        ret = seek_frame_generic(s, stream_index, timestamp, flags); 
     2103    } else 
     2104        ret = -1; 
     2105    if (ret >= 0) { 
     2106        for(i=0; i<s->nb_streams; i++) { 
     2107            st = s->streams[i]; 
     2108            st->first_dts = st->cur_dts; 
     2109            av_log(s, AV_LOG_DEBUG, "after seek st:%d cur:%lld\n", i, st->cur_dts); 
     2110        } 
     2111        return 0; 
    20652112    } 
    2066     else 
    2067         return -1; 
     2113    return ret; 
    20682114} 
    20692115 
    20702116int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) 
    int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int 
    21122158    // try some generic seek like seek_frame_generic() but with new ts semantics 
    21132159} 
    21142160 
     2161/** 
     2162 * Obtain the current dts in AV_TIME_BASE units. 
     2163 * @param stream_index If stream_index is (-1), a default 
     2164 * stream is selected. 
     2165 */ 
     2166int64_t av_get_cur_dts(AVFormatContext *s, int stream_index) 
     2167{ 
     2168    AVStream *st; 
     2169 
     2170    if (stream_index < 0){ 
     2171        stream_index= av_find_default_stream_index(s); 
     2172        if(stream_index < 0) 
     2173            return AV_NOPTS_VALUE; 
     2174    } 
     2175    st= s->streams[stream_index]; 
     2176    if (st->cur_dts == AV_NOPTS_VALUE || is_relative(st->cur_dts)) 
     2177        return AV_NOPTS_VALUE; 
     2178    return av_rescale(st->cur_dts, AV_TIME_BASE * (int64_t)st->time_base.num, 
     2179                      st->time_base.den); 
     2180} 
     2181 
    21152182/*******************************************************/ 
    21162183 
    21172184/** 
    static int has_codec_parameters(AVStream *st, const char **errmsg_ptr) 
    24052472            FAIL("no decodable DTS frames"); 
    24062473        break; 
    24072474    case AVMEDIA_TYPE_VIDEO: 
     2475        if (avctx->codec_id == CODEC_ID_MPEG2VIDEO && 
     2476            avctx->sample_aspect_ratio.num == 0) 
     2477            FAIL("mpeg2v unspecified aspect"); 
    24082478        if (!avctx->width) 
    24092479            FAIL("unspecified size"); 
    24102480        if (st->info->found_decoder >= 0 && avctx->pix_fmt == AV_PIX_FMT_NONE) 
    int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 
    26582728                st->time_base= */ 
    26592729            if(!st->codec->time_base.num) 
    26602730                st->codec->time_base= st->time_base; 
     2731            if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) 
     2732                // aspect ratio may change; re-probe it 
     2733                st->codec->sample_aspect_ratio = (AVRational){0,1}; 
    26612734        } 
    26622735        //only for the split stuff 
    26632736        if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE)) { 
    int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 
    30423115    for (i=0; i < ic->nb_streams; i++) { 
    30433116        if (ic->streams[i]->codec) 
    30443117            ic->streams[i]->codec->thread_count = 0; 
    3045         av_freep(&ic->streams[i]->info); 
     3118        memset(ic->streams[i]->info, 0, sizeof *ic->streams[i]->info); 
    30463119    } 
    30473120    if(ic->pb) 
    30483121        av_log(ic, AV_LOG_DEBUG, "File position after avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb));