INPUT_EVENT_STATE,
/* b_dead is true */
INPUT_EVENT_DEAD,
+ /* a *user* abort has been requested */
+ INPUT_EVENT_ABORT,
/* "rate" has changed */
INPUT_EVENT_RATE,
* Prototypes
*****************************************************************************/
-/* input_CreateThread
- * Release the returned input_thread_t using vlc_object_release() */
+/**
+ * It will create a new input thread.
+ *
+ * You must call input_StopThread() on it and then vlc_object_release().
+ */
#define input_CreateThread(a,b) __input_CreateThread(VLC_OBJECT(a),b)
VLC_EXPORT( input_thread_t *, __input_CreateThread, ( vlc_object_t *, input_item_t * ) );
-VLC_EXPORT( void, input_StopThread, ( input_thread_t * ) );
+/**
+ * It will ask a input_thread_t to stop.
+ *
+ * b_abort must be true when a user stop is requested and not because you have
+ * detected an error or an eof. It will be used to properly send the
+ * INPUT_EVENT_ABORT event.
+ */
+VLC_EXPORT( void, input_StopThread, ( input_thread_t *, bool b_abort ) );
#define input_Read(a,b,c) __input_Read(VLC_OBJECT(a),b, c)
VLC_EXPORT( int, __input_Read, ( vlc_object_t *, input_item_t *, bool ) );
{
if( p_sd->p_sys->pp_input[i] )
{
- input_StopThread( p_sd->p_sys->pp_input[i] );
+ input_StopThread( p_sd->p_sys->pp_input[i], true );
vlc_object_release( p_sd->p_sys->pp_input[i] );
p_sd->p_sys->pp_input[i] = NULL;
}
if( p_sd->p_sys->pp_input[i]->b_eof
|| p_sd->p_sys->pp_input[i]->b_error )
{
- input_StopThread( p_sd->p_sys->pp_input[i] );
+ input_StopThread( p_sd->p_sys->pp_input[i], false );
vlc_object_release( p_sd->p_sys->pp_input[i] );
p_sd->p_sys->pp_input[i] = NULL;
REMOVE_ELEM( p_sys->pp_input, p_sys->i_input, i );
*
* Object lock is NOT held.
*/
-static void release_input_thread( libvlc_media_player_t *p_mi )
+static void release_input_thread( libvlc_media_player_t *p_mi, bool b_input_abort )
{
input_thread_t * p_input_thread;
input_event_changed, p_mi );
/* We owned this one */
- input_StopThread( p_input_thread );
+ input_StopThread( p_input_thread, b_input_abort );
vlc_thread_join( p_input_thread );
var_Destroy( p_input_thread, "drawable-hwnd" );
vlc_mutex_unlock( &p_mi->object_lock );
vlc_mutex_destroy( &p_mi->object_lock );
- release_input_thread( p_mi );
+ release_input_thread( p_mi, true );
libvlc_event_manager_release( p_mi->p_event_manager );
vlc_mutex_lock( &p_mi->object_lock );
- release_input_thread( p_mi );
+ /* FIXME I am not sure if it is a user request or on die(eof/error)
+ * request here */
+ release_input_thread( p_mi,
+ p_mi->p_input_thread &&
+ !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 );
if( p_mi->b_own_its_input_thread )
{
vlc_mutex_lock( &p_mi->object_lock );
- release_input_thread( p_mi ); /* This will stop the input thread */
+ release_input_thread( p_mi, true ); /* This will stop the input thread */
vlc_mutex_unlock( &p_mi->object_lock );
}
else
if( !p_input_thread )
return;
- input_StopThread( p_input_thread );
+ input_StopThread( p_input_thread, true );
vlc_object_release( p_input_thread );
}
}
Trigger( p_input, INPUT_EVENT_DEAD );
}
+void input_SendEventAbort( input_thread_t *p_input )
+{
+ Trigger( p_input, INPUT_EVENT_ABORT );
+}
void input_SendEventTimes( input_thread_t *p_input,
double f_position, mtime_t i_time, mtime_t i_length )
* Event for input.c
*****************************************************************************/
void input_SendEventDead( input_thread_t *p_input );
+void input_SendEventAbort( input_thread_t *p_input );
void input_SendEventTimes( input_thread_t *p_input, double f_position, mtime_t i_time, mtime_t i_length );
void input_SendEventStatistics( input_thread_t *p_input );
void input_SendEventRate( input_thread_t *p_input, int i_rate );
*
* \param the input thread to stop
*/
-void input_StopThread( input_thread_t *p_input )
+void input_StopThread( input_thread_t *p_input, bool b_abort )
{
/* Set die for input and ALL of this childrens (even (grand-)grand-childrens)
* It is needed here even if it is done in INPUT_CONTROL_SET_DIE handler to
ObjectKillChildrens( p_input, VLC_OBJECT(p_input) );
input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
+ if( b_abort )
+ input_SendEventAbort( p_input );
}
input_resource_t *input_DetachResource( input_thread_t *p_input )
while( !p_input->b_eof && !p_input->b_error )
msleep( 100000 );
- input_StopThread( p_input );
+ input_StopThread( p_input, false );
vlc_thread_join( p_input );
vlc_object_release( p_input );
}
{
input_resource_t *p_resource;
- input_StopThread( p_input );
+ input_StopThread( p_input, true );
vlc_thread_join( p_input );
p_resource = input_DetachResource( p_input );
return VLC_SUCCESS;
}
- input_StopThread( p_input );
+ input_StopThread( p_input, !p_input->b_eof && !p_input->b_error );
vlc_thread_join( p_input );
p_instance->p_input_resource = input_DetachResource( p_input );
pl_priv(p_playlist)->request.i_skip = 0;
pl_priv(p_playlist)->request.p_item = p_toplay;
if( pl_priv(p_playlist)->p_input )
- input_StopThread( pl_priv(p_playlist)->p_input );
+ input_StopThread( pl_priv(p_playlist)->p_input, true );
pl_priv(p_playlist)->request.i_status = PLAYLIST_RUNNING;
vlc_cond_signal( &pl_priv(p_playlist)->signal );
}
if( ( p_sys->request.b_request || !vlc_object_alive( p_playlist ) ) && !p_input->b_die )
{
PL_DEBUG( "incoming request - stopping current input" );
- input_StopThread( p_input );
+ input_StopThread( p_input, true );
}
/* This input is dead. Remove it ! */
else if( p_input->b_error || p_input->b_eof )
{
PL_DEBUG( "finished input" );
- input_StopThread( p_input );
+ input_StopThread( p_input, false );
}
return VLC_SUCCESS;
}