📄 input.c
字号:
double f_pos = (double)i_time / (double)i_length; i_ret = demux_Control( p_input->p->input.p_demux, DEMUX_SET_POSITION, f_pos ); } } if( i_ret ) { msg_Warn( p_input, "INPUT_CONTROL_SET_TIME(_OFFSET) %"PRId64 " failed or not possible", i_time ); } else { if( p_input->p->i_slave > 0 ) SlaveSeek( p_input ); b_force_update = true; } break; } case INPUT_CONTROL_SET_STATE: if( ( val.i_int == PLAYING_S && p_input->i_state == PAUSE_S ) || ( val.i_int == PAUSE_S && p_input->i_state == PAUSE_S ) ) { int i_ret; if( p_input->p->input.p_access ) i_ret = access_Control( p_input->p->input.p_access, ACCESS_SET_PAUSE_STATE, false ); else i_ret = demux_Control( p_input->p->input.p_demux, DEMUX_SET_PAUSE_STATE, false ); if( i_ret ) { /* FIXME What to do ? */ msg_Warn( p_input, "cannot unset pause -> EOF" ); vlc_mutex_unlock( &p_input->p->lock_control ); input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL ); vlc_mutex_lock( &p_input->p->lock_control ); } b_force_update = true; /* Switch to play */ input_ChangeStateWithVarCallback( p_input, PLAYING_S, false ); /* */ if( !i_ret ) input_EsOutChangeState( p_input->p->p_es_out ); } else if( val.i_int == PAUSE_S && p_input->i_state == PLAYING_S && p_input->p->b_can_pause ) { int i_ret, state; if( p_input->p->input.p_access ) i_ret = access_Control( p_input->p->input.p_access, ACCESS_SET_PAUSE_STATE, true ); else i_ret = demux_Control( p_input->p->input.p_demux, DEMUX_SET_PAUSE_STATE, true ); b_force_update = true; if( i_ret ) { msg_Warn( p_input, "cannot set pause state" ); state = p_input->i_state; } else { state = PAUSE_S; } /* Switch to new state */ input_ChangeStateWithVarCallback( p_input, state, false ); /* */ if( !i_ret ) input_EsOutChangeState( p_input->p->p_es_out ); } else if( val.i_int == PAUSE_S && !p_input->p->b_can_pause ) { b_force_update = true; /* Correct "state" value */ input_ChangeStateWithVarCallback( p_input, p_input->i_state, false ); } else if( val.i_int != PLAYING_S && val.i_int != PAUSE_S ) { msg_Err( p_input, "invalid state in INPUT_CONTROL_SET_STATE" ); } break; case INPUT_CONTROL_SET_RATE: case INPUT_CONTROL_SET_RATE_SLOWER: case INPUT_CONTROL_SET_RATE_FASTER: { int i_rate; if( i_type == INPUT_CONTROL_SET_RATE ) { i_rate = val.i_int; } else { static const int ppi_factor[][2] = { {1,64}, {1,32}, {1,16}, {1,8}, {1,4}, {1,3}, {1,2}, {2,3}, {1,1}, {3,2}, {2,1}, {3,1}, {4,1}, {8,1}, {16,1}, {32,1}, {64,1}, {0,0} }; int i_error; int i_idx; int i; i_error = INT_MAX; i_idx = -1; for( i = 0; ppi_factor[i][0] != 0; i++ ) { const int i_test_r = INPUT_RATE_DEFAULT * ppi_factor[i][0] / ppi_factor[i][1]; const int i_test_e = abs(p_input->p->i_rate - i_test_r); if( i_test_e < i_error ) { i_idx = i; i_error = i_test_e; } } assert( i_idx >= 0 && ppi_factor[i_idx][0] != 0 ); if( i_type == INPUT_CONTROL_SET_RATE_SLOWER ) { if( ppi_factor[i_idx+1][0] > 0 ) i_rate = INPUT_RATE_DEFAULT * ppi_factor[i_idx+1][0] / ppi_factor[i_idx+1][1]; else i_rate = INPUT_RATE_MAX+1; } else { assert( i_type == INPUT_CONTROL_SET_RATE_FASTER ); if( i_idx > 0 ) i_rate = INPUT_RATE_DEFAULT * ppi_factor[i_idx-1][0] / ppi_factor[i_idx-1][1]; else i_rate = INPUT_RATE_MIN-1; } } if( i_rate < INPUT_RATE_MIN ) { msg_Dbg( p_input, "cannot set rate faster" ); i_rate = INPUT_RATE_MIN; } else if( i_rate > INPUT_RATE_MAX ) { msg_Dbg( p_input, "cannot set rate slower" ); i_rate = INPUT_RATE_MAX; } if( i_rate != INPUT_RATE_DEFAULT && ( ( !p_input->b_can_pace_control && !p_input->p->b_can_rate_control ) || ( p_input->p->p_sout && !p_input->p->b_out_pace_control ) ) ) { msg_Dbg( p_input, "cannot change rate" ); i_rate = INPUT_RATE_DEFAULT; } if( i_rate != p_input->p->i_rate && !p_input->b_can_pace_control && p_input->p->b_can_rate_control ) { int i_ret; if( p_input->p->input.p_access ) i_ret = VLC_EGENERIC; else i_ret = demux_Control( p_input->p->input.p_demux, DEMUX_SET_RATE, &i_rate ); if( i_ret ) { msg_Warn( p_input, "ACCESS/DEMUX_SET_RATE failed" ); i_rate = p_input->p->i_rate; } } /* */ if( i_rate != p_input->p->i_rate ) { val.i_int = i_rate; var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL ); var_SetBool( p_input, "rate-change", true ); p_input->p->i_rate = i_rate; /* FIXME do we need a RESET_PCR when !p_input->p->input.b_rescale_ts ? */ if( p_input->p->input.b_rescale_ts ) input_EsOutChangeRate( p_input->p->p_es_out, i_rate ); b_force_update = true; } break; } case INPUT_CONTROL_SET_PROGRAM: /* No need to force update, es_out does it if needed */ es_out_Control( p_input->p->p_es_out, ES_OUT_SET_GROUP, val.i_int ); demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, val.i_int, NULL ); break; case INPUT_CONTROL_SET_ES: /* No need to force update, es_out does it if needed */ es_out_Control( p_input->p->p_es_out, ES_OUT_SET_ES, input_EsOutGetFromID( p_input->p->p_es_out, val.i_int ) ); break; case INPUT_CONTROL_SET_AUDIO_DELAY: input_EsOutSetDelay( p_input->p->p_es_out, AUDIO_ES, val.i_time ); var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL ); break; case INPUT_CONTROL_SET_SPU_DELAY: input_EsOutSetDelay( p_input->p->p_es_out, SPU_ES, val.i_time ); var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL ); break; case INPUT_CONTROL_SET_TITLE: case INPUT_CONTROL_SET_TITLE_NEXT: case INPUT_CONTROL_SET_TITLE_PREV: if( p_input->p->input.b_title_demux && p_input->p->input.i_title > 0 ) { /* TODO */ /* FIXME handle demux title */ demux_t *p_demux = p_input->p->input.p_demux; int i_title; if( i_type == INPUT_CONTROL_SET_TITLE_PREV ) i_title = p_demux->info.i_title - 1; else if( i_type == INPUT_CONTROL_SET_TITLE_NEXT ) i_title = p_demux->info.i_title + 1; else i_title = val.i_int; if( i_title >= 0 && i_title < p_input->p->input.i_title ) { input_EsOutChangePosition( p_input->p->p_es_out ); demux_Control( p_demux, DEMUX_SET_TITLE, i_title ); input_ControlVarTitle( p_input, i_title ); } } else if( p_input->p->input.i_title > 0 ) { access_t *p_access = p_input->p->input.p_access; int i_title; if( i_type == INPUT_CONTROL_SET_TITLE_PREV ) i_title = p_access->info.i_title - 1; else if( i_type == INPUT_CONTROL_SET_TITLE_NEXT ) i_title = p_access->info.i_title + 1; else i_title = val.i_int; if( i_title >= 0 && i_title < p_input->p->input.i_title ) { input_EsOutChangePosition( p_input->p->p_es_out ); access_Control( p_access, ACCESS_SET_TITLE, i_title ); stream_AccessReset( p_input->p->input.p_stream ); } } break; case INPUT_CONTROL_SET_SEEKPOINT: case INPUT_CONTROL_SET_SEEKPOINT_NEXT: case INPUT_CONTROL_SET_SEEKPOINT_PREV: if( p_input->p->input.b_title_demux && p_input->p->input.i_title > 0 ) { demux_t *p_demux = p_input->p->input.p_demux; int i_seekpoint; int64_t i_input_time; int64_t i_seekpoint_time; if( i_type == INPUT_CONTROL_SET_SEEKPOINT_PREV ) { i_seekpoint = p_demux->info.i_seekpoint; i_seekpoint_time = p_input->p->input.title[p_demux->info.i_title]->seekpoint[i_seekpoint]->i_time_offset; if( i_seekpoint_time >= 0 && !demux_Control( p_demux, DEMUX_GET_TIME, &i_input_time ) ) { if ( i_input_time < i_seekpoint_time + 3000000 ) i_seekpoint--; } else i_seekpoint--; } else if( i_type == INPUT_CONTROL_SET_SEEKPOINT_NEXT ) i_seekpoint = p_demux->info.i_seekpoint + 1; else i_seekpoint = val.i_int; if( i_seekpoint >= 0 && i_seekpoint < p_input->p->input.title[p_demux->info.i_title]->i_seekpoint ) { input_EsOutChangePosition( p_input->p->p_es_out ); demux_Control( p_demux, DEMUX_SET_SEEKPOINT, i_seekpoint ); } } else if( p_input->p->input.i_title > 0 ) { demux_t *p_demux = p_input->p->input.p_demux; access_t *p_access = p_input->p->input.p_access; int i_seekpoint; int64_t i_input_time; int64_t i_seekpoint_time; if( i_type == INPUT_CONTROL_SET_SEEKPOINT_PREV ) { i_seekpoint = p_access->info.i_seekpoint; i_seekpoint_time = p_input->p->input.title[p_access->info.i_title]->seekpoint[i_seekpoint]->i_time_offset; if( i_seekpoint_time >= 0 && demux_Control( p_demux, DEMUX_GET_TIME, &i_input_time ) ) { if ( i_input_time < i_seekpoint_time + 3000000 ) i_seekpoint--; } else i_seekpoint--; } else if( i_type == INPUT_CONTROL_SET_SEEKPOINT_NEXT ) i_seekpoint = p_access->info.i_seekpoint + 1; else i_seekpoint = val.i_int; if( i_seekpoint >= 0 && i_seekpoint < p_input->p->input.title[p_access->info.i_title]->i_seekpoint ) { input_EsOutChangePosition( p_input->p->p_es_out ); access_Control( p_access, ACCESS_SET_SEEKPOINT, i_seekpoint ); stream_AccessReset( p_input->p->input.p_stream ); } } break; case INPUT_CONTROL_ADD_SLAVE: if( val.psz_string ) { input_source_t *slave = InputSourceNew( p_input ); if( !InputSourceInit( p_input, slave, val.psz_string, NULL ) ) { vlc_meta_t *p_meta; int64_t i_time; /* Add the slave */ msg_Dbg( p_input, "adding %s as slave on the fly", val.psz_string ); /* Set position */ if( demux_Control( p_input->p->input.p_demux, DEMUX_GET_TIME, &i_time ) ) { msg_Err( p_input, "demux doesn't like DEMUX_GET_TIME" ); InputSourceClean( slave ); free( slave ); break; } if( demux_Control( slave->p_demux, DEMUX_SET_TIME, i_time ) ) { msg_Err( p_input, "seek failed for new slave" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -