vout_thread_t *p_vout;
/* -- Theses variables need locking on read *and* write -- */
- bool b_exit;
-
/* Pause */
bool b_paused;
struct
p_owner->b_paused = false;
p_owner->b_waiting = false;
p_owner->b_flushing = true;
- p_owner->b_exit = true;
vlc_cond_signal( &p_owner->wait_request );
vlc_mutex_unlock( &p_owner->lock );
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
- if( b_do_pace )
- {
- /* The fifo is not consumed when waiting and so will
- * deadlock vlc.
- * There is no need to lock as b_waiting is never modified
- * inside decoder thread. */
- if( !p_owner->b_waiting )
- block_FifoPace( p_owner->p_fifo, 10, SIZE_MAX );
- }
- else if( block_FifoSize( p_owner->p_fifo ) > 400*1024*1024 /* 400 MiB, ie ~ 50mb/s for 60s */ )
+ vlc_fifo_Lock( p_owner->p_fifo );
+ if( !b_do_pace )
{
/* FIXME: ideally we would check the time amount of data
* in the FIFO instead of its size. */
- msg_Warn( p_dec, "decoder/packetizer fifo full (data not "
- "consumed quickly enough), resetting fifo!" );
- block_FifoEmpty( p_owner->p_fifo );
+ /* 400 MiB, i.e. ~ 50mb/s for 60s */
+ if( vlc_fifo_GetBytes( p_owner->p_fifo ) > 400*1024*1024 )
+ {
+ msg_Warn( p_dec, "decoder/packetizer fifo full (data not "
+ "consumed quickly enough), resetting fifo!" );
+ block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
+ }
+ }
+ else
+ if( !p_owner->b_waiting )
+ { /* The FIFO is not consumed when waiting, so pacing would deadlock VLC.
+ * Locking is not necessary as b_waiting is only read, not written by
+ * the decoder thread. */
+ while( vlc_fifo_GetCount( p_owner->p_fifo ) >= 10 )
+ vlc_fifo_WaitCond( p_owner->p_fifo, &p_owner->wait_acknowledge );
}
- block_FifoPut( p_owner->p_fifo, p_block );
+ vlc_fifo_QueueUnlocked( p_owner->p_fifo, p_block );
+ vlc_fifo_Unlock( p_owner->p_fifo );
}
bool input_DecoderIsEmpty( decoder_t * p_dec )
* - 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->fmt.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 )
+ else if( p_owner->fmt.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 );
}
+/**
+ * Requests that the decoder immediately discard all pending buffers.
+ * This is useful at end of stream, when seeking or when deselecting a stream.
+ */
+void input_DecoderFlush( decoder_t *p_dec )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+
+ vlc_mutex_lock( &p_owner->lock );
+ DecoderFlush( p_dec );
+ vlc_mutex_unlock( &p_owner->lock );
+}
+
void input_DecoderStartWait( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
assert( !p_owner->b_waiting );
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;
*pi_duration = 0;
vlc_mutex_lock( &p_owner->lock );
- if( p_dec->fmt_out.i_cat == VIDEO_ES )
+ if( p_owner->fmt.i_cat == VIDEO_ES )
{
if( p_owner->b_paused && p_owner->p_vout )
{
else
{
/* TODO subtitle should not be flushed */
+ p_owner->b_waiting = false;
DecoderFlush( p_dec );
}
vlc_mutex_unlock( &p_owner->lock );
p_owner->b_fmt_description = false;
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_block = vlc_fifo_DequeueUnlocked( p_owner->p_fifo );
+ if( p_block != NULL )
+ vlc_cond_signal( &p_owner->wait_acknowledge );
+
p_owner->b_woken = false;
vlc_cleanup_run();
/* Empty the fifo */
block_FifoEmpty( p_owner->p_fifo );
- p_owner->b_waiting = false;
/* Monitor for flush end */
p_owner->b_flushing = true;
vlc_cond_signal( &p_owner->wait_request );
*pi_rate = i_rate;
}
-static bool DecoderIsExitRequested( decoder_t *p_dec )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_mutex_lock( &p_owner->lock );
- bool b_exit = p_owner->b_exit;
- vlc_mutex_unlock( &p_owner->lock );
-
- return b_exit;
-}
-
/**
* If *pb_reject, it does nothing, otherwise it waits for the given
* deadline or a flush request (in which case it set *pi_reject to true.
do
{
- if( p_owner->b_flushing || p_owner->b_exit )
+ if( p_owner->b_flushing )
{
*pb_reject = true;
break;
}
else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
{
- if( DecoderIsExitRequested( p_dec ) )
+ if( DecoderIsFlushing( p_dec ) )
{
/* It prevent freezing VLC in case of broken decoder */
block_Release( p_aout_buf );
while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
{
vout_thread_t *p_vout = p_owner->p_vout;
- if( DecoderIsExitRequested( p_dec ) )
- {
- /* It prevent freezing VLC in case of broken decoder */
+ if( DecoderIsFlushing( p_dec ) )
+ { /* It prevent freezing VLC in case of broken decoder */
picture_Release( p_pic );
if( p_block )
block_Release( p_block );
for( ;; )
{
- if( DecoderIsExitRequested( p_dec ) || p_dec->b_error )
+ if( DecoderIsFlushing( p_dec ) || p_dec->b_error )
return NULL;
picture_t *p_picture = vout_GetPicture( p_owner->p_vout );
if( p_picture )
return p_picture;
- if( DecoderIsFlushing( p_dec ) )
- return NULL;
-
/* */
DecoderSignalWait( p_dec );
while( i_attempts-- )
{
- if( DecoderIsExitRequested( p_dec ) || p_dec->b_error )
+ if( DecoderIsFlushing( p_dec ) || p_dec->b_error )
break;
p_vout = input_resource_HoldVout( p_owner->p_resource );