[vlc-devel] [RFC PATCH 3/3] decoder: protect vout and aout during read
Thomas Guillem
thomas at gllm.fr
Wed Apr 1 16:13:18 CEST 2015
---
src/input/decoder.c | 72 ++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 58 insertions(+), 14 deletions(-)
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 1fd5b90..4f0e5f8 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -89,12 +89,11 @@ struct decoder_owner_sys_t
vlc_mutex_t lock;
vlc_cond_t wait;
- /* -- These variables need locking on write(only) -- */
+ /* -- Theses variables need locking on read *and* write -- */
audio_output_t *p_aout;
vout_thread_t *p_vout;
- /* -- Theses variables need locking on read *and* write -- */
/* Pause */
bool b_paused;
struct
@@ -182,6 +181,28 @@ static block_t *DecoderBlockFlushNew()
return p_null;
}
+static audio_output_t *DecoderGetAout( decoder_t *p_dec )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+ audio_output_t *p_aout;
+
+ vlc_mutex_lock( &p_owner->lock );
+ p_aout = p_owner->p_aout;
+ vlc_mutex_unlock( &p_owner->lock );
+ return p_aout;
+}
+
+static vout_thread_t *DecoderGetVout( decoder_t *p_dec )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+ vout_thread_t *p_vout;
+
+ vlc_mutex_lock( &p_owner->lock );
+ p_vout = p_owner->p_vout;
+ vlc_mutex_unlock( &p_owner->lock );
+ return p_vout;
+}
+
/*****************************************************************************
* Buffers allocation callbacks for the decoders
*****************************************************************************/
@@ -870,7 +891,7 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
int *pi_played_sum, int *pi_lost_sum )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
- vout_thread_t *p_vout = p_owner->p_vout;
+ vout_thread_t *p_vout;
if( p_picture->date <= VLC_TS_INVALID )
{
@@ -905,6 +926,7 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
DecoderFixTs( p_dec, &p_picture->date, NULL, NULL,
&i_rate, DECODER_BOGUS_VIDEO_DELAY );
+ p_vout = p_owner->p_vout;
vlc_mutex_unlock( &p_owner->lock );
/* */
@@ -949,14 +971,20 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
{
- vout_thread_t *p_vout = p_owner->p_vout;
- if( DecoderIsFlushing( p_dec ) )
+ vout_thread_t *p_vout;
+
+ vlc_mutex_lock( &p_owner->lock );
+ if( p_owner->b_flushing )
{ /* It prevent freezing VLC in case of broken decoder */
+ vlc_mutex_unlock( &p_owner->lock );
+
picture_Release( p_pic );
if( p_block )
block_Release( p_block );
break;
}
+ p_vout = p_owner->p_vout;
+ vlc_mutex_unlock( &p_owner->lock );
i_decoded++;
@@ -1057,8 +1085,13 @@ static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block, bool b_flus
DecoderDecodeVideo( p_dec, p_block );
}
- if( b_flush && p_owner->p_vout )
- vout_Flush( p_owner->p_vout, VLC_TS_INVALID+1 );
+ if( b_flush )
+ {
+ vout_thread_t *p_vout = DecoderGetVout( p_dec );
+
+ if( p_vout )
+ vout_Flush( p_vout, VLC_TS_INVALID+1 );
+ }
}
static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
@@ -1153,9 +1186,11 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
if( p_owner->i_preroll_end > VLC_TS_INVALID )
{
+ audio_output_t *p_aout = DecoderGetAout( p_dec );
+
msg_Dbg( p_dec, "End of audio preroll" );
- if( p_owner->p_aout )
- aout_DecFlush( p_owner->p_aout, false );
+ if( p_aout )
+ aout_DecFlush( p_aout, false );
/* */
p_owner->i_preroll_end = VLC_TS_INVALID;
}
@@ -1220,8 +1255,13 @@ static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block, bool b_flus
DecoderDecodeAudio( p_dec, p_block );
}
- if( b_flush && p_owner->p_aout )
- aout_DecFlush( p_owner->p_aout, false );
+ if( b_flush )
+ {
+ audio_output_t *p_aout = DecoderGetAout( p_dec );
+
+ if( p_aout )
+ aout_DecFlush( p_aout, false );
+ }
}
static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
@@ -1453,8 +1493,10 @@ static void *DecoderThread( void *p_data )
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 );
+ audio_output_t *p_aout = DecoderGetAout( p_dec );
+
+ if( p_aout != NULL )
+ aout_DecFlush( p_aout, true );
}
vlc_mutex_lock( &p_owner->lock );
p_owner->b_drained = (p_block == NULL);
@@ -2161,9 +2203,11 @@ void input_DecoderFrameNext( decoder_t *p_dec, mtime_t *pi_duration )
{
if( p_owner->b_paused && p_owner->p_vout )
{
+ vout_thread_t *p_vout = p_owner->p_vout;
+
vlc_mutex_unlock( &p_owner->lock );
- vout_NextPicture( p_owner->p_vout, pi_duration );
+ vout_NextPicture( p_vout, pi_duration );
vlc_mutex_lock( &p_owner->lock );
p_owner->pause.i_ignore++;
--
2.1.3
More information about the vlc-devel
mailing list