vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Thu Jun 11 23:21:47 2015 +0300| [165861e38ff7152eb34d7114c3c876e63e2f43d3] | committer: Rémi Denis-Courmont
fourcc: use binary rather than linear search > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=165861e38ff7152eb34d7114c3c876e63e2f43d3 --- src/misc/fourcc.c | 159 ++++++++++++++++++++++------------------------------- 1 file changed, 66 insertions(+), 93 deletions(-) diff --git a/src/misc/fourcc.c b/src/misc/fourcc.c index 46556e2..801146d 100644 --- a/src/misc/fourcc.c +++ b/src/misc/fourcc.c @@ -33,115 +33,89 @@ #include <vlc_es.h> #include <assert.h> +#include "fourcc_tables.h" -typedef struct +static int fourcc_cmp(const void *key, const void *ent) { - char p_class[4]; - char p_fourcc[4]; - char psz_description[56]; -} staticentry_t; - -typedef struct -{ - char p_class[4]; - char p_fourcc[4]; - const char *psz_description; -} entry_t; - -#define NULL4 "\x00\x00\x00\x00" - -/* XXX You don't want to see the preprocessor generated code ;) */ -#ifdef WORDS_BIGENDIAN -# define FCC2STR(f) { ((f)>>24)&0xff, ((f)>>16)&0xff, ((f)>>8)&0xff, ((f)>>0)&0xff } -#else -# define FCC2STR(f) { ((f)>>0)&0xff, ((f)>>8)&0xff, ((f)>>16)&0xff, ((f)>>24)&0xff } -#endif -/* Begin a new class */ -#define B(a, c) { .p_class = FCC2STR(a), .p_fourcc = FCC2STR(a), .psz_description = c } -/* Create a sub-class entry with description */ -#define E(b, c) { .p_class = NULL4, .p_fourcc = b, .psz_description = c } -/* Create a sub-class entry without description (alias) */ -#define A(b) E(b, NULL4) - -#include "misc/fourcc_list.h" - -/* Create a fourcc from a string. - * XXX it assumes that the string is at least four bytes */ -static inline vlc_fourcc_t CreateFourcc( const char *psz_fourcc ) -{ - return VLC_FOURCC( psz_fourcc[0], psz_fourcc[1], - psz_fourcc[2], psz_fourcc[3] ); + return memcmp(key, ent, 4); } -/* */ -static entry_t Lookup( const staticentry_t p_list[], vlc_fourcc_t i_fourcc ) +static vlc_fourcc_t Lookup(vlc_fourcc_t fourcc, const char **restrict dsc, + const struct fourcc_mapping *mapv, size_t mapc, + const struct fourcc_desc *dscv, size_t dscc) { - const char *p_class = NULL; - const char *psz_description = NULL; - - entry_t e = B(0, ""); + const struct fourcc_mapping *mapping; + const struct fourcc_desc *desc; - for( int i = 0; ; i++ ) + mapping = bsearch(&fourcc, mapv, mapc, sizeof (*mapv), fourcc_cmp); + if (mapping != NULL) { - const staticentry_t *p = &p_list[i]; - const vlc_fourcc_t i_entry_fourcc = CreateFourcc( p->p_fourcc ); - const vlc_fourcc_t i_entry_class = CreateFourcc( p->p_class ); - - if( i_entry_fourcc == 0 ) - break; - - if( i_entry_class != 0 ) + if (dsc != NULL) { - p_class = p->p_class; - psz_description = p->psz_description; + desc = bsearch(&fourcc, dscv, dscc, sizeof (*dscv), fourcc_cmp); + if (desc != NULL) + { + *dsc = desc->desc; + return mapping->fourcc; + } } + fourcc = mapping->fourcc; + } - if( i_entry_fourcc == i_fourcc ) - { - assert( p_class != NULL ); + desc = bsearch(&fourcc, dscv, dscc, sizeof (*dscv), fourcc_cmp); + if (desc == NULL) + return 0; /* Unknown FourCC */ + if (dsc != NULL) + *dsc = desc->desc; + return fourcc; /* Known FourCC (has a description) */ +} - memcpy( e.p_class, p_class, 4 ); - memcpy( e.p_fourcc, p->p_fourcc, 4 ); - e.psz_description = p->psz_description[0] != '\0' ? - p->psz_description : psz_description; - break; - } - } - return e; +static vlc_fourcc_t LookupVideo(vlc_fourcc_t fourcc, const char **restrict dsc) +{ + return Lookup(fourcc, dsc, mapping_video, + sizeof (mapping_video) / sizeof (mapping_video[0]), + desc_video, sizeof (desc_video) / sizeof (desc_video[0])); } -/* */ -static entry_t Find( int i_cat, vlc_fourcc_t i_fourcc ) +static vlc_fourcc_t LookupAudio(vlc_fourcc_t fourcc, const char **restrict dsc) { - entry_t e; + return Lookup(fourcc, dsc, mapping_audio, + sizeof (mapping_audio) / sizeof (mapping_audio[0]), + desc_audio, sizeof (desc_audio) / sizeof (desc_audio[0])); +} - switch( i_cat ) +static vlc_fourcc_t LookupSpu(vlc_fourcc_t fourcc, const char **restrict dsc) +{ + return Lookup(fourcc, dsc, mapping_spu, + sizeof (mapping_spu) / sizeof (mapping_spu[0]), + desc_spu, sizeof (desc_spu) / sizeof (desc_spu[0])); +} + +static vlc_fourcc_t LookupCat(vlc_fourcc_t fourcc, const char **restrict dsc, + int cat) +{ + switch (cat) { - case VIDEO_ES: - return Lookup( p_list_video, i_fourcc ); - case AUDIO_ES: - return Lookup( p_list_audio, i_fourcc ); - case SPU_ES: - return Lookup( p_list_spu, i_fourcc ); - - default: - e = Lookup( p_list_video, i_fourcc ); - if( CreateFourcc( e.p_class ) == 0 ) - e = Lookup( p_list_audio, i_fourcc ); - if( CreateFourcc( e.p_class ) == 0 ) - e = Lookup( p_list_spu, i_fourcc ); - return e; + case VIDEO_ES: + return LookupVideo(fourcc, dsc); + case AUDIO_ES: + return LookupAudio(fourcc, dsc); + case SPU_ES: + return LookupSpu(fourcc, dsc); } + + vlc_fourcc_t ret = LookupVideo(fourcc, dsc); + if (!ret) + ret = LookupAudio(fourcc, dsc); + if (!ret) + ret = LookupSpu(fourcc, dsc); + return ret; } -/* */ -vlc_fourcc_t vlc_fourcc_GetCodec( int i_cat, vlc_fourcc_t i_fourcc ) +vlc_fourcc_t vlc_fourcc_GetCodec(int cat, vlc_fourcc_t fourcc) { - entry_t e = Find( i_cat, i_fourcc ); - - if( CreateFourcc( e.p_class ) == 0 ) - return i_fourcc; - return CreateFourcc( e.p_class ); + vlc_fourcc_t codec = LookupCat(fourcc, NULL, cat); + return codec ? codec : fourcc; } vlc_fourcc_t vlc_fourcc_GetCodecFromString( int i_cat, const char *psz_fourcc ) @@ -224,12 +198,11 @@ vlc_fourcc_t vlc_fourcc_GetCodecAudio( vlc_fourcc_t i_fourcc, int i_bits ) } } -/* */ -const char *vlc_fourcc_GetDescription( int i_cat, vlc_fourcc_t i_fourcc ) +const char *vlc_fourcc_GetDescription(int cat, vlc_fourcc_t fourcc) { - entry_t e = Find( i_cat, i_fourcc ); + const char *ret; - return e.psz_description; + return LookupCat(fourcc, &ret, cat) ? ret : ""; } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
