]> git.sesse.net Git - vlc/blobdiff - src/input/input.c
macosx: Ask to send a mail to our bugreport ML if a crash log is detected.
[vlc] / src / input / input.c
index c954bb5e13f32438c8a6078e7bb744d0d4766368..cc5e82813212de27d1785821d6f8537a86a7bc99 100644 (file)
@@ -59,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 );
 
@@ -112,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
@@ -131,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
@@ -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,7 +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;
 
-        Error( p_input );
+        WaitDie( p_input );
 
         /* Tell we're dead */
         p_input->b_dead = true;
@@ -530,7 +525,7 @@ static int Run( input_thread_t *p_input )
     /* Wait until we are asked to die */
     if( !p_input->b_die )
     {
-        Error( p_input );
+        WaitDie( p_input );
     }
 
     /* Clean up */
@@ -1267,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 */
@@ -1292,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 );
@@ -1446,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:
@@ -1568,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 )
@@ -1579,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 );
@@ -1592,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 )
@@ -1612,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 )
             {