[vlc-devel] [RFC PATCH 2/3] decoder: merge locks and conds
Thomas Guillem
thomas at gllm.fr
Wed Apr 1 16:13:17 CEST 2015
---
src/input/decoder.c | 148 ++++++++++++++++++++++++++++------------------------
1 file changed, 79 insertions(+), 69 deletions(-)
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 76c4038..1fd5b90 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -87,9 +87,7 @@ struct decoder_owner_sys_t
/* Lock for communication with decoder thread */
vlc_mutex_t lock;
- vlc_cond_t wait_request;
- vlc_cond_t wait_acknowledge;
- vlc_cond_t wait_fifo; /* TODO: merge with wait_acknowledge */
+ vlc_cond_t wait;
/* -- These variables need locking on write(only) -- */
audio_output_t *p_aout;
@@ -209,15 +207,17 @@ static int aout_update_format( decoder_t *p_dec )
if( p_owner->p_aout
&& !AOUT_FMTS_IDENTICAL(&p_dec->fmt_out.audio, &p_owner->fmt.audio) )
{
- audio_output_t *p_aout = p_owner->p_aout;
+ audio_output_t *p_aout;
/* Parameters changed, restart the aout */
- vlc_mutex_lock( &p_owner->lock );
- aout_DecDelete( p_owner->p_aout );
+ vlc_mutex_lock( &p_owner->lock );
+ p_aout = p_owner->p_aout;
p_owner->p_aout = NULL;
-
vlc_mutex_unlock( &p_owner->lock );
+
+ aout_DecDelete( p_aout );
+
input_resource_PutAout( p_owner->p_resource, p_aout );
}
@@ -270,12 +270,13 @@ static int aout_update_format( decoder_t *p_dec )
DecoderUpdateFormatLocked( p_dec );
aout_FormatPrepare( &p_owner->fmt.audio );
- if( unlikely(p_owner->b_paused) && p_aout != NULL )
- /* fake pause if needed */
- aout_DecChangePause( p_aout, true, mdate() );
-
+ /* fake pause if needed */
+ bool b_pause = unlikely(p_owner->b_paused) && p_aout != NULL;
vlc_mutex_unlock( &p_owner->lock );
+ if( b_pause )
+ aout_DecChangePause( p_aout, true, mdate() );
+
if( p_owner->p_input != NULL )
input_SendEventAout( p_owner->p_input );
@@ -440,7 +441,7 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
if( p_owner->b_waiting )
{
p_owner->b_has_data = true;
- vlc_cond_signal( &p_owner->wait_acknowledge );
+ vlc_cond_signal( &p_owner->wait );
}
vlc_mutex_unlock( &p_owner->lock );
@@ -633,7 +634,7 @@ static bool DecoderWaitUnblock( decoder_t *p_dec )
if( !p_owner->b_waiting || !p_owner->b_has_data )
break;
}
- vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );
+ vlc_cond_wait( &p_owner->wait, &p_owner->lock );
}
return p_owner->b_flushing;
@@ -718,7 +719,7 @@ static void DecoderWaitDate( decoder_t *p_dec,
break;
}
}
- while( vlc_cond_timedwait( &p_owner->wait_request, &p_owner->lock,
+ while( vlc_cond_timedwait( &p_owner->wait, &p_owner->lock,
i_deadline ) == 0 );
}
@@ -737,7 +738,7 @@ static int DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block )
if( p_owner->b_waiting )
{
p_owner->b_has_data = true;
- vlc_cond_signal( &p_owner->wait_acknowledge );
+ vlc_cond_signal( &p_owner->wait );
}
bool b_reject = DecoderWaitUnblock( p_dec );
@@ -885,7 +886,7 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
if( p_owner->b_waiting && !p_owner->b_first )
{
p_owner->b_has_data = true;
- vlc_cond_signal( &p_owner->wait_acknowledge );
+ vlc_cond_signal( &p_owner->wait );
}
bool b_first_after_wait = p_owner->b_waiting && p_owner->b_has_data;
@@ -1064,7 +1065,7 @@ static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
int *pi_played_sum, int *pi_lost_sum )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
- audio_output_t *p_aout = p_owner->p_aout;
+ audio_output_t *p_aout;
/* */
if( p_audio->i_pts <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify audio_output/*
@@ -1081,7 +1082,7 @@ race:
if( p_owner->b_waiting )
{
p_owner->b_has_data = true;
- vlc_cond_signal( &p_owner->wait_acknowledge );
+ vlc_cond_signal( &p_owner->wait );
}
bool b_reject = DecoderWaitUnblock( p_dec );
@@ -1103,8 +1104,10 @@ race:
if( unlikely(p_owner->b_paused != b_paused) )
goto race; /* race with input thread? retry... */
+ p_aout = p_owner->p_aout;
if( p_aout == NULL )
b_reject = true;
+ vlc_mutex_unlock( &p_owner->lock );
if( !b_reject )
{
@@ -1119,7 +1122,6 @@ race:
*pi_lost_sum += 1;
block_Release( p_audio );
}
- vlc_mutex_unlock( &p_owner->lock );
}
static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
@@ -1241,7 +1243,7 @@ static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
if( p_owner->b_waiting )
{
p_owner->b_has_data = true;
- vlc_cond_signal( &p_owner->wait_acknowledge );
+ vlc_cond_signal( &p_owner->wait );
}
bool b_reject = DecoderWaitUnblock( p_dec );
@@ -1326,7 +1328,7 @@ static void DecoderProcessOnFlush( decoder_t *p_dec )
if( p_owner->b_flushing )
{
p_owner->b_flushing = false;
- vlc_cond_signal( &p_owner->wait_acknowledge );
+ vlc_cond_signal( &p_owner->wait );
}
vlc_mutex_unlock( &p_owner->lock );
}
@@ -1421,10 +1423,10 @@ static void *DecoderThread( void *p_data )
{
block_t *p_block;
- vlc_fifo_Lock( p_owner->p_fifo );
- vlc_fifo_CleanupPush( p_owner->p_fifo );
+ vlc_mutex_lock( &p_owner->lock );
+ mutex_cleanup_push( &p_owner->lock );
- vlc_cond_signal( &p_owner->wait_fifo );
+ vlc_cond_signal( &p_owner->wait );
while( vlc_fifo_IsEmpty( p_owner->p_fifo ) )
{
@@ -1448,16 +1450,16 @@ static void *DecoderThread( void *p_data )
int canc = vlc_savecancel();
DecoderProcess( p_dec, p_block );
- vlc_mutex_lock( &p_owner->lock );
if( p_block == NULL )
{ /* Draining: the decoder is drained and all decoded buffers are
* queued to the output at this point. Now drain the output. */
if( p_owner->p_aout != NULL )
aout_DecFlush( p_owner->p_aout, true );
}
+ vlc_mutex_lock( &p_owner->lock );
p_owner->b_drained = (p_block == NULL);
- vlc_cond_signal( &p_owner->wait_acknowledge );
+ vlc_cond_signal( &p_owner->wait );
vlc_mutex_unlock( &p_owner->lock );
vlc_restorecancel( canc );
}
@@ -1523,8 +1525,11 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
p_owner->b_packetizer = b_packetizer;
es_format_Init( &p_owner->fmt, UNKNOWN_ES, 0 );
+ vlc_mutex_init( &p_owner->lock );
+ vlc_cond_init( &p_owner->wait );
+
/* decoder fifo */
- p_owner->p_fifo = block_FifoNew();
+ p_owner->p_fifo = block_FifoNewExt( &p_owner->lock, &p_owner->wait );
if( unlikely(p_owner->p_fifo == NULL) )
{
free( p_owner );
@@ -1594,11 +1599,6 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
}
/* */
- vlc_mutex_init( &p_owner->lock );
- vlc_cond_init( &p_owner->wait_request );
- vlc_cond_init( &p_owner->wait_acknowledge );
- vlc_cond_init( &p_owner->wait_fifo );
-
p_owner->b_fmt_description = false;
p_owner->p_description = NULL;
@@ -1711,10 +1711,8 @@ static void DeleteDecoder( decoder_t * p_dec )
vlc_object_release( p_owner->p_packetizer );
}
- vlc_cond_destroy( &p_owner->wait_fifo );
- vlc_cond_destroy( &p_owner->wait_acknowledge );
- vlc_cond_destroy( &p_owner->wait_request );
vlc_mutex_destroy( &p_owner->lock );
+ vlc_cond_destroy( &p_owner->wait );
vlc_object_release( p_dec );
@@ -1833,7 +1831,7 @@ void input_DecoderDelete( decoder_t *p_dec )
p_owner->b_paused = false;
p_owner->b_waiting = false;
p_owner->b_flushing = true;
- vlc_cond_signal( &p_owner->wait_request );
+ vlc_cond_signal( &p_owner->wait );
vlc_mutex_unlock( &p_owner->lock );
vlc_join( p_owner->thread, NULL );
@@ -1852,18 +1850,13 @@ void input_DecoderDelete( decoder_t *p_dec )
DeleteDecoder( p_dec );
}
-/**
- * Put a block_t in the decoder's fifo.
- * Thread-safe w.r.t. the decoder. May be a cancellation point.
- *
- * \param p_dec the decoder object
- * \param p_block the data block
- */
-void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
+static void DecoderDecode( decoder_t *p_dec, block_t *p_block,
+ bool b_do_pace )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
- vlc_fifo_Lock( p_owner->p_fifo );
+ vlc_assert_locked( &p_owner->lock );
+
if( !b_do_pace )
{
/* FIXME: ideally we would check the time amount of data
@@ -1882,11 +1875,26 @@ void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
* 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_fifo );
+ vlc_fifo_Wait( p_owner->p_fifo );
}
vlc_fifo_QueueUnlocked( p_owner->p_fifo, p_block );
- vlc_fifo_Unlock( p_owner->p_fifo );
+}
+
+/**
+ * Put a block_t in the decoder's fifo.
+ * Thread-safe w.r.t. the decoder. May be a cancellation point.
+ *
+ * \param p_dec the decoder object
+ * \param p_block the data block
+ */
+void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+
+ vlc_mutex_lock( &p_owner->lock );
+ DecoderDecode( p_dec, p_block, b_do_pace );
+ vlc_mutex_unlock( &p_owner->lock );
}
bool input_DecoderIsEmpty( decoder_t * p_dec )
@@ -1924,10 +1932,10 @@ void input_DecoderDrain( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
- vlc_fifo_Lock( p_owner->p_fifo );
+ vlc_mutex_lock( &p_owner->lock );
p_owner->b_draining = true;
- vlc_fifo_Signal( p_owner->p_fifo );
- vlc_fifo_Unlock( p_owner->p_fifo );
+ vlc_cond_signal( &p_owner->wait );
+ vlc_mutex_unlock( &p_owner->lock );
}
static void DecoderFlush( decoder_t *p_dec )
@@ -1936,25 +1944,23 @@ static void DecoderFlush( decoder_t *p_dec )
vlc_assert_locked( &p_owner->lock );
- vlc_fifo_Lock( p_owner->p_fifo );
/* Empty the fifo */
block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
p_owner->b_draining = false; /* flush supersedes drain */
- vlc_fifo_Unlock( p_owner->p_fifo );
/* Monitor for flush end */
p_owner->b_flushing = true;
- vlc_cond_signal( &p_owner->wait_request );
+ vlc_cond_signal( &p_owner->wait );
/* Send a special block */
block_t *p_null = DecoderBlockFlushNew();
if( !p_null )
return;
- input_DecoderDecode( p_dec, p_null, false );
+ DecoderDecode( p_dec, p_null, false );
/* */
while( p_owner->b_flushing )
- vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
+ vlc_cond_wait( &p_owner->wait, &p_owner->lock );
}
/**
@@ -2055,6 +2061,8 @@ int input_DecoderGetCcState( decoder_t *p_dec, bool *pb_decode, int i_channel )
void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
+ audio_output_t *p_aout;
+ vout_thread_t *p_vout;
/* 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
@@ -2066,7 +2074,10 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
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 );
+ vlc_cond_signal( &p_owner->wait );
+ p_aout = p_owner->p_aout;
+ p_vout = p_owner->p_vout;
+ vlc_mutex_unlock( &p_owner->lock );
/* XXX only audio and video output have to be paused.
* - for sout it is useless
@@ -2074,15 +2085,14 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
*/
if( p_owner->fmt.i_cat == AUDIO_ES )
{
- if( p_owner->p_aout )
- aout_DecChangePause( p_owner->p_aout, b_paused, i_date );
+ if( p_aout )
+ aout_DecChangePause( p_aout, b_paused, i_date );
}
else if( p_owner->fmt.i_cat == VIDEO_ES )
{
- if( p_owner->p_vout )
- vout_ChangePause( p_owner->p_vout, b_paused, i_date );
+ if( p_vout )
+ vout_ChangePause( p_vout, b_paused, i_date );
}
- vlc_mutex_unlock( &p_owner->lock );
}
void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay )
@@ -2104,7 +2114,7 @@ void input_DecoderStartWait( decoder_t *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_cond_signal( &p_owner->wait );
vlc_mutex_unlock( &p_owner->lock );
}
@@ -2116,7 +2126,7 @@ void input_DecoderStopWait( decoder_t *p_dec )
vlc_mutex_lock( &p_owner->lock );
p_owner->b_waiting = false;
- vlc_cond_signal( &p_owner->wait_request );
+ vlc_cond_signal( &p_owner->wait );
vlc_mutex_unlock( &p_owner->lock );
}
@@ -2127,7 +2137,6 @@ void input_DecoderWait( decoder_t *p_dec )
assert( p_owner->b_waiting );
vlc_mutex_lock( &p_owner->lock );
- vlc_fifo_Lock( p_owner->p_fifo );
while( !p_owner->b_has_data )
{
if( p_owner->b_idle && vlc_fifo_IsEmpty( p_owner->p_fifo ) )
@@ -2136,11 +2145,8 @@ void input_DecoderWait( decoder_t *p_dec )
break;
}
vlc_fifo_Signal( p_owner->p_fifo );
- vlc_fifo_Unlock( p_owner->p_fifo );
- vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
- vlc_fifo_Lock( p_owner->p_fifo );
+ vlc_cond_wait( &p_owner->wait, &p_owner->lock );
}
- vlc_fifo_Unlock( p_owner->p_fifo );
vlc_mutex_unlock( &p_owner->lock );
}
@@ -2155,9 +2161,13 @@ void input_DecoderFrameNext( decoder_t *p_dec, mtime_t *pi_duration )
{
if( p_owner->b_paused && p_owner->p_vout )
{
+ vlc_mutex_unlock( &p_owner->lock );
+
vout_NextPicture( p_owner->p_vout, pi_duration );
+
+ vlc_mutex_lock( &p_owner->lock );
p_owner->pause.i_ignore++;
- vlc_cond_signal( &p_owner->wait_request );
+ vlc_cond_signal( &p_owner->wait );
}
}
else
--
2.1.3
More information about the vlc-devel
mailing list