[adding libav-devel to recipients, as this concerns API/ABI compatibility]

On date Saturday 2011-04-16 19:12:34 +0200, Nicolas George encoded:
> Le septidi 27 germinal, an CCXIX, Stefano Sabatini a écrit :
> > * implement AVERROR_EOF as a libav* specific error code, rather than
> >   mask the EPIPE POSIX error code which has a different semantics
> > 
> > * implement AVERROR_INVALIDDATA as a libav* specific error code (already
> >   implemented but it was controversial), and fix the
> >   AVERROR(EINVAL)/AVERROR_INVALIDDATA conflict
> 
> Seems reasonable.
> 
> > * drop AVERROR_NUMEXPECTED (not very important, but I believe it is a
> >   too much specific error code, so I'd prefer to replace it with
> >   AVERROR(EINVAL)
> 
> A more generic AVERROR_SYNTAX could be possible too.
> 
> > |bumping it to 51 will changes the codes returned by all libs using 
> > libavutil
> > |all of them would need to bump major.
> > |i dont think this is reasonable, thus we should undo all error 
> > redefinitions
> > |before they become real and debian burns you at the stake
> > 
> > but I don't think this is a real issue (assuming that all the libav*
> > major versions are bumped at the same time), and this is my argument:
> 
> I think the point is precisely in your parentheses: changing the error codes
> requires bumping the major version for all the libraries, not just
> libavutil.
> 

> One thought in passing: If the error codes get changed, it may be a good
> idea to adapt the definition of AVERROR(errno) to something like:
> 
> #define AVERROR(e) (-(e) - 1)
> 
> This would have the benefit that when some old piece of code returns -1
> instead of a meaningful error code, it would not displayed as "Permission
> denied" or whatever errno code is 1 on this particular platform.

I'd prefer to just return the negated POSIX error code, and avoid
other weird mapping.

Possibly we could introduce an AVERROR_GENERIC code and replace -1
with it, not that I like the idea too much.

In attachment an updated patchset.
-- 
FFmpeg = Friendly and Fast Mere Ponderous Emblematic Genius
>From 527e04cba01e80bbc4255ccc071d7bcf44b5b494 Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <stefano.sabatini-l...@poste.it>
Date: Mon, 11 Apr 2011 00:52:04 +0200
Subject: [PATCH] error: add error code AVERROR_OPTION_NOT_FOUND, and use it in opt.c

The new error code is better than AVERROR(ENOENT), which has a
completely different semantics ("No such file or directory").

Signed-off-by: Stefano Sabatini <stefano.sabatini-l...@poste.it>
---
 libavutil/error.c |    1 +
 libavutil/error.h |    1 +
 libavutil/opt.c   |    6 +++---
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/libavutil/error.c b/libavutil/error.c
index 93f8925..d4ebb9c 100644
--- a/libavutil/error.c
+++ b/libavutil/error.c
@@ -33,6 +33,7 @@ int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
     case AVERROR_MUXER_NOT_FOUND:   errstr = "Muxer not found"; break;
     case AVERROR_DECODER_NOT_FOUND: errstr = "Decoder not found"; break;
     case AVERROR_ENCODER_NOT_FOUND: errstr = "Encoder not found"; break;
+    case AVERROR_OPTION_NOT_FOUND:  errstr = "Option not found"; break;
     case AVERROR_PROTOCOL_NOT_FOUND:errstr = "Protocol not found"; break;
     case AVERROR_FILTER_NOT_FOUND:  errstr = "Filter not found"; break;
     case AVERROR_BSF_NOT_FOUND:     errstr = "Bitstream filter not found"; break;
diff --git a/libavutil/error.h b/libavutil/error.h
index 0d47566..8b5795a 100644
--- a/libavutil/error.h
+++ b/libavutil/error.h
@@ -61,6 +61,7 @@
 #define AVERROR_MUXER_NOT_FOUND    (-MKTAG(0xF8,'M','U','X')) ///< Muxer not found
 #define AVERROR_DECODER_NOT_FOUND  (-MKTAG(0xF8,'D','E','C')) ///< Decoder not found
 #define AVERROR_ENCODER_NOT_FOUND  (-MKTAG(0xF8,'E','N','C')) ///< Encoder not found
+#define AVERROR_OPTION_NOT_FOUND   (-MKTAG(0xF8,'O','P','T')) ///< Option not found
 #define AVERROR_PROTOCOL_NOT_FOUND (-MKTAG(0xF8,'P','R','O')) ///< Protocol not found
 #define AVERROR_FILTER_NOT_FOUND   (-MKTAG(0xF8,'F','I','L')) ///< Filter not found
 #define AVERROR_BSF_NOT_FOUND      (-MKTAG(0xF8,'B','S','F')) ///< Bitstream filter not found
diff --git a/libavutil/opt.c b/libavutil/opt.c
index ab6021c..e6cf340 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -57,7 +57,7 @@ static int av_set_number2(void *obj, const char *name, double num, int den, int6
     if (o_out)
         *o_out= o;
     if (!o || o->offset<=0)
-        return AVERROR(ENOENT);
+        return AVERROR_OPTION_NOT_FOUND;
 
     if (o->max*den < num*intnum || o->min*den > num*intnum) {
         av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, name);
@@ -119,7 +119,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons
     if (o_out)
         *o_out = o;
     if (!o)
-        return AVERROR(ENOENT);
+        return AVERROR_OPTION_NOT_FOUND;
     if (!val || o->offset<=0)
         return AVERROR(EINVAL);
 
@@ -490,7 +490,7 @@ static int parse_key_value_pair(void *ctx, const char **buf,
     av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key);
 
     ret = av_set_string3(ctx, key, val, 1, NULL);
-    if (ret == AVERROR(ENOENT))
+    if (ret == AVERROR_OPTION_NOT_FOUND)
         av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
 
     av_free(key);
-- 
1.7.2.3

>From 44e522dd01dbcc0595ca881c262e16add8aeb354 Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <stefano.sabatini-l...@poste.it>
Date: Mon, 11 Apr 2011 00:29:30 +0200
Subject: [PATCH] error: remove AVERROR_NUMEXPECTED at the next major bump

AVERROR_NUMEXPECTED is used only in the image muxer and demuxer, and
has a too much specific meaning, which is better explained through a
log message. Thus it can be replaced by AVERROR(EINVAL). Simplify.

Signed-off-by: Stefano Sabatini <stefano.sabatini-l...@poste.it>
---
 ffmpeg.c            |    2 +-
 libavformat/utils.c |    2 +-
 libavutil/error.c   |    2 ++
 libavutil/error.h   |    1 -
 4 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index 2b7cc86..9339ae8 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -3858,7 +3858,7 @@ static void opt_output_file(const char *filename)
     /* check filename in case of an image number is expected */
     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
         if (!av_filename_number_test(oc->filename)) {
-            print_error(oc->filename, AVERROR_NUMEXPECTED);
+            print_error(oc->filename, AVERROR(EINVAL));
             ffmpeg_exit(1);
         }
     }
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 1919f61..3362c95 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -657,7 +657,7 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
     /* check filename in case an image number is expected */
     if (fmt->flags & AVFMT_NEEDNUMBER) {
         if (!av_filename_number_test(filename)) {
-            err = AVERROR_NUMEXPECTED;
+            err = AVERROR(EINVAL);
             goto fail;
         }
     }
