- }
-
- /* Copy ourself the input replay gain */
- if( fmt->i_cat == AUDIO_ES )
- {
- for( unsigned i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
- {
- if( !p_dec->fmt_out.audio_replay_gain.pb_peak[i] )
- {
- p_dec->fmt_out.audio_replay_gain.pb_peak[i] = fmt->audio_replay_gain.pb_peak[i];
- p_dec->fmt_out.audio_replay_gain.pf_peak[i] = fmt->audio_replay_gain.pf_peak[i];
- }
- if( !p_dec->fmt_out.audio_replay_gain.pb_gain[i] )
- {
- p_dec->fmt_out.audio_replay_gain.pb_gain[i] = fmt->audio_replay_gain.pb_gain[i];
- p_dec->fmt_out.audio_replay_gain.pf_gain[i] = fmt->audio_replay_gain.pf_gain[i];
- }
- }
- }
-
- /* */
- vlc_mutex_init( &p_owner->lock );
- vlc_cond_init( &p_owner->wait_request );
- vlc_cond_init( &p_owner->wait_acknowledge );
-
- p_owner->b_fmt_description = false;
- es_format_Init( &p_owner->fmt_description, UNKNOWN_ES, 0 );
- p_owner->p_description = NULL;
-
- p_owner->b_exit = false;
-
- p_owner->b_paused = false;
- p_owner->pause.i_date = VLC_TS_INVALID;
- p_owner->pause.i_ignore = 0;
-
- p_owner->b_waiting = false;
- p_owner->b_first = true;
- p_owner->b_has_data = false;
-
- p_owner->b_flushing = false;
-
- /* */
- p_owner->cc.b_supported = false;
- if( !b_packetizer )
- {
- if( p_owner->p_packetizer && p_owner->p_packetizer->pf_get_cc )
- p_owner->cc.b_supported = true;
- if( p_dec->pf_get_cc )
- p_owner->cc.b_supported = true;
- }
-
- for( unsigned i = 0; i < 4; i++ )
- {
- p_owner->cc.pb_present[i] = false;
- p_owner->cc.pp_decoder[i] = NULL;
- }
- p_owner->i_ts_delay = 0;
- return p_dec;
-}
-
-/**
- * The decoding main loop
- *
- * \param p_dec the decoder
- */
-static void *DecoderThread( void *p_data )
-{
- decoder_t *p_dec = (decoder_t *)p_data;
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- /* The decoder's main loop */
- for( ;; )
- {
- block_t *p_block = block_FifoGet( p_owner->p_fifo );
-
- /* Make sure there is no cancellation point other than this one^^.
- * If you need one, be sure to push cleanup of p_block. */
- bool end_wait = !p_block || p_block->i_flags & BLOCK_FLAG_CORE_EOS;
- DecoderSignalWait( p_dec, end_wait );
- if (end_wait)
- input_DecoderStopWait( p_dec );
-
- if( p_block )
- {
- int canc = vlc_savecancel();
-
- if( p_block->i_flags & BLOCK_FLAG_CORE_EOS )
- {
- /* calling DecoderProcess() with NULL block will make
- * decoders/packetizers flush their buffers */
- block_Release( p_block );
- p_block = NULL;
- }
-
- DecoderProcess( p_dec, p_block );
-
- vlc_restorecancel( canc );
- }
- }
- return NULL;
-}
-
-static block_t *DecoderBlockFlushNew()
-{
- block_t *p_null = block_Alloc( 128 );
- if( !p_null )
- return NULL;
-
- p_null->i_flags |= BLOCK_FLAG_DISCONTINUITY |
- BLOCK_FLAG_CORRUPTED |
- BLOCK_FLAG_CORE_FLUSH;
- memset( p_null->p_buffer, 0, p_null->i_buffer );
-
- return p_null;
-}
-
-static void DecoderFlush( decoder_t *p_dec )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_assert_locked( &p_owner->lock );
-
- /* Empty the fifo */
- block_FifoEmpty( p_owner->p_fifo );
-
- /* Monitor for flush end */
- p_owner->b_flushing = true;
- vlc_cond_signal( &p_owner->wait_request );
-
- /* Send a special block */
- block_t *p_null = DecoderBlockFlushNew();
- if( !p_null )
- return;
- input_DecoderDecode( p_dec, p_null, false );
-
- /* */
- while( p_owner->b_flushing )
- vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
-}
-
-static void DecoderSignalWait( decoder_t *p_dec, bool b_has_data )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_mutex_lock( &p_owner->lock );
-
- if( p_owner->b_waiting )
- {
- if( b_has_data )
- p_owner->b_has_data = true;
- vlc_cond_signal( &p_owner->wait_acknowledge );
- }
-
- vlc_mutex_unlock( &p_owner->lock );
-}
-
-static bool DecoderIsFlushing( decoder_t *p_dec )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
- bool b_flushing;
-
- vlc_mutex_lock( &p_owner->lock );
-
- b_flushing = p_owner->b_flushing;
-
- vlc_mutex_unlock( &p_owner->lock );
-
- return b_flushing;
-}
-
-static bool DecoderWaitUnblock( decoder_t *p_dec )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_assert_locked( &p_owner->lock );
-
- for( ;; )
- {
- if( p_owner->b_flushing )
- break;
- if( p_owner->b_paused )
- {
- if( p_owner->b_waiting && !p_owner->b_has_data )
- break;
- if( p_owner->pause.i_ignore > 0 )
- {
- p_owner->pause.i_ignore--;
- break;
- }
- }
- else
- {
- if( !p_owner->b_waiting || !p_owner->b_has_data )
- break;
- }
- vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );