[FFmpeg-devel] [PATCH] opt: implement av_opt_set_from_string().

Nicolas George nicolas.george at normalesup.org
Mon Aug 13 17:33:32 CEST 2012


It is similar to av_set_options_string() but accepts a list
of options that can be in shorthand: if the key is omitted
on the first fields, the keys from the shorthand list are
assumed, in order.

It also does not allow to specify the separators, which was
a feature never used anyway.

Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
---
 libavutil/opt.c     |   58 +++++++++++++++++++++++++++++++++++++++++++--------
 libavutil/opt.h     |   21 +++++++++++++++++++
 libavutil/version.h |    2 +-
 3 files changed, 71 insertions(+), 10 deletions(-)

diff --git a/libavutil/opt.c b/libavutil/opt.c
index 0adbddd..b65dea1 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -728,6 +728,11 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
  * separate key from value
  * @param pairs_sep a 0-terminated list of characters used to separate
  * two pairs from each other
+ * @param key_short_sep a 0-terminated list of characters that can terminate
+ * keys: either identical to key_val_sep or to the union of key_val_sep and
+ * pairs_sep
+ * @param shorthand a pointer to a pointer to a NULL terminated array of
+ * option names, for shorthand syntax
  * @return 0 if the key/value pair has been successfully parsed and
  * set, or a negative value corresponding to an AVERROR code in case
  * of error:
@@ -736,28 +741,40 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
  * cannot be set
  */
 static int parse_key_value_pair(void *ctx, const char **buf,
-                                const char *key_val_sep, const char *pairs_sep)
+                                const char *key_val_sep, const char *pairs_sep,
+                                const char *key_short_sep,
+                                const char *const **shorthand)
 {
-    char *key = av_get_token(buf, key_val_sep);
+    char *first_token = av_get_token(buf, key_short_sep);
+    const char *key;
     char *val;
     int ret;
 
-    if (*key && strspn(*buf, key_val_sep)) {
+    if (!first_token)
+        return AVERROR(ENOMEM);
+    if (*first_token && strspn(*buf, key_val_sep)) {
         (*buf)++;
+        key = first_token;
         val = av_get_token(buf, pairs_sep);
+        while (**shorthand) /* named option -> no more shorthand */
+            (*shorthand)++;
     } else {
-        av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
-        av_free(key);
-        return AVERROR(EINVAL);
+        if (!**shorthand) {
+            av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", first_token);
+            av_free(first_token);
+            return AVERROR(EINVAL);
+        }
+        key = *((*shorthand)++);
+        val = first_token;
+        first_token = NULL;
     }
-
     av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
 
     ret = av_opt_set(ctx, key, val, 0);
     if (ret == AVERROR_OPTION_NOT_FOUND)
         av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
 
-    av_free(key);
+    av_free(first_token);
     av_free(val);
     return ret;
 }
@@ -766,12 +783,13 @@ int av_set_options_string(void *ctx, const char *opts,
                           const char *key_val_sep, const char *pairs_sep)
 {
     int ret, count = 0;
+    const char *dummy_shorthand = NULL, *const *shorthand = &dummy_shorthand;
 
     if (!opts)
         return 0;
 
     while (*opts) {
-        if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
+        if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep, key_val_sep, &shorthand)) < 0)
             return ret;
         count++;
 
@@ -782,6 +800,27 @@ int av_set_options_string(void *ctx, const char *opts,
     return count;
 }
 
+int av_opt_set_from_string(void *ctx, const char *opts,
+                           const char *const *shorthand)
+{
+    int ret, count = 0;
+    const char *dummy_shorthand = NULL;
+
+    if (!opts)
+        return 0;
+    if (!shorthand)
+        shorthand = &dummy_shorthand;
+
+    while (*opts) {
+        if ((ret = parse_key_value_pair(ctx, &opts, "=", ":", "=:", &shorthand)) < 0)
+            return ret;
+        count++;
+        if (*opts)
+            opts++;
+    }
+    return count;
+}
+
 void av_opt_free(void *obj)
 {
     const AVOption *o = NULL;
@@ -932,6 +971,7 @@ int main(void)
 {
     int i;
 
+
     printf("\nTesting av_set_options_string()\n");
     {
         TestContext test_ctx = { 0 };
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 3bf30a5..cef820d 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -394,6 +394,27 @@ int av_set_options_string(void *ctx, const char *opts,
                           const char *key_val_sep, const char *pairs_sep);
 
 /**
+ * Parse the key=value pairs list in opts. For each key=value pair found,
+ * set the value of the corresponding option in ctx.
+ *
+ * @param ctx        the AVClass object to set options
+ * @param opts       the options string, "key=value" pairs separated by ':'
+ * @param shorthand  a NULL-terminated array of options names for shorthand
+ *                   notation: if the first field in opts has no "key="
+ *                   part, the key is taken from the first element of
+ *                   shorthand; then again for the second, etc., until
+ *                   either opts is finished, shorthand is finished or a
+ *                   named option is found; after that, all options must be
+ *                   named
+ * @return  the number of successfully set key=value pairs, or a negative
+ *          value corresponding to an AVERROR code in case of error:
+ *          AVERROR(EINVAL) if opts cannot be parsed,
+ *          the error code issued by av_set_string3() if a key/value pair
+ *          cannot be set
+ */
+int av_opt_set_from_string(void *ctx, const char *opts,
+                           const char *const *shorthand);
+/**
  * Free all string and binary options in obj.
  */
 void av_opt_free(void *obj);
diff --git a/libavutil/version.h b/libavutil/version.h
index 0e381b7..0b9ae39 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -39,7 +39,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR 51
-#define LIBAVUTIL_VERSION_MINOR 69
+#define LIBAVUTIL_VERSION_MINOR 70
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
-- 
1.7.10.4



More information about the ffmpeg-devel mailing list