mirror of
https://github.com/videolan/vlc.git
synced 2024-12-04 23:35:52 +08:00
Added lock around es_out for multiple thread access.
It should fix race conditions when using stream demuxer. It is a temporary way until I finish a few es_out modification.
This commit is contained in:
parent
e34927d31d
commit
007185b1ab
@ -99,6 +99,9 @@ struct es_out_sys_t
|
||||
{
|
||||
input_thread_t *p_input;
|
||||
|
||||
/* */
|
||||
vlc_mutex_t lock;
|
||||
|
||||
/* all programs */
|
||||
int i_pgrm;
|
||||
es_out_pgrm_t **pgrm;
|
||||
@ -203,10 +206,11 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
|
||||
vlc_value_t val;
|
||||
int i;
|
||||
|
||||
es_out_t *out = malloc( sizeof( es_out_t ) );
|
||||
if( !out ) return NULL;
|
||||
es_out_t *out = malloc( sizeof( *out ) );
|
||||
if( !out )
|
||||
return NULL;
|
||||
|
||||
es_out_sys_t *p_sys = malloc( sizeof( es_out_sys_t ) );
|
||||
es_out_sys_t *p_sys = malloc( sizeof( *p_sys ) );
|
||||
if( !p_sys )
|
||||
{
|
||||
free( out );
|
||||
@ -220,6 +224,8 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
|
||||
out->p_sys = p_sys;
|
||||
out->b_sout = p_input->p->p_sout != NULL;
|
||||
|
||||
|
||||
vlc_mutex_init_recursive( &p_sys->lock );
|
||||
p_sys->p_input = p_input;
|
||||
|
||||
p_sys->b_active = false;
|
||||
@ -352,6 +358,7 @@ void input_EsOutDelete( es_out_t *out )
|
||||
free( p_pgrm );
|
||||
}
|
||||
TAB_CLEAN( p_sys->i_pgrm, p_sys->pgrm );
|
||||
vlc_mutex_destroy( &p_sys->lock );
|
||||
|
||||
free( p_sys );
|
||||
free( out );
|
||||
@ -362,7 +369,7 @@ es_out_id_t *input_EsOutGetFromID( es_out_t *out, int i_id )
|
||||
int i;
|
||||
if( i_id < 0 )
|
||||
{
|
||||
/* Special HACK, -i_id is tha cat of the stream */
|
||||
/* Special HACK, -i_id is the cat of the stream */
|
||||
return (es_out_id_t*)((uint8_t*)NULL-i_id);
|
||||
}
|
||||
|
||||
@ -652,6 +659,15 @@ void input_EsOutFrameNext( es_out_t *out )
|
||||
p_sys->i_preroll_end = -1;
|
||||
}
|
||||
|
||||
void input_EsOutLock( es_out_t *out )
|
||||
{
|
||||
vlc_mutex_lock( &out->p_sys->lock );
|
||||
}
|
||||
void input_EsOutUnlock( es_out_t *out )
|
||||
{
|
||||
vlc_mutex_unlock( &out->p_sys->lock );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -1275,19 +1291,21 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
|
||||
es_out_sys_t *p_sys = out->p_sys;
|
||||
input_thread_t *p_input = p_sys->p_input;
|
||||
|
||||
es_out_id_t *es = malloc( sizeof( es_out_id_t ) );
|
||||
es_out_pgrm_t *p_pgrm = NULL;
|
||||
int i;
|
||||
|
||||
if( !es ) return NULL;
|
||||
|
||||
if( fmt->i_group < 0 )
|
||||
{
|
||||
msg_Err( p_input, "invalid group number" );
|
||||
free( es );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
es_out_id_t *es = malloc( sizeof( *es ) );
|
||||
es_out_pgrm_t *p_pgrm = NULL;
|
||||
int i;
|
||||
|
||||
if( !es )
|
||||
return NULL;
|
||||
|
||||
vlc_mutex_lock( &p_sys->lock );
|
||||
|
||||
/* Search the program */
|
||||
for( i = 0; i < p_sys->i_pgrm; i++ )
|
||||
{
|
||||
@ -1391,6 +1409,8 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
|
||||
|
||||
EsOutAddInfo( out, es );
|
||||
|
||||
vlc_mutex_unlock( &p_sys->lock );
|
||||
|
||||
return es;
|
||||
}
|
||||
|
||||
@ -1790,6 +1810,8 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
|
||||
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
|
||||
}
|
||||
|
||||
vlc_mutex_lock( &p_sys->lock );
|
||||
|
||||
/* Mark preroll blocks */
|
||||
if( p_sys->i_preroll_end >= 0 )
|
||||
{
|
||||
@ -1806,6 +1828,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
|
||||
if( !es->p_dec )
|
||||
{
|
||||
block_Release( p_block );
|
||||
vlc_mutex_unlock( &p_sys->lock );
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1853,6 +1876,8 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
|
||||
if( b_cc_new )
|
||||
var_SetBool( p_sys->p_input, "intf-change", true );
|
||||
|
||||
vlc_mutex_unlock( &p_sys->lock );
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1865,6 +1890,8 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
|
||||
bool b_reselect = false;
|
||||
int i;
|
||||
|
||||
vlc_mutex_lock( &p_sys->lock );
|
||||
|
||||
/* We don't try to reselect */
|
||||
if( es->p_dec )
|
||||
{
|
||||
@ -1911,17 +1938,21 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
|
||||
|
||||
/* Re-select another track when needed */
|
||||
if( b_reselect )
|
||||
{
|
||||
for( i = 0; i < p_sys->i_es; i++ )
|
||||
{
|
||||
if( es->fmt.i_cat == p_sys->es[i]->fmt.i_cat )
|
||||
EsOutSelect( out, p_sys->es[i], false );
|
||||
}
|
||||
}
|
||||
|
||||
free( es->psz_language );
|
||||
free( es->psz_language_code );
|
||||
|
||||
es_format_Clean( &es->fmt );
|
||||
|
||||
vlc_mutex_unlock( &p_sys->lock );
|
||||
|
||||
free( es );
|
||||
}
|
||||
|
||||
@ -1933,7 +1964,7 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
|
||||
* \param args a variable list of arguments for the query
|
||||
* \return VLC_SUCCESS or an error code
|
||||
*/
|
||||
static int EsOutControl( es_out_t *out, int i_query, va_list args )
|
||||
static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
|
||||
{
|
||||
es_out_sys_t *p_sys = out->p_sys;
|
||||
bool b, *pb;
|
||||
@ -2257,6 +2288,17 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
|
||||
return VLC_EGENERIC;
|
||||
}
|
||||
}
|
||||
static int EsOutControl( es_out_t *out, int i_query, va_list args )
|
||||
{
|
||||
es_out_sys_t *p_sys = out->p_sys;
|
||||
int i_ret;
|
||||
|
||||
vlc_mutex_lock( &p_sys->lock );
|
||||
i_ret = EsOutControlLocked( out, i_query, args );
|
||||
vlc_mutex_unlock( &p_sys->lock );
|
||||
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* LanguageGetName: try to expend iso639 into plain name
|
||||
|
@ -44,4 +44,7 @@ bool input_EsOutDecodersIsEmpty( es_out_t * );
|
||||
bool input_EsOutIsBuffering( es_out_t * );
|
||||
void input_EsOutFrameNext( es_out_t * );
|
||||
|
||||
void input_EsOutLock( es_out_t * );
|
||||
void input_EsOutUnlock( es_out_t * );
|
||||
|
||||
#endif
|
||||
|
@ -743,13 +743,18 @@ static void MainLoop( input_thread_t *p_input )
|
||||
/* FIXME if p_input->i_state == PAUSE_S the access/access_demux
|
||||
* is paused -> this may cause problem with some of them
|
||||
* The same problem can be seen when seeking while paused */
|
||||
input_EsOutLock( p_input->p->p_es_out );
|
||||
b_paused = p_input->i_state == PAUSE_S &&
|
||||
!input_EsOutIsBuffering( p_input->p->p_es_out );
|
||||
input_EsOutUnlock( p_input->p->p_es_out );
|
||||
|
||||
if( !b_paused )
|
||||
{
|
||||
MainLoopDemux( p_input, &b_force_update, &i_start_mdate );
|
||||
|
||||
input_EsOutLock( p_input->p->p_es_out );
|
||||
i_wakeup = input_EsOutGetWakeup( p_input->p->p_es_out );
|
||||
input_EsOutUnlock( p_input->p->p_es_out );
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -764,6 +769,7 @@ static void MainLoop( input_thread_t *p_input )
|
||||
while( !ControlPopNoLock( p_input, &i_type, &val, i_deadline ) )
|
||||
{
|
||||
msg_Dbg( p_input, "control type=%d", i_type );
|
||||
|
||||
if( Control( p_input, i_type, val ) )
|
||||
b_force_update = true;
|
||||
}
|
||||
@ -786,9 +792,11 @@ static void MainLoop( input_thread_t *p_input )
|
||||
/* Check if i_wakeup is still valid */
|
||||
if( i_wakeup != 0 )
|
||||
{
|
||||
input_EsOutLock( p_input->p->p_es_out );
|
||||
mtime_t i_new_wakeup = input_EsOutGetWakeup( p_input->p->p_es_out );
|
||||
if( !i_new_wakeup )
|
||||
i_wakeup = 0;
|
||||
input_EsOutUnlock( p_input->p->p_es_out );
|
||||
}
|
||||
} while( i_current < i_wakeup );
|
||||
}
|
||||
@ -798,7 +806,11 @@ static void MainLoop( input_thread_t *p_input )
|
||||
/* We have finish to demux data but not to play them */
|
||||
while( vlc_object_alive( p_input ) )
|
||||
{
|
||||
if( input_EsOutDecodersIsEmpty( p_input->p->p_es_out ) )
|
||||
input_EsOutLock( p_input->p->p_es_out );
|
||||
bool b_empty = input_EsOutDecodersIsEmpty( p_input->p->p_es_out );
|
||||
input_EsOutUnlock( p_input->p->p_es_out );
|
||||
|
||||
if( b_empty )
|
||||
break;
|
||||
|
||||
msg_Dbg( p_input, "waiting decoder fifos to empty" );
|
||||
@ -1547,6 +1559,8 @@ static bool Control( input_thread_t *p_input, int i_type,
|
||||
if( !p_input )
|
||||
return b_force_update;
|
||||
|
||||
input_EsOutLock( p_input->p->p_es_out );
|
||||
|
||||
switch( i_type )
|
||||
{
|
||||
case INPUT_CONTROL_SET_DIE:
|
||||
@ -2063,6 +2077,8 @@ static bool Control( input_thread_t *p_input, int i_type,
|
||||
break;
|
||||
}
|
||||
|
||||
input_EsOutUnlock( p_input->p->p_es_out );
|
||||
|
||||
return b_force_update;
|
||||
}
|
||||
|
||||
@ -3094,10 +3110,13 @@ static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_for
|
||||
if( count.i_int < list.p_list->i_count )
|
||||
{
|
||||
int i_id = list.p_list->p_values[count.i_int].i_int;
|
||||
|
||||
input_EsOutLock( p_input->p->p_es_out );
|
||||
es_out_id_t *p_es = input_EsOutGetFromID( p_input->p->p_es_out, i_id );
|
||||
|
||||
es_out_Control( p_input->p->p_es_out, ES_OUT_SET_DEFAULT, p_es );
|
||||
es_out_Control( p_input->p->p_es_out, ES_OUT_SET_ES, p_es );
|
||||
input_EsOutUnlock( p_input->p->p_es_out );
|
||||
}
|
||||
var_Change( p_input, "spu-es", VLC_VAR_FREELIST, &list, NULL );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user