[vlc-devel] [PATCH] lib: Add a libvlc_MediaArtChanged event

Hugo Beauzée-Luyssen hugo at beauzee.fr
Fri Mar 3 11:51:29 CET 2017


There is no way of knowing when the art gets updated otherwise, as
libvlc_MediaParsedChanged status isn't related to art fetching
---
 include/vlc/libvlc_events.h |  5 +++++
 include/vlc/libvlc_media.h  | 22 ++++++++++++++++++++--
 include/vlc_events.h        |  5 +++++
 include/vlc_input_item.h    |  6 ++++++
 lib/event.c                 |  1 +
 lib/media.c                 | 41 +++++++++++++++++++++++++++++++++++++++++
 lib/media_internal.h        |  1 +
 src/input/input_interface.h |  1 +
 src/input/item.c            |  8 ++++++++
 src/playlist/fetcher.c      |  2 ++
 10 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/include/vlc/libvlc_events.h b/include/vlc/libvlc_events.h
index b69c5ce2be..3d89b78967 100644
--- a/include/vlc/libvlc_events.h
+++ b/include/vlc/libvlc_events.h
@@ -55,6 +55,7 @@ enum libvlc_event_e {
     libvlc_MediaFreed,
     libvlc_MediaStateChanged,
     libvlc_MediaSubItemTreeAdded,
+    libvlc_MediaArtChanged,
 
     libvlc_MediaPlayerMediaChanged=0x100,
     libvlc_MediaPlayerNothingSpecial,
@@ -157,6 +158,10 @@ typedef struct libvlc_event_t
         } media_parsed_changed;
         struct
         {
+            int new_status; /**< see @ ref libvlc_media_art_status_t */
+        } media_art_changed;
+        struct
+        {
             libvlc_media_t * md;
         } media_freed;
         struct
diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h
index 01e571c519..a7a29ad794 100644
--- a/include/vlc/libvlc_media.h
+++ b/include/vlc/libvlc_media.h
@@ -301,6 +301,24 @@ typedef enum libvlc_media_parsed_status_t
 } libvlc_media_parsed_status_t;
 
 /**
+ * Art fetching status; reported by libvlc_MediaArtChanged event.
+ *
+ * These events will only happen when libvlc_media_parse_with_options gets called with
+ * libvlc_media_fetch_local and/or libvlc_media_fetch_network
+ */
+typedef enum libvlc_media_art_status_t
+{
+    /**
+     * We now have art for this item
+     */
+    libvlc_media_art_status_fetched = 1,
+    /**
+     * No art was found, either because of an error, or because there was no art to be found
+     */
+    libvlc_media_art_status_notfound,
+} libvlc_media_art_status_t;
+
+/**
  * Type of a media slave: subtitle or audio.
  */
 typedef enum libvlc_media_slave_type_t
@@ -669,8 +687,8 @@ LIBVLC_API libvlc_time_t
  * This fetches (local or network) art, meta data and/or tracks information.
  * This method is the extended version of libvlc_media_parse_with_options().
  *
- * To track when this is over you can listen to libvlc_MediaParsedChanged
- * event. However if this functions returns an error, you will not receive any
+ * To track when this is over you can listen to libvlc_MediaParsedChanged and libvlc_MediaArtChanged
+ * events. However if this functions returns an error, you will not receive any
  * events.
  *
  * It uses a flag to specify parse options (see libvlc_media_parse_flag_t). All
