[vlc-devel] [PATCH] vlc_meta: allow multiple metas
Francois Cartegnie
fcvlcdev at free.fr
Sat Aug 9 12:11:59 CEST 2014
Proposal.
We need more than just one entry for some meta types.
(Director, Astist, ...)
* I'm not fan of const char * returns we have with Get for now and the
Extra API does copy everything. I might change GetList to copies as well.
* I've set an arbitrary limit of 255 entries per meta. Do we need a limit ?
* Should we reject multiples entries for some meta ? (ie: does multiple now
playing makes sense ?)
Francois
---
include/vlc_meta.h | 3 ++
src/input/meta.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++-------
src/libvlccore.sym | 2 ++
3 files changed, 90 insertions(+), 11 deletions(-)
diff --git a/include/vlc_meta.h b/include/vlc_meta.h
index c3bf801..e0b5496 100644
--- a/include/vlc_meta.h
+++ b/include/vlc_meta.h
@@ -71,8 +71,11 @@ struct vlc_meta_t;
VLC_API vlc_meta_t * vlc_meta_New( void ) VLC_USED;
VLC_API void vlc_meta_Delete( vlc_meta_t *m );
+VLC_API void vlc_meta_Add( vlc_meta_t *p_meta, vlc_meta_type_t meta_type, const char *psz_val );
VLC_API void vlc_meta_Set( vlc_meta_t *p_meta, vlc_meta_type_t meta_type, const char *psz_val );
VLC_API const char * vlc_meta_Get( const vlc_meta_t *p_meta, vlc_meta_type_t meta_type );
+VLC_API const char ** vlc_meta_GetList( const vlc_meta_t *p_meta, vlc_meta_type_t meta_type,
+ size_t * pi_nb );
VLC_API void vlc_meta_AddExtra( vlc_meta_t *m, const char *psz_name, const char *psz_value );
VLC_API const char * vlc_meta_GetExtra( const vlc_meta_t *m, const char *psz_name );
diff --git a/src/input/meta.c b/src/input/meta.c
index 892b4af..493d466 100644
--- a/src/input/meta.c
+++ b/src/input/meta.c
@@ -38,9 +38,18 @@
#include "input_internal.h"
#include "../playlist/art.h"
+typedef struct vlc_meta_values_t vlc_meta_values_t;
+
+struct vlc_meta_values_t
+{
+ char **ppsz_values;
+ uint8_t i_size; /* allocated size */
+ uint8_t i_count;/* number of values */
+};
+
struct vlc_meta_t
{
- char * ppsz_meta[VLC_META_TYPE_COUNT];
+ vlc_meta_values_t rg_metavals[VLC_META_TYPE_COUNT];
vlc_dictionary_t extra_tags;
@@ -81,6 +90,50 @@ const char * vlc_meta_TypeToLocalizedString( vlc_meta_type_t meta_type )
return vlc_gettext (posix_names[meta_type]);
};
+/**
+ * vlc_meta_values helpers.
+ * Manages the multi-valued meta arrays
+ */
+
+static void vlc_meta_values_add( vlc_meta_values_t *p_metavalues, const char *psz_val )
+{
+ if ( p_metavalues->i_count == UINT8_MAX )
+ return;
+
+ /* resize our storage if needed */
+ if ( p_metavalues->i_count == p_metavalues->i_size )
+ {
+ uint8_t i_newsize = VLC_CLIP( (uint16_t)p_metavalues->i_size * 2, 1, UINT8_MAX );
+ char **ppsz_values_new = realloc( p_metavalues->ppsz_values, i_newsize );
+ if ( ppsz_values_new ) /* realloc can fail */
+ {
+ p_metavalues->ppsz_values = ppsz_values_new;
+ p_metavalues->i_size = i_newsize;
+ }
+ }
+
+ if ( p_metavalues->i_count < p_metavalues->i_size )
+ {
+ p_metavalues->ppsz_values[p_metavalues->i_count] = (psz_val) ? strdup(psz_val) : NULL;
+ p_metavalues->i_count++;
+ }
+}
+
+static void vlc_meta_values_empty( vlc_meta_values_t * const p_metavalues )
+{
+ for (uint8_t i=0; i<p_metavalues->i_count; i++)
+ free(p_metavalues->ppsz_values[i]);
+ p_metavalues->i_count = 0;
+}
+
+/* releases values and storage */
+static void vlc_meta_values_free( vlc_meta_values_t * const p_metavalues )
+{
+ vlc_meta_values_empty( p_metavalues );
+ free(p_metavalues->ppsz_values);
+ p_metavalues->i_size = 0;
+}
+
/**
* vlc_meta contructor.
@@ -91,8 +144,8 @@ vlc_meta_t *vlc_meta_New( void )
vlc_meta_t *m = (vlc_meta_t*)malloc( sizeof(*m) );
if( !m )
return NULL;
- memset( m->ppsz_meta, 0, sizeof(m->ppsz_meta) );
m->i_status = 0;
+ memset( m->rg_metavals, 0, sizeof(m->rg_metavals) );
vlc_dictionary_init( &m->extra_tags, 0 );
return m;
}
@@ -106,9 +159,9 @@ static void vlc_meta_FreeExtraKey( void *p_data, void *p_obj )
void vlc_meta_Delete( vlc_meta_t *m )
{
- int i;
- for( i = 0; i < VLC_META_TYPE_COUNT ; i++ )
- free( m->ppsz_meta[i] );
+ for( int i = 0; i < VLC_META_TYPE_COUNT; i++ )
+ vlc_meta_values_free( &m->rg_metavals[i] );
+
vlc_dictionary_clear( &m->extra_tags, vlc_meta_FreeExtraKey, NULL );
free( m );
}
@@ -119,16 +172,36 @@ void vlc_meta_Delete( vlc_meta_t *m )
* FIXME - Why don't we merge those two?
*/
+void vlc_meta_Add( vlc_meta_t *p_meta, vlc_meta_type_t meta_type, const char *psz_val )
+{
+ assert( psz_val == NULL || IsUTF8( psz_val ) );
+
+ vlc_meta_values_t *p_metavalues = &p_meta->rg_metavals[ meta_type ];
+ vlc_meta_values_add( p_metavalues, psz_val );
+}
+
void vlc_meta_Set( vlc_meta_t *p_meta, vlc_meta_type_t meta_type, const char *psz_val )
{
- free( p_meta->ppsz_meta[meta_type] );
assert( psz_val == NULL || IsUTF8( psz_val ) );
- p_meta->ppsz_meta[meta_type] = psz_val ? strdup( psz_val ) : NULL;
+
+ vlc_meta_values_t *p_metavalues = &p_meta->rg_metavals[ meta_type ];
+ vlc_meta_values_empty( p_metavalues );
+ vlc_meta_Add( p_meta, meta_type, psz_val );
}
const char *vlc_meta_Get( const vlc_meta_t *p_meta, vlc_meta_type_t meta_type )
{
- return p_meta->ppsz_meta[meta_type];
+ const vlc_meta_values_t *p_metavalues = &p_meta->rg_metavals[ meta_type ];
+ return (p_metavalues && p_metavalues->i_count) ? p_metavalues->ppsz_values[0] : NULL;
+}
+
+const char ** vlc_meta_GetList( const vlc_meta_t *p_meta, vlc_meta_type_t meta_type, size_t * pi_nb )
+{
+ *pi_nb = p_meta->rg_metavals[ meta_type ].i_count;
+ if (! *pi_nb)
+ return NULL;
+ else
+ return (const char **) p_meta->rg_metavals[ meta_type ].ppsz_values;
}
void vlc_meta_AddExtra( vlc_meta_t *m, const char *psz_name, const char *psz_value )
@@ -182,10 +255,11 @@ void vlc_meta_Merge( vlc_meta_t *dst, const vlc_meta_t *src )
for( i = 0; i < VLC_META_TYPE_COUNT; i++ )
{
- if( src->ppsz_meta[i] )
+ if( src->rg_metavals[i].i_count )
{
- free( dst->ppsz_meta[i] );
- dst->ppsz_meta[i] = strdup( src->ppsz_meta[i] );
+ vlc_meta_values_empty( &dst->rg_metavals[i] );
+ for (uint8_t j=0; j<src->rg_metavals[i].i_count; j++)
+ vlc_meta_values_add( &dst->rg_metavals[i], src->rg_metavals[i].ppsz_values[j] );
}
}
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index bdd7b06..3497a44 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -533,10 +533,12 @@ vlc_iconv_open
vlc_join
vlc_list_children
vlc_list_release
+vlc_meta_Add
vlc_meta_AddExtra
vlc_meta_CopyExtraNames
vlc_meta_Delete
vlc_meta_Get
+vlc_meta_GetList
vlc_meta_GetExtra
vlc_meta_GetExtraCount
vlc_meta_GetStatus
--
1.9.3
More information about the vlc-devel
mailing list