]> git.sesse.net Git - vlc/commitdiff
libvlc: Make sure the media_player has its own state cached.
authorPierre d'Herbemont <pdherbemont@free.fr>
Mon, 7 Dec 2009 19:35:10 +0000 (20:35 +0100)
committerPierre d'Herbemont <pdherbemont@free.fr>
Mon, 7 Dec 2009 20:49:31 +0000 (21:49 +0100)
A weirdness was introduced somehow. We were relying on the media state. (!)

Also, make sure that we always require stop() to be called when the media_player is destroyed. This may prevent some unwanted bad usage, whose consequence might be that _release() will block on input thread destruction.

src/control/media_list_player.c
src/control/media_player.c
src/control/media_player_internal.h

index 7f300205c9d9717a7fb6f1dbce9054c4e9dba910..c574030698216211b05832d335962d6a3eb7aac7 100644 (file)
@@ -684,7 +684,7 @@ static void stop(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e)
 {
     assert_locked(p_mlp);
 
-    if (p_mlp->p_mi && p_mlp->current_playing_item_path)
+    if (p_mlp->p_mi)
     {
         /* We are not interested in getting media stop event now */
         uninstall_media_player_observer(p_mlp);
index 0a07ce141a4276fc4984275a1d08836dd90b0c41..074b1e00ac15032882e4677aa8b4af573d5e70a7 100644 (file)
@@ -155,6 +155,30 @@ input_thread_t *libvlc_get_input_thread( libvlc_media_player_t *p_mi,
     return p_input_thread;
 }
 
+/*
+ * Set the internal state of the media_player. (media player Internal)
+ *
+ * Function will lock the media_player.
+ */
+static void set_state( libvlc_media_player_t *p_mi, libvlc_state_t state )
+{    
+    lock(p_mi);
+    p_mi->state = state;
+    libvlc_media_t *media = p_mi->p_md;
+    if (media)
+        libvlc_media_retain(media);
+    unlock(p_mi);
+
+
+    if (media) {
+        // Also set the state of the corresponding media
+        // This is strictly for convenience.
+        libvlc_media_set_state(media, state);
+        
+        libvlc_media_release(media);        
+    }
+}
+
 static int
 input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
                         vlc_value_t oldval, vlc_value_t newval,
@@ -166,7 +190,6 @@ input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
     libvlc_media_player_t * p_mi = p_userdata;
     libvlc_event_t event;
 
-    libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial );
     event.type = libvlc_MediaPlayerSeekableChanged;
     event.u.media_player_seekable_changed.new_seekable = newval.b_bool;
 
@@ -185,7 +208,6 @@ input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
     libvlc_media_player_t * p_mi = p_userdata;
     libvlc_event_t event;
 
-    libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial );
     event.type = libvlc_MediaPlayerPausableChanged;
     event.u.media_player_pausable_changed.new_pausable = newval.b_bool;
 
@@ -239,8 +261,8 @@ input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
             default:
                 return VLC_SUCCESS;
         }
-
-        libvlc_media_set_state( p_mi->p_md, libvlc_state );
+        
+        set_state( p_mi, libvlc_state );
         libvlc_event_send( p_mi->p_event_manager, &event );
     }
     else if( newval.i_int == INPUT_EVENT_ABORT )
@@ -248,7 +270,7 @@ input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
         libvlc_state_t libvlc_state = libvlc_Stopped;
         event.type = libvlc_MediaPlayerStopped;
 
-        libvlc_media_set_state( p_mi->p_md, libvlc_state );
+        set_state( p_mi, libvlc_state );
         libvlc_event_send( p_mi->p_event_manager, &event );
     }
     else if( newval.i_int == INPUT_EVENT_POSITION )
@@ -337,6 +359,7 @@ libvlc_media_player_new( libvlc_instance_t *instance, libvlc_exception_t *e )
     mp->drawable.hwnd = NULL;
     mp->drawable.nsobject = NULL;
     mp->keyboard_events = mp->mouse_events = 1;
+    mp->state = libvlc_NothingSpecial;
     mp->p_libvlc_instance = instance;
     mp->p_input_thread = NULL;
     mp->p_input_resource = NULL;