diff --git a/libavutil/error.c b/libavutil/error.c
index d4ebb9c..6c37535 100644
--- a/libavutil/error.c
+++ b/libavutil/error.c
@@ -27,7 +27,9 @@ int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
     switch (errnum) {
     case AVERROR_EOF:               errstr = "End of file"; break;
     case AVERROR_INVALIDDATA:       errstr = "Invalid data found when processing input"; break;
+#if LIBAVUTIL_VERSION_MAJOR < 51
     case AVERROR_NUMEXPECTED:       errstr = "Number syntax expected in filename"; break;
+#endif
     case AVERROR_PATCHWELCOME:      errstr = "Not yet implemented in FFmpeg, patches welcome"; break;
     case AVERROR_DEMUXER_NOT_FOUND: errstr = "Demuxer not found"; break;
     case AVERROR_MUXER_NOT_FOUND:   errstr = "Muxer not found"; break;
diff --git a/libavutil/error.h b/libavutil/error.h
index 8b5795a..212fe80 100644
--- a/libavutil/error.h
+++ b/libavutil/error.h
@@ -54,7 +54,6 @@
 
 #if LIBAVUTIL_VERSION_MAJOR > 50
 #define AVERROR_INVALIDDATA     (-MKTAG('I','N','D','A')) ///< Invalid data found when processing input
-#define AVERROR_NUMEXPECTED     (-MKTAG('N','U','E','X')) ///< Number syntax expected in filename
 #endif
 
 #define AVERROR_DEMUXER_NOT_FOUND  (-MKTAG(0xF8,'D','E','M')) ///< Demuxer not found
-- 
1.7.2.3

>From 70ea18df733b69a5eb0d1ca2b1eecf684a97f998 Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <stefano.sabatini-l...@poste.it>
Date: Mon, 18 Apr 2011 11:38:18 +0200
Subject: [PATCH] error: change AVERROR_EOF value at the next major bump

The current value is masking the POSIX error code EPIPE, which has a
different semantics.

Signed-off-by: Stefano Sabatini <stefano.sabatini-l...@poste.it>
---
 libavutil/error.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavutil/error.h b/libavutil/error.h
index 212fe80..b8d3364 100644
--- a/libavutil/error.h
+++ b/libavutil/error.h
@@ -39,6 +39,7 @@
 
 #if LIBAVUTIL_VERSION_MAJOR < 51
 #define AVERROR_INVALIDDATA AVERROR(EINVAL)  ///< Invalid data found when processing input
+#define AVERROR_EOF         AVERROR(EPIPE)   ///< End of file
 #define AVERROR_IO          AVERROR(EIO)     ///< I/O error
 #define AVERROR_NOENT       AVERROR(ENOENT)  ///< No such file or directory
 #define AVERROR_NOFMT       AVERROR(EILSEQ)  ///< Unknown format
@@ -48,12 +49,11 @@
 #define AVERROR_UNKNOWN     AVERROR(EINVAL)  ///< Unknown error
 #endif
 
-#define AVERROR_EOF         AVERROR(EPIPE)   ///< End of file
-
 #define AVERROR_PATCHWELCOME    (-MKTAG('P','A','W','E')) ///< Not yet implemented in FFmpeg, patches welcome
 
 #if LIBAVUTIL_VERSION_MAJOR > 50
 #define AVERROR_INVALIDDATA     (-MKTAG('I','N','D','A')) ///< Invalid data found when processing input
+#define AVERROR_EOF             (-MKTAG('E','O','F',' ')) ///< End of file
 #endif
 
 #define AVERROR_DEMUXER_NOT_FOUND  (-MKTAG(0xF8,'D','E','M')) ///< Demuxer not found
-- 
1.7.2.3

>From 5198cee5be8e8ffb94acbf8ee63293692b91be5f Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <stefano.sabatini-l...@poste.it>
Date: Mon, 18 Apr 2011 13:16:35 +0200
Subject: [PATCH] error: introduce a table for mapping error codes and error strings

Also add a test which can be used for showing the error code/string
mapping.

The table is mainly useful for the test, so is maybe overkill (and is
slightly slower since av_strerror() will have to perform an O(log2(n))
search on the known error codes table).

Signed-off-by: Stefano Sabatini <stefano.sabatini-l...@poste.it>
---
 libavutil/error.c |   96 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 74 insertions(+), 22 deletions(-)

diff --git a/libavutil/error.c b/libavutil/error.c
index 6c37535..bd9eeae 100644
--- a/libavutil/error.c
+++ b/libavutil/error.c
@@ -19,32 +19,59 @@
 #include "avutil.h"
 #include "avstring.h"
 
-int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
-{
-    int ret = 0;
-    const char *errstr = NULL;
+struct errnum_errstr_entry {
+    int errnum;
+    const char *errtag;
+    const char *errstr;
+};
 
-    switch (errnum) {
-    case AVERROR_EOF:               errstr = "End of file"; break;
-    case AVERROR_INVALIDDATA:       errstr = "Invalid data found when processing input"; break;
+/* ENTRIES NEED TO BE NUMERICALLY SORTED ON THE ERROR CODE */
+struct errnum_errstr_entry errnum_errstr_table[] = {
+    { AVERROR_MUXER_NOT_FOUND,    "MUXER_NOT_FOUND",    "Muxer not found"                                }, // -1481985528
+    { AVERROR_OPTION_NOT_FOUND,   "OPTION_NOT_FOUND",   "Option not found"                               }, // -1414549496
+    { AVERROR_EXIT,               "EXIT",               "Immediate exit requested"                       }, // -1414092869
+    { AVERROR_STREAM_NOT_FOUND,   "STREAM_NOT_FOUND",   "Stream not found"                               }, // -1381258232
+    { AVERROR_PROTOCOL_NOT_FOUND, "PROTOCOL_NOT_FOUND", "Protocol not found"                             }, // -1330794744
+    { AVERROR_DEMUXER_NOT_FOUND,  "DEMUXER_NOT_FOUND",  "Demuxer not found"                              }, // -1296385272
+    { AVERROR_FILTER_NOT_FOUND,   "FILTER_NOT_FOUND",   "Filter not found"                               }, // -1279870712
+    { AVERROR_BSF_NOT_FOUND,      "BSF_NOT_FOUND",      "Bitstream filter not found"                     }, // -1179861752
+    { AVERROR_PATCHWELCOME,       "PATCHWELCOME",       "Not yet implemented in FFmpeg, patches welcome" }, // -1163346256
+    { AVERROR_ENCODER_NOT_FOUND,  "ENCODER_NOT_FOUND",  "Encoder not found"                              }, // -1129203192
+    { AVERROR_DECODER_NOT_FOUND,  "DECODER_NOT_FOUND",  "Decoder not found"                              }, // -1128613112
+#if LIBAVUTIL_VERSION_MAJOR > 50
+    { AVERROR_INVALIDDATA,        "INVALIDDATA",        "Invalid data found when processing input"       }, // -1094995529
+#endif
+#if LIBAVUTIL_VERSION_MAJOR > 50
+    { AVERROR_EOF,                "EOF",                "End of file"                                    }, // -541478725
+#endif
 #if LIBAVUTIL_VERSION_MAJOR < 51
-    case AVERROR_NUMEXPECTED:       errstr = "Number syntax expected in filename"; break;
+    { AVERROR_NUMEXPECTED,        "NUMEXPECTED",        "Number syntax expected in filename"             }, // -33
 #endif
-    case AVERROR_PATCHWELCOME:      errstr = "Not yet implemented in FFmpeg, patches welcome"; break;
-    case AVERROR_DEMUXER_NOT_FOUND: errstr = "Demuxer not found"; break;
-    case AVERROR_MUXER_NOT_FOUND:   errstr = "Muxer not found"; break;
-    case AVERROR_DECODER_NOT_FOUND: errstr = "Decoder not found"; break;
-    case AVERROR_ENCODER_NOT_FOUND: errstr = "Encoder not found"; break;
-    case AVERROR_OPTION_NOT_FOUND:  errstr = "Option not found"; break;
-    case AVERROR_PROTOCOL_NOT_FOUND:errstr = "Protocol not found"; break;
-    case AVERROR_FILTER_NOT_FOUND:  errstr = "Filter not found"; break;
-    case AVERROR_BSF_NOT_FOUND:     errstr = "Bitstream filter not found"; break;
-    case AVERROR_STREAM_NOT_FOUND:  errstr = "Stream not found"; break;
-    case AVERROR_EXIT:              errstr = "Immediate exit requested"; break;
-    }
+#if LIBAVUTIL_VERSION_MAJOR < 51
+    { AVERROR_EOF,                "EOF",                "End of file"                                    }, // -32
+#endif
+#if LIBAVUTIL_VERSION_MAJOR < 51
+    { AVERROR_INVALIDDATA,        "INVALIDDATA",        "Invalid data found when processing input"       }, // -22
+#endif
+};
+
+static int errnum_errstr_entry_compare(const void *lhs, const void *rhs)
+{
+    return *(const int *)lhs - ((const struct errnum_errstr_entry *)rhs)->errnum;
+}
+
+int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
+{
+    int ret = 0;
+    struct errnum_errstr_entry *entry;
 
-    if (errstr) {
-        av_strlcpy(errbuf, errstr, errbuf_size);
+    entry = bsearch(&errnum,
+                    errnum_errstr_table,
+                    FF_ARRAY_ELEMS(errnum_errstr_table),
+                    sizeof(struct errnum_errstr_entry),
+                    errnum_errstr_entry_compare);
+    if (entry) {
+        av_strlcpy(errbuf, entry->errstr, errbuf_size);
     } else {
 #if HAVE_STRERROR_R
         ret = strerror_r(AVUNERROR(errnum), errbuf, errbuf_size);
@@ -57,3 +84,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(errnum_errstr_table); i++) {
+        struct errnum_errstr_entry *entry = &errnum_errstr_table[i];
+        av_strerror(entry->errnum, errbuf, sizeof(errbuf));
+        printf("%-20s : %20d : %s\n", entry->errtag, entry->errnum, 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.2.3

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to