[FFmpeg-devel] [PATCH 1/2] opt: Add support to query ranges

Michael Niedermayer michaelni at gmx.at
Sun Nov 25 17:39:36 CET 2012


Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavutil/log.h |    6 +++++
 libavutil/opt.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 libavutil/opt.h |   48 ++++++++++++++++++++++++++++++++++
 3 files changed, 132 insertions(+)

diff --git a/libavutil/log.h b/libavutil/log.h
index ba7315f..b5205c5 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -114,6 +114,12 @@ typedef struct AVClass {
      * available since version (51 << 16 | 59 << 8 | 100)
      */
     AVClassCategory (*get_category)(void* ctx);
+
+    /**
+     * Callback to return the supported/allowed ranges.
+     * available since version (???)
+     */
+    struct AVOptionRanges *(*query_ranges)(void *obj, const char *key, int flags);
 } AVClass;
 
 /* av_log API */
diff --git a/libavutil/opt.c b/libavutil/opt.c
index 7a7f893..d1825fd 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -1027,6 +1027,84 @@ void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
     return (uint8_t*)obj + opt->offset;
 }
 
+AVOptionRanges *av_opt_query_ranges(void *obj, const char *key, int flags) {
+    const AVClass *c = *(AVClass**)obj;
+    AVOptionRanges *(*callback)(void *obj, const char *key, int flags) = NULL;
+
+    if(c->version > (52 << 16 | 8 << 9))
+        callback = c->query_ranges;
+
+    if(!callback)
+        callback = av_opt_query_ranges_default;
+
+    return callback(obj, key, flags);
+}
+
+AVOptionRanges *av_opt_query_ranges_default(void *obj, const char *key, int flags) {
+    AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
+    AVOptionRange **range_array = av_mallocz(sizeof(void*));
+    AVOptionRange *range = av_mallocz(sizeof(*range));
+    const AVOption *field = av_opt_find(obj, key, NULL, 0, 0);
+
+    if(!ranges || !range || !range_array || !field)
+        goto fail;
+
+    ranges->range = range_array;
+    ranges->range[0] = range;
+    ranges->nb_ranges = 1;
+    range->is_range = 1;
+    range->value[0].dbl = field->min;
+    range->value[1].dbl = field->max;
+
+    switch(field->type){
+    case AV_OPT_TYPE_INT:
+    case AV_OPT_TYPE_INT64:
+    case AV_OPT_TYPE_PIXEL_FMT:
+    case AV_OPT_TYPE_SAMPLE_FMT:
+    case AV_OPT_TYPE_FLOAT:
+    case AV_OPT_TYPE_DOUBLE:
+        break;
+    case AV_OPT_TYPE_STRING:
+        range->component[0].dbl = 0;
+        range->component[1].dbl = 0x10FFFF;
+        range->value[0].dbl = -1;
+        range->value[1].dbl = INT_MAX;
+        break;
+    case AV_OPT_TYPE_RATIONAL:
+        range->component[0].dbl = INT_MIN;
+        range->component[1].dbl = INT_MAX;
+        break;
+    case AV_OPT_TYPE_IMAGE_SIZE:
+        range->component[0].dbl = 0;
+        range->component[1].dbl = INT_MAX/128/8;
+        range->value[0].dbl = 0;
+        range->value[1].dbl = INT_MAX/8;
+        break;
+    default:
+        goto fail;
+    }
+
+    return ranges;
+fail:
+    av_free(ranges);
+    av_free(range);
+    return NULL;
+}
+
+void av_opt_freep_ranges(AVOptionRanges **rangesp) {
+    int i;
+    AVOptionRanges *ranges = *rangesp;
+
+    for(i=0; i<ranges->nb_ranges; i++){
+        AVOptionRange *range = ranges->range[i];
+        if (!range->is_range)
+            av_freep(&range->value[0].str);
+        av_freep(&ranges->range[i]);
+    }
+    av_freep(&ranges->range);
+    av_freep(rangesp);
+}
+
 #ifdef TEST
 
 #undef printf
diff --git a/libavutil/opt.h b/libavutil/opt.h
index c168f59..934d723 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -291,6 +291,29 @@ typedef struct AVOption {
     const char *unit;
 } AVOption;
 
+/**
+ * A single allowed range of values, or a single allowed value.
+ */
+typedef struct AVOptionRange {
+    union {
+        double dbl;     ///< For string ranges this represents the min/max length
+        const char *str;
+    } value[2];
+    union {
+        double dbl;     ///< For string this represents the unicode range for chars, 0-127 limits to ASCII
+    } component[2];
+    int is_range;       ///< 1->range, 0->single value
+} AVOptionRange;
+
+/**
+ * List of AVOptionRange structs
+ */
+typedef struct AVOptionRanges {
+    AVOptionRange **range;
+    int nb_ranges;
+} AVOptionRanges;
+
+
 #if FF_API_FIND_OPT
 /**
  * Look for an option in obj. Look only for the options which
@@ -664,6 +687,31 @@ int av_opt_get_q     (void *obj, const char *name, int search_flags, AVRational
  *          or written to.
  */
 void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
+
+/**
+ * Frees a AVOptionRanges struct and sets it to NULL
+ */
+void av_opt_freep_ranges(AVOptionRanges **ranges);
+
+/**
+ * Gets a list of allowed ranges for the given option.
+ *
+ * The returned list may depend on other fields in obj like for example profile.
+ *
+ * The result must be freed with av_opt_freep_ranges
+ */
+AVOptionRanges *av_opt_query_ranges(void *obj, const char *key, int flags);
+
+/**
+ * Gets a default list of allowed ranges for the given option.
+ *
+ * This list is constructed without using the callback and can be used as
+ * fallback from within the callback.
+ *
+ * The result must be freed with av_opt_free_ranges
+ */
+AVOptionRanges *av_opt_query_ranges_default(void *obj, const char *key, int flags);
+
 /**
  * @}
  */
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list