[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