X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Finput.c;h=cc5e82813212de27d1785821d6f8537a86a7bc99;hb=04804702d97e0667fdf05ed3ceeae6759fe732d4;hp=2786b146b60183aeba827030d8f474db71d5280e;hpb=6a938c3c6d2c933cba002cb93c286865def8ba40;p=vlc diff --git a/src/input/input.c b/src/input/input.c index 2786b146b6..cc5e828132 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -43,7 +43,6 @@ #include #include #include -#include #ifdef HAVE_SYS_STAT_H # include @@ -60,7 +59,7 @@ static int RunAndDestroy ( input_thread_t *p_input ); static input_thread_t * Create ( vlc_object_t *, input_item_t *, const char *, bool, sout_instance_t * ); static int Init ( input_thread_t *p_input ); -static void Error ( input_thread_t *p_input ); +static void WaitDie ( input_thread_t *p_input ); static void End ( input_thread_t *p_input ); static void MainLoop( input_thread_t *p_input ); @@ -113,6 +112,7 @@ static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_atta * - seekable (if you can seek, it doesn't say if 'bar display' has be shown * or not, for that check position != 0.0) * - can-pause + * - teletext-es to get the index of spu track that is teletext --1 if no teletext) * * For intf callback upon changes * - intf-change * - rate-change for when playback rate changes @@ -132,16 +132,16 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, p_input = vlc_custom_create( p_parent, sizeof( *p_input ), VLC_OBJECT_INPUT, input_name ); if( p_input == NULL ) - { - msg_Err( p_parent, "out of memory" ); return NULL; - } /* Construct a nice name for the input timer */ char psz_timer_name[255]; char * psz_name = input_item_GetName( p_item ); snprintf( psz_timer_name, sizeof(psz_timer_name), "input launching for '%s'", psz_name ); + + msg_Dbg( p_input, "Creating an input for '%s'", psz_name); + free( psz_name ); /* Start a timer to mesure how long it takes @@ -170,6 +170,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, vlc_event_manager_t * p_em = &p_input->p->event_manager; vlc_event_manager_init_with_vlc_object( p_em, p_input ); vlc_event_manager_register_event_type( p_em, vlc_InputStateChanged ); + vlc_event_manager_register_event_type( p_em, vlc_InputSelectedStreamChanged ); /* Init Common fields */ p_input->b_eof = false; @@ -298,12 +299,12 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, memset( &p_input->p->counters, 0, sizeof( p_input->p->counters ) ); vlc_mutex_init( &p_input->p->counters.counters_lock ); - /* Attach only once we are ready */ - vlc_object_attach( p_input, p_parent ); - /* Set the destructor when we are sure we are initialized */ vlc_object_set_destructor( p_input, (vlc_destructor_t)Destructor ); + /* Attach only once we are ready */ + vlc_object_attach( p_input, p_parent ); + return p_input; } @@ -314,6 +315,12 @@ static void Destructor( input_thread_t * p_input ) { input_thread_private_t *priv = p_input->p; +#ifndef NDEBUG + char * psz_name = input_item_GetName( p_input->p->input.p_item ); + msg_Dbg( p_input, "Destroying the input for '%s'", psz_name); + free( psz_name ); +#endif + vlc_event_manager_fini( &p_input->p->event_manager ); stats_TimerDump( p_input, STATS_TIMER_INPUT_LAUNCHING ); @@ -437,41 +444,29 @@ int __input_Preparse( vlc_object_t *p_parent, input_item_t *p_item ) * * \param the input thread to stop */ -void input_StopThread( input_thread_t *p_input ) +static void ObjectKillChildrens( input_thread_t *p_input, vlc_object_t *p_obj ) { vlc_list_t *p_list; int i; - /* Set die for input */ - vlc_object_kill( p_input ); - /* FIXME: seems to be duplicated in ControlPush(INPUT_CONTROL_SET_DIE) */ - - /* We cannot touch p_input fields directly (we come from another thread), - * so use the vlc_object_find way, it's perfectly safe */ - - /* Set die for all access */ - p_list = vlc_list_find( p_input, VLC_OBJECT_ACCESS, FIND_CHILD ); - for( i = 0; i < p_list->i_count; i++ ) - { - vlc_object_kill( p_list->p_values[i].p_object ); - } - vlc_list_release( p_list ); + if( p_obj->i_object_type == VLC_OBJECT_VOUT || + p_obj->i_object_type == VLC_OBJECT_AOUT || + p_obj == VLC_OBJECT(p_input->p->p_sout) ) + return; - /* Set die for all stream */ - p_list = vlc_list_find( p_input, VLC_OBJECT_STREAM, FIND_CHILD ); - for( i = 0; i < p_list->i_count; i++ ) - { - vlc_object_kill( p_list->p_values[i].p_object ); - } - vlc_list_release( p_list ); + vlc_object_kill( p_obj ); - /* Set die for all demux */ - p_list = vlc_list_find( p_input, VLC_OBJECT_DEMUX, FIND_CHILD ); + p_list = vlc_list_children( p_obj ); for( i = 0; i < p_list->i_count; i++ ) - { - vlc_object_kill( p_list->p_values[i].p_object ); - } + ObjectKillChildrens( p_input, p_list->p_values[i].p_object ); vlc_list_release( p_list ); +} +void input_StopThread( input_thread_t *p_input ) +{ + /* 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 + * unlock the control loop */ + ObjectKillChildrens( p_input, VLC_OBJECT(p_input) ); input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL ); } @@ -499,16 +494,7 @@ static int Run( input_thread_t *p_input ) /* If we failed, wait before we are killed, and exit */ p_input->b_error = true; - /* FIXME: we don't want to depend on the playlist */ - playlist_t * p_playlist = vlc_object_find( p_input, - VLC_OBJECT_PLAYLIST, FIND_PARENT ); - if( p_playlist ) - { - playlist_Signal( p_playlist ); - vlc_object_release( p_playlist ); - } - - Error( p_input ); + WaitDie( p_input ); /* Tell we're dead */ p_input->b_dead = true; @@ -533,13 +519,13 @@ static int Run( input_thread_t *p_input ) /* We have finished */ p_input->b_eof = true; - playlist_Signal( libvlc_priv (p_input->p_libvlc)->p_playlist ); + input_ChangeState( p_input, END_S ); } /* Wait until we are asked to die */ if( !p_input->b_die ) { - Error( p_input ); + WaitDie( p_input ); } /* Clean up */ @@ -644,7 +630,6 @@ static void MainLoop( input_thread_t *p_input ) { /* End of file - we do not set b_die because only the * playlist is allowed to do so. */ - input_ChangeState( p_input, END_S ); msg_Dbg( p_input, "EOF reached" ); p_input->p->input.b_eof = true; } @@ -1277,13 +1262,13 @@ error: } /***************************************************************************** - * Error: RunThread() error loop + * WaitDie: Wait until we are asked to die. ***************************************************************************** * This function is called when an error occurred during thread main's loop. *****************************************************************************/ -static void Error( input_thread_t *p_input ) +static void WaitDie( input_thread_t *p_input ) { - input_ChangeState( p_input, ERROR_S ); + input_ChangeState( p_input, p_input->b_error ? ERROR_S : END_S ); while( !p_input->b_die ) { /* Sleep a while */ @@ -1302,7 +1287,7 @@ static void End( input_thread_t * p_input ) input_ChangeState( p_input, END_S ); /* Clean control variables */ - input_ControlVarClean( p_input ); + input_ControlVarStop( p_input ); /* Clean up master */ InputSourceClean( &p_input->p->input ); @@ -1456,14 +1441,9 @@ static bool Control( input_thread_t *p_input, int i_type, { case INPUT_CONTROL_SET_DIE: msg_Dbg( p_input, "control: stopping input" ); - /* Mark all submodules to die */ - if( p_input->p->input.p_access ) - vlc_object_kill( p_input->p->input.p_access ); - if( p_input->p->input.p_stream ) - vlc_object_kill( p_input->p->input.p_stream ); - vlc_object_kill( p_input->p->input.p_demux ); - vlc_object_kill( p_input ); + /* Mark all submodules to die */ + ObjectKillChildrens( p_input, VLC_OBJECT(p_input) ); break; case INPUT_CONTROL_SET_POSITION: @@ -1578,9 +1558,7 @@ static bool Control( input_thread_t *p_input, int i_type, b_force_update = true; /* Switch to play */ - p_input->i_state = PLAYING_S; - val.i_int = PLAYING_S; - var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); + input_ChangeStateWithVarCallback( p_input, PLAYING_S, false ); /* */ if( !i_ret ) @@ -1589,7 +1567,7 @@ static bool Control( input_thread_t *p_input, int i_type, else if( val.i_int == PAUSE_S && p_input->i_state == PLAYING_S && p_input->p->b_can_pause ) { - int i_ret; + int i_ret, state; if( p_input->p->input.p_access ) i_ret = access_Control( p_input->p->input.p_access, ACCESS_SET_PAUSE_STATE, true ); @@ -1602,16 +1580,15 @@ static bool Control( input_thread_t *p_input, int i_type, if( i_ret ) { msg_Warn( p_input, "cannot set pause state" ); - val.i_int = p_input->i_state; + state = p_input->i_state; } else { - val.i_int = PAUSE_S; + state = PAUSE_S; } /* Switch to new state */ - p_input->i_state = val.i_int; - var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); + input_ChangeStateWithVarCallback( p_input, state, false ); /* */ if( !i_ret ) @@ -1622,8 +1599,7 @@ static bool Control( input_thread_t *p_input, int i_type, b_force_update = true; /* Correct "state" value */ - val.i_int = p_input->i_state; - var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); + input_ChangeStateWithVarCallback( p_input, p_input->i_state, false ); } else if( val.i_int != PLAYING_S && val.i_int != PAUSE_S ) { @@ -2864,3 +2840,12 @@ bool input_AddSubtitles( input_thread_t *p_input, char *psz_subtitle, return true; } + +/***************************************************************************** + * input_get_event_manager + *****************************************************************************/ +vlc_event_manager_t * +input_get_event_manager( input_thread_t *p_input ) +{ + return &p_input->p->event_manager; +}