case ES_OUT_SET_PCR: case ES_OUT_SET_GROUP_PCR: { ...... /* TODO do not use vlc_tick_now() but proper stream acquisition date */ const bool b_low_delay = priv->b_low_delay; bool b_extra_buffering_allowed = !b_low_delay && EsOutIsExtraBufferingAllowed( out ); vlc_tick_t i_late = input_clock_Update( p_pgrm->p_input_clock, VLC_OBJECT(p_sys->p_input), input_CanPaceControl(p_sys->p_input) || p_sys->b_buffering, b_extra_buffering_allowed, i_pcr, vlc_tick_now() ); if ( !p_sys->p_pgrm ) return VLC_SUCCESS; //如果es_out处于buffering状态,需要检查下buffering是否应该结束 if ( p_sys->b_buffering ) { /* Check buffering state on master clock update */ EsOutDecodersStopBuffering( out, false ); } else if ( p_pgrm == p_sys->p_pgrm ) { /* Last pcr/clock update was late. We need to compensate by offsetting from the clock the rendering dates */ if ( i_late > 0 && ( !priv->p_sout || !priv->b_out_pace_control ) ) { /* input_clock_GetJitter returns compound delay: * - initial pts delay (buffering/caching) * - jitter compensation * - track offset pts delay * updated on input_clock_Update * Late/jitter amount is updated from median of late values */ vlc_tick_t i_clock_total_delay = input_clock_GetJitter( p_pgrm->p_input_clock ); /* Current jitter */ vlc_tick_t i_new_jitter = i_clock_total_delay - p_sys->i_tracks_pts_delay - p_sys->i_pts_delay; /* If the clock update is late, we have 2 possibilities: * - offset rendering a bit more by increasing the total pts-delay * - ignore, set clock to a new reference ahead of previous one * and flush buffers (because all previous pts will now be late) */ /* Avoid dangerously high value */ /* If the jitter increase is over our max or the total hits the maximum */ if ( i_new_jitter > priv->i_jitter_max || i_clock_total_delay > INPUT_PTS_DELAY_MAX || /* jitter is always 0 due to median calculation first output and low delay can't allow non reversible jitter increase in branch below */ (b_low_delay && i_late > priv->i_jitter_max) ) { msg_Err( p_sys->p_input, "ES_OUT_SET_(GROUP_)PCR is called %d ms late (jitter of %d ms ignored)" , ( int )MS_FROM_VLC_TICK(i_late), ( int )MS_FROM_VLC_TICK(i_new_jitter) ); /* don't change the current jitter */ i_new_jitter = p_sys->i_pts_jitter; } else { msg_Err( p_sys->p_input, "ES_OUT_SET_(GROUP_)PCR is called %d ms late (pts_delay increased to %d ms)" , ( int )MS_FROM_VLC_TICK(i_late), ( int )MS_FROM_VLC_TICK(i_clock_total_delay) ); } /* Force a rebufferization when we are too late */ EsOutControlLocked( out, source, ES_OUT_RESET_PCR ); EsOutPrivControlLocked( out, ES_OUT_PRIV_SET_JITTER, p_sys->i_pts_delay, i_new_jitter, p_sys->i_cr_average ); } } return VLC_SUCCESS; } |