]> git.sesse.net Git - ffmpeg/commitdiff
opt: Add support to query ranges
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 25 Nov 2012 16:10:09 +0000 (17:10 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 8 Dec 2012 00:34:28 +0000 (01:34 +0100)
Reviewed-by: Stefano Sabatini <stefasab@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavutil/log.h
libavutil/opt.c
libavutil/opt.h
libavutil/version.h

index ba7315fa64594a8d2dd3825952d78c255a8a5945..6c445536c0876ecbee008733139a37e8ea10bb27 100644 (file)
@@ -40,6 +40,8 @@ typedef enum {
     AV_CLASS_CATEGORY_NB, ///< not part of ABI/API
 }AVClassCategory;
 
+struct AVOptionRanges;
+
 /**
  * Describe the class of an AVClass context structure. That is an
  * arbitrary struct of which the first field is a pointer to an
@@ -114,6 +116,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 (52.12)
+     */
+    int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags);
 } AVClass;
 
 /* av_log API */
index dfee6d24b8938bd39ca5bca5c0404ec2e7293e2b..f060bd1a488fe6e9487a1152ee220802ef818e34 100644 (file)
@@ -1166,6 +1166,86 @@ void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
     return (uint8_t*)obj + opt->offset;
 }
 
+int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) {
+    const AVClass *c = *(AVClass**)obj;
+    int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL;
+
+    if(c->version > (52 << 16 | 11 << 8))
+        callback = c->query_ranges;
+
+    if(!callback)
+        callback = av_opt_query_ranges_default;
+
+    return callback(ranges_arg, obj, key, flags);
+}
+
+int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, 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, flags);
+
+    *ranges_arg = NULL;
+
+    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_min = field->min;
+    range->value_max = 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_min = 0;
+        range->component_max = 0x10FFFF; // max unicode value
+        range->value_min = -1;
+        range->value_max = INT_MAX;
+        break;
+    case AV_OPT_TYPE_RATIONAL:
+        range->component_min = INT_MIN;
+        range->component_max = INT_MAX;
+        break;
+    case AV_OPT_TYPE_IMAGE_SIZE:
+        range->component_min = 0;
+        range->component_max = INT_MAX/128/8;
+        range->value_min = 0;
+        range->value_max = INT_MAX/8;
+        break;
+    default:
+        goto fail;
+    }
+
+    *ranges_arg = ranges;
+    return 0;
+fail:
+    av_free(ranges);
+    av_free(range);
+    return -1;
+}
+
+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];
+        av_freep(&range->str);
+        av_freep(&ranges->range[i]);
+    }
+    av_freep(&ranges->range);
+    av_freep(rangesp);
+}
+
 #ifdef TEST
 
 typedef struct TestContext
index bf84a9bc57f5daa2abfb8ec2d3049125f85cad54..baf1b8233f663876b6df43fa9529ae2dd52218d2 100644 (file)
@@ -293,6 +293,25 @@ typedef struct AVOption {
     const char *unit;
 } AVOption;
 
+/**
+ * A single allowed range of values, or a single allowed value.
+ */
+typedef struct AVOptionRange {
+    const char *str;
+    double value_min, value_max;             ///< For string ranges this represents the min/max length, for dimensions this represents the min/max pixel count
+    double component_min, component_max;     ///< For string this represents the unicode range for chars, 0-127 limits to ASCII
+    int is_range;                            ///< if set to 1 the struct encodes a range, if set to 0 a 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
@@ -672,6 +691,41 @@ int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AV
  *          or written to.
  */
 void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
+
+/**
+ * Free an AVOptionRanges struct and set it to NULL.
+ */
+void av_opt_freep_ranges(AVOptionRanges **ranges);
+
+/**
+ * Get a list of allowed ranges for the given option.
+ *
+ * The returned list may depend on other fields in obj like for example profile.
+ *
+ * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+ *              AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+ *
+ * The result must be freed with av_opt_freep_ranges.
+ *
+ * @return >= 0 on success, a negative errro code otherwise
+ */
+int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
+
+/**
+ * Get a default list of allowed ranges for the given option.
+ *
+ * This list is constructed without using the AVClass.query_ranges() callback
+ * and can be used as fallback from within the callback.
+ *
+ * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+ *              AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+ *
+ * The result must be freed with av_opt_free_ranges.
+ *
+ * @return >= 0 on success, a negative errro code otherwise
+ */
+int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
+
 /**
  * @}
  */
index 1724369a3eb097e6190224bd7004685f7eb27a1d..f5ccd1ff2b415e93d439fb807e60aa3c6351db6f 100644 (file)
@@ -75,8 +75,8 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  52
-#define LIBAVUTIL_VERSION_MINOR  11
-#define LIBAVUTIL_VERSION_MICRO 102
+#define LIBAVUTIL_VERSION_MINOR  12
+#define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                LIBAVUTIL_VERSION_MINOR, \