Diederick Niehorster (12021-06-08): > This function allows formatting an option value stored in a double (such as > the min and max fields of an AVOption, or min_value and max_value of an > AVOptionRange) properly, e.g. 1 for a AV_OPT_TYPE_PIXEL_FMT -> yuyv422. > Useful when printing more info about an option than just its value. Usage > will be shown in upcoming device_get_capabilities example. av_opt_get (body > changed) still passes FATE.
Please wrap this. > > Signed-off-by: Diederick Niehorster <dcni...@gmail.com> > --- > libavutil/opt.c | 93 +++++++++++++++++++++++++++++++++++++-------- > libavutil/opt.h | 12 +++++- > libavutil/version.h | 2 +- > 3 files changed, 89 insertions(+), 18 deletions(-) > > diff --git a/libavutil/opt.c b/libavutil/opt.c > index ab127b30fa..3e385852eb 100644 > --- a/libavutil/opt.c > +++ b/libavutil/opt.c > @@ -776,24 +776,14 @@ static void format_duration(char *buf, size_t size, > int64_t d) > *(--e) = 0; > } > > -int av_opt_get(void *obj, const char *name, int search_flags, uint8_t > **out_val) > +static int print_option(void* dst, enum AVOptionType type, int search_flags, > uint8_t** out_val) I really do not like the fact that it always makes a dynamic allocation, especially since in most cases we know the buffer has a small bounded size. I'd rather have AVWriter here, but in the meantime, please consider using AVBPrint. > { > - void *dst, *target_obj; > - const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, > &target_obj); > - uint8_t *bin, buf[128]; > + uint8_t* bin, buf[128]; Here and everywhere, the pointer mark belongs with the variable name. This is an obvious example of why: written like this, it seems that bin and buf[128] are both uint8_t*. Correctly written, it's obvious that only bin is a pointer. > int len, i, ret; > int64_t i64; > > - if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST)) > - return AVERROR_OPTION_NOT_FOUND; > - > - if (o->flags & AV_OPT_FLAG_DEPRECATED) > - av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", > name, o->help); > - > - dst = (uint8_t *)target_obj + o->offset; > - > buf[0] = 0; > - switch (o->type) { > + switch (type) { > case AV_OPT_TYPE_BOOL: > ret = snprintf(buf, sizeof(buf), "%s", (char > *)av_x_if_null(get_bool_name(*(int *)dst), "invalid")); > break; > @@ -819,9 +809,6 @@ int av_opt_get(void *obj, const char *name, int > search_flags, uint8_t **out_val) > case AV_OPT_TYPE_RATIONAL: > ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational *)dst)->num, > ((AVRational *)dst)->den); > break; > - case AV_OPT_TYPE_CONST: > - ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl); > - break; I think you should have left the case here. > case AV_OPT_TYPE_STRING: > if (*(uint8_t **)dst) { > *out_val = av_strdup(*(uint8_t **)dst); > @@ -889,6 +876,80 @@ int av_opt_get(void *obj, const char *name, int > search_flags, uint8_t **out_val) > return *out_val ? 0 : AVERROR(ENOMEM); > } > > +int av_opt_get(void *obj, const char *name, int search_flags, uint8_t > **out_val) > +{ > + void *dst, *target_obj; > + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, > &target_obj); > + uint8_t buf[128]; > + int ret; > + > + if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST)) > + return AVERROR_OPTION_NOT_FOUND; > + > + if (o->flags & AV_OPT_FLAG_DEPRECATED) > + av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", > name, o->help); > + > + dst = (uint8_t *)target_obj + o->offset; > + > + > + if (o->type != AV_OPT_TYPE_CONST) > + return print_option(dst, o->type, search_flags, out_val); > + > + // special case for a const > + ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl); > + if (ret >= sizeof(buf)) > + return AVERROR(EINVAL); > + *out_val = av_strdup(buf); > + return *out_val ? 0 : AVERROR(ENOMEM); > +} > +int av_opt_to_string(double val, enum AVOptionType type, uint8_t** out_val) > +{ > + *out_val = NULL; > + > + switch (type) { > + case AV_OPT_TYPE_FLAGS: > + case AV_OPT_TYPE_BOOL: > + case AV_OPT_TYPE_INT: > + case AV_OPT_TYPE_PIXEL_FMT: > + case AV_OPT_TYPE_SAMPLE_FMT: > + { > + int temp = lrint(val); > + return print_option(&temp, type, 0, out_val); > + } > + case AV_OPT_TYPE_INT64: > + case AV_OPT_TYPE_DURATION: > + case AV_OPT_TYPE_CHANNEL_LAYOUT: > + { > + int64_t temp = llrint(val); > + return print_option(&temp, type, 0, out_val); > + } > + case AV_OPT_TYPE_UINT64: > + { > + uint64_t temp = llrint(val); > + return print_option(&temp, type, 0, out_val); > + } > + case AV_OPT_TYPE_FLOAT: > + { > + float temp = (float)val; > + return print_option(&temp, type, 0, out_val); > + } > + case AV_OPT_TYPE_DOUBLE: > + return print_option(&val, type, 0, out_val); > + > + default: > + // AV_OPT_TYPE_DICT, > + // AV_OPT_TYPE_COLOR, > + // AV_OPT_TYPE_BINARY, > + // AV_OPT_TYPE_STRING, > + // AV_OPT_TYPE_RATIONAL, > + // AV_OPT_TYPE_IMAGE_SIZE, > + // AV_OPT_TYPE_VIDEO_RATE, > + // AV_OPT_TYPE_CONST > + // cannot be stored in a single double, and are thus not a valid > input > + return AVERROR(EINVAL); > + } > +} > + > static int get_number(void *obj, const char *name, const AVOption **o_out, > double *num, int *den, int64_t *intnum, > int search_flags) > { > diff --git a/libavutil/opt.h b/libavutil/opt.h > index ac0b4567a6..bd386c411b 100644 > --- a/libavutil/opt.h > +++ b/libavutil/opt.h > @@ -361,7 +361,7 @@ typedef struct AVOptionRanges { > * for (range_index = 0; range_index < ranges->nb_ranges; range_index++) > { > * for (component_index = 0; component_index < > ranges->nb_components; component_index++) > * range[component_index] = ranges->range[ranges->nb_ranges * > component_index + range_index]; > - * //do something with range here. > + * //do something with range here. For printing the value, > av_opt_to_string() may be of use. > * } > * av_opt_freep_ranges(&ranges); > * @endcode > @@ -760,6 +760,16 @@ int av_opt_get_channel_layout(void *obj, const char > *name, int search_flags, int > * be freed with av_dict_free() by the caller > */ > int av_opt_get_dict_val(void *obj, const char *name, int search_flags, > AVDictionary **out_val); > +/** Empty line please. > + * Format option value and output to string. > + * @param[in] val an option value that can be represented as a double. > + * @param[in] type of the option. > + * @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 be av_malloc()ed and must be av_free()ed > by the caller > + */ > +int av_opt_to_string(double val, enum AVOptionType type, uint8_t **out_val); If it only works for number-like options, then the name should reflect it, and the documentation should state it. Also, I have reservations about using double here: large integers cannot be accurately coded with double. > /** > * @} > */ > diff --git a/libavutil/version.h b/libavutil/version.h > index 34b83112de..77ca4becd6 100644 > --- a/libavutil/version.h > +++ b/libavutil/version.h > @@ -79,7 +79,7 @@ > */ > > #define LIBAVUTIL_VERSION_MAJOR 57 > -#define LIBAVUTIL_VERSION_MINOR 1 > +#define LIBAVUTIL_VERSION_MINOR 2 > #define LIBAVUTIL_VERSION_MICRO 100 > > #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ Regards, -- Nicolas George
signature.asc
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".