diff --git a/include/vlc_events.h b/include/vlc_events.h
index 82245cbbd0..0cdd25e421 100644
--- a/include/vlc_events.h
+++ b/include/vlc_events.h
@@ -120,6 +120,7 @@ typedef enum vlc_event_type_t {
     vlc_InputItemInfoChanged,
     vlc_InputItemErrorWhenReadingChanged,
     vlc_InputItemPreparseEnded,
+    vlc_InputItemArtChanged,
 
     /* Renderer Discovery events */
     vlc_RendererDiscoveryItemAdded=vlc_InputItemPreparseEnded+6,
@@ -175,6 +176,10 @@ typedef struct vlc_event_t
         {
             int new_status;
         } input_item_preparse_ended;
+        struct input_item_art_changed
+        {
+            int new_status;
+        } input_item_art_changed;
 
         /* Renderer discovery events */
         struct vlc_renderer_discovery_item_added
diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h
index 20bc492eca..50945ef167 100644
--- a/include/vlc_input_item.h
+++ b/include/vlc_input_item.h
@@ -388,6 +388,12 @@ enum input_item_preparse_status
     ITEM_PREPARSE_DONE
 };
 
+enum input_item_art_status
+{
+    ITEM_ART_STATUS_FETCHED,
+    ITEM_ART_STATUS_NOTFOUND,
+};
+
 VLC_API int libvlc_MetadataRequest( libvlc_int_t *, input_item_t *,
                                     input_item_meta_request_option_t,
                                     int, void * );
diff --git a/lib/event.c b/lib/event.c
index e6ec83c556..cdd6251455 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -171,6 +171,7 @@ static const event_name_t event_list[] = {
     DEF(MediaFreed)
     DEF(MediaStateChanged)
     DEF(MediaSubItemTreeAdded)
+    DEF(MediaArtChanged)
 
     DEF(MediaPlayerMediaChanged)
     DEF(MediaPlayerNothingSpecial)
diff --git a/lib/media.c b/lib/media.c
index f3be2c93db..1aed3b7c73 100644
--- a/lib/media.c
+++ b/lib/media.c
@@ -305,6 +305,39 @@ static void input_item_preparse_ended( const vlc_event_t * p_event,
 }
 
 /**************************************************************************
+ * Install event handler (Private) (vlc event Callback)
+ **************************************************************************/
+static void input_item_art_changed( const vlc_event_t * p_event,
+                                    void * user_data )
+{
+    libvlc_media_t * p_md = user_data;
+    libvlc_event_t ev;
+
+    ev.type = libvlc_MediaArtChanged;
+    switch ( p_event->u.input_item_art_changed.new_status )
+    {
+        case ITEM_ART_STATUS_FETCHED:
+            ev.u.media_art_changed.new_status = libvlc_media_art_status_fetched;
+            break;
+        case ITEM_ART_STATUS_NOTFOUND:
+            ev.u.media_art_changed.new_status = libvlc_media_art_status_notfound;
+            break;
+        default:
+            return;
+    }
+    vlc_mutex_lock( &p_md->parsed_lock );
+    if ( ev.u.media_art_changed.new_status == p_md->art_status )
+    {
+        vlc_mutex_unlock( &p_md->parsed_lock );
+        return;
+    }
+    p_md->art_status = ev.u.media_art_changed.new_status;
+    vlc_mutex_unlock( &p_md->parsed_lock );
+
+    libvlc_event_send( p_md->p_event_manager, &ev );
+}
+
+/**************************************************************************
  * Install event handler (Private)
  **************************************************************************/
 static void install_input_item_observer( libvlc_media_t *p_md )
@@ -329,6 +362,10 @@ static void install_input_item_observer( libvlc_media_t *p_md )
                       vlc_InputItemPreparseEnded,
                       input_item_preparse_ended,
                       p_md );
