Changeset e444ba72b207c6d6131a3e9942d4aedbe34fe4fb

Show
Ignore:
Timestamp:
08/06/07 01:05:16 (1 year ago)
Author:
Laurent Aimar <fenrir@videolan.org>
git-committer:
Laurent Aimar <fenrir@videolan.org> 1181257516 +0000
git-parent:

[bf16abda22682951f3aa4c551d48dcd4b8133ef9]

git-author:
Laurent Aimar <fenrir@videolan.org> 1181257516 +0000
Message:

clock: clean up/simplify + remove 1/90000 reference.
all: improve input rate (no more out of order/dropped pictures on
rate change).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/input/clock.c

    r13ec575 re444ba7  
    7373 
    7474/* Maximum gap allowed between two CRs. */ 
    75 #define CR_MAX_GAP 2000000 
     75#define CR_MAX_GAP (I64C(2000000)*100/9) 
    7676 
    7777/* Latency introduced on DVDs with CR == 0 on chapter change - this is from 
     
    8282 * ClockToSysdate: converts a movie clock to system date 
    8383 *****************************************************************************/ 
    84 static mtime_t ClockToSysdate( input_thread_t *p_input, 
    85                                input_clock_t *cl, mtime_t i_clock ) 
    86 
    87     mtime_t     i_sysdate = 0; 
    88  
    89     if( cl->i_synchro_state == SYNCHRO_OK ) 
    90     { 
    91         i_sysdate = (mtime_t)(i_clock - cl->cr_ref) 
    92                         * (mtime_t)p_input->p->i_rate 
    93                         * (mtime_t)300; 
    94         i_sysdate /= 27; 
    95         i_sysdate /= INPUT_RATE_DEFAULT; 
    96         i_sysdate += (mtime_t)cl->sysdate_ref; 
    97     } 
    98  
    99     return( i_sysdate ); 
     84static mtime_t ClockToSysdate( input_clock_t *cl, mtime_t i_clock ) 
     85
     86    if( cl->i_synchro_state != SYNCHRO_OK ) 
     87        return 0; 
     88 
     89    return (i_clock - cl->cr_ref) * cl->i_rate / INPUT_RATE_DEFAULT + 
     90           cl->sysdate_ref; 
    10091} 
    10192 
     
    10596 * Caution : the synchro state must be SYNCHRO_OK for this to operate. 
    10697 *****************************************************************************/ 
    107 static mtime_t ClockCurrent( input_thread_t *p_input, 
    108                              input_clock_t *cl ) 
    109 
    110     return( (mdate() - cl->sysdate_ref) * 27 * INPUT_RATE_DEFAULT 
    111              / p_input->p->i_rate / 300 
    112              + cl->cr_ref ); 
     98static mtime_t ClockCurrent( input_clock_t *cl ) 
     99
     100    return (mdate() - cl->sysdate_ref) * INPUT_RATE_DEFAULT / cl->i_rate + 
     101           cl->cr_ref; 
    113102} 
    114103 
     
    127116 *                  discontinuity 
    128117 *****************************************************************************/ 
    129 void input_ClockInit( input_clock_t *cl, vlc_bool_t b_master, int i_cr_average ) 
     118void input_ClockInit( input_thread_t *p_input, 
     119                      input_clock_t *cl, vlc_bool_t b_master, int i_cr_average ) 
    130120{ 
    131121    cl->i_synchro_state = SYNCHRO_START; 
     
    138128    cl->delta_cr = 0; 
    139129    cl->i_delta_cr_residue = 0; 
     130    cl->i_rate = p_input->p->i_rate; 
    140131 
    141132    cl->i_cr_average = i_cr_average; 
     
    150141                        input_clock_t *cl, mtime_t i_clock ) 
    151142{ 
     143    const vlc_bool_t b_synchronize = p_input->b_can_pace_control && cl->b_master; 
     144    const mtime_t i_mdate = mdate(); 
     145 
    152146    if( ( cl->i_synchro_state != SYNCHRO_OK ) || 
    153147        ( i_clock == 0 && cl->last_cr != 0 ) ) 
     
    155149        /* Feed synchro with a new reference point. */ 
    156150        ClockNewRef( cl, i_clock, 
    157                      cl->last_pts + CR_MEAN_PTS_GAP > mdate() ? 
    158                      cl->last_pts + CR_MEAN_PTS_GAP : mdate() ); 
     151                         __MAX( cl->last_pts + CR_MEAN_PTS_GAP, i_mdate ) ); 
    159152        cl->i_synchro_state = SYNCHRO_OK; 
    160153 
    161         if( p_input->b_can_pace_control && cl->b_master ) 
    162         { 
    163             cl->last_cr = i_clock; 
    164             if( !p_input->p->b_out_pace_control ) 
    165             { 
    166                 mtime_t i_wakeup = ClockToSysdate( p_input, cl, i_clock ); 
    167                 while( (i_wakeup - mdate()) / CLOCK_FREQ > 1 ) 
    168                 { 
    169                     msleep( CLOCK_FREQ ); 
    170                     if( p_input->b_die ) i_wakeup = mdate(); 
    171                 } 
    172                 mwait( i_wakeup ); 
    173             } 
    174         } 
    175         else 
     154        if( !b_synchronize ) 
    176155        { 
    177156            cl->last_cr = 0; 
    178             cl->last_sysdate = 0; 
    179157            cl->delta_cr = 0; 
    180158            cl->i_delta_cr_residue = 0; 
     159            cl->last_sysdate = 0; 
     160            cl->last_update = 0; 
    181161        } 
    182162    } 
    183     else 
    184     { 
    185         if ( cl->last_cr != 0 && 
    186                (    (cl->last_cr - i_clock) > CR_MAX_GAP 
    187                  || (cl->last_cr - i_clock) < - CR_MAX_GAP ) ) 
     163    else if ( cl->last_cr != 0 && 
     164              ( (cl->last_cr - i_clock) > CR_MAX_GAP || 
     165                (cl->last_cr - i_clock) < - CR_MAX_GAP ) ) 
     166    { 
     167        /* Stream discontinuity, for which we haven't received a 
     168         * warning from the stream control facilities (dd-edited 
     169         * stream ?). */ 
     170        msg_Warn( p_input, "clock gap, unexpected stream discontinuity" ); 
     171        input_ClockInit( p_input, cl, cl->b_master, cl->i_cr_average ); 
     172    } 
     173 
     174    cl->last_cr = i_clock; 
     175    cl->last_sysdate = i_mdate; 
     176 
     177    if( b_synchronize ) 
     178    { 
     179        /* Wait a while before delivering the packets to the decoder. 
     180         * In case of multiple programs, we arbitrarily follow the 
     181         * clock of the selected program. */ 
     182        if( !p_input->p->b_out_pace_control ) 
    188183        { 
    189             /* Stream discontinuity, for which we haven't received a 
    190              * warning from the stream control facilities (dd-edited 
    191              * stream ?). */ 
    192             msg_Warn( p_input, "clock gap, unexpected stream discontinuity" ); 
    193             input_ClockInit( cl, cl->b_master, cl->i_cr_average ); 
     184            mtime_t i_wakeup = ClockToSysdate( cl, i_clock ); 
     185            while( (i_wakeup - mdate()) / CLOCK_FREQ > 1 ) 
     186            { 
     187                msleep( CLOCK_FREQ ); 
     188                if( p_input->b_die ) i_wakeup = mdate(); 
     189            } 
     190            mwait( i_wakeup ); 
    194191        } 
    195  
    196         cl->last_cr = i_clock; 
    197  
    198         if( p_input->b_can_pace_control && cl->b_master ) 
    199         { 
    200             /* Wait a while before delivering the packets to the decoder. 
    201              * In case of multiple programs, we arbitrarily follow the 
    202              * clock of the selected program. */ 
    203             if( !p_input->p->b_out_pace_control ) 
    204             { 
    205                 mtime_t i_wakeup = ClockToSysdate( p_input, cl, i_clock ); 
    206                 while( (i_wakeup - mdate()) / CLOCK_FREQ > 1 ) 
    207                 { 
    208                     msleep( CLOCK_FREQ ); 
    209                     if( p_input->b_die ) i_wakeup = mdate(); 
    210                 } 
    211                 mwait( i_wakeup ); 
    212             } 
    213         } 
    214         else if ( mdate() - cl->last_sysdate > 200000 ) 
    215         { 
    216             /* Smooth clock reference variations. */ 
    217             mtime_t i_extrapoled_clock = ClockCurrent( p_input, cl ); 
    218             mtime_t delta_cr; 
    219  
    220             /* Bresenham algorithm to smooth variations. */ 
    221             delta_cr = ( cl->delta_cr * (cl->i_cr_average - 1) 
    222                                + ( i_extrapoled_clock - i_clock ) 
    223                                + cl->i_delta_cr_residue ) 
    224                            / cl->i_cr_average; 
    225             cl->i_delta_cr_residue = ( cl->delta_cr * (cl->i_cr_average - 1) 
    226                                        + ( i_extrapoled_clock - i_clock ) 
    227                                        + cl->i_delta_cr_residue ) 
    228                                     % cl->i_cr_average; 
    229             cl->delta_cr = delta_cr; 
    230             cl->last_sysdate = mdate(); 
    231         } 
     192    } 
     193    else if ( i_mdate - cl->last_update > 200000 ) 
     194    { 
     195        /* Smooth clock reference variations. */ 
     196        const mtime_t i_extrapoled_clock = ClockCurrent( cl ); 
     197        /* Bresenham algorithm to smooth variations. */ 
     198        const mtime_t i_tmp = cl->delta_cr * (cl->i_cr_average - 1) + 
     199                              ( i_extrapoled_clock - i_clock ) * 1  + 
     200                              cl->i_delta_cr_residue; 
     201 
     202        cl->i_delta_cr_residue = i_tmp % cl->i_cr_average; 
     203        cl->delta_cr           = i_tmp / cl->i_cr_average; 
     204 
     205        cl->last_update = i_mdate; 
    232206    } 
    233207} 
     
    242216        return 0; 
    243217 
    244     cl->last_pts = ClockToSysdate( p_input, cl, i_ts + cl->delta_cr ); 
     218    cl->last_pts = ClockToSysdate( cl, i_ts + cl->delta_cr ); 
    245219    return cl->last_pts + p_input->i_pts_delay; 
    246220} 
    247221 
     222/***************************************************************************** 
     223 * input_ClockSetRate: 
     224 *****************************************************************************/ 
     225void input_ClockSetRate( input_thread_t *p_input, input_clock_t *cl ) 
     226{ 
     227    if( cl->i_synchro_state == SYNCHRO_OK ) 
     228    { 
     229        /* Move the reference point */ 
     230        cl->cr_ref = cl->last_cr; 
     231        cl->sysdate_ref = cl->last_sysdate; 
     232    } 
     233    cl->i_rate = p_input->p->i_rate; 
     234} 
     235 
  • src/input/es_out.c

    rb012efb re444ba7  
    315315    } 
    316316} 
     317void input_EsOutSetRate( es_out_t *out ) 
     318{ 
     319    es_out_sys_t      *p_sys = out->p_sys; 
     320    int i; 
     321 
     322    for( i = 0; i < p_sys->i_pgrm; i++ ) 
     323        input_ClockSetRate( p_sys->p_input, &p_sys->pgrm[i]->clock ); 
     324} 
    317325 
    318326void input_EsOutSetDelay( es_out_t *out, int i_cat, int64_t i_delay ) 
     
    508516    p_pgrm->psz_publisher = NULL; 
    509517    p_pgrm->p_epg = NULL; 
    510     input_ClockInit( &p_pgrm->clock, VLC_FALSE, p_input->p->input.i_cr_average ); 
     518    input_ClockInit( p_input, &p_pgrm->clock, VLC_FALSE, p_input->p->input.i_cr_average ); 
    511519 
    512520    /* Append it */ 
     
    12171225    { 
    12181226        p_block->i_dts = 
    1219             input_ClockGetTS( p_input, &p_pgrm->clock, 
    1220                               ( p_block->i_dts + 11 ) * 9 / 100 ) + i_delay; 
     1227            input_ClockGetTS( p_input, &p_pgrm->clock, p_block->i_dts ) + i_delay; 
    12211228    } 
    12221229    if( p_block->i_pts > 0 && (p_block->i_flags&BLOCK_FLAG_PREROLL) ) 
     
    12271234    { 
    12281235        p_block->i_pts = 
    1229             input_ClockGetTS( p_input, &p_pgrm->clock, 
    1230                               ( p_block->i_pts + 11 ) * 9 / 100 ) + i_delay; 
     1236            input_ClockGetTS( p_input, &p_pgrm->clock, p_block->i_pts ) + i_delay; 
    12311237    } 
    12321238    if ( es->fmt.i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' ) ) 
     
    15071513            /* search program */ 
    15081514            /* 11 is a vodoo trick to avoid non_pcr*9/100 to be null */ 
    1509             input_ClockSetPCR( p_sys->p_input, &p_pgrm->clock, 
    1510                                (i_pcr + 11 ) * 9 / 100); 
     1515            input_ClockSetPCR( p_sys->p_input, &p_pgrm->clock, i_pcr ); 
    15111516            return VLC_SUCCESS; 
    15121517        } 
     
    15261531                int64_t *pi_ts = (int64_t *)va_arg( args, int64_t * ); 
    15271532                *pi_ts = input_ClockGetTS( p_sys->p_input, 
    1528                                            &p_sys->p_pgrm->clock, 
    1529                                            ( i_ts + 11 ) * 9 / 100 ); 
     1533                                           &p_sys->p_pgrm->clock, i_ts ); 
    15301534                return VLC_SUCCESS; 
    15311535            } 
  • src/input/input.c

    rda48f25 re444ba7  
    16731673                /* We will not send audio data if new rate != default */ 
    16741674                if( i_rate != INPUT_RATE_DEFAULT && p_input->p->i_rate == INPUT_RATE_DEFAULT ) 
    1675                     input_EsOutDiscontinuity( p_input->p->p_es_out, VLC_TRUE, VLC_TRUE ); 
     1675                    input_EsOutDiscontinuity( p_input->p->p_es_out, VLC_FALSE, VLC_TRUE ); 
    16761676 
    16771677                p_input->p->i_rate  = i_rate; 
    16781678 
    1679                 /* Reset clock */ 
    1680                 es_out_Control( p_input->p->p_es_out, ES_OUT_RESET_PCR ); 
     1679                input_EsOutSetRate( p_input->p->p_es_out ); 
    16811680 
    16821681                b_force_update = VLC_TRUE; 
  • src/input/input_internal.h

    r9d8ceda re444ba7  
    264264void       input_EsOutDiscontinuity( es_out_t *, vlc_bool_t b_flush, vlc_bool_t b_audio ); 
    265265void       input_EsOutSetDelay( es_out_t *, int i_cat, int64_t ); 
     266void       input_EsOutSetRate( es_out_t * ); 
    266267vlc_bool_t input_EsOutDecodersEmpty( es_out_t * ); 
    267268 
     
    283284                                      * discontinuities                      */ 
    284285    mtime_t                 last_pts; 
     286    mtime_t                 last_update; 
    285287    int                     i_synchro_state; 
    286288 
    287289    vlc_bool_t              b_master; 
     290 
     291    int                     i_rate; 
    288292 
    289293    /* Config */ 
     
    292296} input_clock_t; 
    293297 
    294 void input_ClockInit( input_clock_t *, vlc_bool_t b_master, int i_cr_average ); 
     298void    input_ClockInit( input_thread_t *, input_clock_t *, vlc_bool_t b_master, int i_cr_average ); 
    295299void    input_ClockSetPCR( input_thread_t *, input_clock_t *, mtime_t ); 
    296300mtime_t input_ClockGetTS( input_thread_t *, input_clock_t *, mtime_t ); 
     301void    input_ClockSetRate( input_thread_t *, input_clock_t *cl ); 
    297302 
    298303/* Subtitles */