]> git.sesse.net Git - vlc/blobdiff - src/control/media_instance.c
fix for libvlc_get_input_thread: check for null before locking. fixes #1522
[vlc] / src / control / media_instance.c
index de362093a4fa72bbad86576c41f30d3ba4002fd2..e7dc33d3aa09b231b8df190713f4124daa266684 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
+#include "libvlc_internal.h"
+
 #include <vlc/libvlc.h>
 #include <vlc_demux.h>
 #include <vlc_input.h>
-#include "libvlc_internal.h"
 #include "libvlc.h"
 
 static int
@@ -32,6 +33,14 @@ input_state_changed( vlc_object_t * p_this, char const * psz_cmd,
                      vlc_value_t oldval, vlc_value_t newval,
                      void * p_userdata );
 static int
+input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
+                        vlc_value_t oldval, vlc_value_t newval,
+                        void * p_userdata );
+static int
+input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
+                        vlc_value_t oldval, vlc_value_t newval,
+                        void * p_userdata );
+static int
 input_position_changed( vlc_object_t * p_this, char const * psz_cmd,
                      vlc_value_t oldval, vlc_value_t newval,
                      void * p_userdata );
@@ -70,30 +79,27 @@ static void release_input_thread( libvlc_media_instance_t *p_mi )
     if( !p_mi || p_mi->i_input_id == -1 )
         return;
 
-    p_input_thread = (input_thread_t*)vlc_object_get(
-                                             p_mi->p_libvlc_instance->p_libvlc_int,
-                                             p_mi->i_input_id );
+    p_input_thread = (input_thread_t*)vlc_object_get( p_mi->i_input_id );
 
     p_mi->i_input_id = -1;
 
     if( !p_input_thread )
         return;
  
-    /* release for previous vlc_object_get */
-    vlc_object_release( p_input_thread );
 
     /* No one is tracking this input_thread appart us. Destroy it */
     if( p_mi->b_own_its_input_thread )
     {
         var_DelCallback( p_input_thread, "state", input_state_changed, p_mi );
-        var_DelCallback( p_input_thread, "seekable", input_state_changed, p_mi );
-        var_DelCallback( p_input_thread, "pausable", input_state_changed, p_mi );
+        var_DelCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
+        var_DelCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
         var_DelCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
         var_DelCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
+
         /* We owned this one */
-        //input_StopThread( p_input_thread );
-        //var_Destroy( p_input_thread, "drawable" );
-        //input_DestroyThread( p_input_thread );
+        input_StopThread( p_input_thread );
+
+        var_Destroy( p_input_thread, "drawable" );
     }
     else
     {
@@ -103,7 +109,7 @@ static void release_input_thread( libvlc_media_instance_t *p_mi )
         vlc_object_release( p_input_thread );
     }
 
-    /* release for initial p_input_thread yield (see _new()) */
+    /* release for previous vlc_object_get */
     vlc_object_release( p_input_thread );
 }
 
