X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Fresource.c;h=9132bf6bd4ee5728dc87bd3f129eca3da5cb082e;hb=2f9d9766dfe25f100ef04d0d812aebdd18401c0d;hp=b3e140fc2ef3b18cab80bfc29773da5209b05ae0;hpb=c5746ee26ca344047dbb9f963a2e39483f85da4c;p=vlc diff --git a/src/input/resource.c b/src/input/resource.c index b3e140fc2e..9132bf6bd4 100644 --- a/src/input/resource.c +++ b/src/input/resource.c @@ -51,14 +51,20 @@ struct input_resource_t sout_instance_t *p_sout; vout_thread_t *p_vout_free; - aout_instance_t *p_aout; /* This lock is used to protect vout resources access (for hold) * It is a special case because of embed video (possible deadlock - * between vout window request and vout holds in some(qt4) interface) */ - vlc_mutex_t lock_vout; + * between vout window request and vout holds in some(qt4) interface) + */ + vlc_mutex_t lock_hold; + + /* You need lock+lock_hold to write to the following variables and + * only lock or lock_hold to read them */ + int i_vout; vout_thread_t **pp_vout; + + aout_instance_t *p_aout; }; /* */ @@ -70,6 +76,15 @@ static void DestroySout( input_resource_t *p_resource ) #endif p_resource->p_sout = NULL; } + +static sout_instance_t *DetachSout( input_resource_t *p_resource ) +{ + sout_instance_t *p_sout = p_resource->p_sout; + p_resource->p_sout = NULL; + + return p_sout; +} + static sout_instance_t *RequestSout( input_resource_t *p_resource, sout_instance_t *p_sout, const char *psz_sout ) { @@ -135,6 +150,15 @@ static void DestroyVout( input_resource_t *p_resource ) p_resource->p_vout_free = NULL; } +static vout_thread_t *DetachVout( input_resource_t *p_resource ) +{ + assert( p_resource->i_vout == 0 ); + vout_thread_t *p_vout = p_resource->p_vout_free; + p_resource->p_vout_free = NULL; + + return p_vout; +} + static void DisplayVoutTitle( input_resource_t *p_resource, vout_thread_t *p_vout ) { @@ -207,9 +231,9 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, { assert( p_vout != p_resource->p_vout_free ); - vlc_mutex_lock( &p_resource->lock_vout ); + vlc_mutex_lock( &p_resource->lock_hold ); TAB_REMOVE( p_resource->i_vout, p_resource->pp_vout, p_vout ); - vlc_mutex_unlock( &p_resource->lock_vout ); + vlc_mutex_unlock( &p_resource->lock_hold ); } /* */ @@ -219,9 +243,9 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, DisplayVoutTitle( p_resource, p_vout ); - vlc_mutex_lock( &p_resource->lock_vout ); + vlc_mutex_lock( &p_resource->lock_hold ); TAB_APPEND( p_resource->i_vout, p_resource->pp_vout, p_vout ); - vlc_mutex_unlock( &p_resource->lock_vout ); + vlc_mutex_unlock( &p_resource->lock_hold ); return p_vout; } @@ -229,10 +253,10 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, { assert( p_vout ); - vlc_mutex_lock( &p_resource->lock_vout ); + vlc_mutex_lock( &p_resource->lock_hold ); TAB_REMOVE( p_resource->i_vout, p_resource->pp_vout, p_vout ); const int i_vout_active = p_resource->i_vout; - vlc_mutex_unlock( &p_resource->lock_vout ); + vlc_mutex_unlock( &p_resource->lock_hold ); if( p_resource->p_vout_free || i_vout_active > 0 || !b_recycle ) { @@ -244,7 +268,7 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, { msg_Dbg( p_resource->p_input, "saving a free vout" ); vout_Flush( p_vout, 1 ); - spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR, -1 ); + spu_Control( vout_GetSpu( p_vout ), SPU_CHANNEL_CLEAR, -1 ); p_resource->p_vout_free = p_vout; } @@ -253,17 +277,14 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, } static vout_thread_t *HoldVout( input_resource_t *p_resource ) { - if( p_resource->i_vout <= 0 ) - return NULL; - /* TODO FIXME: p_resource->pp_vout order is NOT stable */ - vlc_mutex_lock( &p_resource->lock_vout ); + vlc_mutex_lock( &p_resource->lock_hold ); - vout_thread_t *p_vout = p_resource->pp_vout[0]; + vout_thread_t *p_vout = p_resource->i_vout > 0 ? p_resource->pp_vout[0] : NULL; + if( p_vout ) + vlc_object_hold( p_vout ); - vlc_object_hold( p_vout ); - - vlc_mutex_unlock( &p_resource->lock_vout ); + vlc_mutex_unlock( &p_resource->lock_hold ); return p_vout; } @@ -274,7 +295,7 @@ static void HoldVouts( input_resource_t *p_resource, vout_thread_t ***ppp_vout, *pi_vout = 0; *ppp_vout = NULL; - vlc_mutex_lock( &p_resource->lock_vout ); + vlc_mutex_lock( &p_resource->lock_hold ); if( p_resource->i_vout <= 0 ) goto exit; @@ -293,7 +314,7 @@ static void HoldVouts( input_resource_t *p_resource, vout_thread_t ***ppp_vout, } exit: - vlc_mutex_unlock( &p_resource->lock_vout ); + vlc_mutex_unlock( &p_resource->lock_hold ); } /* */ @@ -303,6 +324,18 @@ static void DestroyAout( input_resource_t *p_resource ) vlc_object_release( p_resource->p_aout ); p_resource->p_aout = NULL; } +static aout_instance_t *DetachAout( input_resource_t *p_resource ) +{ + vlc_mutex_lock( &p_resource->lock_hold ); + + aout_instance_t *p_aout = p_resource->p_aout; + p_resource->p_aout = NULL; + + vlc_mutex_unlock( &p_resource->lock_hold ); + + return p_aout; +} + static aout_instance_t *RequestAout( input_resource_t *p_resource, aout_instance_t *p_aout ) { assert( p_resource->p_input ); @@ -315,33 +348,39 @@ static aout_instance_t *RequestAout( input_resource_t *p_resource, aout_instance } else { - if( !p_resource->p_aout ) + p_aout = p_resource->p_aout; + if( !p_aout ) { msg_Dbg( p_resource->p_input, "creating aout" ); - p_resource->p_aout = aout_New( p_resource->p_input ); + p_aout = aout_New( p_resource->p_input ); + + vlc_mutex_lock( &p_resource->lock_hold ); + p_resource->p_aout = p_aout; + vlc_mutex_unlock( &p_resource->lock_hold ); } else { msg_Dbg( p_resource->p_input, "reusing aout" ); } - if( !p_resource->p_aout ) + if( !p_aout ) return NULL; - vlc_object_detach( p_resource->p_aout ); - vlc_object_attach( p_resource->p_aout, p_resource->p_input ); - vlc_object_hold( p_resource->p_aout ); - return p_resource->p_aout; + vlc_object_detach( p_aout ); + vlc_object_attach( p_aout, p_resource->p_input ); + vlc_object_hold( p_aout ); + return p_aout; } } static aout_instance_t *HoldAout( input_resource_t *p_resource ) { - if( !p_resource->p_aout ) - return NULL; + vlc_mutex_lock( &p_resource->lock_hold ); aout_instance_t *p_aout = p_resource->p_aout; + if( p_aout ) + vlc_object_hold( p_aout ); - vlc_object_hold( p_aout ); + vlc_mutex_unlock( &p_resource->lock_hold ); return p_aout; } @@ -354,7 +393,7 @@ input_resource_t *input_resource_New( void ) return NULL; vlc_mutex_init( &p_resource->lock ); - vlc_mutex_init( &p_resource->lock_vout ); + vlc_mutex_init( &p_resource->lock_hold ); return p_resource; } @@ -364,7 +403,7 @@ void input_resource_Delete( input_resource_t *p_resource ) DestroyVout( p_resource ); DestroyAout( p_resource ); - vlc_mutex_destroy( &p_resource->lock_vout ); + vlc_mutex_destroy( &p_resource->lock_hold ); vlc_mutex_destroy( &p_resource->lock ); free( p_resource ); } @@ -392,6 +431,22 @@ void input_resource_SetInput( input_resource_t *p_resource, input_thread_t *p_in vlc_mutex_unlock( &p_resource->lock ); } +input_resource_t *input_resource_Detach( input_resource_t *p_resource ) +{ + input_resource_t *p_ret = input_resource_New(); + if( !p_ret ) + return NULL; + + vlc_mutex_lock( &p_resource->lock ); + assert( !p_resource->p_input ); + p_ret->p_sout = DetachSout( p_resource ); + p_ret->p_vout_free = DetachVout( p_resource ); + p_ret->p_aout = DetachAout( p_resource ); + vlc_mutex_unlock( &p_resource->lock ); + + return p_ret; +} + vout_thread_t *input_resource_RequestVout( input_resource_t *p_resource, vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recycle ) { @@ -434,11 +489,7 @@ aout_instance_t *input_resource_RequestAout( input_resource_t *p_resource, aout_ } aout_instance_t *input_resource_HoldAout( input_resource_t *p_resource ) { - vlc_mutex_lock( &p_resource->lock ); - aout_instance_t *p_ret = HoldAout( p_resource ); - vlc_mutex_unlock( &p_resource->lock ); - - return p_ret; + return HoldAout( p_resource ); } /* */ sout_instance_t *input_resource_RequestSout( input_resource_t *p_resource, sout_instance_t *p_sout, const char *psz_sout )