From 55a1c1a0504f4b291774966a880802a437364951 Mon Sep 17 00:00:00 2001 From: Francois Cartegnie <fcvlcdev@free.fr> Date: Wed, 20 Jun 2018 15:45:09 +0200 Subject: [PATCH] sout: transcode: fix bogus encoding thread with multiple video es --- modules/stream_out/transcode/transcode.c | 6 +- modules/stream_out/transcode/transcode.h | 17 ++-- modules/stream_out/transcode/video.c | 113 +++++++++++------------ 3 files changed, 69 insertions(+), 67 deletions(-) diff --git a/modules/stream_out/transcode/transcode.c b/modules/stream_out/transcode/transcode.c index ea8f7d4b5a88..a2d8261171e3 100644 --- a/modules/stream_out/transcode/transcode.c +++ b/modules/stream_out/transcode/transcode.c @@ -367,7 +367,11 @@ static int Open( vlc_object_t *p_this ) p_sys->i_threads = var_GetInteger( p_stream, SOUT_CFG_PREFIX "threads" ); p_sys->pool_size = var_GetInteger( p_stream, SOUT_CFG_PREFIX "pool-size" ); - p_sys->b_high_priority = var_GetBool( p_stream, SOUT_CFG_PREFIX "high-priority" ); + + if( var_GetBool( p_stream, SOUT_CFG_PREFIX "high-priority" ) ) + p_sys->i_thread_priority = VLC_THREAD_PRIORITY_OUTPUT; + else + p_sys->i_thread_priority = VLC_THREAD_PRIORITY_VIDEO; if( p_sys->i_vcodec ) { diff --git a/modules/stream_out/transcode/transcode.h b/modules/stream_out/transcode/transcode.h index 071f5d20bf37..be371297bb21 100644 --- a/modules/stream_out/transcode/transcode.h +++ b/modules/stream_out/transcode/transcode.h @@ -19,14 +19,7 @@ typedef struct sout_stream_id_sys_t sout_stream_id_sys_t; typedef struct { sout_stream_id_sys_t *id_video; - block_t *p_buffers; - vlc_mutex_t lock_out; - vlc_cond_t cond; - bool b_abort; - picture_fifo_t *pp_pics; - vlc_sem_t picture_pool_has_room; uint32_t pool_size; - vlc_thread_t thread; /* Audio */ vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */ @@ -50,7 +43,7 @@ typedef struct char *psz_deinterlace; config_chain_t *p_deinterlace_cfg; int i_threads; - bool b_high_priority; + int i_thread_priority; bool b_hurry_up; unsigned int fps_num,fps_den; @@ -125,6 +118,14 @@ struct sout_stream_id_sys_t /* Encoder */ encoder_t *p_encoder; + block_t *p_buffers; + vlc_thread_t thread; + vlc_mutex_t lock_out; + bool b_abort; + picture_fifo_t *pp_pics; + vlc_sem_t picture_pool_has_room; + vlc_cond_t cond; + /* Sync */ date_t next_input_pts; /**< Incoming calculated PTS */ diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c index f612ddd53afa..8e70eb563cfd 100644 --- a/modules/stream_out/transcode/video.c +++ b/modules/stream_out/transcode/video.c @@ -101,52 +101,51 @@ static picture_t *transcode_video_filter_buffer_new( filter_t *p_filter ) static void* EncoderThread( void *obj ) { - sout_stream_sys_t *p_sys = (sout_stream_sys_t*)obj; - sout_stream_id_sys_t *id = p_sys->id_video; + sout_stream_id_sys_t *id = (sout_stream_id_sys_t *) obj; picture_t *p_pic = NULL; int canc = vlc_savecancel (); block_t *p_block = NULL; - vlc_mutex_lock( &p_sys->lock_out ); + vlc_mutex_lock( &id->lock_out ); for( ;; ) { - while( !p_sys->b_abort && - (p_pic = picture_fifo_Pop( p_sys->pp_pics )) == NULL ) - vlc_cond_wait( &p_sys->cond, &p_sys->lock_out ); - vlc_sem_post( &p_sys->picture_pool_has_room ); + while( !id->b_abort && + (p_pic = picture_fifo_Pop( id->pp_pics )) == NULL ) + vlc_cond_wait( &id->cond, &id->lock_out ); + vlc_sem_post( &id->picture_pool_has_room ); if( p_pic ) { /* release lock while encoding */ - vlc_mutex_unlock( &p_sys->lock_out ); + vlc_mutex_unlock( &id->lock_out ); p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic ); picture_Release( p_pic ); - vlc_mutex_lock( &p_sys->lock_out ); + vlc_mutex_lock( &id->lock_out ); - block_ChainAppend( &p_sys->p_buffers, p_block ); + block_ChainAppend( &id->p_buffers, p_block ); } - if( p_sys->b_abort ) + if( id->b_abort ) break; } /*Encode what we have in the buffer on closing*/ - while( (p_pic = picture_fifo_Pop( p_sys->pp_pics )) != NULL ) + while( (p_pic = picture_fifo_Pop( id->pp_pics )) != NULL ) { - vlc_sem_post( &p_sys->picture_pool_has_room ); + vlc_sem_post( &id->picture_pool_has_room ); p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic ); picture_Release( p_pic ); - block_ChainAppend( &p_sys->p_buffers, p_block ); + block_ChainAppend( &id->p_buffers, p_block ); } /*Now flush encoder*/ do { p_block = id->p_encoder->pf_encode_video(id->p_encoder, NULL ); - block_ChainAppend( &p_sys->p_buffers, p_block ); + block_ChainAppend( &id->p_buffers, p_block ); } while( p_block ); - vlc_mutex_unlock( &p_sys->lock_out ); + vlc_mutex_unlock( &id->lock_out ); vlc_restorecancel (canc); @@ -272,11 +271,9 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_sys_t *i if( p_sys->i_threads <= 0 ) return VLC_SUCCESS; - int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT : - VLC_THREAD_PRIORITY_VIDEO; p_sys->id_video = id; - p_sys->pp_pics = picture_fifo_New(); - if( p_sys->pp_pics == NULL ) + id->pp_pics = picture_fifo_New(); + if( id->pp_pics == NULL ) { msg_Err( p_stream, "cannot create picture fifo" ); module_unneed( id->p_decoder, id->p_decoder->p_module ); @@ -284,17 +281,17 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_sys_t *i return VLC_ENOMEM; } - vlc_sem_init( &p_sys->picture_pool_has_room, p_sys->pool_size ); - vlc_mutex_init( &p_sys->lock_out ); - vlc_cond_init( &p_sys->cond ); - p_sys->p_buffers = NULL; - p_sys->b_abort = false; - if( vlc_clone( &p_sys->thread, EncoderThread, p_sys, i_priority ) ) + vlc_sem_init( &id->picture_pool_has_room, p_sys->pool_size ); + vlc_mutex_init( &id->lock_out ); + vlc_cond_init( &id->cond ); + id->p_buffers = NULL; + id->b_abort = false; + if( vlc_clone( &id->thread, EncoderThread, id, p_sys->i_thread_priority ) ) { msg_Err( p_stream, "cannot spawn encoder thread" ); - vlc_mutex_destroy( &p_sys->lock_out ); - vlc_cond_destroy( &p_sys->cond ); - picture_fifo_Delete( p_sys->pp_pics ); + vlc_mutex_destroy( &id->lock_out ); + vlc_cond_destroy( &id->cond ); + picture_fifo_Delete( id->pp_pics ); module_unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = NULL; return VLC_EGENERIC; @@ -673,23 +670,23 @@ void transcode_video_close( sout_stream_t *p_stream, sout_stream_id_sys_t *id ) { sout_stream_sys_t *p_sys = p_stream->p_sys; - if( p_sys->i_threads >= 1 && !p_sys->b_abort ) + if( p_sys->i_threads >= 1 && !id->b_abort ) { - vlc_mutex_lock( &p_sys->lock_out ); - p_sys->b_abort = true; - vlc_cond_signal( &p_sys->cond ); - vlc_mutex_unlock( &p_sys->lock_out ); + vlc_mutex_lock( &id->lock_out ); + id->b_abort = true; + vlc_cond_signal( &id->cond ); + vlc_mutex_unlock( &id->lock_out ); - vlc_join( p_sys->thread, NULL ); + vlc_join( id->thread, NULL ); - picture_fifo_Delete( p_sys->pp_pics ); - block_ChainRelease( p_sys->p_buffers ); + picture_fifo_Delete( id->pp_pics ); + block_ChainRelease( id->p_buffers ); } if( p_sys->i_threads >= 1 ) { - vlc_mutex_destroy( &p_sys->lock_out ); - vlc_cond_destroy( &p_sys->cond ); + vlc_mutex_destroy( &id->lock_out ); + vlc_cond_destroy( &id->cond ); } /* Close decoder */ @@ -765,11 +762,11 @@ static void OutputFrame( sout_stream_t *p_stream, picture_t *p_pic, sout_stream_ if( p_sys->i_threads ) { - vlc_sem_wait( &p_sys->picture_pool_has_room ); - vlc_mutex_lock( &p_sys->lock_out ); - picture_fifo_Push( p_sys->pp_pics, p_pic ); - vlc_cond_signal( &p_sys->cond ); - vlc_mutex_unlock( &p_sys->lock_out ); + vlc_sem_wait( &id->picture_pool_has_room ); + vlc_mutex_lock( &id->lock_out ); + picture_fifo_Push( id->pp_pics, p_pic ); + vlc_cond_signal( &id->cond ); + vlc_mutex_unlock( &id->lock_out ); } if ( p_sys->i_threads == 0 ) @@ -890,10 +887,10 @@ error: if( p_sys->i_threads >= 1 ) { /* Pick up any return data the encoder thread wants to output. */ - vlc_mutex_lock( &p_sys->lock_out ); - *out = p_sys->p_buffers; - p_sys->p_buffers = NULL; - vlc_mutex_unlock( &p_sys->lock_out ); + vlc_mutex_lock( &id->lock_out ); + *out = id->p_buffers; + id->p_buffers = NULL; + vlc_mutex_unlock( &id->lock_out ); } end: @@ -914,16 +911,16 @@ end: else { msg_Dbg( p_stream, "Flushing thread and waiting that"); - vlc_mutex_lock( &p_sys->lock_out ); - p_sys->b_abort = true; - vlc_cond_signal( &p_sys->cond ); - vlc_mutex_unlock( &p_sys->lock_out ); - - vlc_join( p_sys->thread, NULL ); - vlc_mutex_lock( &p_sys->lock_out ); - *out = p_sys->p_buffers; - p_sys->p_buffers = NULL; - vlc_mutex_unlock( &p_sys->lock_out ); + vlc_mutex_lock( &id->lock_out ); + id->b_abort = true; + vlc_cond_signal( &id->cond ); + vlc_mutex_unlock( &id->lock_out ); + + vlc_join( id->thread, NULL ); + vlc_mutex_lock( &id->lock_out ); + *out = id->p_buffers; + id->p_buffers = NULL; + vlc_mutex_unlock( &id->lock_out ); msg_Dbg( p_stream, "Flushing done"); } -- GitLab