[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