[vlc-devel] [PATCH] Adjusted meta data signalling to only send events when the meta data has actually changed.
Johannes Marbach
johannesmarbach at googlemail.com
Wed Oct 12 13:52:39 CEST 2011
The emission of vlc_InputItemMetaChanged signals has been limited to cases in which the meta data has actually changed. Unset meta fields (null pointers) are treated as empty strings. The vlc_meta_Merge function has been forked into vlc_meta_MergeAndRemember, which gives the caller access to the meta types that were changed during the merge.
---
include/vlc_meta.h | 3 +++
src/input/es_out.c | 32 ++++++++++++++++++++++----------
src/input/event.c | 4 ++--
src/input/event.h | 2 +-
src/input/input.c | 6 +++---
src/input/meta.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 78 insertions(+), 16 deletions(-)
diff --git a/include/vlc_meta.h b/include/vlc_meta.h
index a5278e7..e5672aa 100644
--- a/include/vlc_meta.h
+++ b/include/vlc_meta.h
@@ -79,6 +79,9 @@ VLC_API unsigned vlc_meta_GetExtraCount( const vlc_meta_t *m );
VLC_API char ** vlc_meta_CopyExtraNames( const vlc_meta_t *m ) VLC_USED;
VLC_API void vlc_meta_Merge( vlc_meta_t *dst, const vlc_meta_t *src );
+VLC_API void vlc_meta_MergeAndRemember( vlc_meta_t *dst, const vlc_meta_t *src,
+ vlc_meta_type_t **p_changed_types, int *p_i_n_changed_types);
+VLC_API int vlc_meta_CompareValues( char* psz1, char* psz2 );
VLC_API int vlc_meta_GetStatus( vlc_meta_t *m );
VLC_API void vlc_meta_SetStatus( vlc_meta_t *m, int status );
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 760e57b..d856f3a 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -1045,10 +1045,12 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm )
}
/* Update now playing */
- input_item_SetNowPlaying( p_input->p->p_item, p_pgrm->psz_now_playing );
- input_item_SetPublisher( p_input->p->p_item, p_pgrm->psz_publisher );
+ if( vlc_meta_CompareValues( input_item_GetNowPlaying( p_input->p->p_item ), p_pgrm->psz_now_playing ) )
+ input_item_SetNowPlaying( p_input->p->p_item, p_pgrm->psz_now_playing );
- input_SendEventMeta( p_input );
+ /* Update publisher */
+ if( vlc_meta_CompareValues( input_item_GetPublisher( p_input->p->p_item ), p_pgrm->psz_publisher ) )
+ input_item_SetPublisher( p_input->p->p_item, p_pgrm->psz_publisher );
}
/* EsOutAddProgram:
@@ -1267,8 +1269,8 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, const vlc_meta_t *p_me
{
if( p_sys->p_pgrm == p_pgrm )
{
- input_item_SetPublisher( p_input->p->p_item, psz_provider );
- input_SendEventMeta( p_input );
+ if( vlc_meta_CompareValues( input_item_GetPublisher( p_input->p->p_item ), psz_provider ) )
+ input_item_SetPublisher( p_input->p->p_item, psz_provider );
}
if( p_cat )
info_category_AddInfo( p_cat, vlc_meta_TypeToLocalizedString(vlc_meta_Publisher),
@@ -1326,8 +1328,8 @@ static void EsOutProgramEpg( es_out_t *out, int i_group, const vlc_epg_t *p_epg
if( p_pgrm == p_sys->p_pgrm )
{
- input_item_SetNowPlaying( p_input->p->p_item, p_pgrm->psz_now_playing );
- input_SendEventMeta( p_input );
+ if( vlc_meta_CompareValues( input_item_GetNowPlaying( p_input->p->p_item ), p_pgrm->psz_now_playing ) )
+ input_item_SetNowPlaying( p_input->p->p_item, p_pgrm->psz_now_playing );
}
if( p_pgrm->psz_now_playing )
@@ -1388,9 +1390,12 @@ static void EsOutMeta( es_out_t *p_out, const vlc_meta_t *p_meta )
if( vlc_meta_Get( p_meta, vlc_meta_Title ) && !p_item->b_fixed_name )
psz_title = strdup( vlc_meta_Get( p_meta, vlc_meta_Title ) );
- vlc_meta_Merge( p_item->p_meta, p_meta );
+ /* Merge meta data & remember changed fields */
+ vlc_meta_type_t *p_changed_types = 0;
+ int i_n_changed_types;
+ vlc_meta_MergeAndRemember( p_item->p_meta, p_meta, &p_changed_types, &i_n_changed_types );
- if( !psz_arturl || *psz_arturl == '\0' )
+ if( p_item->p_meta && (!psz_arturl || *psz_arturl == '\0') )
{
const char *psz_tmp = vlc_meta_Get( p_item->p_meta, vlc_meta_ArtworkURL );
if( psz_tmp )
@@ -1421,7 +1426,14 @@ static void EsOutMeta( es_out_t *p_out, const vlc_meta_t *p_meta )
}
input_item_SetPreparsed( p_item, true );
- input_SendEventMeta( p_input );
+ if( p_changed_types )
+ {
+ /* Send meta changed event for each updated field */
+ int i;
+ for( i = 0; i < i_n_changed_types; ++i )
+ input_SendEventMeta( p_input, p_changed_types[i] );
+ free( p_changed_types );
+ }
/* TODO handle sout meta ? */
}
diff --git a/src/input/event.c b/src/input/event.c
index f0a4205..d0dde39 100644
--- a/src/input/event.c
+++ b/src/input/event.c
@@ -198,7 +198,7 @@ void input_SendEventCache( input_thread_t *p_input, double f_level )
/* FIXME: review them because vlc_event_send might be
* moved inside input_item* functions.
*/
-void input_SendEventMeta( input_thread_t *p_input )
+void input_SendEventMeta( input_thread_t *p_input, vlc_meta_type_t type )
{
Trigger( p_input, INPUT_EVENT_ITEM_META );
@@ -206,7 +206,7 @@ void input_SendEventMeta( input_thread_t *p_input )
vlc_event_t event;
event.type = vlc_InputItemMetaChanged;
- event.u.input_item_meta_changed.meta_type = vlc_meta_ArtworkURL;
+ event.u.input_item_meta_changed.meta_type = type;
vlc_event_send( &p_input->p->p_item->event_manager, &event );
}
diff --git a/src/input/event.h b/src/input/event.h
index 31eea4d..27c7acc 100644
--- a/src/input/event.h
+++ b/src/input/event.h
@@ -45,7 +45,7 @@ void input_SendEventState( input_thread_t *p_input, int i_state );
void input_SendEventCache( input_thread_t *p_input, double f_level );
/* TODO rename Item* */
-void input_SendEventMeta( input_thread_t *p_input );
+void input_SendEventMeta( input_thread_t *p_input, vlc_meta_type_t type );
void input_SendEventMetaInfo( input_thread_t *p_input );
void input_SendEventMetaName( input_thread_t *p_input, const char *psz_name );
void input_SendEventMetaEpg( input_thread_t *p_input );
diff --git a/src/input/input.c b/src/input/input.c
index b43df74..b05384a 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -475,9 +475,9 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
}
}
- /* Remove 'Now playing' info as it is probably outdated */
- input_item_SetNowPlaying( p_item, NULL );
- input_SendEventMeta( p_input );
+ /* Remove 'Now playing' info in case it is outdated */
+ if( vlc_meta_CompareValues( input_item_GetNowPlaying( p_item ), 0 ) )
+ input_item_SetNowPlaying( p_item, NULL );
/* */
if( p_input->b_preparsing )
diff --git a/src/input/meta.c b/src/input/meta.c
index 5d7e980..853c223 100644
--- a/src/input/meta.c
+++ b/src/input/meta.c
@@ -195,6 +195,53 @@ void vlc_meta_Merge( vlc_meta_t *dst, const vlc_meta_t *src )
free( ppsz_all_keys );
}
+void vlc_meta_MergeAndRemember( vlc_meta_t *dst, const vlc_meta_t *src,
+ vlc_meta_type_t **p_changed_types, int *p_i_n_changed_types)
+{
+ char **ppsz_all_keys;
+ int i;
+ *p_changed_types = 0;
+ *p_i_n_changed_types = 0;
+
+ if( !dst || !src )
+ return;
+
+ for( i = 0; i < VLC_META_TYPE_COUNT; i++ )
+ {
+ if( src->ppsz_meta[i] )
+ {
+ if( vlc_meta_CompareValues( src->ppsz_meta[i], dst->ppsz_meta[i] ) )
+ {
+ *p_i_n_changed_types += 1;
+ *p_changed_types = realloc( *p_changed_types, (*p_i_n_changed_types) * sizeof( vlc_meta_type_t ) );
+ (*p_changed_types)[(*p_i_n_changed_types) - 1] = i;
+ }
+
+ free( dst->ppsz_meta[i] );
+ dst->ppsz_meta[i] = strdup( src->ppsz_meta[i] );
+ }
+ }
+
+ /* XXX: If speed up are needed, it is possible */
+ ppsz_all_keys = vlc_dictionary_all_keys( &src->extra_tags );
+ for( i = 0; ppsz_all_keys && ppsz_all_keys[i]; i++ )
+ {
+ /* Always try to remove the previous value */
+ vlc_dictionary_remove_value_for_key( &dst->extra_tags, ppsz_all_keys[i], vlc_meta_FreeExtraKey, NULL );
+
+ void *p_value = vlc_dictionary_value_for_key( &src->extra_tags, ppsz_all_keys[i] );
+ vlc_dictionary_insert( &dst->extra_tags, ppsz_all_keys[i], strdup( (const char*)p_value ) );
+ free( ppsz_all_keys[i] );
+ }
+ free( ppsz_all_keys );
+}
+
+int vlc_meta_CompareValues( char* psz1, char* psz2 )
+{
+ /* Resolves null pointers to empty strings */
+ return strcmp( (psz1) ? psz1 : "\0", (psz2) ? psz2 : "\0" );
+}
+
void input_ExtractAttachmentAndCacheArt( input_thread_t *p_input )
{
--
1.7.7
More information about the vlc-devel
mailing list