+    vlc_event_attach( &p_md->p_input_item->event_manager,
+                      vlc_InputItemArtChanged,
+                      input_item_art_changed,
+                      p_md );
 }
 
 /**************************************************************************
@@ -356,6 +393,10 @@ static void uninstall_input_item_observer( libvlc_media_t *p_md )
                       vlc_InputItemPreparseEnded,
                       input_item_preparse_ended,
                       p_md );
+    vlc_event_detach( &p_md->p_input_item->event_manager,
+                      vlc_InputItemArtChanged,
+                      input_item_art_changed,
+                      p_md );
 }
 
 /**************************************************************************
diff --git a/lib/media_internal.h b/lib/media_internal.h
index f063ddb5fa..fc3d020266 100644
--- a/lib/media_internal.h
+++ b/lib/media_internal.h
@@ -46,6 +46,7 @@ struct libvlc_media_t
     vlc_mutex_t subitems_lock;
 
     libvlc_media_parsed_status_t parsed_status;
+    libvlc_media_art_status_t art_status;
     bool is_parsed;
     bool has_asked_preparse;
 };
diff --git a/src/input/input_interface.h b/src/input/input_interface.h
index b5f9795bd9..322cbb8207 100644
--- a/src/input/input_interface.h
+++ b/src/input/input_interface.h
@@ -34,6 +34,7 @@ void input_item_SignalPreparseEnded( input_item_t *p_i, int new_status );
 void input_item_SetPreparsed( input_item_t *p_i, bool b_preparsed );
 void input_item_SetArtNotFound( input_item_t *p_i, bool b_not_found );
 void input_item_SetArtFetched( input_item_t *p_i, bool b_art_fetched );
+void input_item_SignalArtChanged( input_item_t *p_i, int status );
 void input_item_SetEpg( input_item_t *p_item, const vlc_epg_t *p_epg, bool );
 void input_item_ChangeEPGSource( input_item_t *p_item, int i_source_id );
 void input_item_SetEpgEvent( input_item_t *p_item, const vlc_epg_event_t *p_epg_evt );
diff --git a/src/input/item.c b/src/input/item.c
index 8cf9336567..68d8dadb5b 100644
--- a/src/input/item.c
+++ b/src/input/item.c
@@ -139,6 +139,13 @@ void input_item_SetArtFetched( input_item_t *p_i, bool b_art_fetched )
     vlc_mutex_unlock( &p_i->lock );
 }
 
+void input_item_SignalArtChanged( input_item_t *p_i, int status )
+{
+    vlc_event_send( &p_i->event_manager, &(vlc_event_t) {
+        .type = vlc_InputItemArtChanged,
+        .u.input_item_art_changed.new_status = status } );
+}
+
 void input_item_SetMeta( input_item_t *p_i, vlc_meta_type_t meta_type, const char *psz_val )
 {
     vlc_mutex_lock( &p_i->lock );
@@ -1111,6 +1118,7 @@ input_item_NewExt( const char *psz_uri, const char *psz_name,
     vlc_event_manager_register_event_type( p_em, vlc_InputItemInfoChanged );
     vlc_event_manager_register_event_type( p_em, vlc_InputItemErrorWhenReadingChanged );
     vlc_event_manager_register_event_type( p_em, vlc_InputItemPreparseEnded );
+    vlc_event_manager_register_event_type( p_em, vlc_InputItemArtChanged );
 
     if( type != ITEM_TYPE_UNKNOWN )
         p_input->i_type = type;
diff --git a/src/playlist/fetcher.c b/src/playlist/fetcher.c
index 1fdb64cee5..f0cc189ce7 100644
--- a/src/playlist/fetcher.c
+++ b/src/playlist/fetcher.c
@@ -559,12 +559,14 @@ static void *Thread( void *p_data )
             {
                 msg_Dbg( obj, "found art for %s in cache", psz_name );
                 input_item_SetArtFetched( p_entry->p_item, true );
+                input_item_SignalArtChanged( p_entry->p_item, ITEM_ART_STATUS_FETCHED );
                 var_SetAddress( obj, "item-change", p_entry->p_item );
             }
             else
             {
                 msg_Dbg( obj, "art not found for %s", psz_name );
                 input_item_SetArtNotFound( p_entry->p_item, true );
+                input_item_SignalArtChanged( p_entry->p_item, ITEM_ART_STATUS_NOTFOUND );
             }
             free( psz_name );
             vlc_gc_decref( p_entry->p_item );
-- 
2.11.0



More information about the vlc-devel mailing list