@@ -415,8 +438,13 @@ static void libvlc_media_player_destroy( libvlc_media_player_t *p_mi )
     var_DelCallback( p_mi->p_libvlc_instance->p_libvlc_int,
                      "snapshot-file", snapshot_was_taken, p_mi );
 
-    /* Release the input thread */
-    release_input_thread( p_mi, true );
+    /* If the input thread hasn't been already deleted it means
+     * that the owners didn't stop the thread before releasing it. */
+    assert(!p_mi->p_input_thread);
+
+    /* Fallback for those who don't use NDEBUG */
+    if (p_mi->p_input_thread)
+        release_input_thread(p_mi, true);
 
     if( p_mi->p_input_resource )
     {
@@ -474,9 +502,6 @@ void libvlc_media_player_set_media(
 {
     VLC_UNUSED(p_e);
 
-    if( !p_mi )
-        return;
-
     lock(p_mi);
 
     /* FIXME I am not sure if it is a user request or on die(eof/error)
@@ -485,9 +510,11 @@ void libvlc_media_player_set_media(
                           p_mi->p_input_thread &&
                           !p_mi->p_input_thread->b_eof &&
                           !p_mi->p_input_thread->b_error );
+    unlock(p_mi);
 
-    if( p_mi->p_md )
-        libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial );
+    set_state( p_mi, libvlc_NothingSpecial );
+
+    lock(p_mi);
 
     libvlc_media_release( p_mi->p_md );
 
@@ -659,23 +686,21 @@ void libvlc_media_player_stop( libvlc_media_player_t *p_mi,
 {
     libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
 
-    if( state == libvlc_Playing ||
-        state == libvlc_Paused ||
-        state == libvlc_Buffering )
+    lock(p_mi);
+    release_input_thread( p_mi, true ); /* This will stop the input thread */
+    unlock(p_mi);
+
+    /* Force to go to stopped state, in case we were in Ended, or Error
+     * state. */
+    if( state != libvlc_Stopped )
     {
-        /* Send a stop notification event only if we are in playing,
-         * buffering or paused states */
-        libvlc_media_set_state( p_mi->p_md, libvlc_Stopped );
+        set_state( p_mi, libvlc_Stopped );
 
         /* Construct and send the event */
         libvlc_event_t event;
         event.type = libvlc_MediaPlayerStopped;
         libvlc_event_send( p_mi->p_event_manager, &event );
     }
-
-    lock(p_mi);
-    release_input_thread( p_mi, true ); /* This will stop the input thread */
-    unlock(p_mi);
 }
 
 /**************************************************************************
@@ -1081,30 +1106,12 @@ float libvlc_media_player_get_rate(
     return f_rate;
 }
 
-libvlc_state_t libvlc_media_player_get_state(
-                                 libvlc_media_player_t *p_mi,
-                                 libvlc_exception_t *p_e )
+libvlc_state_t libvlc_media_player_get_state( libvlc_media_player_t *p_mi, libvlc_exception_t *p_e )
 {
-    input_thread_t *p_input_thread;
-    libvlc_state_t state = libvlc_Ended;
-
-    p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
-    if( !p_input_thread )
-    {
-        /* We do return the right value, no need to throw an exception */
-        clear_if_needed(p_e);
-        return state;
-    }
-
-    state = libvlc_media_get_state( p_mi->p_md );
-    if( state == libvlc_Playing )
-    {
-        float caching;
-        caching = var_GetFloat( p_input_thread, "cache" );
-        if( caching > 0.0 && caching < 1.0 )
-            state = libvlc_Buffering;
-    }
-    vlc_object_release( p_input_thread );
+    VLC_UNUSED(p_e);
+    lock(p_mi);
+    libvlc_state_t state = p_mi->state;
+    unlock(p_mi);
     return state;
 }
 
index efdd95c282b373b15380c9f2737204c8958f79f0..955491c5e581881f0e13850462a2d6e779027bf7 100644 (file)
@@ -43,6 +43,7 @@ struct libvlc_media_player_t
     struct libvlc_instance_t * p_libvlc_instance; /* Parent instance */
     libvlc_media_t * p_md; /* current media descriptor */
     libvlc_event_manager_t * p_event_manager;
+    libvlc_state_t state;
     struct
     {
         void *hwnd;