diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-11-25 17:10:09 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-12-08 01:34:28 +0100 |
commit | a8e0d51bb8141bbe64d4e22aec72742199208192 (patch) | |
tree | c595a019f9cd97d7b978b86cf18bc19649be26f6 | |
parent | 419ade4b6193c6eb626cda01b21e7091f42b2cc2 (diff) | |
download | ffmpeg-a8e0d51bb8141bbe64d4e22aec72742199208192.tar.gz |
opt: Add support to query ranges
Reviewed-by: Stefano Sabatini <stefasab@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavutil/log.h | 8 | ||||
-rw-r--r-- | libavutil/opt.c | 80 | ||||
-rw-r--r-- | libavutil/opt.h | 54 | ||||
-rw-r--r-- | libavutil/version.h | 4 |
4 files changed, 144 insertions, 2 deletions
diff --git a/libavutil/log.h b/libavutil/log.h index ba7315fa64..6c445536c0 100644 --- a/libavutil/log.h +++ b/libavutil/log.h @@ -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 */ diff --git a/libavutil/opt.c b/libavutil/opt.c index dfee6d24b8..f060bd1a48 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -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 diff --git a/libavutil/opt.h b/libavutil/opt.h index bf84a9bc57..baf1b8233f 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -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); + /** * @} */ diff --git a/libavutil/version.h b/libavutil/version.h index 1724369a3e..f5ccd1ff2b 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -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, \ |