From 41d9d51a72674562f01118a087cd01093dbead3e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 5 Sep 2011 21:37:02 +0200 Subject: [PATCH] AVOptions: add av_opt_get*, deprecate av_get*. New functions can get values from child objects, properly report error codes and have consistent naming and signatures. --- libavutil/opt.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++----- libavutil/opt.h | 33 ++++++++++++++--- 2 files changed, 127 insertions(+), 13 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index 709beed..3d42a36 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -275,6 +275,7 @@ int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags) return set_number(obj, name, val.num, val.den, 1, search_flags); } +#if FF_API_OLD_AVOPTIONS /** * * @param buf a buffer which is used for returning non string values as strings, can be NULL @@ -312,15 +313,63 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c } return buf; } +#endif -static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum) +int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) { - const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); - void *dst; - if (!o) + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + uint8_t *bin, buf[128]; + int len, i, ret; + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + + dst = (uint8_t*)target_obj + o->offset; + + buf[0] = 0; + switch (o->type) { + case FF_OPT_TYPE_FLAGS: ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);break; + case FF_OPT_TYPE_INT: ret = snprintf(buf, sizeof(buf), "%d" , *(int *)dst);break; + case FF_OPT_TYPE_INT64: ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break; + case FF_OPT_TYPE_FLOAT: ret = snprintf(buf, sizeof(buf), "%f" , *(float *)dst);break; + case FF_OPT_TYPE_DOUBLE: ret = snprintf(buf, sizeof(buf), "%f" , *(double *)dst);break; + case FF_OPT_TYPE_RATIONAL: ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; + case FF_OPT_TYPE_STRING: + if (*(uint8_t**)dst) + *out_val = av_strdup(*(uint8_t**)dst); + else + *out_val = av_strdup(""); + return 0; + case FF_OPT_TYPE_BINARY: + len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *)); + if ((uint64_t)len*2 + 1 > INT_MAX) + return AVERROR(EINVAL); + if (!(*out_val = av_malloc(len*2 + 1))) + return AVERROR(ENOMEM); + bin = *(uint8_t**)dst; + for (i = 0; i < len; i++) + snprintf(*out_val + i*2, 3, "%02X", bin[i]); + return 0; + default: + return AVERROR(EINVAL); + } + + if (ret >= sizeof(buf)) + return AVERROR(EINVAL); + *out_val = av_strdup(buf); + return 0; +} + +static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum, + int search_flags) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) goto error; - dst= ((uint8_t*)obj) + o->offset; + dst = ((uint8_t*)target_obj) + o->offset; if (o_out) *o_out= o; @@ -339,13 +388,14 @@ error: return -1; } +#if FF_API_OLD_AVOPTIONS double av_get_double(void *obj, const char *name, const AVOption **o_out) { int64_t intnum=1; double num=1; int den=1; - if (get_number(obj, name, o_out, &num, &den, &intnum) < 0) + if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0) return NAN; return num*intnum/den; } @@ -356,7 +406,7 @@ AVRational av_get_q(void *obj, const char *name, const AVOption **o_out) double num=1; int den=1; - if (get_number(obj, name, o_out, &num, &den, &intnum) < 0) + if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0) return (AVRational){0, 0}; if (num == 1.0 && (int)intnum == intnum) return (AVRational){intnum, den}; @@ -370,10 +420,51 @@ int64_t av_get_int(void *obj, const char *name, const AVOption **o_out) double num=1; int den=1; - if (get_number(obj, name, o_out, &num, &den, &intnum) < 0) + if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0) return -1; return num*intnum/den; } +#endif + +int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + *out_val = num*intnum/den; + return 0; +} + +int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + *out_val = num*intnum/den; + return 0; +} + +int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + + if (num == 1.0 && (int)intnum == intnum) + *out_val = (AVRational){intnum, den}; + else + *out_val = av_d2q(num*intnum/den, 1<<24); + return 0; +} int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) { diff --git a/libavutil/opt.h b/libavutil/opt.h index 93da88c..e40db11 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -145,12 +145,12 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons attribute_deprecated const AVOption *av_set_double(void *obj, const char *name, double n); attribute_deprecated const AVOption *av_set_q(void *obj, const char *name, AVRational n); attribute_deprecated const AVOption *av_set_int(void *obj, const char *name, int64_t n); -#endif -double av_get_double(void *obj, const char *name, const AVOption **o_out); -AVRational av_get_q(void *obj, const char *name, const AVOption **o_out); -int64_t av_get_int(void *obj, const char *name, const AVOption **o_out); -const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len); +attribute_deprecated double av_get_double(void *obj, const char *name, const AVOption **o_out); +attribute_deprecated AVRational av_get_q(void *obj, const char *name, const AVOption **o_out); +attribute_deprecated int64_t av_get_int(void *obj, const char *name, const AVOption **o_out); +attribute_deprecated const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len); +#endif const AVOption *av_next_option(void *obj, const AVOption *last); /** @@ -335,4 +335,27 @@ int av_opt_set_q (void *obj, const char *name, AVRational val, int search_f * @} */ +/** + * @defgroup opt_get_funcs Option getting functions + * @{ + * Those functions get a value of the option with the given name from an object. + * + * @param[in] obj a struct whose first element is a pointer to an AVClass. + * @param[in] name name of the option to get. + * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN + * is passed here, then the option may be found in a child of obj. + * @param[out] out_val value of the option will be written here + * @return 0 on success, a negative error code otherwise + */ +/** + * @note the returned string will av_malloc()ed and must be av_free()ed by the caller + */ +int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val); +int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val); +int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val); +int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val); +/** + * @} + */ + #endif /* AVUTIL_OPT_H */ -- 2.7.4