#define register_event(a, b) __register_event(a, libvlc_MediaPlayer ## b)
static inline void __register_event(libvlc_media_player_t *mp, libvlc_event_type_t type)
{
- libvlc_event_manager_register_event_type(mp->p_event_manager, type, NULL);
+ libvlc_event_manager_register_event_type(mp->p_event_manager, type);
}
static inline void lock(libvlc_media_player_t *mp)
vlc_mutex_unlock(&mp->object_lock);
}
-static inline void clear_if_needed(libvlc_exception_t *e)
-{
- if (libvlc_exception_raised(e))
- libvlc_exception_clear(e);
-}
-
/*
* Release the associated 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,
+ bool b_locked )
+{
+ if(!b_locked)
+ lock(p_mi);
+ p_mi->state = state;
+ libvlc_media_t *media = p_mi->p_md;
+ if (media)
+ libvlc_media_retain(media);
+ if(!b_locked)
+ 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,
libvlc_media_player_t * p_mi = p_userdata;
libvlc_event_t event;
- libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
event.type = libvlc_MediaPlayerSeekableChanged;
event.u.media_player_seekable_changed.new_seekable = newval.b_bool;
libvlc_media_player_t * p_mi = p_userdata;
libvlc_event_t event;
- libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
event.type = libvlc_MediaPlayerPausableChanged;
event.u.media_player_pausable_changed.new_pausable = newval.b_bool;
return VLC_SUCCESS;
}
- libvlc_media_set_state( p_mi->p_md, libvlc_state, NULL );
+ set_state( p_mi, libvlc_state, false );
libvlc_event_send( p_mi->p_event_manager, &event );
}
else if( newval.i_int == INPUT_EVENT_ABORT )
libvlc_state_t libvlc_state = libvlc_Stopped;
event.type = libvlc_MediaPlayerStopped;
- libvlc_media_set_state( p_mi->p_md, libvlc_state, NULL );
+ set_state( p_mi, libvlc_state, false );
libvlc_event_send( p_mi->p_event_manager, &event );
}
else if( newval.i_int == INPUT_EVENT_POSITION )
/* */
event.type = libvlc_MediaPlayerTimeChanged;
event.u.media_player_time_changed.new_time =
- var_GetTime( p_input, "time" );
+ from_mtime(var_GetTime( p_input, "time" ));
libvlc_event_send( p_mi->p_event_manager, &event );
}
else if( newval.i_int == INPUT_EVENT_LENGTH )
{
event.type = libvlc_MediaPlayerLengthChanged;
event.u.media_player_length_changed.new_length =
- var_GetTime( p_input, "length" );
+ from_mtime(var_GetTime( p_input, "length" ));
libvlc_event_send( p_mi->p_event_manager, &event );
}
mp->drawable.xid = 0;
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;
mp->i_refcount = 1;
- vlc_mutex_init(&mp->object_lock);
- mp->p_event_manager = libvlc_event_manager_new(mp, instance, e);
- if (libvlc_exception_raised(e))
+ mp->p_event_manager = libvlc_event_manager_new(mp, instance);
+ if (unlikely(mp->p_event_manager == NULL))
{
- vlc_mutex_destroy(&mp->object_lock);
free(mp);
return NULL;
}
+ vlc_mutex_init(&mp->object_lock);
register_event(mp, NothingSpecial);
register_event(mp, Opening);
register_event(mp, Backward);
register_event(mp, EndReached);
register_event(mp, EncounteredError);
+ register_event(mp, SeekableChanged);
register_event(mp, PositionChanged);
register_event(mp, TimeChanged);
/* Snapshot initialization */
register_event(mp, SnapshotTaken);
+ register_event(mp, MediaChanged);
+
/* Attach a var callback to the global object to provide the glue between
* vout_thread that generates the event and media_player that re-emits it
* with its own event manager
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 )
{
input_resource_Delete( p_mi->p_input_resource );
- p_mi->p_input_resource = NULL;
+ p_mi->p_input_resource = NULL;
}
libvlc_event_manager_release( p_mi->p_event_manager );
**************************************************************************/
void libvlc_media_player_set_media(
libvlc_media_player_t *p_mi,
- libvlc_media_t *p_md,
- libvlc_exception_t *p_e )
+ libvlc_media_t *p_md )
{
- 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)
!p_mi->p_input_thread->b_eof &&
!p_mi->p_input_thread->b_error );
- if( p_mi->p_md )
- libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, p_e );
+ set_state( p_mi, libvlc_NothingSpecial, true );
libvlc_media_release( p_mi->p_md );
p_mi->p_libvlc_instance = p_md->p_libvlc_instance;
unlock(p_mi);
+
+ /* Send an event for the newly available media */
+ libvlc_event_t event;
+ event.type = libvlc_MediaPlayerMediaChanged;
+ event.u.media_player_media_changed.new_media = p_md;
+ libvlc_event_send( p_mi->p_event_manager, &event );
+
}
/**************************************************************************
* Get the Media descriptor associated with the instance.
**************************************************************************/
libvlc_media_t *
-libvlc_media_player_get_media(
- libvlc_media_player_t *p_mi,
- libvlc_exception_t *p_e )
+libvlc_media_player_get_media( libvlc_media_player_t *p_mi )
{
libvlc_media_t *p_m;
- VLC_UNUSED(p_e);
lock(p_mi);
p_m = p_mi->p_md;
* Get the event Manager.
**************************************************************************/
libvlc_event_manager_t *
-libvlc_media_player_event_manager(
- libvlc_media_player_t *p_mi,
- libvlc_exception_t *p_e )
+libvlc_media_player_event_manager( libvlc_media_player_t *p_mi )
{
- VLC_UNUSED(p_e);
-
return p_mi->p_event_manager;
}
if( p_mi->drawable.nsobject != NULL )
var_SetAddress( p_input_thread, "drawable-nsobject", p_mi->drawable.nsobject );
+ var_Create( p_input_thread, "keyboard-events", VLC_VAR_BOOL );
+ var_SetBool( p_input_thread, "keyboard-events", p_mi->keyboard_events );
+ var_Create( p_input_thread, "mouse-events", VLC_VAR_BOOL );
+ var_SetBool( p_input_thread, "mouse-events", p_mi->mouse_events );
+
var_AddCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi );
var_AddCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi );
var_AddCallback( p_input_thread, "intf-event", input_event_changed, p_mi );
if( !p_input_thread )
return;
- libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
+ libvlc_state_t state = libvlc_media_player_get_state( p_mi );
if( state == libvlc_Playing || state == libvlc_Buffering )
{
if( libvlc_media_player_can_pause( p_mi, p_e ) )
input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
else
- libvlc_media_player_stop( p_mi, p_e );
+ libvlc_media_player_stop( p_mi );
}
else
input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
*
* Enter with lock held.
**************************************************************************/
-int libvlc_media_player_is_playing( libvlc_media_player_t *p_mi,
- libvlc_exception_t *p_e )
+int libvlc_media_player_is_playing( 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 );
return (libvlc_Playing == state) || (libvlc_Buffering == state);
}
/**************************************************************************
* Stop playing.
**************************************************************************/
-void libvlc_media_player_stop( libvlc_media_player_t *p_mi,
- libvlc_exception_t *p_e )
+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 );
+
+ lock(p_mi);
+ release_input_thread( p_mi, true ); /* This will stop the input thread */
+ unlock(p_mi);
- if( state == libvlc_Playing ||
- state == libvlc_Paused ||
- state == libvlc_Buffering )
+ /* 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, p_e );
+ set_state( p_mi, libvlc_Stopped, false );
/* 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);
}
/**************************************************************************
* set_nsobject
**************************************************************************/
void libvlc_media_player_set_nsobject( libvlc_media_player_t *p_mi,
- void * drawable,
- libvlc_exception_t *p_e )
+ void * drawable )
{
- (void) p_e;
p_mi->drawable.nsobject = drawable;
}
* set_agl
**************************************************************************/
void libvlc_media_player_set_agl( libvlc_media_player_t *p_mi,
- uint32_t drawable,
- libvlc_exception_t *p_e )
+ uint32_t drawable )
{
- (void) p_e;
p_mi->drawable.agl = drawable;
}
* set_xwindow
**************************************************************************/
void libvlc_media_player_set_xwindow( libvlc_media_player_t *p_mi,
- uint32_t drawable,
- libvlc_exception_t *p_e )
+ uint32_t drawable )
{
- (void) p_e;
p_mi->drawable.xid = drawable;
}
* set_hwnd
**************************************************************************/
void libvlc_media_player_set_hwnd( libvlc_media_player_t *p_mi,
- void *drawable,
- libvlc_exception_t *p_e )
+ void *drawable )
{
- (void) p_e;
p_mi->drawable.hwnd = drawable;
}
if( !p_input_thread )
return -1;
- i_time = var_GetTime( p_input_thread, "length" );
+ i_time = from_mtime(var_GetTime( p_input_thread, "length" ));
vlc_object_release( p_input_thread );
- return (i_time+500LL)/1000LL;
+ return i_time;
}
libvlc_time_t libvlc_media_player_get_time(
if( !p_input_thread )
return -1;
- i_time = var_GetTime( p_input_thread , "time" );
+ i_time = from_mtime(var_GetTime( p_input_thread , "time" ));
vlc_object_release( p_input_thread );
- return (i_time+500LL)/1000LL;
+ return i_time;
}
void libvlc_media_player_set_time(
if( !p_input_thread )
return;
- var_SetTime( p_input_thread, "time", i_time*1000LL );
+ var_SetTime( p_input_thread, "time", to_mtime(i_time) );
vlc_object_release( p_input_thread );
}
int libvlc_media_player_will_play( libvlc_media_player_t *p_mi,
libvlc_exception_t *p_e)
{
+ bool b_will_play;
input_thread_t *p_input_thread =
libvlc_get_input_thread ( p_mi, p_e);
if ( !p_input_thread )
return false;
- if ( !p_input_thread->b_die && !p_input_thread->b_dead )
- {
- vlc_object_release( p_input_thread );
- return true;
- }
+ b_will_play = !p_input_thread->b_die && !p_input_thread->b_dead;
vlc_object_release( p_input_thread );
- return false;
+
+ return b_will_play;
}
void libvlc_media_player_set_rate(
return;
}
- var_SetInteger( p_input_thread, "rate", 1000.0f/rate );
+ var_SetFloat( p_input_thread, "rate", rate );
vlc_object_release( p_input_thread );
}
libvlc_exception_t *p_e )
{
input_thread_t *p_input_thread;
- int i_rate;
+ float f_rate;
bool b_can_rewind;
p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
if( !p_input_thread )
return 0.0; /* rate < 0 indicates rewind */
- i_rate = var_GetInteger( p_input_thread, "rate" );
+ f_rate = var_GetFloat( p_input_thread, "rate" );
b_can_rewind = var_GetBool( p_input_thread, "can-rewind" );
- if( i_rate < 0 && !b_can_rewind )
+ /* FIXME: why are negative values forbidden ?? (rewinding) */
+ if( f_rate < 0 && !b_can_rewind )
{
vlc_object_release( p_input_thread );
return 0.0;
}
vlc_object_release( p_input_thread );
- return (float)1000.0f/i_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 )
{
- 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, NULL );
- 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 );
+ lock(p_mi);
+ libvlc_state_t state = p_mi->state;
+ unlock(p_mi);
return state;
}
libvlc_printerr( "No active input" );
}
}
+
+/**************************************************************************
+ * get_input_thread (Public API version)
+ **************************************************************************/
+struct input_thread_t *libvlc_media_player_get_input_thread( libvlc_media_player_t *player )
+{
+ libvlc_exception_t e;
+ libvlc_exception_init(&e);
+ input_thread_t *input = libvlc_get_input_thread(player, &e);
+ clear_if_needed(&e);
+ return input;
+}