@@ -118,6 +124,11 @@ input_thread_t *libvlc_get_input_thread( libvlc_media_instance_t *p_mi,
 {
     input_thread_t *p_input_thread;
 
+    if ( !p_mi )
+    {
+        RAISENULL( "Input is NULL" );
+    }
+
     vlc_mutex_lock( &p_mi->object_lock );
 
     if( !p_mi || p_mi->i_input_id == -1 )
@@ -126,9 +137,7 @@ input_thread_t *libvlc_get_input_thread( libvlc_media_instance_t *p_mi,
         RAISENULL( "Input is NULL" );
     }
 
-    p_input_thread = (input_thread_t*)vlc_object_get(
-                                             p_mi->p_libvlc_instance->p_libvlc_int,
-                                             p_mi->i_input_id );
+    p_input_thread = (input_thread_t*)vlc_object_get( p_mi->i_input_id );
     if( !p_input_thread )
     {
         vlc_mutex_unlock( &p_mi->object_lock );
@@ -147,13 +156,13 @@ input_state_changed( vlc_object_t * p_this, char const * psz_cmd,
                      vlc_value_t oldval, vlc_value_t newval,
                      void * p_userdata )
 {
+    VLC_UNUSED(oldval);
+    VLC_UNUSED(p_this);
+    VLC_UNUSED(psz_cmd);
     libvlc_media_instance_t * p_mi = p_userdata;
     libvlc_event_t event;
     libvlc_event_type_t type = newval.i_int;
 
-    if( strcmp( psz_cmd, "state" ) )
-        type = var_GetBool( p_this, "state" );
-
     switch ( type )
     {
         case END_S:
@@ -180,6 +189,44 @@ input_state_changed( vlc_object_t * p_this, char const * psz_cmd,
     return VLC_SUCCESS;
 }
 
+static int
+input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
+                        vlc_value_t oldval, vlc_value_t newval,
+                        void * p_userdata )
+{
+    VLC_UNUSED(oldval);
+    VLC_UNUSED(p_this);
+    VLC_UNUSED(psz_cmd);
+    libvlc_media_instance_t * p_mi = p_userdata;
+    libvlc_event_t event;
+
+    libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
+    event.type = libvlc_MediaInstanceSeekableChanged;
+    event.u.media_instance_seekable_changed.new_seekable = newval.b_bool;
+
+    libvlc_event_send( p_mi->p_event_manager, &event );
+    return VLC_SUCCESS;
+}
+
+static int
+input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
+                        vlc_value_t oldval, vlc_value_t newval,
+                        void * p_userdata )
+{
+    VLC_UNUSED(oldval);
+    VLC_UNUSED(p_this);
+    VLC_UNUSED(psz_cmd);
+    libvlc_media_instance_t * p_mi = p_userdata;
+    libvlc_event_t event;
+
+    libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
+    event.type = libvlc_MediaInstancePausableChanged;
+    event.u.media_instance_pausable_changed.new_pausable = newval.b_bool;
+
+    libvlc_event_send( p_mi->p_event_manager, &event );
+    return VLC_SUCCESS;
+}
+
 /*
  * input_position_changed (Private) (input var "intf-change" Callback)
  */
@@ -188,6 +235,7 @@ input_position_changed( vlc_object_t * p_this, char const * psz_cmd,
                      vlc_value_t oldval, vlc_value_t newval,
                      void * p_userdata )
 {
+    VLC_UNUSED(oldval);
     libvlc_media_instance_t * p_mi = p_userdata;
     vlc_value_t val;
 
@@ -220,6 +268,7 @@ input_time_changed( vlc_object_t * p_this, char const * psz_cmd,
                      vlc_value_t oldval, vlc_value_t newval,
                      void * p_userdata )
 {
+    VLC_UNUSED(oldval);
     libvlc_media_instance_t * p_mi = p_userdata;
     vlc_value_t val;
 
@@ -296,6 +345,10 @@ libvlc_media_instance_new( libvlc_instance_t * p_libvlc_instance,
             libvlc_MediaInstancePositionChanged, p_e );
     libvlc_event_manager_register_event_type( p_mi->p_event_manager,
             libvlc_MediaInstanceTimeChanged, p_e );
+    libvlc_event_manager_register_event_type( p_mi->p_event_manager,
+            libvlc_MediaInstanceSeekableChanged, p_e );
+    libvlc_event_manager_register_event_type( p_mi->p_event_manager,
+            libvlc_MediaInstancePausableChanged, p_e );
 
     return p_mi;
 }
@@ -454,6 +507,9 @@ void libvlc_media_instance_set_media_descriptor(
 
     release_input_thread( p_mi );
 
+    if( p_mi->p_md )
+        libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL );
+
     libvlc_media_descriptor_release( p_mi->p_md );
 
     if( !p_md )
@@ -513,15 +569,12 @@ void libvlc_media_instance_play( libvlc_media_instance_t *p_mi,
 
     if( (p_input_thread = libvlc_get_input_thread( p_mi, p_e )) )
     {
-        printf(")))))))))))))))))))p_input_thread %p\n", p_input_thread);
         /* A thread alread exists, send it a play message */
         input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
         vlc_object_release( p_input_thread );
         return;
     }
 
-    printf(")))))))))))))))))))p_input_thread NOT\n");
-
     /* Ignore previous exception */
     libvlc_exception_clear( p_e );
 
@@ -535,11 +588,9 @@ void libvlc_media_instance_play( libvlc_media_instance_t *p_mi,
     }
 
     p_mi->i_input_id = input_Read( p_mi->p_libvlc_instance->p_libvlc_int,
-                                         p_mi->p_md->p_input_item, VLC_FALSE );
+                                   p_mi->p_md->p_input_item, VLC_FALSE );
 
-    /* Released in _release() */
-    p_input_thread = (input_thread_t*)vlc_object_get( p_mi->p_libvlc_instance->p_libvlc_int,
-                                                      p_mi->i_input_id );
+    p_input_thread = (input_thread_t*)vlc_object_get( p_mi->i_input_id );
 
     if( !p_input_thread )
     {
@@ -555,11 +606,12 @@ void libvlc_media_instance_play( libvlc_media_instance_t *p_mi,
         var_Set( p_input_thread, "drawable", val );
     }
     var_AddCallback( p_input_thread, "state", input_state_changed, p_mi );
-    var_AddCallback( p_input_thread, "seekable", input_state_changed, p_mi );
-    var_AddCallback( p_input_thread, "pausable", input_state_changed, p_mi );
+    var_AddCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
+    var_AddCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
     var_AddCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
     var_AddCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
 
+    vlc_object_release( p_input_thread );
     vlc_mutex_unlock( &p_mi->object_lock );
 }
 
@@ -616,6 +668,7 @@ void libvlc_media_instance_set_drawable( libvlc_media_instance_t *p_mi,
                                          libvlc_drawable_t drawable,
                                          libvlc_exception_t *p_e )
 {
+    (void)p_e;
     p_mi->drawable = drawable;
 }
 
@@ -625,6 +678,7 @@ void libvlc_media_instance_set_drawable( libvlc_media_instance_t *p_mi,
 libvlc_drawable_t
 libvlc_media_instance_get_drawable ( libvlc_media_instance_t *p_mi, libvlc_exception_t *p_e )
 {
+    (void)p_e;
     return p_mi->drawable;
 }