+
+ 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" );
+ input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
+ }
+
+ 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->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 );
+ 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;
+
+ if( i_type == INPUT_CONTROL_SET_SEEKPOINT_PREV )
+ i_seekpoint = p_demux->info.i_seekpoint - 1;
+ 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->input.title[p_demux->info.i_title]->i_seekpoint )
+ {
+ demux2_Control( p_demux, DEMUX_SET_SEEKPOINT, i_seekpoint );
+
+ input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE );
+ es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR );
+ }
+ }
+ else if( p_input->input.i_title > 0 )
+ {
+ access_t *p_access = p_input->input.p_access;
+ int i_seekpoint;
+
+ if( i_type == INPUT_CONTROL_SET_SEEKPOINT_PREV )
+ i_seekpoint = p_access->info.i_seekpoint - 1;
+ else if( i_type == INPUT_CONTROL_SET_TITLE_NEXT )
+ i_seekpoint = p_access->info.i_seekpoint + 1;
+ else
+ i_seekpoint = val.i_int;
+
+ if( i_seekpoint >= 0 && i_seekpoint <
+ p_input->input.title[p_access->info.i_title]->i_seekpoint )
+ {
+ access2_Control( p_access, ACCESS_SET_SEEKPOINT, i_seekpoint );
+ 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_BOOKMARK:
+ default:
+ msg_Err( p_input, "not yet implemented" );
+ break;