[FFmpeg-devel] [PATCH] lavu/error: use a sorted table for storing error codes and strings, add test

Stefano Sabatini stefasab at gmail.com
Mon Feb 6 14:31:51 CET 2012


The table is mostly useful for enumerating the available AVERROR* in the
test output.
---
 libavutil/Makefile |    2 +-
 libavutil/error.c  |   86 +++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 66 insertions(+), 22 deletions(-)

diff --git a/libavutil/Makefile b/libavutil/Makefile
index 5034f5a..7b3a660 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -81,7 +81,7 @@ OBJS-$(ARCH_PPC) += ppc/cpu.o
 OBJS-$(ARCH_X86) += x86/cpu.o
 
 
-TESTPROGS = adler32 aes avstring base64 cpu crc des eval file fifo lfg lls \
+TESTPROGS = adler32 aes avstring base64 cpu crc des eval error file fifo lfg lls \
             md5 opt pca parseutils rational sha tree
 TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo
 
diff --git a/libavutil/error.c b/libavutil/error.c
index 1d944eb..5850c3f 100644
--- a/libavutil/error.c
+++ b/libavutil/error.c
@@ -20,31 +20,50 @@
 #include "avutil.h"
 #include "avstring.h"
 
+struct error_entry {
+    int num;
+    const char *tag;
+    const char *str;
+};
+
+/* ENTRIES NEED TO BE NUMERICALLY SORTED ON THE ERROR CODE */
+
+#define ERROR_TAG(tag) AVERROR_##tag, #tag
+struct error_entry error_entries[] = {
+    { ERROR_TAG(MUXER_NOT_FOUND),    "Muxer not found"                                }, // -1481985528
+    { ERROR_TAG(OPTION_NOT_FOUND),   "Option not found"                               }, // -1414549496
+    { ERROR_TAG(EXIT),               "Immediate exit requested"                       }, // -1414092869
+    { ERROR_TAG(STREAM_NOT_FOUND),   "Stream not found"                               }, // -1381258232
+    { ERROR_TAG(PROTOCOL_NOT_FOUND), "Protocol not found"                             }, // -1330794744
+    { ERROR_TAG(DEMUXER_NOT_FOUND),  "Demuxer not found"                              }, // -1296385272
+    { ERROR_TAG(FILTER_NOT_FOUND),   "Filter not found"                               }, // -1279870712
+    { ERROR_TAG(BSF_NOT_FOUND),      "Bitstream filter not found"                     }, // -1179861752
+    { ERROR_TAG(PATCHWELCOME),       "Not yet implemented in FFmpeg, patches welcome" }, // -1163346256
+    { ERROR_TAG(ENCODER_NOT_FOUND),  "Encoder not found"                              }, // -1129203192
+    { ERROR_TAG(DECODER_NOT_FOUND),  "Decoder not found"                              }, // -1128613112
+    { ERROR_TAG(INVALIDDATA),        "Invalid data found when processing input"       }, // -1094995529
+    { ERROR_TAG(BUG),                "Internal bug, should not have happened"         }, // -558323010
+    { ERROR_TAG(BUG2),               "Internal bug, should not have happened"         }, // -541545794
+    { ERROR_TAG(EOF),                "End of file"                                    }, // -541478725
+};
+
+static int error_entry_compare(const void *lhs, const void *rhs)
+{
+    return *(const int *)lhs - ((const struct error_entry *)rhs)->num;
+}
+
 int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
 {
     int ret = 0;
-    const char *errstr = NULL;
-
-    switch (errnum) {
-    case AVERROR_BSF_NOT_FOUND:     errstr = "Bitstream filter not found"                   ; break;
-    case AVERROR_BUG2:
-    case AVERROR_BUG:               errstr = "Internal bug, should not have happened"       ; break;
-    case AVERROR_DECODER_NOT_FOUND: errstr = "Decoder not found"                            ; break;
-    case AVERROR_DEMUXER_NOT_FOUND: errstr = "Demuxer not found"                            ; break;
-    case AVERROR_ENCODER_NOT_FOUND: errstr = "Encoder not found"                            ; break;
-    case AVERROR_EOF:               errstr = "End of file"                                  ; break;
-    case AVERROR_EXIT:              errstr = "Immediate exit requested"                     ; break;
-    case AVERROR_FILTER_NOT_FOUND:  errstr = "Filter not found"                             ; break;
-    case AVERROR_INVALIDDATA:       errstr = "Invalid data found when processing input"     ; break;
-    case AVERROR_MUXER_NOT_FOUND:   errstr = "Muxer not found"                              ; break;
-    case AVERROR_OPTION_NOT_FOUND:  errstr = "Option not found"                             ; break;
-    case AVERROR_PATCHWELCOME:      errstr = "Not yet implemented in FFmpeg, patches welcome"; break;
-    case AVERROR_PROTOCOL_NOT_FOUND:errstr = "Protocol not found"                           ; break;
-    case AVERROR_STREAM_NOT_FOUND:  errstr = "Stream not found"                             ; break;
-    }
+    struct error_entry *entry;
 
-    if (errstr) {
-        av_strlcpy(errbuf, errstr, errbuf_size);
+    entry = bsearch(&errnum,
+                    error_entries,
+                    FF_ARRAY_ELEMS(error_entries),
+                    sizeof(struct error_entry),
+                    error_entry_compare);
+    if (entry) {
+        av_strlcpy(errbuf, entry->str, errbuf_size);
     } else {
 #if HAVE_STRERROR_R
         ret = strerror_r(AVUNERROR(errnum), errbuf, errbuf_size);
@@ -57,3 +76,28 @@ int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
 
     return ret;
 }
+
+#ifdef TEST
+
+#undef printf
+
+int main(void)
+{
+    int i;
+    char errbuf[256];
+
+    for (i = 0; i < FF_ARRAY_ELEMS(error_entries); i++) {
+        struct error_entry *entry = &error_entries[i];
+        av_strerror(entry->num, errbuf, sizeof(errbuf));
+        printf("%d: [%s] %s\n", entry->num, entry->tag, errbuf);
+    }
+
+    for (i = 0; i < 256; i++) {
+        av_strerror(-i, errbuf, sizeof(errbuf));
+        printf("%d: %s\n", -i, errbuf);
+    }
+
+    return 0;
+}
+
+#endif /* TEST */
-- 
1.7.5.4



More information about the ffmpeg-devel mailing list