Reviewed-by: Stefano Sabatini <stefasab@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>tags/n1.1
| @@ -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 */ | |||
| @@ -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 | |||
| @@ -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); | |||
| /** | |||
| * @} | |||
| */ | |||
| @@ -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, \ | |||