- if( i_channel < 0 || i_channel >= 4 || !p_owner->cc.pb_present[i_channel] )
- return VLC_EGENERIC;
-
- if( b_decode )
- {
- static const vlc_fourcc_t fcc[4] = {
- VLC_FOURCC('c', 'c', '1', ' '),
- VLC_FOURCC('c', 'c', '2', ' '),
- VLC_FOURCC('c', 'c', '3', ' '),
- VLC_FOURCC('c', 'c', '4', ' '),
- };
- decoder_t *p_cc;
- es_format_t fmt;
-
- es_format_Init( &fmt, SPU_ES, fcc[i_channel] );
- p_cc = input_DecoderNew( p_owner->p_input, &fmt,
- p_dec->p_owner->p_clock, p_owner->p_sout );
- if( !p_cc )
- {
- msg_Err( p_dec, "could not create decoder" );
- dialog_Fatal( p_dec, _("Streaming / Transcoding failed"), "%s",
- _("VLC could not open the decoder module.") );
- return VLC_EGENERIC;
- }
- else if( !p_cc->p_module )
- {
- DecoderUnsupportedCodec( p_dec, fcc[i_channel] );
- input_DecoderDelete(p_cc);
- return VLC_EGENERIC;
- }
- p_cc->p_owner->p_clock = p_owner->p_clock;
-
- vlc_mutex_lock( &p_owner->lock );
- p_owner->cc.pp_decoder[i_channel] = p_cc;
- vlc_mutex_unlock( &p_owner->lock );
- }
- else
- {
- decoder_t *p_cc;
-
- vlc_mutex_lock( &p_owner->lock );
- p_cc = p_owner->cc.pp_decoder[i_channel];
- p_owner->cc.pp_decoder[i_channel] = NULL;
- vlc_mutex_unlock( &p_owner->lock );
-
- if( p_cc )
- input_DecoderDelete(p_cc);
- }
- return VLC_SUCCESS;
-}
-int input_DecoderGetCcState( decoder_t *p_dec, bool *pb_decode, int i_channel )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- *pb_decode = false;
- if( i_channel < 0 || i_channel >= 4 || !p_owner->cc.pb_present[i_channel] )
- return VLC_EGENERIC;
-
- vlc_mutex_lock( &p_owner->lock );
- *pb_decode = p_owner->cc.pp_decoder[i_channel] != NULL;
- vlc_mutex_unlock( &p_owner->lock );
- return VLC_EGENERIC;
-}
-
-void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_mutex_lock( &p_owner->lock );
- /* Normally, p_owner->b_paused != b_paused here. But if a track is added
- * while the input is paused (e.g. add sub file), then b_paused is
- * (incorrectly) false. */
- if( likely(p_owner->b_paused != b_paused) ) {
- p_owner->b_paused = b_paused;
- p_owner->pause.i_date = i_date;
- p_owner->pause.i_ignore = 0;
- vlc_cond_signal( &p_owner->wait_request );
-
- /* XXX only audio and video output have to be paused.
- * - for sout it is useless
- * - for subs, it is done by the vout
- */
- if( p_dec->fmt_out.i_cat == AUDIO_ES )
- {
- if( p_owner->p_aout )
- aout_DecChangePause( p_owner->p_aout, b_paused, i_date );
- }
- else if( p_dec->fmt_out.i_cat == VIDEO_ES )
- {
- if( p_owner->p_vout )
- vout_ChangePause( p_owner->p_vout, b_paused, i_date );
- }
- }
- vlc_mutex_unlock( &p_owner->lock );
-}
-
-void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_mutex_lock( &p_owner->lock );
- p_owner->i_ts_delay = i_delay;
- vlc_mutex_unlock( &p_owner->lock );
-}
-
-void input_DecoderStartWait( decoder_t *p_dec )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_mutex_lock( &p_owner->lock );
-
- DecoderFlush( p_dec );
-
- p_owner->b_first = true;
- p_owner->b_has_data = false;
-
- p_owner->b_waiting = true;
-
- vlc_cond_signal( &p_owner->wait_request );
-
- vlc_mutex_unlock( &p_owner->lock );
-}
-
-void input_DecoderStopWait( decoder_t *p_dec )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_mutex_lock( &p_owner->lock );
-
- p_owner->b_waiting = false;
-
- vlc_cond_signal( &p_owner->wait_request );
-
- vlc_mutex_unlock( &p_owner->lock );
-}
-
-void input_DecoderWait( decoder_t *p_dec )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_mutex_lock( &p_owner->lock );
-
- while( p_owner->b_waiting && !p_owner->b_has_data )
- {
- block_FifoWake( p_owner->p_fifo );
- vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
- }
-
- vlc_mutex_unlock( &p_owner->lock );
-}
-
-void input_DecoderFrameNext( decoder_t *p_dec, mtime_t *pi_duration )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- *pi_duration = 0;
-
- vlc_mutex_lock( &p_owner->lock );
- if( p_dec->fmt_out.i_cat == VIDEO_ES )
- {
- if( p_owner->b_paused && p_owner->p_vout )