X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Fresource.c;h=779c921a2c69a87cfee59de2071dcd49c4dba96e;hb=7df464879acb66d7a0a19905e3d48b7e6b5fcf33;hp=f683e61b3679d7c3b8b5c276075236ee6f522e4e;hpb=a8f019f23091a4b65790f74a39939b0c0749686f;p=vlc diff --git a/src/input/resource.c b/src/input/resource.c index f683e61b36..779c921a2c 100644 --- a/src/input/resource.c +++ b/src/input/resource.c @@ -6,19 +6,19 @@ * * Authors: Laurent Aimar < fenrir _AT_ videolan _DOT_ org > * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -44,7 +45,7 @@ struct input_resource_t { - VLC_GC_MEMBERS + atomic_uint refs; vlc_object_t *p_parent; @@ -67,10 +68,11 @@ struct input_resource_t /* 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; + int i_vout; - aout_instance_t *p_aout; + bool b_aout_busy; + audio_output_t *p_aout; }; /* */ @@ -95,7 +97,6 @@ static sout_instance_t *RequestSout( input_resource_t *p_resource, return NULL; } - assert( p_resource->p_input ); assert( !p_sout || ( !p_resource->p_sout && !psz_sout ) ); /* Check the validity of the sout */ @@ -131,6 +132,7 @@ static sout_instance_t *RequestSout( input_resource_t *p_resource, return NULL; } #else + VLC_UNUSED (p_resource); VLC_UNUSED (p_sout); VLC_UNUSED (psz_sout); return NULL; #endif } @@ -149,7 +151,8 @@ static void DestroyVout( input_resource_t *p_resource ) static void DisplayVoutTitle( input_resource_t *p_resource, vout_thread_t *p_vout ) { - assert( p_resource->p_input ); + if( p_resource->p_input == NULL ) + return; /* TODO display the title only one time for the same input ? */ @@ -206,7 +209,6 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, return NULL; } - assert( p_resource->p_input ); if( p_fmt ) { /* */ @@ -258,7 +260,7 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, if( p_resource->p_vout_free || i_vout_active > 0 || !b_recycle ) { if( b_recycle ) - msg_Dbg( p_resource->p_parent, "detroying vout (already one saved or active)" ); + msg_Dbg( p_resource->p_parent, "destroying vout (already one saved or active)" ); vout_CloseAndRelease( p_vout ); } else @@ -323,93 +325,97 @@ exit: vlc_mutex_unlock( &p_resource->lock_hold ); } -/* */ -static void DestroyAout( input_resource_t *p_resource ) -{ - if( p_resource->p_aout ) - vlc_object_release( p_resource->p_aout ); - p_resource->p_aout = NULL; -} -static aout_instance_t *RequestAout( input_resource_t *p_resource, aout_instance_t *p_aout ) +/* Audio output */ +audio_output_t *input_resource_GetAout( input_resource_t *p_resource ) { - vlc_assert_locked( &p_resource->lock ); - assert( p_resource->p_input ); + audio_output_t *p_aout; - if( p_aout ) + vlc_mutex_lock( &p_resource->lock_hold ); + p_aout = p_resource->p_aout; + + if( p_aout == NULL || p_resource->b_aout_busy ) { - msg_Dbg( p_resource->p_parent, "releasing aout" ); - vlc_object_release( p_aout ); - return NULL; + msg_Dbg( p_resource->p_parent, "creating audio output" ); + vlc_mutex_unlock( &p_resource->lock_hold ); + + p_aout = aout_New( p_resource->p_parent ); + if( p_aout == NULL ) + return NULL; /* failed */ + + vlc_mutex_lock( &p_resource->lock_hold ); + if( p_resource->p_aout == NULL ) + p_resource->p_aout = p_aout; } else + msg_Dbg( p_resource->p_parent, "reusing audio output" ); + + if( p_resource->p_aout == p_aout ) { - p_aout = p_resource->p_aout; - if( !p_aout ) - { - msg_Dbg( p_resource->p_parent, "creating aout" ); - p_aout = aout_New( p_resource->p_parent ); + assert( !p_resource->b_aout_busy ); + p_resource->b_aout_busy = true; + } + vlc_mutex_unlock( &p_resource->lock_hold ); + return p_aout; +} - 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_parent, "reusing aout" ); - } +void input_resource_PutAout( input_resource_t *p_resource, + audio_output_t *p_aout ) +{ + assert( p_aout != NULL ); - if( !p_aout ) - return NULL; - vlc_object_hold( p_aout ); - return p_aout; + vlc_mutex_lock( &p_resource->lock_hold ); + if( p_aout == p_resource->p_aout ) + { + assert( p_resource->b_aout_busy ); + p_resource->b_aout_busy = false; + msg_Dbg( p_resource->p_parent, "keeping audio output" ); + p_aout = NULL; } + else + msg_Dbg( p_resource->p_parent, "destroying extra audio output" ); + vlc_mutex_unlock( &p_resource->lock_hold ); + + if( p_aout != NULL ) + aout_Destroy( p_aout ); } -static aout_instance_t *HoldAout( input_resource_t *p_resource ) + +audio_output_t *input_resource_HoldAout( input_resource_t *p_resource ) { - vlc_mutex_lock( &p_resource->lock_hold ); + audio_output_t *p_aout; - aout_instance_t *p_aout = p_resource->p_aout; - if( p_aout ) + vlc_mutex_lock( &p_resource->lock_hold ); + p_aout = p_resource->p_aout; + if( p_aout != NULL ) vlc_object_hold( p_aout ); - vlc_mutex_unlock( &p_resource->lock_hold ); return p_aout; } -static void TerminateAout( input_resource_t *p_resource ) + +void input_resource_ResetAout( input_resource_t *p_resource ) { + audio_output_t *p_aout = NULL; + vlc_mutex_lock( &p_resource->lock_hold ); + if( !p_resource->b_aout_busy ) + p_aout = p_resource->p_aout; - aout_instance_t *p_aout = p_resource->p_aout; p_resource->p_aout = NULL; - + p_resource->b_aout_busy = false; vlc_mutex_unlock( &p_resource->lock_hold ); - if( p_aout ) - vlc_object_release( p_aout ); + if( p_aout != NULL ) + aout_Destroy( p_aout ); } -static void Destructor( gc_object_t *p_gc ) -{ - input_resource_t *p_resource = vlc_priv( p_gc, input_resource_t ); - - DestroySout( p_resource ); - DestroyVout( p_resource ); - DestroyAout( p_resource ); - - vlc_mutex_destroy( &p_resource->lock_hold ); - vlc_mutex_destroy( &p_resource->lock ); - free( p_resource ); -} - -/* */ +/* Common */ input_resource_t *input_resource_New( vlc_object_t *p_parent ) { input_resource_t *p_resource = calloc( 1, sizeof(*p_resource) ); if( !p_resource ) return NULL; - vlc_gc_init( p_resource, Destructor ); + atomic_init( &p_resource->refs, 1 ); p_resource->p_parent = p_parent; vlc_mutex_init( &p_resource->lock ); vlc_mutex_init( &p_resource->lock_hold ); @@ -418,12 +424,22 @@ input_resource_t *input_resource_New( vlc_object_t *p_parent ) void input_resource_Release( input_resource_t *p_resource ) { - vlc_gc_decref( p_resource ); + if( atomic_fetch_sub( &p_resource->refs, 1 ) != 1 ) + return; + + DestroySout( p_resource ); + DestroyVout( p_resource ); + if( p_resource->p_aout != NULL ) + aout_Destroy( p_resource->p_aout ); + + vlc_mutex_destroy( &p_resource->lock_hold ); + vlc_mutex_destroy( &p_resource->lock ); + free( p_resource ); } input_resource_t *input_resource_Hold( input_resource_t *p_resource ) { - vlc_gc_incref( p_resource ); + atomic_fetch_add( &p_resource->refs, 1 ); return p_resource; } @@ -476,20 +492,6 @@ bool input_resource_HasVout( input_resource_t *p_resource ) return b_vout; } -/* */ -aout_instance_t *input_resource_RequestAout( input_resource_t *p_resource, aout_instance_t *p_aout ) -{ - vlc_mutex_lock( &p_resource->lock ); - aout_instance_t *p_ret = RequestAout( p_resource, p_aout ); - vlc_mutex_unlock( &p_resource->lock ); - - return p_ret; -} -aout_instance_t *input_resource_HoldAout( input_resource_t *p_resource ) -{ - return HoldAout( p_resource ); -} - /* */ sout_instance_t *input_resource_RequestSout( input_resource_t *p_resource, sout_instance_t *p_sout, const char *psz_sout ) { @@ -507,11 +509,7 @@ void input_resource_TerminateSout( input_resource_t *p_resource ) void input_resource_Terminate( input_resource_t *p_resource ) { input_resource_TerminateSout( p_resource ); - - vlc_mutex_lock( &p_resource->lock ); - TerminateAout( p_resource ); - vlc_mutex_unlock( &p_resource->lock ); - + input_resource_ResetAout( p_resource ); input_resource_TerminateVout( p_resource ); }