]> git.sesse.net Git - vlc/blobdiff - src/playlist/engine.c
Improve meta/art logic
[vlc] / src / playlist / engine.c
index f66a33b6b4fe3f54f0b510cd2c50fc8324c85088..b0cdddee6178a61b3693642b2fa5cb77b7a92845 100644 (file)
@@ -2,7 +2,7 @@
  * engine.c : Run the playlist and handle its control
  *****************************************************************************
  * Copyright (C) 1999-2004 the VideoLAN team
- * $Id: /local/vlc/0.8.6-playlist-vlm/src/playlist/playlist.c 13741 2006-03-21T19:29:39.792444Z zorglub  $
+ * $Id$
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          ClĂ©ment Stenac <zorglub@videolan.org>
@@ -53,6 +53,7 @@ playlist_t * playlist_Create( vlc_object_t *p_parent )
         msg_Err( p_parent, "out of memory" );
         return NULL;
     }
+    p_parent->p_libvlc->p_playlist = p_playlist;
 
     VariablesInit( p_playlist );
 
@@ -142,9 +143,11 @@ void playlist_Destroy( playlist_t *p_playlist )
     playlist_MLDump( p_playlist );
 
     vlc_thread_join( p_playlist->p_preparse );
+    vlc_thread_join( p_playlist->p_secondary_preparse );
     vlc_thread_join( p_playlist );
 
     vlc_object_detach( p_playlist->p_preparse );
+    vlc_object_detach( p_playlist->p_secondary_preparse );
 
     var_Destroy( p_playlist, "intf-change" );
     var_Destroy( p_playlist, "item-change" );
@@ -170,6 +173,8 @@ void playlist_Destroy( playlist_t *p_playlist )
 
     vlc_mutex_destroy( &p_playlist->gc_lock );
     vlc_object_destroy( p_playlist->p_preparse );
+    vlc_object_destroy( p_playlist->p_secondary_preparse );
+    vlc_object_detach( p_playlist );
     vlc_object_destroy( p_playlist );
 
 }
@@ -333,7 +338,7 @@ void playlist_MainLoop( playlist_t *p_playlist )
                 if( b_playexit == VLC_TRUE )
                 {
                     msg_Info( p_playlist, "end of playlist, exiting" );
-                    p_playlist->p_vlc->b_die = VLC_TRUE;
+                    p_playlist->p_libvlc->b_die = VLC_TRUE;
                 }
                 p_playlist->status.i_status = PLAYLIST_STOPPED;
                 PL_UNLOCK
@@ -442,15 +447,16 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj )
 {
     playlist_t *p_playlist = (playlist_t *)p_obj->p_parent;
     int i_activity;
+    uint32_t i_m, i_o;
 
     vlc_mutex_lock( &p_obj->object_lock );
 
     if( p_obj->i_waiting > 0 )
     {
-        input_item_t *p_current = p_playlist->p_preparse->pp_waiting[0];
+        input_item_t *p_current = p_obj->pp_waiting[0];
         REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 );
         vlc_mutex_unlock( &p_obj->object_lock );
-        vlc_mutex_lock( &p_playlist->object_lock );
+        PL_LOCK;
         if( p_current )
         {
             vlc_bool_t b_preparsed = VLC_FALSE;
@@ -466,23 +472,47 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj )
                 b_preparsed = VLC_TRUE;
                 stats_TimerStart( p_playlist, "Preparse run",
                                   STATS_TIMER_PREPARSE );
+                PL_UNLOCK;
                 input_Preparse( p_playlist, p_current );
+                PL_LOCK;
                 stats_TimerStop( p_playlist, STATS_TIMER_PREPARSE );
             }
-            vlc_mutex_unlock( &p_playlist->object_lock );
+            PL_UNLOCK;
             if( b_preparsed )
             {
-                var_SetInteger( p_playlist, "item-change",
-                                p_current->i_id );
+                p_current->p_meta->i_status |= ITEM_PREPARSED;
+                var_SetInteger( p_playlist, "item-change", p_current->i_id );
+            }
+            PL_LOCK;
+            /* If we haven't retrieved enough meta, add to secondary queue
+             * which will run the "meta fetchers"
+             * TODO:
+             *  don't do this for things we won't get meta for, like
+             *  videos
+             */
+            if( !input_MetaSatisfied( p_playlist, p_current, &i_m, &i_o,
+                                      VLC_TRUE ) )
+            {
+                preparse_item_t p;
+                p.p_item = p_current;
+                p.b_fetch_art = VLC_FALSE;
+                vlc_mutex_lock( &p_playlist->p_secondary_preparse->object_lock);
+                INSERT_ELEM( p_playlist->p_secondary_preparse->p_waiting,
+                             p_playlist->p_secondary_preparse->i_waiting,
+                             p_playlist->p_secondary_preparse->i_waiting,
+                             p );
+                vlc_mutex_unlock(
+                            &p_playlist->p_secondary_preparse->object_lock);
             }
-            vlc_gc_decref( p_current );
+            else
+                vlc_gc_decref( p_current );
+            PL_UNLOCK;
         }
         else
-        {
-            vlc_mutex_unlock( &p_playlist->object_lock );
-        }
+            PL_UNLOCK;
+
         vlc_mutex_lock( &p_obj->object_lock );
-        i_activity var_GetInteger( p_playlist, "activity" );
+        i_activity = var_GetInteger( p_playlist, "activity" );
         if( i_activity < 0 ) i_activity = 0;
         vlc_mutex_unlock( &p_obj->object_lock );
         msleep( (i_activity+1) * 1000 );
@@ -491,6 +521,39 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj )
     vlc_mutex_unlock( &p_obj->object_lock );
 }
 
+/** Main loop for secondary preparser queue */
+void playlist_SecondaryPreparseLoop( playlist_secondary_preparse_t *p_obj )
+{
+    playlist_t *p_playlist = (playlist_t *)p_obj->p_parent;
+
+    vlc_mutex_lock( &p_obj->object_lock );
+
+    if( p_obj->i_waiting > 0 )
+    {
+        vlc_bool_t b_fetch_art = p_obj->p_waiting->b_fetch_art;
+        input_item_t *p_item = p_obj->p_waiting->p_item;
+        REMOVE_ELEM( p_obj->p_waiting, p_obj->i_waiting, 0 );
+        vlc_mutex_unlock( &p_obj->object_lock );
+        if( p_item )
+        {
+            if( !b_fetch_art )
+            {
+                input_MetaFetch( p_playlist, p_item );
+                p_item->p_meta->i_status |= ITEM_META_FETCHED;
+            }
+            else
+            {
+                input_ArtFetch( p_playlist, p_item );
+                p_item->p_meta->i_status |= ITEM_ART_FETCHED;
+            }
+            var_SetInteger( p_playlist, "item-change", p_item->i_id );
+            vlc_gc_decref( p_item );
+        }
+        return;
+    }
+    vlc_mutex_unlock( &p_obj->object_lock );
+}
+
 static void VariablesInit( playlist_t *p_playlist )
 {
     vlc_value_t val;