]> git.sesse.net Git - vlc/blobdiff - src/input/resource.c
decoder: fix potential NULL dereference
[vlc] / src / input / resource.c
index 3748fbc1f684343c675563e2f196b075c8193d87..779c921a2c69a87cfee59de2071dcd49c4dba96e 100644 (file)
@@ -71,7 +71,6 @@ struct input_resource_t
     vout_thread_t   **pp_vout;
     int             i_vout;
 
-    /* TODO? track more than one audio output (like video outputs) */
     bool            b_aout_busy;
     audio_output_t *p_aout;
 };
@@ -133,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
 }
@@ -260,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
@@ -325,103 +325,90 @@ exit:
     vlc_mutex_unlock( &p_resource->lock_hold );
 }
 
-/* */
-static void DestroyAout( input_resource_t *p_resource )
-{
-    if( p_resource->p_aout )
-    {
-        aout_Destroy( p_resource->p_aout );
-        p_resource->p_aout = NULL;
-    }
-}
-
-static void ReleaseAout( input_resource_t *p_resource,
-                         audio_output_t *p_aout )
-{
-    if( likely(p_aout == p_resource->p_aout) )
-    {
-        assert( p_resource->b_aout_busy );
-        p_resource->b_aout_busy = false;
-        msg_Dbg( p_resource->p_parent, "releasing audio output" );
-        vlc_object_release( p_aout );
-    }
-    else
-    {
-        msg_Dbg( p_resource->p_parent, "destroying extra audio output" );
-        aout_Destroy( p_aout );
-    }
-}
-
-static audio_output_t *AllocateAout( input_resource_t *p_resource )
+/* Audio output */
+audio_output_t *input_resource_GetAout( input_resource_t *p_resource )
 {
     audio_output_t *p_aout;
 
-    if( unlikely(p_resource->b_aout_busy) )
-    {
-        msg_Dbg( p_resource->p_parent, "creating extra audio output" );
-        return aout_New( p_resource->p_parent );
-    }
-
+    vlc_mutex_lock( &p_resource->lock_hold );
     p_aout = p_resource->p_aout;
-    if( p_aout == NULL )
+
+    if( p_aout == NULL || p_resource->b_aout_busy )
     {
         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( unlikely(p_aout == NULL) )
-            return NULL;
+        if( p_aout == NULL )
+            return NULL; /* failed */
 
         vlc_mutex_lock( &p_resource->lock_hold );
-        assert( p_resource->p_aout == NULL );
-        p_resource->p_aout = p_aout;
-        vlc_mutex_unlock( &p_resource->lock_hold );
+        if( p_resource->p_aout == NULL )
+            p_resource->p_aout = p_aout;
     }
     else
-        msg_Dbg( p_resource->p_parent, "recycling audio output" );
+        msg_Dbg( p_resource->p_parent, "reusing audio output" );
 
-    p_resource->b_aout_busy = true;
-    vlc_object_hold( p_aout );
+    if( p_resource->p_aout == p_aout )
+    {
+        assert( !p_resource->b_aout_busy );
+        p_resource->b_aout_busy = true;
+    }
+    vlc_mutex_unlock( &p_resource->lock_hold );
     return p_aout;
 }
 
-static audio_output_t *RequestAout( input_resource_t *p_resource, audio_output_t *p_aout )
+void input_resource_PutAout( input_resource_t *p_resource,
+                             audio_output_t *p_aout )
 {
-    vlc_assert_locked( &p_resource->lock );
+    assert( p_aout != NULL );
 
-    if( p_aout )
+    vlc_mutex_lock( &p_resource->lock_hold );
+    if( p_aout == p_resource->p_aout )
     {
-        ReleaseAout( p_resource, p_aout );
-        return NULL;
+        assert( p_resource->b_aout_busy );
+        p_resource->b_aout_busy = false;
+        msg_Dbg( p_resource->p_parent, "keeping audio output" );
+        p_aout = NULL;
     }
-    return AllocateAout( p_resource );
+    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 audio_output_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;
 
-    audio_output_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;
 
-    audio_output_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 )
+    if( p_aout != NULL )
         aout_Destroy( p_aout );
 }
 
-/* */
+/* Common */
 input_resource_t *input_resource_New( vlc_object_t *p_parent )
 {
     input_resource_t *p_resource = calloc( 1, sizeof(*p_resource) );
@@ -442,7 +429,8 @@ void input_resource_Release( input_resource_t *p_resource )
 
     DestroySout( p_resource );
     DestroyVout( p_resource );
-    DestroyAout( 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 );
@@ -504,20 +492,6 @@ bool input_resource_HasVout( input_resource_t *p_resource )
     return b_vout;
 }
 
-/* */
-audio_output_t *input_resource_RequestAout( input_resource_t *p_resource, audio_output_t *p_aout )
-{
-    vlc_mutex_lock( &p_resource->lock );
-    audio_output_t *p_ret = RequestAout( p_resource, p_aout );
-    vlc_mutex_unlock( &p_resource->lock );
-
-    return p_ret;
-}
-audio_output_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 )
 {
@@ -535,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 );
 }