📄 input.c
字号:
{ int i; for( i = 0; i < p_input->i_control; i++ ) { p_input->control[i].i_type = p_input->control[i+1].i_type; p_input->control[i].val = p_input->control[i+1].val; } } return VLC_SUCCESS;}static void ControlReduce( input_thread_t *p_input ){ int i; for( i = 1; i < p_input->i_control; i++ ) { const int i_lt = p_input->control[i-1].i_type; const int i_ct = p_input->control[i].i_type; /* XXX We can't merge INPUT_CONTROL_SET_ES *//* msg_Dbg( p_input, "[%d/%d] l=%d c=%d", i, p_input->i_control, i_lt, i_ct );*/ if( i_lt == i_ct && ( i_ct == INPUT_CONTROL_SET_STATE || i_ct == INPUT_CONTROL_SET_RATE || i_ct == INPUT_CONTROL_SET_POSITION || i_ct == INPUT_CONTROL_SET_TIME || i_ct == INPUT_CONTROL_SET_PROGRAM || i_ct == INPUT_CONTROL_SET_TITLE || i_ct == INPUT_CONTROL_SET_SEEKPOINT || i_ct == INPUT_CONTROL_SET_BOOKMARK ) ) { int j;// msg_Dbg( p_input, "merged at %d", i ); /* Remove the i-1 */ for( j = i; j < p_input->i_control; j++ ) p_input->control[j-1] = p_input->control[j]; p_input->i_control--; } else { /* TODO but that's not that important - merge SET_X with SET_X_CMD - remove SET_SEEKPOINT/SET_POSITION/SET_TIME before a SET_TITLE - remove SET_SEEKPOINT/SET_POSITION/SET_TIME before another among them - ? */ } }}static vlc_bool_t Control( input_thread_t *p_input, int i_type, vlc_value_t val ){ vlc_bool_t b_force_update = VLC_FALSE; switch( i_type ) { case INPUT_CONTROL_SET_DIE: msg_Dbg( p_input, "control: stopping input" ); /* Mark all submodules to die */ if( p_input->input.p_access ) p_input->input.p_access->b_die = VLC_TRUE; if( p_input->input.p_stream ) p_input->input.p_stream->b_die = VLC_TRUE; p_input->input.p_demux->b_die = VLC_TRUE; p_input->b_die = VLC_TRUE; break; case INPUT_CONTROL_SET_POSITION: case INPUT_CONTROL_SET_POSITION_OFFSET: { double f_pos; if( i_type == INPUT_CONTROL_SET_POSITION ) { f_pos = val.f_float; } else { /* Should not fail */ demux2_Control( p_input->input.p_demux, DEMUX_GET_POSITION, &f_pos ); f_pos += val.f_float; } if( f_pos < 0.0 ) f_pos = 0.0; if( f_pos > 1.0 ) f_pos = 1.0; /* Reset the decoders states and clock synch (before calling the demuxer */ es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); if( demux2_Control( p_input->input.p_demux, DEMUX_SET_POSITION, f_pos ) ) { msg_Err( p_input, "INPUT_CONTROL_SET_POSITION(_OFFSET) " "%2.1f%% failed", f_pos * 100 ); } else { if( p_input->i_slave > 0 ) SlaveSeek( p_input ); //input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); //es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); b_force_update = VLC_TRUE; } break; } case INPUT_CONTROL_SET_TIME: case INPUT_CONTROL_SET_TIME_OFFSET: { int64_t i_time; int i_ret; if( i_type == INPUT_CONTROL_SET_TIME ) { i_time = val.i_time; } else { /* Should not fail */ demux2_Control( p_input->input.p_demux, DEMUX_GET_TIME, &i_time ); i_time += val.i_time; } if( i_time < 0 ) i_time = 0; /* Reset the decoders states and clock synch (before calling the demuxer */ es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); i_ret = demux2_Control( p_input->input.p_demux, DEMUX_SET_TIME, i_time ); if( i_ret ) { int64_t i_length; /* Emulate it with a SET_POS */ demux2_Control( p_input->input.p_demux, DEMUX_GET_LENGTH, &i_length ); if( i_length > 0 ) { double f_pos = (double)i_time / (double)i_length; i_ret = demux2_Control( p_input->input.p_demux, DEMUX_SET_POSITION, f_pos ); } } if( i_ret ) { msg_Err( p_input, "INPUT_CONTROL_SET_TIME(_OFFSET) "I64Fd " failed", i_time ); } else { if( p_input->i_slave > 0 ) SlaveSeek( p_input ); //input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); //es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); b_force_update = VLC_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->input.p_access ) i_ret = access2_Control( p_input->input.p_access, ACCESS_SET_PAUSE_STATE, VLC_FALSE ); else i_ret = demux2_Control( p_input->input.p_demux, DEMUX_SET_PAUSE_STATE, VLC_FALSE ); if( i_ret ) { /* FIXME What to do ? */ msg_Warn( p_input, "cannot unset pause -> EOF" ); vlc_mutex_unlock( &p_input->lock_control ); input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL ); vlc_mutex_lock( &p_input->lock_control ); } b_force_update = VLC_TRUE; /* Switch to play */ p_input->i_state = PLAYING_S; val.i_int = PLAYING_S; var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); /* Reset clock */ es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); } else if( val.i_int == PAUSE_S && p_input->i_state == PLAYING_S && p_input->b_can_pause ) { int i_ret; if( p_input->input.p_access ) i_ret = access2_Control( p_input->input.p_access, ACCESS_SET_PAUSE_STATE, VLC_TRUE ); else i_ret = demux2_Control( p_input->input.p_demux, DEMUX_SET_PAUSE_STATE, VLC_TRUE ); b_force_update = VLC_TRUE; if( i_ret ) { msg_Warn( p_input, "cannot set pause state" ); val.i_int = p_input->i_state; } else { val.i_int = PAUSE_S; } /* Switch to new state */ p_input->i_state = val.i_int; var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); } else if( val.i_int == PAUSE_S && !p_input->b_can_pause ) { b_force_update = VLC_TRUE; /* Correct "state" value */ val.i_int = p_input->i_state; var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); } 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_SLOWER ) i_rate = p_input->i_rate * 2; else if( i_type == INPUT_CONTROL_SET_RATE_FASTER ) i_rate = p_input->i_rate / 2; else i_rate = val.i_int; 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_sout && !p_input->b_out_pace_control ) ) ) { msg_Dbg( p_input, "cannot change rate" ); i_rate = INPUT_RATE_DEFAULT; } if( i_rate != p_input->i_rate ) { p_input->i_rate = i_rate; val.i_int = i_rate; var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL ); /* We haven't send data to decoder when rate != default */ if( i_rate == INPUT_RATE_DEFAULT ) input_EsOutDiscontinuity( p_input->p_es_out, VLC_TRUE ); /* Reset clock */ es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); b_force_update = VLC_TRUE; } break; } case INPUT_CONTROL_SET_PROGRAM: /* No need to force update, es_out does it if needed */ es_out_Control( p_input->p_es_out, ES_OUT_SET_GROUP, val.i_int ); demux2_Control( p_input->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_es_out, ES_OUT_SET_ES, input_EsOutGetFromID( p_input->p_es_out, val.i_int ) ); break; case INPUT_CONTROL_SET_AUDIO_DELAY: input_EsOutSetDelay( p_input->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_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->input.b_title_demux && p_input->input.i_title > 0 ) { /* TODO */ /* FIXME handle demux title */ demux_t *p_demux = p_input->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->input.i_title ) { demux2_Control( p_demux, DEMUX_SET_TITLE, i_title ); input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); input_ControlVarTitle( p_input, i_title ); } } else if( p_input->input.i_title > 0 ) { access_t *p_access = p_input->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->input.i_title ) { access2_Control( p_access, ACCESS_SET_TITLE, i_title ); stream_AccessReset( p_input->input.p_stream ); input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); } } break; case INPUT_CONTROL_SET_SEEKPOINT: case INPUT_CONTROL_SET_SEEKPOINT_NEXT: case INPUT_CONTROL_SET_SEEKPOINT_PREV: if( p_input->input.b_title_demux && p_input->input.i_title > 0 ) { demux_t *p_demux = p_input->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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -