]> git.sesse.net Git - vlc/blobdiff - src/input/input.c
Don't loop continuously the playlist thread, use cond.
[vlc] / src / input / input.c
index cacd0c64259390460700441fba33f0ccdf97a50e..484d7764a64459a588304c95bf94b77912c11114 100644 (file)
@@ -39,7 +39,7 @@
 #include "vlc_playlist.h"
 #include "vlc_interface.h"
 #include "vlc_interaction.h"
-#include "vlc_meta_engine.h"
+#include "vlc_url.h"
 
 #include "charset.h"
 
@@ -70,7 +70,6 @@ static int  UpdateMeta( input_thread_t * );
 
 static void UpdateItemLength( input_thread_t *, int64_t i_length );
 
-static void DecodeUrl( char * );
 static void MRLSections( input_thread_t *, char *, int *, int *, int *, int *);
 
 static input_source_t *InputSourceNew( input_thread_t *);
@@ -121,6 +120,19 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
         msg_Err( p_parent, "out of memory" );
         return NULL;
     }
+
+    /* One "randomly" selected input thread is responsible for computing
+     * the global stats. Check if there is already someone doing this */
+    if( p_input->p_libvlc->p_playlist->p_stats && !b_quick )
+    {
+        vlc_mutex_lock( &p_input->p_libvlc->p_playlist->p_stats->lock );
+        if( p_input->p_libvlc->p_playlist->p_stats_computer == NULL )
+        {
+            p_input->p_libvlc->p_playlist->p_stats_computer = p_input;
+        }
+        vlc_mutex_unlock( &p_input->p_libvlc->p_playlist->p_stats->lock );
+    }
+
     p_input->b_preparsing = b_quick;
     p_input->psz_header = psz_header ? strdup( psz_header ) : NULL;
 
@@ -158,7 +170,13 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
 
     if( !p_input->input.p_item->p_meta )
         p_input->input.p_item->p_meta = vlc_meta_New();
-    stats_ReinitInputStats( p_item->p_stats );
+
+    if( !p_item->p_stats )
+    {
+        p_item->p_stats = (input_stats_t*)malloc( sizeof( input_stats_t ) );
+        vlc_mutex_init( p_input, &p_item->p_stats->lock );
+        stats_ReinitInputStats( p_item->p_stats );
+    }
 
     /* No slave */
     p_input->i_slave = 0;
@@ -349,46 +367,6 @@ int __input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
     return VLC_SUCCESS;
 }
 
-int __input_SecondaryPreparse( vlc_object_t *p_parent, input_item_t *p_item )
-{
-    struct meta_engine_t *p_me;
-
-    /* FIXME: don't launch any module if we already have all the needed
-     * info. Easiest way to do this would be to add a dummy module.
-     * I'll do that later */
-
-    p_me = vlc_object_create( p_parent, VLC_OBJECT_META_ENGINE );
-    p_me->i_flags |= OBJECT_FLAGS_NOINTERACT;
-    p_me->i_mandatory =   VLC_META_ENGINE_TITLE
-                        | VLC_META_ENGINE_ARTIST;
-    p_me->i_optional = 0;
-    if( var_CreateGetInteger( p_parent, "album-art" ) != ALBUM_ART_NEVER )
-    {
-        p_me->i_mandatory |= VLC_META_ENGINE_ART_URL;
-    }
-    else
-    {
-        p_me->i_optional |= VLC_META_ENGINE_ART_URL;
-    }
-    p_me->p_item = p_item;
-    p_me->p_module = module_Need( p_me, "meta engine", 0, VLC_FALSE );
-
-
-    if( !p_me->p_module )
-    {
-        msg_Err( p_parent, "no suitable meta engine module" );
-        vlc_object_detach( p_me );
-        vlc_object_destroy( p_me );
-        return VLC_EGENERIC;
-    }
-
-    module_Unneed( p_me, p_me->p_module );
-
-    vlc_object_destroy( p_me );
-
-    return VLC_SUCCESS;
-}
-
 /**
  * Request a running input thread to stop and die
  *
@@ -402,7 +380,7 @@ void input_StopThread( input_thread_t *p_input )
     /* Set die for input */
     p_input->b_die = VLC_TRUE;
 
-    /* We cannot touch p_input fields directly (we can from another thread),
+    /* 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 */
@@ -464,6 +442,7 @@ static int Run( input_thread_t *p_input )
     {
         /* If we failed, wait before we are killed, and exit */
         p_input->b_error = VLC_TRUE;
+        playlist_Signal( pl_Get( p_input ) );
 
         Error( p_input );
 
@@ -490,6 +469,7 @@ static int Run( input_thread_t *p_input )
 
         /* We have finished */
         p_input->b_eof = VLC_TRUE;
+        playlist_Signal( pl_Get( p_input ) );
     }
 
     /* Wait until we are asked to die */
@@ -556,6 +536,7 @@ static int RunAndClean( input_thread_t *p_input )
 static void MainLoop( input_thread_t *p_input )
 {
     int64_t i_intf_update = 0;
+    int i_updates = 0;
     while( !p_input->b_die && !p_input->b_error && !p_input->input.b_eof )
     {
         vlc_bool_t b_force_update = VLC_FALSE;
@@ -703,6 +684,17 @@ static void MainLoop( input_thread_t *p_input )
             var_SetBool( p_input, "intf-change", VLC_TRUE );
             i_intf_update = mdate() + I64C(150000);
         }
+        /* 150ms * 8 = ~ 1 second */
+        if( ++i_updates % 8 == 0 )
+        {
+            stats_ComputeInputStats( p_input, p_input->input.p_item->p_stats );
+            /* Are we the thread responsible for computing global stats ? */
+            if( p_input->p_libvlc->p_playlist->p_stats_computer == p_input )
+            {
+                stats_ComputeGlobalStats( p_input->p_libvlc->p_playlist,
+                                     p_input->p_libvlc->p_playlist->p_stats );
+            }
+        }
     }
 }
 
@@ -725,6 +717,8 @@ static int Init( input_thread_t * p_input )
      * want to add more logic, just force file by file:// or code it ;)
      */
     memset( &p_input->counters, 0, sizeof( p_input->counters ) );
+    vlc_mutex_init( p_input, &p_input->counters.counters_lock );
+
     if( !p_input->b_preparsing )
     {
         /* Prepare statistics */
@@ -752,7 +746,6 @@ static int Init( input_thread_t * p_input )
             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" );
@@ -942,6 +935,7 @@ static int Init( input_thread_t * p_input )
                     {
                         TAB_APPEND( p_input->i_slave, p_input->slave, sub );
                     }
+                    else free( sub );
                 }
                 free( subs[i] );
             }
@@ -977,6 +971,7 @@ static int Init( input_thread_t * p_input )
                 {
                     TAB_APPEND( p_input->i_slave, p_input->slave, slave );
                 }
+                else free( slave );
                 psz = psz_delim;
             }
         }
@@ -1160,7 +1155,14 @@ static void End( input_thread_t * p_input )
 #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 );
+        /* make sure we are up to date */
+        stats_ComputeInputStats( p_input, p_input->input.p_item->p_stats );
+        if( p_input->p_libvlc->p_playlist->p_stats_computer == p_input )
+        {
+            stats_ComputeGlobalStats( p_input->p_libvlc->p_playlist,
+                                      p_input->p_libvlc->p_playlist->p_stats );
+            p_input->p_libvlc->p_playlist->p_stats_computer = NULL;
+        }
         CL_CO( read_bytes );
         CL_CO( read_packets );
         CL_CO( demux_read );
@@ -1173,7 +1175,6 @@ static void End( input_thread_t * p_input )
         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 */
@@ -1181,11 +1182,9 @@ static void End( input_thread_t * p_input )
     {
         vlc_value_t keep;
 
-        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 )
         {
@@ -1200,8 +1199,10 @@ static void End( input_thread_t * p_input )
             sout_DeleteInstance( p_input->p_sout );
         }
     }
-
 #undef CL_CO
+
+    vlc_mutex_destroy( &p_input->counters.counters_lock );
+
     /* Tell we're dead */
     p_input->b_dead = VLC_TRUE;
 }
@@ -1706,6 +1707,7 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type,
                 }
                 else
                 {
+                    free( slave );
                     msg_Warn( p_input, "failed to add %s as slave",
                               val.psz_string );
                 }
@@ -1972,8 +1974,8 @@ static int InputSourceInit( input_thread_t *p_input,
     {
         psz_path = psz_mrl;
         msg_Dbg( p_input, "trying to pre-parse %s",  psz_path );
-        psz_demux = strdup( "" );
-        psz_access = strdup( "file" );
+        psz_demux = "";
+        psz_access = "file";
     }
 
     if( in->p_demux )
@@ -2016,7 +2018,7 @@ static int InputSourceInit( input_thread_t *p_input,
         /* Access failed, URL encoded ? */
         if( in->p_access == NULL && strchr( psz_path, '%' ) )
         {
-            DecodeUrl( psz_path );
+            decode_URI( psz_path );
 
             msg_Dbg( p_input, "retrying with access `%s' demux `%s' path `%s'",
                      psz_access, psz_demux, psz_path );
@@ -2290,7 +2292,6 @@ static void InputMetaUser( input_thread_t *p_input )
     free( val.psz_string )
 
     GET_META( title, "meta-title" );
-    GET_META( author, "meta-author" );
     GET_META( artist, "meta-artist" );
     GET_META( genre, "meta-genre" );
     GET_META( copyright, "meta-copyright" );
@@ -2300,44 +2301,6 @@ static void InputMetaUser( input_thread_t *p_input )
 #undef GET_META
 }
 
-/*****************************************************************************
- * DecodeUrl: decode a given encoded url
- *****************************************************************************/
-static void DecodeUrl( char *psz )
-{
-    char *dup = strdup( psz );
-    char *p = dup;
-
-    while( *p )
-    {
-        if( *p == '%' )
-        {
-            char val[3];
-            p++;
-            if( !*p )
-            {
-                break;
-            }
-
-            val[0] = *p++;
-            val[1] = *p++;
-            val[2] = '\0';
-
-            *psz++ = strtol( val, NULL, 16 );
-        }
-        else if( *p == '+' )
-        {
-            *psz++ = ' ';
-            p++;
-        }
-        else
-        {
-            *psz++ = *p++;
-        }
-    }
-    if( psz ) *psz++  ='\0';
-    if( dup ) free( dup );
-}
 
 /*****************************************************************************
  * MRLSplit: parse the access, demux and url part of the
@@ -2525,99 +2488,7 @@ vlc_bool_t input_AddSubtitles( input_thread_t *p_input, char *psz_subtitle,
             var_Change( p_input, "spu-es", VLC_VAR_FREELIST, &list, NULL );
         }
     }
+    else free( sub );
 
     return VLC_TRUE;
 }
-
-#ifndef MAX_PATH
-#   define MAX_PATH 250
-#endif
-int input_DownloadAndCacheArt( vlc_object_t *p_parent, input_item_t *p_item )
-{
-    char *psz_artist;
-    char *psz_album;
-    char *psz_type;
-    char *psz_filename;
-    int i_status = VLC_EGENERIC;
-    int i_ret;
-    struct stat a;
-
-    if( !p_item->p_meta
-        || !p_item->p_meta->psz_arturl
-        || !*p_item->p_meta->psz_arturl )
-    {
-        return VLC_EGENERIC;
-    }
-    if( !strncmp( p_item->p_meta->psz_arturl, "file", 4 ) )
-    {
-        return VLC_SUCCESS;
-    }
-
-    psz_artist = p_item->p_meta->psz_artist;
-    psz_album = p_item->p_meta->psz_album;
-    psz_type = strrchr( p_item->p_meta->psz_arturl, '.' );
-    psz_filename = (char *)malloc( MAX_PATH );
-
-
-    snprintf( psz_filename, MAX_PATH,
-              "file://%s" DIR_SEP CONFIG_DIR DIR_SEP "art"
-              DIR_SEP "%s" DIR_SEP "%s" DIR_SEP "art%s",
-              p_parent->p_libvlc->psz_homedir,
-              psz_artist, psz_album, psz_type );
-    msg_Dbg( p_parent, "Saving album art to %s", psz_filename );
-
-    /* Check if file exists */
-    i_ret = utf8_stat( psz_filename+7, &a );
-    if( i_ret == 0 )
-    {
-        msg_Dbg( p_parent, "Album art %s already exists", psz_filename );
-    }
-    else
-    {
-        //if( i_ret == -1 && errno == ENOTDIR )
-        {
-            /* GRUIKKKKKKKKKK (make sure that all the directories exist) */
-            char *psz_dir = malloc( MAX_PATH );
-            snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR,
-                      p_parent->p_libvlc->psz_homedir );
-            utf8_mkdir( psz_dir );
-            snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP "art",
-                      p_parent->p_libvlc->psz_homedir );
-            utf8_mkdir( psz_dir );
-            snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP
-                      "art" DIR_SEP "%s",
-                      p_parent->p_libvlc->psz_homedir, psz_artist );
-            utf8_mkdir( psz_dir );
-            snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP
-                      "art" DIR_SEP "%s" DIR_SEP "%s",
-                      p_parent->p_libvlc->psz_homedir,
-                      psz_artist, psz_album );
-            utf8_mkdir( psz_dir );
-            free( psz_dir );
-        }
-
-        stream_t *p_stream = stream_UrlNew( p_parent,
-                                            p_item->p_meta->psz_arturl );
-
-        if( p_stream )
-        {
-            void *p_buffer = malloc( 1<<16 );
-            long int l_read;
-            FILE *p_file = utf8_fopen( psz_filename+7, "w" );
-            while( ( l_read = stream_Read( p_stream, p_buffer, 1<<16 ) ) )
-            {
-                fwrite( p_buffer, l_read, 1, p_file );
-            }
-            free( p_buffer );
-            fclose( p_file );
-            stream_Delete( p_stream );
-            msg_Dbg( p_parent, "Album art saved to %s\n", psz_filename );
-            free( p_item->p_meta->psz_arturl );
-            p_item->p_meta->psz_arturl = strdup( psz_filename );
-            i_status = VLC_SUCCESS;
-        }
-    }
-    free( psz_filename );
-
-    return i_status;
-}