Changeset e444ba72b207c6d6131a3e9942d4aedbe34fe4fb
- Timestamp:
- 08/06/07 01:05:16 (1 year ago)
- git-parent:
- Files:
-
- src/input/clock.c (modified) (8 diffs)
- src/input/es_out.c (modified) (6 diffs)
- src/input/input.c (modified) (1 diff)
- src/input/input_internal.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
src/input/clock.c
r13ec575 re444ba7 73 73 74 74 /* Maximum gap allowed between two CRs. */ 75 #define CR_MAX_GAP 200000075 #define CR_MAX_GAP (I64C(2000000)*100/9) 76 76 77 77 /* Latency introduced on DVDs with CR == 0 on chapter change - this is from … … 82 82 * ClockToSysdate: converts a movie clock to system date 83 83 *****************************************************************************/ 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 ); 84 static 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; 100 91 } 101 92 … … 105 96 * Caution : the synchro state must be SYNCHRO_OK for this to operate. 106 97 *****************************************************************************/ 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 ); 98 static mtime_t ClockCurrent( input_clock_t *cl ) 99 { 100 return (mdate() - cl->sysdate_ref) * INPUT_RATE_DEFAULT / cl->i_rate + 101 cl->cr_ref; 113 102 } 114 103 … … 127 116 * discontinuity 128 117 *****************************************************************************/ 129 void input_ClockInit( input_clock_t *cl, vlc_bool_t b_master, int i_cr_average ) 118 void input_ClockInit( input_thread_t *p_input, 119 input_clock_t *cl, vlc_bool_t b_master, int i_cr_average ) 130 120 { 131 121 cl->i_synchro_state = SYNCHRO_START; … … 138 128 cl->delta_cr = 0; 139 129 cl->i_delta_cr_residue = 0; 130 cl->i_rate = p_input->p->i_rate; 140 131 141 132 cl->i_cr_average = i_cr_average; … … 150 141 input_clock_t *cl, mtime_t i_clock ) 151 142 { 143 const vlc_bool_t b_synchronize = p_input->b_can_pace_control && cl->b_master; 144 const mtime_t i_mdate = mdate(); 145 152 146 if( ( cl->i_synchro_state != SYNCHRO_OK ) || 153 147 ( i_clock == 0 && cl->last_cr != 0 ) ) … … 155 149 /* Feed synchro with a new reference point. */ 156 150 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 ) ); 159 152 cl->i_synchro_state = SYNCHRO_OK; 160 153 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 ) 176 155 { 177 156 cl->last_cr = 0; 178 cl->last_sysdate = 0;179 157 cl->delta_cr = 0; 180 158 cl->i_delta_cr_residue = 0; 159 cl->last_sysdate = 0; 160 cl->last_update = 0; 181 161 } 182 162 } 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 ) 188 183 { 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 ); 194 191 } 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; 232 206 } 233 207 } … … 242 216 return 0; 243 217 244 cl->last_pts = ClockToSysdate( p_input,cl, i_ts + cl->delta_cr );218 cl->last_pts = ClockToSysdate( cl, i_ts + cl->delta_cr ); 245 219 return cl->last_pts + p_input->i_pts_delay; 246 220 } 247 221 222 /***************************************************************************** 223 * input_ClockSetRate: 224 *****************************************************************************/ 225 void 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 315 315 } 316 316 } 317 void 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 } 317 325 318 326 void input_EsOutSetDelay( es_out_t *out, int i_cat, int64_t i_delay ) … … 508 516 p_pgrm->psz_publisher = NULL; 509 517 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 ); 511 519 512 520 /* Append it */ … … 1217 1225 { 1218 1226 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; 1221 1228 } 1222 1229 if( p_block->i_pts > 0 && (p_block->i_flags&BLOCK_FLAG_PREROLL) ) … … 1227 1234 { 1228 1235 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; 1231 1237 } 1232 1238 if ( es->fmt.i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' ) ) … … 1507 1513 /* search program */ 1508 1514 /* 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 ); 1511 1516 return VLC_SUCCESS; 1512 1517 } … … 1526 1531 int64_t *pi_ts = (int64_t *)va_arg( args, int64_t * ); 1527 1532 *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 ); 1530 1534 return VLC_SUCCESS; 1531 1535 } src/input/input.c
rda48f25 re444ba7 1673 1673 /* We will not send audio data if new rate != default */ 1674 1674 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 ); 1676 1676 1677 1677 p_input->p->i_rate = i_rate; 1678 1678 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 ); 1681 1680 1682 1681 b_force_update = VLC_TRUE; src/input/input_internal.h
r9d8ceda re444ba7 264 264 void input_EsOutDiscontinuity( es_out_t *, vlc_bool_t b_flush, vlc_bool_t b_audio ); 265 265 void input_EsOutSetDelay( es_out_t *, int i_cat, int64_t ); 266 void input_EsOutSetRate( es_out_t * ); 266 267 vlc_bool_t input_EsOutDecodersEmpty( es_out_t * ); 267 268 … … 283 284 * discontinuities */ 284 285 mtime_t last_pts; 286 mtime_t last_update; 285 287 int i_synchro_state; 286 288 287 289 vlc_bool_t b_master; 290 291 int i_rate; 288 292 289 293 /* Config */ … … 292 296 } input_clock_t; 293 297 294 void input_ClockInit(input_clock_t *, vlc_bool_t b_master, int i_cr_average );298 void input_ClockInit( input_thread_t *, input_clock_t *, vlc_bool_t b_master, int i_cr_average ); 295 299 void input_ClockSetPCR( input_thread_t *, input_clock_t *, mtime_t ); 296 300 mtime_t input_ClockGetTS( input_thread_t *, input_clock_t *, mtime_t ); 301 void input_ClockSetRate( input_thread_t *, input_clock_t *cl ); 297 302 298 303 /* Subtitles */
