Changeset 2e3381e626d5cf41d336f3283cc76aaef2654a34

Show
Ignore:
Timestamp:
17/11/03 12:25:54 (5 years ago)
Author:
Laurent Aimar <fenrir@videolan.org>
git-committer:
Laurent Aimar <fenrir@videolan.org> 1069068354 +0000
git-parent:

[1672cb91be5ad0d200c379eefac3b891a459aa15]

git-author:
Laurent Aimar <fenrir@videolan.org> 1069068354 +0000
Message:
  • ts: improve PCR handling. pcr-soft doesn't exist anymore.
    Options:
    • caching: time on which bitrate smouthing is applied (default: 200ms)
    • pcr : delay between 2 PCR (Really more accurate). (default: 30ms)
    • bmin and bmax doesn't work anymore.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/mux/mpeg/ts.c

    rccfe579 r2e3381e  
    33 ***************************************************************************** 
    44 * Copyright (C) 2001, 2002 VideoLAN 
    5  * $Id: ts.c,v 1.33 2003/11/07 18:41:09 massiot Exp $ 
     5 * $Id: ts.c,v 1.34 2003/11/17 11:25:54 fenrir Exp $ 
    66 * 
    77 * Authors: Laurent Aimar <fenrir@via.ecp.fr> 
     
    102102 * Local prototypes 
    103103 *****************************************************************************/ 
    104 #define SOUT_BUFFER_FLAGS_PRIVATE_PCR_SOFT  ( 1 << SOUT_BUFFER_FLAGS_PRIVATE_SHIFT ) 
     104#define SOUT_BUFFER_FLAGS_PRIVATE_PCR  ( 1 << SOUT_BUFFER_FLAGS_PRIVATE_SHIFT ) 
    105105typedef struct 
    106106{ 
     
    146146    return b; 
    147147} 
     148static inline void BufferChainClean( sout_instance_t *p_sout, sout_buffer_chain_t *c ) 
     149{ 
     150    sout_buffer_t *b; 
     151 
     152    while( ( b = BufferChainGet( c ) ) ) 
     153    { 
     154        sout_BufferDelete( p_sout, b ); 
     155    } 
     156    BufferChainInit( c ); 
     157} 
    148158 
    149159typedef struct ts_stream_s 
     
    164174    uint8_t         *p_decoder_specific_info; 
    165175 
    166     /* for TS building */ 
    167     sout_buffer_chain_t chain_ts; 
     176    sout_buffer_chain_t chain_pes; 
     177    mtime_t             i_pes_dts; 
     178    mtime_t             i_pes_length; 
     179    int                 i_pes_used; 
    168180 
    169181} ts_stream_t; 
     
    197209    int64_t             i_bitrate_min; 
    198210    int64_t             i_bitrate_max; 
     211 
     212    int64_t             i_caching_delay; 
    199213    int64_t             i_pcr_delay; 
    200     int64_t             i_pcr_soft_delay; 
    201  
    202     mtime_t             i_pcr;  /* last PCR emited (for pcr-soft) */ 
    203     mtime_t             i_dts; 
    204     mtime_t             i_length; 
    205     sout_buffer_chain_t chain_ts; 
     214 
     215    mtime_t             i_pcr;  /* last PCR emited */ 
    206216}; 
    207217 
     
    231241static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c ); 
    232242 
    233 static int  TSFill   ( sout_mux_t *, sout_input_t * ); 
    234 static void PEStoTS  ( sout_instance_t *, sout_buffer_chain_t *, sout_buffer_t *, ts_stream_t *, vlc_bool_t ); 
    235 static void TSSetDate( sout_buffer_chain_t *, mtime_t, mtime_t, mtime_t ); 
    236 static void TSSetConstraints( sout_mux_t*, sout_buffer_chain_t *, 
    237                               mtime_t i_length, int i_bitrate_min, int i_bitrate_max ); 
     243static sout_buffer_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr ); 
     244static void TSSetPCR( sout_buffer_t *p_ts, mtime_t i_dts ); 
     245 
     246static void PEStoTS  ( sout_instance_t *, sout_buffer_chain_t *, sout_buffer_t *, ts_stream_t * ); 
    238247 
    239248/***************************************************************************** 
     
    320329        p_sys->i_bitrate_max = 0; 
    321330    } 
    322     p_sys->i_pcr_delay = 90000; 
     331    if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 ) 
     332    { 
     333        msg_Err( p_mux, "bmin and bmax no more supported (if you need them report it)" ); 
     334    } 
     335 
     336    p_sys->i_caching_delay = 200000; 
     337    if( ( val = sout_cfg_find_value( p_mux->p_cfg, "caching" ) ) ) 
     338    { 
     339        p_sys->i_caching_delay = (int64_t)atoi( val ) * 1000; 
     340        if( p_sys->i_caching_delay <= 0 ) 
     341        { 
     342            msg_Err( p_mux, 
     343                     "invalid caching ("I64Fd"ms) reseting to 200ms", 
     344                     p_sys->i_caching_delay / 1000 ); 
     345            p_sys->i_caching_delay = 200000; 
     346        } 
     347    } 
     348    p_sys->i_pcr_delay = 30000; 
    323349    if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pcr" ) ) ) 
    324350    { 
    325351        p_sys->i_pcr_delay = (int64_t)atoi( val ) * 1000; 
    326         if( p_sys->i_pcr_delay <= 0 ) 
     352        if( p_sys->i_pcr_delay <= 0 || 
     353            p_sys->i_pcr_delay >= p_sys->i_caching_delay ) 
    327354        { 
    328355            msg_Err( p_mux, 
    329                      "invalid pcr delay ("I64Fd"ms) reseting to 90ms", 
     356                     "invalid pcr delay ("I64Fd"ms) reseting to 30ms", 
    330357                     p_sys->i_pcr_delay / 1000 ); 
    331             p_sys->i_pcr_delay = 90000; 
    332         } 
    333     } 
    334     p_sys->i_pcr_soft_delay = 0; 
    335     if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pcr-soft" ) ) ) 
    336     { 
    337         p_sys->i_pcr_soft_delay = (int64_t)atoi( val ) * 1000; 
    338         if( p_sys->i_pcr_soft_delay <= 0 || 
    339             p_sys->i_pcr_soft_delay >= p_sys->i_pcr_delay ) 
    340         { 
    341             msg_Err( p_mux, 
    342                      "invalid pcr-soft delay ("I64Fd"ms) disabled", 
    343                      p_sys->i_pcr_soft_delay / 1000 ); 
    344             p_sys->i_pcr_soft_delay = 0; 
    345         } 
    346     } 
    347  
    348     msg_Dbg( p_mux, "pcr_delay="I64Fd" pcr_soft_delay="I64Fd, 
    349              p_sys->i_pcr_delay, p_sys->i_pcr_soft_delay ); 
     358            p_sys->i_pcr_delay = 30000; 
     359        } 
     360    } 
     361 
     362    msg_Dbg( p_mux, "caching="I64Fd" pcr="I64Fd, 
     363             p_sys->i_caching_delay, p_sys->i_pcr_delay ); 
    350364 
    351365    /* for TS generation */ 
    352366    p_sys->i_pcr    = 0; 
    353     p_sys->i_dts    = 0; 
    354     p_sys->i_length = 0; 
    355     BufferChainInit( &p_sys->chain_ts ); 
    356367    return VLC_SUCCESS; 
    357368} 
     
    364375    sout_mux_t          *p_mux = (sout_mux_t*)p_this; 
    365376    sout_mux_sys_t      *p_sys = p_mux->p_sys; 
    366     sout_buffer_t       *p_data; 
    367377 
    368378    msg_Dbg( p_mux, "Close" ); 
    369  
    370     /* Empty TS buffer */ 
    371     while( ( p_data = BufferChainGet( &p_sys->chain_ts ) ) ) 
    372     { 
    373         sout_BufferDelete( p_mux->p_sout, p_data ); 
    374     } 
    375379 
    376380    free( p_sys ); 
     
    504508                p_input->p_fmt->i_extra_data ); 
    505509    } 
    506     /* Init chain for TS building */ 
    507     BufferChainInit( &p_stream->chain_ts ); 
     510 
     511    /* Init pes chain */ 
     512    BufferChainInit( &p_stream->chain_pes ); 
     513    p_stream->i_pes_dts    = 0; 
     514    p_stream->i_pes_length = 0; 
     515    p_stream->i_pes_used   = 0; 
    508516 
    509517    /* We only change PMT version (PAT isn't changed) */ 
     
    514522        ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) ) 
    515523    { 
    516         sout_buffer_t *p_data; 
    517  
    518524        if( p_sys->p_pcr_input ) 
    519525        { 
    520526            /* There was already a PCR stream, so clean context */ 
    521             ts_stream_t   *p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys; 
    522  
    523             while( ( p_data = BufferChainGet( &p_pcr_stream->chain_ts ) ) ) 
    524             { 
    525                 sout_BufferDelete( p_mux->p_sout, p_data ); 
    526             } 
     527            /* FIXME */ 
    527528        } 
    528529        p_sys->i_pcr_pid   = p_stream->i_pid; 
    529530        p_sys->p_pcr_input = p_input; 
    530  
    531         /* Empty TS buffer (avoid broken data/problems with pcr stream changement ) */ 
    532         while( ( p_data = BufferChainGet( &p_sys->chain_ts ) ) ) 
    533         { 
    534             sout_BufferDelete( p_mux->p_sout, p_data ); 
    535         } 
    536531    } 
    537532 
     
    546541    sout_mux_sys_t  *p_sys = p_mux->p_sys; 
    547542    ts_stream_t     *p_stream; 
    548     sout_buffer_t   *p_data; 
    549543 
    550544    msg_Dbg( p_mux, "removing input" ); 
     
    583577        { 
    584578            /* Empty TS buffer */ 
    585             while( ( p_data = BufferChainGet( &((ts_stream_t*)p_sys->p_pcr_input->p_sys)->chain_ts ) ) ) 
    586             { 
    587                 sout_BufferDelete( p_mux->p_sout, p_data ); 
    588             } 
    589         } 
    590     } 
    591  
    592     /* Empty all data in chain_ts */ 
    593     while( ( p_data = BufferChainGet( &p_stream->chain_ts ) ) ) 
    594     { 
    595         sout_BufferDelete( p_mux->p_sout, p_data ); 
    596     } 
     579            /* FIXME */ 
     580        } 
     581    } 
     582 
     583    /* Empty all data in chain_pes */ 
     584    BufferChainClean( p_mux->p_sout, &p_stream->chain_pes ); 
     585 
    597586    if( p_stream->p_decoder_specific_info ) 
    598587    { 
     
    607596    /* We only change PMT version (PAT isn't changed) */ 
    608597    p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32; 
    609  
    610     /*Empty TS buffer (avoid broken data/problems with pcr stream changement) */ 
    611     while( ( p_data = BufferChainGet( &p_sys->chain_ts ) ) ) 
    612     { 
    613         sout_BufferDelete( p_mux->p_sout, p_data ); 
    614     } 
    615598 
    616599    return VLC_SUCCESS; 
     
    625608{ 
    626609    sout_mux_sys_t  *p_sys = p_mux->p_sys; 
    627  
    628     sout_input_t    *p_pcr_input = p_sys->p_pcr_input; 
    629     ts_stream_t     *p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys; 
     610    ts_stream_t     *p_pcr_stream; 
    630611 
    631612    if( p_sys->i_pcr_pid == 0x1fff ) 
     
    635616        return VLC_SUCCESS; 
    636617    } 
     618    p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys; 
    637619 
    638620    for( ;; ) 
    639621    { 
    640         ts_stream_t   *p_stream = NULL; 
    641         sout_buffer_t *p_data; 
    642  
    643         int     i_stream, i; 
    644         mtime_t i_dts; 
    645  
    646         /* fill ts packets for pcr XXX before GetPAT/GetPMT */ 
    647         if( p_pcr_stream->chain_ts.p_first == NULL && TSFill( p_mux, p_pcr_input ) ) 
    648         { 
    649             /* We need more data */ 
    650             return VLC_SUCCESS; 
    651         } 
    652  
    653         if( p_sys->chain_ts.p_first == NULL  ) 
    654         { 
    655             /* Every pcr packet send PAT/PMT */ 
    656             GetPAT( p_mux, &p_sys->chain_ts); 
    657             GetPMT( p_mux, &p_sys->chain_ts ); 
    658         } 
    659  
    660         /* search stream with lowest dts */ 
    661         for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ ) 
    662         { 
    663             p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys; 
    664  
    665             if( p_stream->chain_ts.p_first == NULL ) 
    666             { 
    667                 if( TSFill( p_mux, p_mux->pp_inputs[i] ) ) 
     622        sout_buffer_chain_t chain_ts; 
     623        int                 i_packet_count; 
     624        int                 i_packet_pos; 
     625        mtime_t             i_pcr_dts; 
     626        mtime_t             i_pcr_length; 
     627        int i; 
     628 
     629        /* 1: get enough PES packet for all input */ 
     630        for( ;; ) 
     631        { 
     632            vlc_bool_t b_ok = VLC_TRUE; 
     633            sout_buffer_t *p_data; 
     634 
     635            /* Accumulate enough data in the pcr stream (>i_caching_delay) */ 
     636            /* Accumulate enough data in all other stream ( >= length of pcr) */ 
     637            for( i = 0; i < p_mux->i_nb_inputs; i++ ) 
     638            { 
     639                sout_input_t *p_input = p_mux->pp_inputs[i]; 
     640                ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys; 
     641 
     642                if( p_stream->i_pes_length <= p_sys->i_caching_delay || 
     643                    p_stream->i_pes_dts + p_stream->i_pes_length < p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length ) 
    668644                { 
    669                     /* We need more data */ 
    670                     return VLC_SUCCESS; 
     645                    /* Need more data */ 
     646                    if( p_input->p_fifo->i_depth <= 1 ) 
     647                    { 
     648                        if( p_input->p_fmt->i_cat == AUDIO_ES || 
     649                            p_input->p_fmt->i_cat == VIDEO_ES ) 
     650                        { 
     651                            /* We need more data */ 
     652                            return VLC_SUCCESS; 
     653                        } 
     654                        else if( p_input->p_fifo->i_depth <= 0 ) 
     655                        { 
     656                            /* spu, only one packet is needed */ 
     657                            continue; 
     658                        } 
     659                    } 
     660                    b_ok = VLC_FALSE; 
     661 
     662                    p_data = sout_FifoGet( p_input->p_fifo ); 
     663 
     664                    if( ( p_pcr_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length ) || 
     665                        p_data->i_dts < p_stream->i_pes_dts || 
     666                        ( p_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_stream->i_pes_dts + p_stream->i_pes_length ) ) 
     667                    { 
     668                        msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)", 
     669                                  p_data->i_dts, 
     670                                  p_stream->i_pes_dts, 
     671                                  p_pcr_stream->i_pes_dts ); 
     672                        sout_BufferDelete( p_mux->p_sout, p_data ); 
     673 
     674                        BufferChainClean( p_mux->p_sout, &p_stream->chain_pes ); 
     675                        p_stream->i_pes_dts = 0; 
     676                        p_stream->i_pes_used = 0; 
     677                        p_stream->i_pes_length = 0; 
     678 
     679                        BufferChainClean( p_mux->p_sout, &p_pcr_stream->chain_pes ); 
     680                        p_pcr_stream->i_pes_dts = 0; 
     681                        p_pcr_stream->i_pes_used = 0; 
     682                        p_pcr_stream->i_pes_length = 0; 
     683 
     684                    } 
     685                    else 
     686                    { 
     687                        p_stream->i_pes_length += p_data->i_length; 
     688                        if( p_stream->i_pes_dts == 0 ) 
     689                        { 
     690                            p_stream->i_pes_dts = p_data->i_dts; 
     691                        } 
     692 
     693                        /* Convert to pes */ 
     694                        E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 ); 
     695 
     696                        BufferChainAppend( &p_stream->chain_pes, p_data ); 
     697                    } 
    671698                } 
    672                 if( p_stream->chain_ts.p_first == NULL ) 
     699            } 
     700 
     701            if( b_ok ) 
     702            { 
     703                break; 
     704            } 
     705        } 
     706 
     707        /* save */ 
     708        i_pcr_dts      = p_pcr_stream->i_pes_dts; 
     709        i_pcr_length   = p_pcr_stream->i_pes_length; 
     710 
     711        /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */ 
     712        /* 2: calculate non accurate total size of muxed ts */ 
     713        i_packet_count = 0; 
     714        for( i = 0; i < p_mux->i_nb_inputs; i++ ) 
     715        { 
     716            ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys; 
     717            sout_buffer_t *p_pes; 
     718 
     719            /* False for pcr stream but it will be eough to do PCR algo */ 
     720            for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next ) 
     721            { 
     722                int i_size = p_pes->i_size; 
     723                if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length ) 
    673724                { 
    674                     continue; /* SPU_ES */ 
     725                    mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts; 
     726                    if( i_frag < 0 ) 
     727                    { 
     728                        /* Next stream */ 
     729                        break; 
     730                    } 
     731                    i_size = p_pes->i_size * i_frag / p_pes->i_length; 
    675732                } 
    676             } 
    677  
    678             if( i_stream == -1 || 
    679                 p_stream->chain_ts.p_first->i_dts < i_dts ) 
    680             { 
    681                 i_stream = i; 
    682                 i_dts = p_stream->chain_ts.p_first->i_dts; 
    683             } 
    684         } 
    685  
    686         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys; 
    687  
    688         p_data = BufferChainGet( &p_stream->chain_ts ); 
    689         BufferChainAppend( &p_sys->chain_ts, p_data ); 
    690  
    691         if( p_stream->i_pid == p_pcr_stream->i_pid && p_stream->chain_ts.p_first == NULL ) 
    692         { 
    693             sout_buffer_t *p_ts = p_sys->chain_ts.p_first; 
    694  
    695             /* We have consume all TS packets from the PCR stream */ 
    696  
    697             if( p_sys->i_length > p_sys->i_pcr_delay ) 
    698             { 
    699                 /* Send TS data if last PCR was i_pcr_delay ago */ 
    700  
    701                 if( p_sys->i_bitrate_min > 0 || 
    702                     p_sys->i_bitrate_max > 0 ) 
     733                i_packet_count += ( i_size + 183 ) / 184; 
     734            } 
     735        } 
     736        /* add overhead for PCR (not really exact) */ 
     737        i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176; 
     738 
     739 
     740        /* 3: mux PES into TS */ 
     741        BufferChainInit( &chain_ts ); 
     742        /* append PAT/PMT  -> FIXME with big pcr delay it won't have enough pat/pmt */ 
     743        GetPAT( p_mux, &chain_ts); 
     744        GetPMT( p_mux, &chain_ts ); 
     745        i_packet_pos = 0; 
     746        i_packet_count += chain_ts.i_depth; 
     747        /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */ 
     748 
     749        for( ;; ) 
     750        { 
     751            int         i_stream; 
     752            mtime_t     i_dts; 
     753            ts_stream_t *p_stream; 
     754            sout_buffer_t *p_ts; 
     755            vlc_bool_t   b_pcr; 
     756 
     757            /* Select stream (lowest dts)*/ 
     758            for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ ) 
     759            { 
     760                p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys; 
     761 
     762                if( p_stream->i_pes_dts == 0 ) 
    703763                { 
    704                     TSSetConstraints( p_mux, &p_sys->chain_ts, p_sys->i_length, 
    705                                       p_sys->i_bitrate_min, p_sys->i_bitrate_max ); 
     764                    continue; 
    706765                } 
    707766 
    708                 /* Send all data */ 
    709                 TSSetDate( &p_sys->chain_ts, 
    710                            p_sys->i_dts, 
    711                            p_sys->i_length, 
    712                            3 * p_sys->i_pcr_delay/2 );  /* latency is equal to i_pcr_delay 
    713                                                          3/2 is for security */ 
    714                 sout_AccessOutWrite( p_mux->p_access, p_ts ); 
    715  
    716                 /* Reset the ts chain */ 
    717                 BufferChainInit( &p_sys->chain_ts ); 
    718  
    719                 p_sys->i_length = 0; 
    720             } 
    721         } 
    722     } 
    723  
    724     return VLC_SUCCESS; 
    725 
    726  
    727  
    728  
    729 /***************************************************************************** 
    730  * 
    731  * 
    732  *****************************************************************************/ 
    733 static int TSFill( sout_mux_t *p_mux, sout_input_t *p_input ) 
    734 
    735     sout_mux_sys_t  *p_sys = p_mux->p_sys; 
    736  
    737     ts_stream_t     *p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys; 
    738     ts_stream_t     *p_stream = (ts_stream_t*)p_input->p_sys; 
    739     mtime_t         i_dts, i_length; 
    740     sout_buffer_t   *p_data; 
    741     vlc_bool_t      b_pcr = VLC_FALSE; 
    742     vlc_bool_t      b_pcr_soft = VLC_FALSE; 
    743  
    744  
    745     for( ;; ) 
    746     { 
    747         if( p_input->p_fifo->i_depth <= 1 ) 
    748         { 
    749             if( p_input->p_fmt->i_cat == AUDIO_ES || 
    750                 p_input->p_fmt->i_cat == VIDEO_ES ) 
    751             { 
    752                 /* We need more data */ 
    753                 return VLC_EGENERIC; 
    754             } 
    755             else if( p_input->p_fifo->i_depth <= 0 ) 
    756             { 
    757                 /* spu, only one packet is needed */ 
    758                 return VLC_SUCCESS; 
    759             } 
    760         } 
    761         p_data = sout_FifoGet( p_input->p_fifo ); 
    762         i_dts    = p_data->i_dts; 
    763         i_length = p_data->i_length; 
    764  
    765         if(  p_stream->i_pid == p_pcr_stream->i_pid && 
    766              p_stream->chain_ts.p_first == NULL ) 
    767         { 
    768             /* I need that length == dts_next - dts, but be carefull if 
    769              * some dts are broken length >= 0.5s are suspicious */ 
    770             sout_buffer_t   *p_next; 
    771             mtime_t         i_dts_next; 
    772  
    773             p_next = sout_FifoShow( p_input->p_fifo ); 
    774             i_dts_next = p_next->i_dts; 
    775  
    776             if( i_dts_next > i_dts && 
    777                 i_dts_next - i_dts < (mtime_t)500000 ) 
    778             { 
    779                 i_length = i_dts_next - i_dts; 
    780             } 
    781             p_sys->i_length+= i_length; 
    782             if( p_sys->chain_ts.p_first == NULL ) 
    783             { 
    784                 p_sys->i_dts    = i_dts; 
    785                 p_sys->i_pcr    = i_dts; 
     767                if( i_stream == -1 || 
     768                    p_stream->i_pes_dts < i_dts ) 
     769                { 
     770                    i_stream = i; 
     771                    i_dts = p_stream->i_pes_dts; 
     772                } 
     773            } 
     774            if( i_stream == -1 ) 
     775            { 
     776                break; 
     777            } 
     778            p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys; 
     779 
     780            /* do we need to issue pcr */ 
     781            b_pcr = VLC_FALSE; 
     782            if( p_stream == p_pcr_stream && 
     783                i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay ) 
     784            { 
    786785                b_pcr = VLC_TRUE; 
    787             } 
    788             else if( p_sys->i_pcr_soft_delay > 0 && 
    789                      p_sys->i_pcr + p_sys->i_pcr_soft_delay < i_dts ) 
    790             { 
    791                 p_sys->i_pcr    = i_dts; 
    792                 b_pcr = VLC_TRUE; 
    793                 b_pcr_soft = VLC_TRUE; 
    794             } 
    795             break; 
    796         } 
    797  
    798         if( ( p_sys->i_dts + p_sys->i_length ) - i_dts > 2000000 || 
    799             ( p_sys->i_dts + p_sys->i_length ) - i_dts < -2000000 ) 
    800         { 
    801             msg_Err( p_mux, "| buffer_dts - pcr_pts | > 2s ("I64Fd") empting " 
    802                      "pcr TS buffers", p_sys->i_dts + p_sys->i_length - i_dts); 
    803  
    804             sout_BufferDelete( p_mux->p_sout, p_data ); 
    805  
    806             while( ( p_data = BufferChainGet( &p_pcr_stream->chain_ts ) ) ) 
    807             { 
    808                 sout_BufferDelete( p_mux->p_sout, p_data ); 
    809             } 
    810             while( ( p_data = BufferChainGet( &p_sys->chain_ts ) ) ) 
    811             { 
    812                 sout_BufferDelete( p_mux->p_sout, p_data ); 
    813             } 
    814             return VLC_EGENERIC; 
    815         } 
    816  
    817         if( i_dts >= p_sys->i_dts ) 
    818         { 
    819             break; 
    820         } 
    821  
    822         msg_Dbg( p_mux, "dropping buffer size=%d dts="I64Fd" pcr_dts="I64Fd 
    823                  " diff="I64Fd, p_data->i_size, i_dts, p_sys->i_dts, 
    824                  p_sys->i_dts + p_sys->i_length - i_dts ); 
    825         sout_BufferDelete( p_mux->p_sout, p_data ); 
    826     } 
    827  
    828     E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1); 
    829  
    830     BufferChainInit( &p_stream->chain_ts ); 
    831     PEStoTS( p_mux->p_sout, &p_stream->chain_ts, p_data, p_stream, b_pcr ); 
    832  
    833     TSSetDate( &p_stream->chain_ts, i_dts, i_length, 0 ); 
    834  
    835     if( b_pcr_soft && p_stream->chain_ts.p_first ) 
    836     { 
    837         p_stream->chain_ts.p_first->i_flags=SOUT_BUFFER_FLAGS_PRIVATE_PCR_SOFT; 
    838     } 
    839  
    840     return VLC_SUCCESS; 
    841 
    842  
     786                p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count; 
     787            } 
     788 
     789            /* Build the TS packet */ 
     790            p_ts = TSNew( p_mux, p_stream, b_pcr ); 
     791            i_packet_pos++; 
     792 
     793            /* */ 
     794            BufferChainAppend( &chain_ts, p_ts ); 
     795        } 
     796 
     797        /* 4: date and send */ 
     798        i_packet_count = chain_ts.i_depth; 
     799        /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */ 
     800        for( i = 0; i < i_packet_count; i++ ) 
     801        { 
     802            sout_buffer_t *p_ts = BufferChainGet( &chain_ts ); 
     803 
     804            p_ts->i_dts    = i_pcr_dts + i_pcr_length * i / i_packet_count; 
     805            p_ts->i_length = i_pcr_length / i_packet_count; 
     806 
     807            if( p_ts->i_flags&SOUT_BUFFER_FLAGS_PRIVATE_PCR ) 
     808            { 
     809                /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */ 
     810                TSSetPCR( p_ts, p_ts->i_dts ); 
     811            } 
     812 
     813            /* latency */ 
     814            p_ts->i_dts += 3*p_sys->i_caching_delay/2; 
     815 
     816            sout_AccessOutWrite( p_mux->p_access, p_ts ); 
     817        } 
     818    } 
     819
     820 
     821static sout_buffer_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr ) 
     822
     823    sout_buffer_t *p_pes = p_stream->chain_pes.p_first; 
     824    sout_buffer_t *p_ts; 
     825 
     826    vlc_bool_t b_new_pes = VLC_FALSE; 
     827    vlc_bool_t b_adaptation_field = VLC_FALSE; 
     828 
     829    int        i_payload_max = 184 - ( b_pcr ? 8 : 0 ); 
     830    int        i_payload; 
     831 
     832    if( p_stream->i_pes_used <= 0 ) 
     833    { 
     834        b_new_pes = VLC_TRUE; 
     835    } 
     836    i_payload = __MIN( (int)p_pes->i_size - p_stream->i_pes_used, i_payload_max ); 
     837 
     838    if( b_pcr || i_payload < i_payload_max ) 
     839    { 
     840        b_adaptation_field = VLC_TRUE; 
     841    } 
     842 
     843    p_ts = sout_BufferNew( p_mux->p_sout, 188 ); 
     844 
     845    p_ts->p_buffer[0] = 0x47; 
     846    p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f ); 
     847    p_ts->p_buffer[2] = p_stream->i_pid & 0xff; 
     848    p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter; 
     849 
     850    p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16; 
     851 
     852    if( b_adaptation_field ) 
     853    { 
     854        int i; 
     855 
     856        if( b_pcr ) 
     857        { 
     858            int     i_stuffing = i_payload_max - i_payload; 
     859 
     860            p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR; 
     861 
     862            p_ts->p_buffer[4] = 7 + i_stuffing; 
     863            p_ts->p_buffer[5] = 0x10;   /* flags */ 
     864            p_ts->p_buffer[6] = ( 0 )&0xff; 
     865            p_ts->p_buffer[7] = ( 0 )&0xff; 
     866            p_ts->p_buffer[8] = ( 0 )&0xff; 
     867            p_ts->p_buffer[9] = ( 0 )&0xff; 
     868            p_ts->p_buffer[10]= ( 0 )&0x80; 
     869            p_ts->p_buffer[11]= 0; 
     870 
     871            for( i = 12; i < 12 + i_stuffing; i++ ) 
     872            { 
     873                p_ts->p_buffer[i] = 0xff; 
     874            } 
     875        } 
     876        else 
     877        { 
     878            int i_stuffing = i_payload_max - i_payload; 
     879 
     880            p_ts->p_buffer[4] = i_stuffing - 1; 
     881            if( i_stuffing > 1 ) 
     882            { 
     883                p_ts->p_buffer[5] = 0x00; 
     884                for( i = 6; i < 6 + i_stuffing - 2; i++ ) 
     885                { 
     886                    p_ts->p_buffer[i] = 0xff; 
     887                } 
     888            } 
     889        } 
     890    } 
     891 
     892    /* copy payload */ 
     893    memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload ); 
     894 
     895    p_stream->i_pes_used += i_payload; 
     896    p_stream->i_pes_dts      = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_size; 
     897    p_stream->i_pes_length  -= p_pes->i_length * i_payload / p_pes->i_size; 
     898 
     899    if( p_stream->i_pes_used >= (int)p_pes->i_size ) 
     900    { 
     901        p_pes = BufferChainGet( &p_stream->chain_pes ); 
     902        sout_BufferDelete( p_mux->p_sout, p_pes ); 
     903 
     904        p_pes = p_stream->chain_pes.p_first; 
     905        if( p_pes ) 
     906        { 
     907            p_stream->i_pes_dts    = p_pes->i_dts; 
     908            p_stream->i_pes_length = 0; 
     909            while( p_pes ) 
     910            { 
     911                p_stream->i_pes_length += p_pes->i_length; 
     912 
     913                p_pes = p_pes->p_next; 
     914            } 
     915        } 
     916        else 
     917        { 
     918            p_stream->i_pes_dts = 0; 
     919            p_stream->i_pes_length = 0; 
     920        } 
     921        p_stream->i_pes_used = 0; 
     922    } 
     923 
     924    return p_ts; 
     925
     926 
     927 
     928static void TSSetPCR( sout_buffer_t *p_ts, mtime_t i_dts ) 
     929
     930    mtime_t i_pcr = 9 * p_ts->i_dts / 100; 
     931 
     932    p_ts->p_buffer[6]  = ( i_pcr >> 25 )&0xff; 
     933    p_ts->p_buffer[7]  = ( i_pcr >> 17 )&0xff; 
     934    p_ts->p_buffer[8]  = ( i_pcr >> 9  )&0xff; 
     935    p_ts->p_buffer[9]  = ( i_pcr >> 1  )&0xff; 
     936    p_ts->p_buffer[10]|= ( i_pcr << 7  )&0x80; 
     937
     938 
     939#if 0 
    843940static void TSSetConstraints( sout_mux_t *p_mux, sout_buffer_chain_t *c, mtime_t i_length, int i_bitrate_min, int i_bitrate_max ) 
    844941{ 
     
    9241021    } 
    9251022} 
    926  
    927 static void TSSetDate( sout_buffer_chain_t *c, 
    928                        mtime_t i_dts, mtime_t i_length, mtime_t i_send_offset ) 
    929 
    930     sout_buffer_t *p_ts; 
    931     mtime_t       i_delta = i_length / c->i_depth; 
    932     int           i_packet = 0; 
    933  
    934     for( p_ts = c->p_first; p_ts != NULL; p_ts = p_ts->p_next ) 
    935     { 
    936         p_ts->i_dts    = i_dts + i_packet * i_length / c->i_depth;  /* avoid rounding error */ 
    937         p_ts->i_length = i_delta; 
    938  
    939         if( p_ts->i_flags&SOUT_BUFFER_FLAGS_PRIVATE_PCR_SOFT ) 
    940         { 
    941             mtime_t i_pcr = 9 * p_ts->i_dts / 100; 
    942  
    943             p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff; 
    944             p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff; 
    945             p_ts->p_buffer[8] = ( i_pcr >> 9  )&0xff; 
    946             p_ts->p_buffer[9] = ( i_pcr >> 1  )&0xff; 
    947             p_ts->p_buffer[10]= ( i_pcr << 7  )&0x80; 
    948         } 
    949         p_ts->i_dts += i_send_offset; 
    950  
    951         i_packet++; 
    952     } 
    953 
     1023#endif 
    9541024 
    9551025static void PEStoTS( sout_instance_t *p_sout, 
    9561026                     sout_buffer_chain_t *c, sout_buffer_t *p_pes, 
    957                      ts_stream_t *p_stream, 
    958                      vlc_bool_t b_pcr ) 
     1027                     ts_stream_t *p_stream ) 
    9591028{ 
    9601029    uint8_t *p_data; 
     
    9661035    p_data = p_pes->p_buffer; 
    9671036 
    968     /* Set pcr only with valid DTS */ 
    969     if( p_pes->i_dts <= 0 ) 
    970     { 
    971         b_pcr = VLC_FALSE; 
    972     } 
    973  
    9741037    b_new_pes = VLC_TRUE; 
    9751038 
     
    9771040    { 
    9781041        int           b_adaptation_field; 
    979         int           i_payload; 
    9801042        int           i_copy; 
    9811043        sout_buffer_t *p_ts; 
     
    9931055         */ 
    9941056 
    995         i_payload = 184 - ( b_pcr ? 8 : 0 ); 
    996         i_copy    = __MIN( i_size, i_payload ); 
    997         b_adaptation_field = (b_pcr||i_size<i_payload) ? VLC_TRUE : VLC_FALSE; 
     1057        i_copy    = __MIN( i_size, 184 ); 
     1058        b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE; 
    9981059 
    9991060        p_ts->p_buffer[0] = 0x47; 
     
    10091070        if( b_adaptation_field ) 
    10101071        { 
     1072            int i_stuffing = 184 - i_copy; 
    10111073            int i; 
    10121074 
    1013             if( b_pcr ) 
    1014             { 
    1015                 mtime_t i_pcr = p_pes->i_dts * 9 / 100; 
    1016                 int     i_stuffing = i_payload - i_copy; 
    1017  
    1018                 p_ts->p_buffer[4] = 7 + i_stuffing; 
    1019                 p_ts->p_buffer[5] = 0x10;   /* flags */ 
    1020                 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff; 
    1021                 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff; 
    1022                 p_ts->p_buffer[8] = ( i_pcr >> 9  )&0xff; 
    1023                 p_ts->p_buffer[9] = ( i_pcr >> 1  )&0xff; 
    1024                 p_ts->p_buffer[10]= ( i_pcr << 7  )&0x80; 
    1025                 p_ts->p_buffer[11]= 0; 
    1026  
    1027                 b_pcr = VLC_FALSE; 
    1028                 for( i = 12; i < 12 + i_stuffing; i++ ) 
     1075            p_ts->p_buffer[4] = i_stuffing - 1; 
     1076            if( i_stuffing > 1 ) 
     1077            { 
     1078                p_ts->p_buffer[5] = 0x00; 
     1079                for( i = 6; i < 6 + i_stuffing - 2; i++ ) 
    10291080                { 
    10301081                    p_ts->p_buffer[i] = 0xff; 
    1031                 } 
    1032             } 
    1033             else 
    1034             { 
    1035                 int i_stuffing = i_payload - i_copy; 
    1036  
    1037                 p_ts->p_buffer[4] = i_stuffing - 1; 
    1038                 if( i_stuffing > 1 ) 
    1039                 { 
    1040                     p_ts->p_buffer[5] = 0x00; 
    1041                     for( i = 6; i < 6 + i_stuffing - 2; i++ ) 
    1042                     { 
    1043                         p_ts->p_buffer[i] = 0xff; 
    1044                     } 
    10451082                } 
    10461083            } 
     
    11931230    p_pat->i_size = bits.i_data; 
    11941231 
    1195     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat, VLC_FALSE ); 
     1232    PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat ); 
    11961233} 
    11971234 
     
    12491286    p_pmt->i_size = bits.i_data; 
    12501287 
    1251     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt, VLC_FALSE ); 
     1288    PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt ); 
    12521289} 
    12531290#elif defined MODULE_NAME_IS_mux_ts_dvbpsi 
     
    13071344    p_pat = WritePSISection( p_mux->p_sout, p_section ); 
    13081345 
    1309     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat, VLC_FALSE ); 
     1346    PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat ); 
    13101347 
    13111348    dvbpsi_DeletePSISections( p_section ); 
     
    15131550    p_pmt = WritePSISection( p_mux->p_sout, p_section ); 
    15141551 
    1515     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt, VLC_FALSE ); 
     1552    PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt ); 
    15161553 
    15171554    dvbpsi_DeletePSISections( p_section );