Commit bbce7c4c authored by Pierre d'Herbemont's avatar Pierre d'Herbemont

libvlc: Make sure the media_player has its own state cached.

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.
parent 71eb5e10
...@@ -684,7 +684,7 @@ static void stop(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e) ...@@ -684,7 +684,7 @@ static void stop(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e)
{ {
assert_locked(p_mlp); 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 */ /* We are not interested in getting media stop event now */
uninstall_media_player_observer(p_mlp); uninstall_media_player_observer(p_mlp);
......
...@@ -155,6 +155,30 @@ input_thread_t *libvlc_get_input_thread( libvlc_media_player_t *p_mi, ...@@ -155,6 +155,30 @@ input_thread_t *libvlc_get_input_thread( libvlc_media_player_t *p_mi,
return p_input_thread; 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 static int
input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd, input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
vlc_value_t oldval, vlc_value_t newval, vlc_value_t oldval, vlc_value_t newval,
...@@ -166,7 +190,6 @@ input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd, ...@@ -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_media_player_t * p_mi = p_userdata;
libvlc_event_t event; libvlc_event_t event;
libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial );
event.type = libvlc_MediaPlayerSeekableChanged; event.type = libvlc_MediaPlayerSeekableChanged;
event.u.media_player_seekable_changed.new_seekable = newval.b_bool; 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, ...@@ -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_media_player_t * p_mi = p_userdata;
libvlc_event_t event; libvlc_event_t event;
libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial );
event.type = libvlc_MediaPlayerPausableChanged; event.type = libvlc_MediaPlayerPausableChanged;
event.u.media_player_pausable_changed.new_pausable = newval.b_bool; event.u.media_player_pausable_changed.new_pausable = newval.b_bool;
...@@ -240,7 +262,7 @@ input_event_changed( vlc_object_t * p_this, char const * psz_cmd, ...@@ -240,7 +262,7 @@ input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
return VLC_SUCCESS; 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 ); libvlc_event_send( p_mi->p_event_manager, &event );
} }
else if( newval.i_int == INPUT_EVENT_ABORT ) else if( newval.i_int == INPUT_EVENT_ABORT )
...@@ -248,7 +270,7 @@ input_event_changed( vlc_object_t * p_this, char const * psz_cmd, ...@@ -248,7 +270,7 @@ input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
libvlc_state_t libvlc_state = libvlc_Stopped; libvlc_state_t libvlc_state = libvlc_Stopped;
event.type = libvlc_MediaPlayerStopped; 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 ); libvlc_event_send( p_mi->p_event_manager, &event );
} }
else if( newval.i_int == INPUT_EVENT_POSITION ) else if( newval.i_int == INPUT_EVENT_POSITION )
...@@ -337,6 +359,7 @@ libvlc_media_player_new( libvlc_instance_t *instance, libvlc_exception_t *e ) ...@@ -337,6 +359,7 @@ libvlc_media_player_new( libvlc_instance_t *instance, libvlc_exception_t *e )
mp->drawable.hwnd = NULL; mp->drawable.hwnd = NULL;
mp->drawable.nsobject = NULL; mp->drawable.nsobject = NULL;
mp->keyboard_events = mp->mouse_events = 1; mp->keyboard_events = mp->mouse_events = 1;
mp->state = libvlc_NothingSpecial;
mp->p_libvlc_instance = instance; mp->p_libvlc_instance = instance;
mp->p_input_thread = NULL; mp->p_input_thread = NULL;
mp->p_input_resource = NULL; mp->p_input_resource = NULL;
...@@ -415,8 +438,13 @@ static void libvlc_media_player_destroy( libvlc_media_player_t *p_mi ) ...@@ -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, var_DelCallback( p_mi->p_libvlc_instance->p_libvlc_int,
"snapshot-file", snapshot_was_taken, p_mi ); "snapshot-file", snapshot_was_taken, p_mi );
/* Release the input thread */ /* If the input thread hasn't been already deleted it means
release_input_thread( p_mi, true ); * 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 ) if( p_mi->p_input_resource )
{ {
...@@ -474,9 +502,6 @@ void libvlc_media_player_set_media( ...@@ -474,9 +502,6 @@ void libvlc_media_player_set_media(
{ {
VLC_UNUSED(p_e); VLC_UNUSED(p_e);
if( !p_mi )
return;
lock(p_mi); lock(p_mi);
/* FIXME I am not sure if it is a user request or on die(eof/error) /* 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( ...@@ -485,9 +510,11 @@ void libvlc_media_player_set_media(
p_mi->p_input_thread && p_mi->p_input_thread &&
!p_mi->p_input_thread->b_eof && !p_mi->p_input_thread->b_eof &&
!p_mi->p_input_thread->b_error ); !p_mi->p_input_thread->b_error );
unlock(p_mi);
if( p_mi->p_md ) set_state( p_mi, libvlc_NothingSpecial );
libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial );
lock(p_mi);
libvlc_media_release( p_mi->p_md ); libvlc_media_release( p_mi->p_md );
...@@ -659,23 +686,21 @@ void libvlc_media_player_stop( libvlc_media_player_t *p_mi, ...@@ -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 ); libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
if( state == libvlc_Playing || lock(p_mi);
state == libvlc_Paused || release_input_thread( p_mi, true ); /* This will stop the input thread */
state == libvlc_Buffering ) 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, set_state( p_mi, libvlc_Stopped );
* buffering or paused states */
libvlc_media_set_state( p_mi->p_md, libvlc_Stopped );
/* Construct and send the event */ /* Construct and send the event */
libvlc_event_t event; libvlc_event_t event;
event.type = libvlc_MediaPlayerStopped; event.type = libvlc_MediaPlayerStopped;
libvlc_event_send( p_mi->p_event_manager, &event ); 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( ...@@ -1081,30 +1106,12 @@ float libvlc_media_player_get_rate(
return f_rate; return f_rate;
} }
libvlc_state_t libvlc_media_player_get_state( libvlc_state_t libvlc_media_player_get_state( libvlc_media_player_t *p_mi, libvlc_exception_t *p_e )
libvlc_media_player_t *p_mi,
libvlc_exception_t *p_e )
{ {
input_thread_t *p_input_thread; VLC_UNUSED(p_e);
libvlc_state_t state = libvlc_Ended; lock(p_mi);
libvlc_state_t state = p_mi->state;
p_input_thread = libvlc_get_input_thread ( p_mi, p_e ); unlock(p_mi);
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 );
return state; return state;
} }
......
...@@ -43,6 +43,7 @@ struct libvlc_media_player_t ...@@ -43,6 +43,7 @@ struct libvlc_media_player_t
struct libvlc_instance_t * p_libvlc_instance; /* Parent instance */ struct libvlc_instance_t * p_libvlc_instance; /* Parent instance */
libvlc_media_t * p_md; /* current media descriptor */ libvlc_media_t * p_md; /* current media descriptor */
libvlc_event_manager_t * p_event_manager; libvlc_event_manager_t * p_event_manager;
libvlc_state_t state;
struct struct
{ {
void *hwnd; void *hwnd;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment