]> git.sesse.net Git - vlc/blobdiff - src/input/input.c
Remove vlc_object_find for playlist from the core
[vlc] / src / input / input.c
index 7b8cbcf030fe4baded4b71a48d981d6e9ae02a69..26c85aa325a7bdcb33dee35c30ad545bc7fe9658 100644 (file)
@@ -40,6 +40,8 @@
 #include "vlc_interface.h"
 #include "vlc_interaction.h"
 
+#include "charset.h"
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -322,7 +324,7 @@ int __input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
 
     /* Allocate descriptor */
     p_input = Create( p_parent, p_item, NULL, VLC_TRUE );
-    p_input->i_flags |= OBJECT_FLAGS_NODBG;
+    p_input->i_flags |= OBJECT_FLAGS_QUIET;
     p_input->i_flags |= OBJECT_FLAGS_NOINTERACT;
 
     /* Now we can attach our new input */
@@ -445,7 +447,7 @@ static int Run( input_thread_t *p_input )
         p_input->b_eof = VLC_TRUE;
     }
 
-    /* Wait we are asked to die */
+    /* Wait until we are asked to die */
     if( !p_input->b_die )
     {
         Error( p_input );
@@ -477,7 +479,7 @@ static int RunAndClean( input_thread_t *p_input )
 
     if( !p_input->b_eof && !p_input->b_error && p_input->input.b_eof )
     {
-        /* We have finish to demux data but not to play them */
+        /* We have finished demuxing data but not playing it */
         while( !p_input->b_die )
         {
             if( input_EsOutDecodersEmpty( p_input->p_es_out ) )
@@ -487,6 +489,7 @@ static int RunAndClean( input_thread_t *p_input )
 
             msleep( INPUT_IDLE_SLEEP );
         }
+
         /* We have finished */
         p_input->b_eof = VLC_TRUE;
     }
@@ -676,32 +679,35 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
      * (this will break playing of file starting by 'vlc:' but I don't
      * want to add more logic, just force file by file:// or code it ;)
      */
+    memset( &p_input->counters, 0, sizeof( p_input->counters ) );
     if( !b_quick )
     {
         /* Prepare statistics */
-        counter_t *p_counter;
-        stats_Create( p_input, "read_bytes", STATS_READ_BYTES,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
-        stats_Create( p_input, "read_packets", STATS_READ_PACKETS,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
-        stats_Create( p_input, "demux_read", STATS_DEMUX_READ,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
-        stats_Create( p_input, "input_bitrate", STATS_INPUT_BITRATE,
-                      VLC_VAR_FLOAT, STATS_DERIVATIVE );
-        stats_Create( p_input, "demux_bitrate", STATS_DEMUX_BITRATE,
-                      VLC_VAR_FLOAT,  STATS_DERIVATIVE );
-
-        p_counter = stats_CounterGet( p_input, p_input->i_object_id,
-                                      STATS_INPUT_BITRATE );
-        if( p_counter ) p_counter->update_interval = 1000000;
-        p_counter = stats_CounterGet( p_input, p_input->i_object_id,
-                                      STATS_DEMUX_BITRATE );
-        if( p_counter ) p_counter->update_interval = 1000000;
-
-        stats_Create( p_input, "played_abuffers", STATS_PLAYED_ABUFFERS,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
-        stats_Create( p_input, "lost_abuffers", STATS_LOST_ABUFFERS,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
+#define INIT_COUNTER( p, type, compute ) p_input->counters.p_##p = \
+     stats_CounterCreate( p_input, VLC_VAR_##type, STATS_##compute);
+        if( p_input->p_libvlc->b_stats )
+        {
+            INIT_COUNTER( read_bytes, INTEGER, COUNTER );
+            INIT_COUNTER( read_packets, INTEGER, COUNTER );
+            INIT_COUNTER( demux_read, INTEGER, COUNTER );
+            INIT_COUNTER( input_bitrate, FLOAT, DERIVATIVE );
+            INIT_COUNTER( demux_bitrate, FLOAT, DERIVATIVE );
+            INIT_COUNTER( played_abuffers, INTEGER, COUNTER );
+            INIT_COUNTER( lost_abuffers, INTEGER, COUNTER );
+            INIT_COUNTER( displayed_pictures, INTEGER, COUNTER );
+            INIT_COUNTER( lost_pictures, INTEGER, COUNTER );
+            INIT_COUNTER( decoded_audio, INTEGER, COUNTER );
+            INIT_COUNTER( decoded_video, INTEGER, COUNTER );
+            INIT_COUNTER( decoded_sub, INTEGER, COUNTER );
+            p_input->counters.p_sout_send_bitrate = NULL;
+            p_input->counters.p_sout_sent_packets = NULL;
+            p_input->counters.p_sout_sent_bytes = NULL;
+            if( p_input->counters.p_demux_bitrate )
+                p_input->counters.p_demux_bitrate->update_interval = 1000000;
+            if( p_input->counters.p_input_bitrate )
+                p_input->counters.p_input_bitrate->update_interval = 1000000;
+        }
+        vlc_mutex_init( p_input, &p_input->counters.counters_lock );
 
         /* handle sout */
         psz = var_GetString( p_input, "sout" );
@@ -715,6 +721,15 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
                 free( psz );
                 return VLC_EGENERIC;
             }
+            if( p_input->p_libvlc->b_stats )
+            {
+                INIT_COUNTER( sout_sent_packets, INTEGER, COUNTER );
+                INIT_COUNTER (sout_sent_bytes, INTEGER, COUNTER );
+                INIT_COUNTER( sout_send_bitrate, FLOAT, DERIVATIVE );
+                if( p_input->counters.p_sout_send_bitrate )
+                     p_input->counters.p_sout_send_bitrate->update_interval =
+                             1000000;
+            }
         }
         free( psz );
     }
@@ -849,38 +864,8 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
         psz_subtitle = var_GetString( p_input, "sub-file" );
         if( *psz_subtitle )
         {
-            input_source_t *sub;
-            vlc_value_t count;
-            vlc_value_t list;
-
             msg_Dbg( p_input, "forced subtitle: %s", psz_subtitle );
-
-            var_Change( p_input, "spu-es", VLC_VAR_CHOICESCOUNT, &count, NULL );
-
-            /* */
-            sub = InputSourceNew( p_input );
-            if( !InputSourceInit( p_input, sub, psz_subtitle, "subtitle",
-                                  VLC_FALSE ) )
-            {
-                TAB_APPEND( p_input->i_slave, p_input->slave, sub );
-
-                /* Select the ES */
-                if( !var_Change( p_input, "spu-es", VLC_VAR_GETLIST, &list,
-                                 NULL ) )
-                {
-                    if( count.i_int == 0 )
-                        count.i_int++;
-                        /* if it was first one, there is disable too */
-
-                    if( count.i_int < list.p_list->i_count )
-                    {
-                        input_ControlPush( p_input, INPUT_CONTROL_SET_ES,
-                                          &list.p_list->p_values[count.i_int] );
-                    }
-                    var_Change( p_input, "spu-es", VLC_VAR_FREELIST, &list,
-                                NULL );
-                }
-            }
+            input_AddSubtitles( p_input, psz_subtitle, VLC_FALSE );
         }
 
         var_Get( p_input, "sub-autodetect-file", &val );
@@ -890,12 +875,20 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
             char **subs = subtitles_Detect( p_input, psz_autopath,
                                             p_input->input.p_item->psz_uri );
             input_source_t *sub;
-            vlc_value_t count;
-            vlc_value_t list;
 
-            var_Change( p_input, "spu-es", VLC_VAR_CHOICESCOUNT, &count, NULL );
+            i = 0;
 
-            for( i = 0; subs && subs[i]; i++ )
+            /* Try to autoselect the first autodetected subtitles file
+             * if no subtitles file was specified */
+            if( *psz_subtitle == 0 && subs && subs[0] )
+            {
+                input_AddSubtitles( p_input, subs[0], VLC_FALSE );
+                free( subs[0] );
+                i = 1;
+            }
+
+            /* Then, just add the following subtitles files */
+            for( ; subs && subs[i]; i++ )
             {
                 if( strcmp( psz_subtitle, subs[i] ) )
                 {
@@ -904,26 +897,6 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
                                           VLC_FALSE ) )
                     {
                         TAB_APPEND( p_input->i_slave, p_input->slave, sub );
-
-                        /* If no subtitle was specified, select the first
-                         * autodetected subtitle. */
-                        if( i == 0 && psz_subtitle != NULL )
-                        {
-                            /* Select the ES */
-                            if( !var_Change( p_input, "spu-es", VLC_VAR_GETLIST, &list, NULL ) )
-                            {
-                                if( count.i_int == 0 )
-                                    count.i_int++;
-                                /* if it was first one, there is disable too */
-
-                                if( count.i_int < list.p_list->i_count )
-                                {
-                                    input_ControlPush( p_input, INPUT_CONTROL_SET_ES,
-                                                       &list.p_list->p_values[count.i_int] );
-                                }
-                                var_Change( p_input, "spu-es", VLC_VAR_FREELIST, &list, NULL );
-                            }
-                        }
                     }
                 }
                 free( subs[i] );
@@ -1075,10 +1048,7 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
     }
 
     /* initialization is complete */
-    p_input->i_state = PLAYING_S;
-
-    val.i_int = PLAYING_S;
-    var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL );
+    input_ChangeState(p_input, PLAYING_S);
 
     return VLC_SUCCESS;
 
@@ -1118,16 +1088,12 @@ static void Error( input_thread_t *p_input )
  *****************************************************************************/
 static void End( input_thread_t * p_input )
 {
-    vlc_value_t val;
     int i;
 
     msg_Dbg( p_input, "closing input" );
 
     /* We are at the end */
-    p_input->i_state = END_S;
-
-    val.i_int = END_S;
-    var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL );
+    input_ChangeState(p_input, END_S);
 
     /* Clean control variables */
     input_ControlVarClean( p_input );
@@ -1147,29 +1113,51 @@ static void End( input_thread_t * p_input )
     if( p_input->p_es_out )
         input_EsOutDelete( p_input->p_es_out );
 
+#define CL_CO( c ) stats_CounterClean( p_input->counters.p_##c ); p_input->counters.p_##c = NULL;
+    if( p_input->p_libvlc->b_stats )
+    {
+        vlc_mutex_lock( &p_input->counters.counters_lock );
+        CL_CO( read_bytes );
+        CL_CO( read_packets );
+        CL_CO( demux_read );
+        CL_CO( input_bitrate );
+        CL_CO( demux_bitrate );
+        CL_CO( played_abuffers );
+        CL_CO( lost_abuffers );
+        CL_CO( displayed_pictures );
+        CL_CO( lost_pictures );
+        CL_CO( decoded_audio) ;
+        CL_CO( decoded_video );
+        CL_CO( decoded_sub) ;
+        vlc_mutex_unlock( &p_input->counters.counters_lock );
+    }
+
     /* Close optional stream output instance */
     if( p_input->p_sout )
     {
-        vlc_object_t *p_pl =
-            vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
         vlc_value_t keep;
 
-        if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool && p_pl )
+        vlc_mutex_lock( &p_input->counters.counters_lock );
+        CL_CO( sout_sent_packets );
+        CL_CO( sout_sent_bytes );
+        CL_CO( sout_send_bitrate );
+        vlc_mutex_unlock( &p_input->counters.counters_lock );
+
+        if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool )
         {
             /* attach sout to the playlist */
             msg_Dbg( p_input, "keeping sout" );
             vlc_object_detach( p_input->p_sout );
-            vlc_object_attach( p_input->p_sout, p_pl );
+            vlc_object_attach( p_input->p_sout, p_input->p_libvlc->p_playlist );
         }
         else
         {
             msg_Dbg( p_input, "destroying sout" );
             sout_DeleteInstance( p_input->p_sout );
         }
-        if( p_pl )
-            vlc_object_release( p_pl );
     }
 
+#undef CL_CO
     /* Tell we're dead */
     p_input->b_dead = VLC_TRUE;
 }
@@ -1832,21 +1820,16 @@ static int  UpdateMeta( input_thread_t *p_input, vlc_bool_t b_quick )
 static void UpdateItemLength( input_thread_t *p_input, int64_t i_length,
                               vlc_bool_t b_quick )
 {
-    playlist_t *p_playlist;
     char psz_buffer[MSTRTIME_MAX_SIZE];
 
     vlc_mutex_lock( &p_input->input.p_item->lock );
     p_input->input.p_item->i_duration = i_length;
     vlc_mutex_unlock( &p_input->input.p_item->lock );
 
-        p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
-                                               FIND_PARENT);
-    if( p_playlist )
-    {
-        var_SetInteger( p_playlist, "item-change",
-                        p_input->input.p_item->i_id );
-        vlc_object_release( p_playlist );
-    }
+    pl_Yield( p_input );
+    var_SetInteger( pl_Get( p_input ), "item-change",
+                    p_input->input.p_item->i_id );
+    pl_Release( p_input )
 
     input_Control( p_input, INPUT_ADD_INFO, _("General"), _("Duration"),
                    msecstotimestr( psz_buffer, i_length / 1000 ) );
@@ -1984,6 +1967,8 @@ static int InputSourceInit( input_thread_t *p_input,
     {
         int64_t i_pts_delay;
 
+        input_ChangeState( p_input, OPENING_S);
+
         /* Now try a real access */
         in->p_access = access2_New( p_input, psz_access, psz_demux, psz_path,
                                     b_quick );
@@ -2026,8 +2011,10 @@ static int InputSourceInit( input_thread_t *p_input,
         if( in->p_access == NULL )
         {
             msg_Err( p_input, "no suitable access module for `%s'", psz_mrl );
-            intf_UserFatal( VLC_OBJECT( p_input),
-                            _("Errors"),"Unable to open '%s'", psz_mrl );
+            intf_UserFatal( VLC_OBJECT( p_input), VLC_FALSE,
+                            _("Your input can't be opened"),
+                            _("VLC is unable to open the MRL '%s'."
+                            " Check the log for details."), psz_mrl );
             goto error;
         }
 
@@ -2078,6 +2065,8 @@ static int InputSourceInit( input_thread_t *p_input,
             var_Set( p_input, "seekable", val );
         }
 
+        input_ChangeState( p_input, BUFFERING_S);
+
         /* Create the stream_t */
         in->p_stream = stream_AccessNew( in->p_access, b_quick );
         if( in->p_stream == NULL )
@@ -2097,8 +2086,10 @@ static int InputSourceInit( input_thread_t *p_input,
         {
             msg_Err( p_input, "no suitable demux module for `%s/%s://%s'",
                      psz_access, psz_demux, psz_path );
-            intf_UserFatal( VLC_OBJECT( p_input), _("Errors"),
-                            "Unrecognized format for '%s'", psz_mrl );
+            intf_UserFatal( VLC_OBJECT( p_input), VLC_FALSE, 
+                            _("Can't recognize the input's format"),
+                            _("The format of '%s' can't be detected. "
+                            "Have a look the log for details."), psz_mrl );
             goto error;
         }
 
@@ -2441,12 +2432,36 @@ vlc_bool_t input_AddSubtitles( input_thread_t *p_input, char *psz_subtitle,
     input_source_t *sub;
     vlc_value_t count;
     vlc_value_t list;
+    char *psz_path, *psz_extension;
 
     if( b_check_extension && !subtitles_Filter( psz_subtitle ) )
     {
         return VLC_FALSE;
     }
 
+    /* if we are provided a subtitle.sub file,
+     * see if we don't have a subtitle.idx and use it instead */
+    psz_path = strdup( psz_subtitle );
+    if( psz_path )
+    {
+        psz_extension = strrchr( psz_path, '.');
+        if( psz_extension && strcmp( psz_extension, ".sub" ) == 0 )
+        {
+            FILE *f;
+
+            strcpy( psz_extension, ".idx" );
+            /* FIXME: a portable wrapper for stat() or access() would be more suited */
+            if( ( f = utf8_fopen( psz_path, "rt" ) ) )
+            {
+                fclose( f );
+                msg_Dbg( p_input, "using %s subtitles file instead of %s",
+                         psz_path, psz_subtitle );
+                strcpy( psz_subtitle, psz_path );
+            }
+        }
+        free( psz_path );
+    }
+
     var_Change( p_input, "spu-es", VLC_VAR_CHOICESCOUNT, &count, NULL );
 
     sub = InputSourceNew( p_input );