[vlc-commits] fourcc: use binary rather than linear search
Rémi Denis-Courmont
git at videolan.org
Thu Jun 11 22:40:11 CEST 2015
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | 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 : "";
}
More information about the vlc-commits
mailing list