mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-12 02:19:35 +00:00
lavu/opt: add array options
This commit is contained in:
parent
fc706276c0
commit
efe4478778
@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
|
|||||||
|
|
||||||
API changes, most recent first:
|
API changes, most recent first:
|
||||||
|
|
||||||
|
2024-03-08 - xxxxxxxxxx - lavu 59.1.100 - opt.h
|
||||||
|
Add AV_OPT_TYPE_FLAG_ARRAY and AVOptionArrayDef.
|
||||||
|
|
||||||
2024-03-08 - xxxxxxxxxx - lavc 61.0.100 - vdpau.h
|
2024-03-08 - xxxxxxxxxx - lavc 61.0.100 - vdpau.h
|
||||||
Deprecate av_vdpau_alloc_context(), av_alloc_vdpaucontext(),
|
Deprecate av_vdpau_alloc_context(), av_alloc_vdpaucontext(),
|
||||||
av_vdpau_hwaccel_get_render2() and av_vdpau_hwaccel_set_render2().
|
av_vdpau_hwaccel_get_render2() and av_vdpau_hwaccel_set_render2().
|
||||||
|
360
libavutil/opt.c
360
libavutil/opt.c
@ -43,6 +43,8 @@
|
|||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
|
#define TYPE_BASE(type) ((type) & ~AV_OPT_TYPE_FLAG_ARRAY)
|
||||||
|
|
||||||
const AVOption *av_opt_next(const void *obj, const AVOption *last)
|
const AVOption *av_opt_next(const void *obj, const AVOption *last)
|
||||||
{
|
{
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
@ -100,6 +102,54 @@ static int opt_is_pod(enum AVOptionType type)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t opt_array_sep(const AVOption *o)
|
||||||
|
{
|
||||||
|
const AVOptionArrayDef *d = o->default_val.arr;
|
||||||
|
av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY);
|
||||||
|
return (d && d->sep) ? d->sep : ',';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *opt_array_pelem(const AVOption *o, void *array, unsigned idx)
|
||||||
|
{
|
||||||
|
av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY);
|
||||||
|
return (uint8_t *)array + idx * opt_elem_size[TYPE_BASE(o->type)];
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned *opt_array_pcount(const void *parray)
|
||||||
|
{
|
||||||
|
return (unsigned *)((const void * const *)parray + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void opt_free_elem(const AVOption *o, void *ptr)
|
||||||
|
{
|
||||||
|
switch (TYPE_BASE(o->type)) {
|
||||||
|
case AV_OPT_TYPE_STRING:
|
||||||
|
case AV_OPT_TYPE_BINARY:
|
||||||
|
av_freep(ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AV_OPT_TYPE_DICT:
|
||||||
|
av_dict_free((AVDictionary **)ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AV_OPT_TYPE_CHLAYOUT:
|
||||||
|
av_channel_layout_uninit((AVChannelLayout *)ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void opt_free_array(const AVOption *o, void *parray, unsigned *count)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < *count; i++)
|
||||||
|
opt_free_elem(o, opt_array_pelem(o, *(void **)parray, i));
|
||||||
|
|
||||||
|
av_freep(parray);
|
||||||
|
*count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum)
|
static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum)
|
||||||
{
|
{
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
@ -140,14 +190,16 @@ static int read_number(const AVOption *o, const void *dst, double *num, int *den
|
|||||||
|
|
||||||
static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
|
static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
|
||||||
{
|
{
|
||||||
if (o->type != AV_OPT_TYPE_FLAGS &&
|
const enum AVOptionType type = TYPE_BASE(o->type);
|
||||||
|
|
||||||
|
if (type != AV_OPT_TYPE_FLAGS &&
|
||||||
(!den || o->max * den < num * intnum || o->min * den > num * intnum)) {
|
(!den || o->max * den < num * intnum || o->min * den > num * intnum)) {
|
||||||
num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN);
|
num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN);
|
||||||
av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
|
av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
|
||||||
num, o->name, o->min, o->max);
|
num, o->name, o->min, o->max);
|
||||||
return AVERROR(ERANGE);
|
return AVERROR(ERANGE);
|
||||||
}
|
}
|
||||||
if (o->type == AV_OPT_TYPE_FLAGS) {
|
if (type == AV_OPT_TYPE_FLAGS) {
|
||||||
double d = num*intnum/den;
|
double d = num*intnum/den;
|
||||||
if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
|
if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
|
||||||
av_log(obj, AV_LOG_ERROR,
|
av_log(obj, AV_LOG_ERROR,
|
||||||
@ -157,7 +209,7 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (o->type) {
|
switch (type) {
|
||||||
case AV_OPT_TYPE_PIXEL_FMT:
|
case AV_OPT_TYPE_PIXEL_FMT:
|
||||||
*(enum AVPixelFormat *)dst = llrint(num / den) * intnum;
|
*(enum AVPixelFormat *)dst = llrint(num / den) * intnum;
|
||||||
break;
|
break;
|
||||||
@ -271,9 +323,10 @@ static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **d
|
|||||||
|
|
||||||
static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
|
static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
|
||||||
{
|
{
|
||||||
|
const enum AVOptionType type = TYPE_BASE(o->type);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (o->type == AV_OPT_TYPE_RATIONAL || o->type == AV_OPT_TYPE_VIDEO_RATE) {
|
if (type == AV_OPT_TYPE_RATIONAL || type == AV_OPT_TYPE_VIDEO_RATE) {
|
||||||
int num, den;
|
int num, den;
|
||||||
char c;
|
char c;
|
||||||
if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
|
if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
|
||||||
@ -290,7 +343,7 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con
|
|||||||
double d;
|
double d;
|
||||||
int64_t intnum = 1;
|
int64_t intnum = 1;
|
||||||
|
|
||||||
if (o->type == AV_OPT_TYPE_FLAGS) {
|
if (type == AV_OPT_TYPE_FLAGS) {
|
||||||
if (*val == '+' || *val == '-')
|
if (*val == '+' || *val == '-')
|
||||||
cmd = *(val++);
|
cmd = *(val++);
|
||||||
for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
|
for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
|
||||||
@ -346,7 +399,7 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (o->type == AV_OPT_TYPE_FLAGS) {
|
if (type == AV_OPT_TYPE_FLAGS) {
|
||||||
intnum = *(unsigned int*)dst;
|
intnum = *(unsigned int*)dst;
|
||||||
if (cmd == '+')
|
if (cmd == '+')
|
||||||
d = intnum | (int64_t)d;
|
d = intnum | (int64_t)d;
|
||||||
@ -531,18 +584,17 @@ static int set_string_channel_layout(void *obj, const AVOption *o,
|
|||||||
static int opt_set_elem(void *obj, void *target_obj, const AVOption *o,
|
static int opt_set_elem(void *obj, void *target_obj, const AVOption *o,
|
||||||
const char *val, void *dst)
|
const char *val, void *dst)
|
||||||
{
|
{
|
||||||
|
const enum AVOptionType type = TYPE_BASE(o->type);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
FF_DISABLE_DEPRECATION_WARNINGS
|
if (!val && (type != AV_OPT_TYPE_STRING &&
|
||||||
if (!val && (o->type != AV_OPT_TYPE_STRING &&
|
type != AV_OPT_TYPE_PIXEL_FMT && type != AV_OPT_TYPE_SAMPLE_FMT &&
|
||||||
o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
|
type != AV_OPT_TYPE_IMAGE_SIZE &&
|
||||||
o->type != AV_OPT_TYPE_IMAGE_SIZE &&
|
type != AV_OPT_TYPE_DURATION && type != AV_OPT_TYPE_COLOR &&
|
||||||
o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
|
type != AV_OPT_TYPE_BOOL))
|
||||||
o->type != AV_OPT_TYPE_BOOL))
|
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
FF_ENABLE_DEPRECATION_WARNINGS
|
|
||||||
|
|
||||||
switch (o->type) {
|
switch (type) {
|
||||||
case AV_OPT_TYPE_BOOL:
|
case AV_OPT_TYPE_BOOL:
|
||||||
return set_string_bool(obj, o, val, dst);
|
return set_string_bool(obj, o, val, dst);
|
||||||
case AV_OPT_TYPE_STRING:
|
case AV_OPT_TYPE_STRING:
|
||||||
@ -604,6 +656,85 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
|||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int opt_set_array(void *obj, void *target_obj, const AVOption *o,
|
||||||
|
const char *val, void *dst)
|
||||||
|
{
|
||||||
|
const AVOptionArrayDef *arr = o->default_val.arr;
|
||||||
|
const size_t elem_size = opt_elem_size[TYPE_BASE(o->type)];
|
||||||
|
const uint8_t sep = opt_array_sep(o);
|
||||||
|
uint8_t *str = NULL;
|
||||||
|
|
||||||
|
void *elems = NULL;
|
||||||
|
unsigned nb_elems = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (val && *val) {
|
||||||
|
str = av_malloc(strlen(val) + 1);
|
||||||
|
if (!str)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
// split and unescape the string
|
||||||
|
while (val && *val) {
|
||||||
|
uint8_t *p = str;
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
if (arr && arr->size_max && nb_elems >= arr->size_max) {
|
||||||
|
av_log(obj, AV_LOG_ERROR,
|
||||||
|
"Cannot assign more than %u elements to array option %s\n",
|
||||||
|
arr->size_max, o->name);
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; *val; val++, p++) {
|
||||||
|
if (*val == '\\' && val[1])
|
||||||
|
val++;
|
||||||
|
else if (*val == sep) {
|
||||||
|
val++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*p = *val;
|
||||||
|
}
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
tmp = av_realloc_array(elems, nb_elems + 1, elem_size);
|
||||||
|
if (!tmp) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
elems = tmp;
|
||||||
|
|
||||||
|
tmp = opt_array_pelem(o, elems, nb_elems);
|
||||||
|
memset(tmp, 0, elem_size);
|
||||||
|
|
||||||
|
ret = opt_set_elem(obj, target_obj, o, str, tmp);
|
||||||
|
if (ret < 0)
|
||||||
|
goto fail;
|
||||||
|
nb_elems++;
|
||||||
|
}
|
||||||
|
av_freep(&str);
|
||||||
|
|
||||||
|
opt_free_array(o, dst, opt_array_pcount(dst));
|
||||||
|
|
||||||
|
if (arr && nb_elems < arr->size_min) {
|
||||||
|
av_log(obj, AV_LOG_ERROR,
|
||||||
|
"Cannot assign fewer than %u elements to array option %s\n",
|
||||||
|
arr->size_min, o->name);
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
*((void **)dst) = elems;
|
||||||
|
*opt_array_pcount(dst) = nb_elems;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
av_freep(&str);
|
||||||
|
opt_free_array(o, &elems, &nb_elems);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
|
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
|
||||||
{
|
{
|
||||||
void *dst, *target_obj;
|
void *dst, *target_obj;
|
||||||
@ -619,7 +750,8 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
|
|||||||
|
|
||||||
dst = ((uint8_t *)target_obj) + o->offset;
|
dst = ((uint8_t *)target_obj) + o->offset;
|
||||||
|
|
||||||
return opt_set_elem(obj, target_obj, o, val, dst);
|
return ((o->type & AV_OPT_TYPE_FLAG_ARRAY) ?
|
||||||
|
opt_set_array : opt_set_elem)(obj, target_obj, o, val, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPT_EVAL_NUMBER(name, opttype, vartype) \
|
#define OPT_EVAL_NUMBER(name, opttype, vartype) \
|
||||||
@ -647,7 +779,7 @@ static int set_number(void *obj, const char *name, double num, int den, int64_t
|
|||||||
if (!o || !target_obj)
|
if (!o || !target_obj)
|
||||||
return AVERROR_OPTION_NOT_FOUND;
|
return AVERROR_OPTION_NOT_FOUND;
|
||||||
|
|
||||||
if (o->flags & AV_OPT_FLAG_READONLY)
|
if ((o->flags & AV_OPT_FLAG_READONLY) || (o->type & AV_OPT_TYPE_FLAG_ARRAY))
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
|
|
||||||
dst = ((uint8_t *)target_obj) + o->offset;
|
dst = ((uint8_t *)target_obj) + o->offset;
|
||||||
@ -730,7 +862,8 @@ int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int searc
|
|||||||
return AVERROR_OPTION_NOT_FOUND;
|
return AVERROR_OPTION_NOT_FOUND;
|
||||||
if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
|
if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
|
||||||
av_log(obj, AV_LOG_ERROR,
|
av_log(obj, AV_LOG_ERROR,
|
||||||
"The value set by option '%s' is not a video rate.\n", o->name);
|
"The value set by option '%s' is not a video rate.\n",
|
||||||
|
o->name);
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
if (val.num <= 0 || val.den <= 0)
|
if (val.num <= 0 || val.den <= 0)
|
||||||
@ -852,7 +985,7 @@ static int opt_get_elem(const AVOption *o, uint8_t **pbuf, size_t buf_len,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch (o->type) {
|
switch (TYPE_BASE(o->type)) {
|
||||||
case AV_OPT_TYPE_BOOL:
|
case AV_OPT_TYPE_BOOL:
|
||||||
ret = snprintf(*pbuf, buf_len, "%s", get_bool_name(*(int *)dst));
|
ret = snprintf(*pbuf, buf_len, "%s", get_bool_name(*(int *)dst));
|
||||||
break;
|
break;
|
||||||
@ -949,6 +1082,66 @@ static int opt_get_elem(const AVOption *o, uint8_t **pbuf, size_t buf_len,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int opt_get_array(const AVOption *o, void *dst, uint8_t **out_val)
|
||||||
|
{
|
||||||
|
const unsigned count = *opt_array_pcount(dst);
|
||||||
|
const uint8_t sep = opt_array_sep(o);
|
||||||
|
|
||||||
|
uint8_t *str = NULL;
|
||||||
|
size_t str_len = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*out_val = NULL;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < count; i++) {
|
||||||
|
uint8_t buf[128], *out = buf;
|
||||||
|
size_t out_len;
|
||||||
|
|
||||||
|
ret = opt_get_elem(o, &out, sizeof(buf),
|
||||||
|
opt_array_pelem(o, *(void **)dst, i), 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
out_len = strlen(out);
|
||||||
|
if (out_len > SIZE_MAX / 2 - !!i ||
|
||||||
|
!!i + out_len * 2 > SIZE_MAX - str_len - 1) {
|
||||||
|
ret = AVERROR(ERANGE);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// terminator escaping separator
|
||||||
|
// ↓ ↓ ↓
|
||||||
|
ret = av_reallocp(&str, str_len + 1 + out_len * 2 + !!i);
|
||||||
|
if (ret < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
// add separator if needed
|
||||||
|
if (i)
|
||||||
|
str[str_len++] = sep;
|
||||||
|
|
||||||
|
// escape the element
|
||||||
|
for (unsigned j = 0; j < out_len; j++) {
|
||||||
|
uint8_t val = out[j];
|
||||||
|
if (val == sep || val == '\\')
|
||||||
|
str[str_len++] = '\\';
|
||||||
|
str[str_len++] = val;
|
||||||
|
}
|
||||||
|
str[str_len] = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (out != buf)
|
||||||
|
av_freep(&out);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_freep(&str);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_val = str;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
|
int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
|
||||||
{
|
{
|
||||||
void *dst, *target_obj;
|
void *dst, *target_obj;
|
||||||
@ -964,8 +1157,19 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
|
|||||||
|
|
||||||
dst = (uint8_t *)target_obj + o->offset;
|
dst = (uint8_t *)target_obj + o->offset;
|
||||||
|
|
||||||
buf[0] = 0;
|
if (o->type & AV_OPT_TYPE_FLAG_ARRAY) {
|
||||||
|
ret = opt_get_array(o, dst, out_val);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (!*out_val && !(search_flags & AV_OPT_ALLOW_NULL)) {
|
||||||
|
*out_val = av_strdup("");
|
||||||
|
if (!*out_val)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = 0;
|
||||||
out = buf;
|
out = buf;
|
||||||
ret = opt_get_elem(o, &out, sizeof(buf), dst, search_flags);
|
ret = opt_get_elem(o, &out, sizeof(buf), dst, search_flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -988,6 +1192,8 @@ static int get_number(void *obj, const char *name, double *num, int *den, int64_
|
|||||||
const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
||||||
if (!o || !target_obj)
|
if (!o || !target_obj)
|
||||||
return AVERROR_OPTION_NOT_FOUND;
|
return AVERROR_OPTION_NOT_FOUND;
|
||||||
|
if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
|
||||||
dst = ((uint8_t *)target_obj) + o->offset;
|
dst = ((uint8_t *)target_obj) + o->offset;
|
||||||
|
|
||||||
@ -1045,7 +1251,7 @@ int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_
|
|||||||
return AVERROR_OPTION_NOT_FOUND;
|
return AVERROR_OPTION_NOT_FOUND;
|
||||||
if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
|
if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
|
||||||
av_log(obj, AV_LOG_ERROR,
|
av_log(obj, AV_LOG_ERROR,
|
||||||
"The value for option '%s' is not an image size.\n", name);
|
"The value for option '%s' is not a image size.\n", name);
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1252,11 +1458,16 @@ static void log_type(void *av_log_obj, const AVOption *o,
|
|||||||
[AV_OPT_TYPE_CHLAYOUT] = "<channel_layout>",
|
[AV_OPT_TYPE_CHLAYOUT] = "<channel_layout>",
|
||||||
[AV_OPT_TYPE_BOOL] = "<boolean>",
|
[AV_OPT_TYPE_BOOL] = "<boolean>",
|
||||||
};
|
};
|
||||||
|
const enum AVOptionType type = TYPE_BASE(o->type);
|
||||||
|
|
||||||
if (o->type == AV_OPT_TYPE_CONST && parent_type == AV_OPT_TYPE_INT)
|
if (o->type == AV_OPT_TYPE_CONST && TYPE_BASE(parent_type) == AV_OPT_TYPE_INT)
|
||||||
av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", o->default_val.i64);
|
av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", o->default_val.i64);
|
||||||
else if (o->type < FF_ARRAY_ELEMS(desc) && desc[o->type])
|
else if (type < FF_ARRAY_ELEMS(desc) && desc[type]) {
|
||||||
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", desc[o->type]);
|
if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
|
||||||
|
av_log(av_log_obj, AV_LOG_INFO, "[%-10s]", desc[type]);
|
||||||
|
else
|
||||||
|
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", desc[type]);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
|
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
|
||||||
}
|
}
|
||||||
@ -1274,6 +1485,13 @@ static void log_default(void *obj, void *av_log_obj, const AVOption *opt)
|
|||||||
!opt->default_val.str)
|
!opt->default_val.str)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) {
|
||||||
|
const AVOptionArrayDef *arr = opt->default_val.arr;
|
||||||
|
if (arr && arr->def)
|
||||||
|
av_log(av_log_obj, AV_LOG_INFO, " (default %s)", arr->def);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
av_log(av_log_obj, AV_LOG_INFO, " (default ");
|
av_log(av_log_obj, AV_LOG_INFO, " (default ");
|
||||||
switch (opt->type) {
|
switch (opt->type) {
|
||||||
case AV_OPT_TYPE_BOOL:
|
case AV_OPT_TYPE_BOOL:
|
||||||
@ -1434,6 +1652,21 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
|
|||||||
if (opt->flags & AV_OPT_FLAG_READONLY)
|
if (opt->flags & AV_OPT_FLAG_READONLY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) {
|
||||||
|
const AVOptionArrayDef *arr = opt->default_val.arr;
|
||||||
|
const char sep = opt_array_sep(opt);
|
||||||
|
|
||||||
|
av_assert0(sep && sep != '\\' &&
|
||||||
|
(sep < 'a' || sep > 'z') &&
|
||||||
|
(sep < 'A' || sep > 'Z') &&
|
||||||
|
(sep < '0' || sep > '9'));
|
||||||
|
|
||||||
|
if (arr && arr->def)
|
||||||
|
opt_set_array(s, s, opt, arr->def, dst);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (opt->type) {
|
switch (opt->type) {
|
||||||
case AV_OPT_TYPE_CONST:
|
case AV_OPT_TYPE_CONST:
|
||||||
/* Nothing to be done here */
|
/* Nothing to be done here */
|
||||||
@ -1676,23 +1909,12 @@ void av_opt_free(void *obj)
|
|||||||
{
|
{
|
||||||
const AVOption *o = NULL;
|
const AVOption *o = NULL;
|
||||||
while ((o = av_opt_next(obj, o))) {
|
while ((o = av_opt_next(obj, o))) {
|
||||||
switch (o->type) {
|
void *pitem = (uint8_t *)obj + o->offset;
|
||||||
case AV_OPT_TYPE_STRING:
|
|
||||||
case AV_OPT_TYPE_BINARY:
|
|
||||||
av_freep((uint8_t *)obj + o->offset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AV_OPT_TYPE_DICT:
|
if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
|
||||||
av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset));
|
opt_free_array(o, pitem, opt_array_pcount(pitem));
|
||||||
break;
|
else
|
||||||
|
opt_free_elem(o, pitem);
|
||||||
case AV_OPT_TYPE_CHLAYOUT:
|
|
||||||
av_channel_layout_uninit((AVChannelLayout *)(((uint8_t *)obj) + o->offset));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1794,7 +2016,9 @@ const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter)
|
|||||||
void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
|
void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
|
||||||
{
|
{
|
||||||
const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
|
const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
|
||||||
if(!opt)
|
|
||||||
|
// no direct access to array-type options
|
||||||
|
if (!opt || (opt->type & AV_OPT_TYPE_FLAG_ARRAY))
|
||||||
return NULL;
|
return NULL;
|
||||||
return (uint8_t*)obj + opt->offset;
|
return (uint8_t*)obj + opt->offset;
|
||||||
}
|
}
|
||||||
@ -1844,6 +2068,40 @@ static int opt_copy_elem(void *logctx, enum AVOptionType type,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int opt_copy_array(void *logctx, const AVOption *o,
|
||||||
|
void **pdst, const void * const *psrc)
|
||||||
|
{
|
||||||
|
unsigned nb_elems = *opt_array_pcount(psrc);
|
||||||
|
void *dst = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (*pdst == *psrc) {
|
||||||
|
*pdst = NULL;
|
||||||
|
*opt_array_pcount(pdst) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt_free_array(o, pdst, opt_array_pcount(pdst));
|
||||||
|
|
||||||
|
dst = av_calloc(nb_elems, opt_elem_size[TYPE_BASE(o->type)]);
|
||||||
|
if (!dst)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < nb_elems; i++) {
|
||||||
|
ret = opt_copy_elem(logctx, TYPE_BASE(o->type),
|
||||||
|
opt_array_pelem(o, dst, i),
|
||||||
|
opt_array_pelem(o, *(void**)psrc, i));
|
||||||
|
if (ret < 0) {
|
||||||
|
opt_free_array(o, &dst, &nb_elems);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*pdst = dst;
|
||||||
|
*opt_array_pcount(pdst) = nb_elems;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int av_opt_copy(void *dst, const void *src)
|
int av_opt_copy(void *dst, const void *src)
|
||||||
{
|
{
|
||||||
const AVOption *o = NULL;
|
const AVOption *o = NULL;
|
||||||
@ -1861,7 +2119,9 @@ int av_opt_copy(void *dst, const void *src)
|
|||||||
void *field_dst = (uint8_t *)dst + o->offset;
|
void *field_dst = (uint8_t *)dst + o->offset;
|
||||||
void *field_src = (uint8_t *)src + o->offset;
|
void *field_src = (uint8_t *)src + o->offset;
|
||||||
|
|
||||||
int err = opt_copy_elem(dst, o->type, field_dst, field_src);
|
int err = (o->type & AV_OPT_TYPE_FLAG_ARRAY) ?
|
||||||
|
opt_copy_array(dst, o, field_dst, field_src) :
|
||||||
|
opt_copy_elem (dst, o->type, field_dst, field_src);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
ret = err;
|
ret = err;
|
||||||
}
|
}
|
||||||
@ -1990,6 +2250,24 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o)
|
|||||||
|
|
||||||
dst = ((uint8_t*)obj) + o->offset;
|
dst = ((uint8_t*)obj) + o->offset;
|
||||||
|
|
||||||
|
if (o->type & AV_OPT_TYPE_FLAG_ARRAY) {
|
||||||
|
const char *def = o->default_val.arr ? o->default_val.arr->def : NULL;
|
||||||
|
uint8_t *val;
|
||||||
|
|
||||||
|
ret = opt_get_array(o, dst, &val);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!!val != !!def)
|
||||||
|
ret = 0;
|
||||||
|
else if (val)
|
||||||
|
ret = !strcmp(val, def);
|
||||||
|
|
||||||
|
av_freep(&val);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
case AV_OPT_TYPE_CONST:
|
case AV_OPT_TYPE_CONST:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -250,6 +250,17 @@ enum AVOptionType{
|
|||||||
AV_OPT_TYPE_COLOR,
|
AV_OPT_TYPE_COLOR,
|
||||||
AV_OPT_TYPE_BOOL,
|
AV_OPT_TYPE_BOOL,
|
||||||
AV_OPT_TYPE_CHLAYOUT,
|
AV_OPT_TYPE_CHLAYOUT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* May be combined with another regular option type to declare an array
|
||||||
|
* option.
|
||||||
|
*
|
||||||
|
* For array options, @ref AVOption.offset should refer to a pointer
|
||||||
|
* corresponding to the option type. The pointer should be immediately
|
||||||
|
* followed by an unsigned int that will store the number of elements in the
|
||||||
|
* array.
|
||||||
|
*/
|
||||||
|
AV_OPT_TYPE_FLAG_ARRAY = (1 << 16),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -295,6 +306,40 @@ enum AVOptionType{
|
|||||||
*/
|
*/
|
||||||
#define AV_OPT_FLAG_CHILD_CONSTS (1 << 18)
|
#define AV_OPT_FLAG_CHILD_CONSTS (1 << 18)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* May be set as default_val for AV_OPT_TYPE_FLAG_ARRAY options.
|
||||||
|
*/
|
||||||
|
typedef struct AVOptionArrayDef {
|
||||||
|
/**
|
||||||
|
* Native access only.
|
||||||
|
*
|
||||||
|
* Default value of the option, as would be serialized by av_opt_get() (i.e.
|
||||||
|
* using the value of sep as the separator).
|
||||||
|
*/
|
||||||
|
const char *def;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum number of elements in the array. When this field is non-zero, def
|
||||||
|
* must be non-NULL and contain at least this number of elements.
|
||||||
|
*/
|
||||||
|
unsigned size_min;
|
||||||
|
/**
|
||||||
|
* Maximum number of elements in the array, 0 when unlimited.
|
||||||
|
*/
|
||||||
|
unsigned size_max;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Separator between array elements in string representations of this
|
||||||
|
* option, used by av_opt_set() and av_opt_get(). It must be a printable
|
||||||
|
* ASCII character, excluding alphanumeric and the backslash. A comma is
|
||||||
|
* used when sep=0.
|
||||||
|
*
|
||||||
|
* The separator and the backslash must be backslash-escaped in order to
|
||||||
|
* appear in string representations of the option value.
|
||||||
|
*/
|
||||||
|
char sep;
|
||||||
|
} AVOptionArrayDef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AVOption
|
* AVOption
|
||||||
*/
|
*/
|
||||||
@ -317,8 +362,7 @@ typedef struct AVOption {
|
|||||||
enum AVOptionType type;
|
enum AVOptionType type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Native access only.
|
* Native access only, except when documented otherwise.
|
||||||
*
|
|
||||||
* the default value for scalar options
|
* the default value for scalar options
|
||||||
*/
|
*/
|
||||||
union {
|
union {
|
||||||
@ -327,6 +371,14 @@ typedef struct AVOption {
|
|||||||
const char *str;
|
const char *str;
|
||||||
/* TODO those are unused now */
|
/* TODO those are unused now */
|
||||||
AVRational q;
|
AVRational q;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for AV_OPT_TYPE_FLAG_ARRAY options. May be NULL.
|
||||||
|
*
|
||||||
|
* Foreign access to some members allowed, as noted in AVOptionArrayDef
|
||||||
|
* documentation.
|
||||||
|
*/
|
||||||
|
const AVOptionArrayDef *arr;
|
||||||
} default_val;
|
} default_val;
|
||||||
double min; ///< minimum valid value for the option
|
double min; ///< minimum valid value for the option
|
||||||
double max; ///< maximum valid value for the option
|
double max; ///< maximum valid value for the option
|
||||||
|
@ -57,6 +57,15 @@ typedef struct TestContext {
|
|||||||
int bool3;
|
int bool3;
|
||||||
AVDictionary *dict1;
|
AVDictionary *dict1;
|
||||||
AVDictionary *dict2;
|
AVDictionary *dict2;
|
||||||
|
|
||||||
|
int **array_int;
|
||||||
|
unsigned nb_array_int;
|
||||||
|
|
||||||
|
char **array_str;
|
||||||
|
unsigned nb_array_str;
|
||||||
|
|
||||||
|
AVDictionary **array_dict;
|
||||||
|
unsigned nb_array_dict;
|
||||||
} TestContext;
|
} TestContext;
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(TestContext, x)
|
#define OFFSET(x) offsetof(TestContext, x)
|
||||||
@ -65,6 +74,16 @@ typedef struct TestContext {
|
|||||||
#define TEST_FLAG_LAME 02
|
#define TEST_FLAG_LAME 02
|
||||||
#define TEST_FLAG_MU 04
|
#define TEST_FLAG_MU 04
|
||||||
|
|
||||||
|
static const AVOptionArrayDef array_str = {
|
||||||
|
.sep = '|',
|
||||||
|
.def = "str0|str\\|1|str\\\\2",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const AVOptionArrayDef array_dict = {
|
||||||
|
// there are three levels of escaping - C string, array option, dict - so 8 backslashes are needed to get a literal one inside a dict key/val
|
||||||
|
.def = "k00=v\\\\\\\\00:k01=v\\,01,k10=v\\\\=1\\\\:0",
|
||||||
|
};
|
||||||
|
|
||||||
static const AVOption test_options[]= {
|
static const AVOption test_options[]= {
|
||||||
{"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, 1 },
|
{"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, 1 },
|
||||||
{"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, 1 },
|
{"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, 1 },
|
||||||
@ -93,6 +112,9 @@ static const AVOption test_options[]= {
|
|||||||
{"bool3", "set boolean value", OFFSET(bool3), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 1 },
|
{"bool3", "set boolean value", OFFSET(bool3), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 1 },
|
||||||
{"dict1", "set dictionary value", OFFSET(dict1), AV_OPT_TYPE_DICT, { .str = NULL}, 0, 0, 1 },
|
{"dict1", "set dictionary value", OFFSET(dict1), AV_OPT_TYPE_DICT, { .str = NULL}, 0, 0, 1 },
|
||||||
{"dict2", "set dictionary value", OFFSET(dict2), AV_OPT_TYPE_DICT, { .str = "happy=':-)'"}, 0, 0, 1 },
|
{"dict2", "set dictionary value", OFFSET(dict2), AV_OPT_TYPE_DICT, { .str = "happy=':-)'"}, 0, 0, 1 },
|
||||||
|
{"array_int", "array of ints", OFFSET(array_int), AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = AV_OPT_FLAG_RUNTIME_PARAM },
|
||||||
|
{"array_str", "array of strings", OFFSET(array_str), AV_OPT_TYPE_STRING | AV_OPT_TYPE_FLAG_ARRAY, { .arr = &array_str }, .flags = AV_OPT_FLAG_RUNTIME_PARAM },
|
||||||
|
{"array_dict", "array of dicts", OFFSET(array_dict), AV_OPT_TYPE_DICT | AV_OPT_TYPE_FLAG_ARRAY, { .arr = &array_dict }, .flags = AV_OPT_FLAG_RUNTIME_PARAM },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,6 +168,17 @@ int main(void)
|
|||||||
printf("flt=%.6f\n", test_ctx.flt);
|
printf("flt=%.6f\n", test_ctx.flt);
|
||||||
printf("dbl=%.6f\n", test_ctx.dbl);
|
printf("dbl=%.6f\n", test_ctx.dbl);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < test_ctx.nb_array_str; i++)
|
||||||
|
printf("array_str[%u]=%s\n", i, test_ctx.array_str[i]);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < test_ctx.nb_array_dict; i++) {
|
||||||
|
AVDictionary *d = test_ctx.array_dict[i];
|
||||||
|
const AVDictionaryEntry *e = NULL;
|
||||||
|
|
||||||
|
while ((e = av_dict_iterate(d, e)))
|
||||||
|
printf("array_dict[%u]: %s\t%s\n", i, e->key, e->value);
|
||||||
|
}
|
||||||
|
|
||||||
av_opt_show2(&test_ctx, NULL, -1, 0);
|
av_opt_show2(&test_ctx, NULL, -1, 0);
|
||||||
|
|
||||||
av_opt_free(&test_ctx);
|
av_opt_free(&test_ctx);
|
||||||
@ -177,6 +210,9 @@ int main(void)
|
|||||||
TestContext test_ctx = { 0 };
|
TestContext test_ctx = { 0 };
|
||||||
TestContext test2_ctx = { 0 };
|
TestContext test2_ctx = { 0 };
|
||||||
const AVOption *o = NULL;
|
const AVOption *o = NULL;
|
||||||
|
char *val = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
test_ctx.class = &test_class;
|
test_ctx.class = &test_class;
|
||||||
test2_ctx.class = &test_class;
|
test2_ctx.class = &test_class;
|
||||||
|
|
||||||
@ -209,6 +245,17 @@ int main(void)
|
|||||||
av_free(value1);
|
av_free(value1);
|
||||||
av_free(value2);
|
av_free(value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// av_opt_set(NULL) with an array option resets it
|
||||||
|
ret = av_opt_set(&test_ctx, "array_dict", NULL, 0);
|
||||||
|
printf("av_opt_set(\"array_dict\", NULL) -> %d\n", ret);
|
||||||
|
printf("array_dict=%sNULL; nb_array_dict=%u\n",
|
||||||
|
test_ctx.array_dict ? "non-" : "", test_ctx.nb_array_dict);
|
||||||
|
|
||||||
|
// av_opt_get() on an empty array should return a NULL string
|
||||||
|
ret = av_opt_get(&test_ctx, "array_dict", AV_OPT_ALLOW_NULL, (uint8_t**)&val);
|
||||||
|
printf("av_opt_get(\"array_dict\") -> %s\n", val ? val : "NULL");
|
||||||
|
|
||||||
av_opt_free(&test_ctx);
|
av_opt_free(&test_ctx);
|
||||||
av_opt_free(&test2_ctx);
|
av_opt_free(&test2_ctx);
|
||||||
}
|
}
|
||||||
@ -303,6 +350,8 @@ int main(void)
|
|||||||
"bool1=true",
|
"bool1=true",
|
||||||
"bool2=auto",
|
"bool2=auto",
|
||||||
"dict1='happy=\\:-):sad=\\:-('",
|
"dict1='happy=\\:-):sad=\\:-('",
|
||||||
|
"array_int=0,32,2147483647",
|
||||||
|
"array_int=2147483648", // out of range, should fail
|
||||||
};
|
};
|
||||||
|
|
||||||
test_ctx.class = &test_class;
|
test_ctx.class = &test_class;
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define LIBAVUTIL_VERSION_MAJOR 59
|
#define LIBAVUTIL_VERSION_MAJOR 59
|
||||||
#define LIBAVUTIL_VERSION_MINOR 0
|
#define LIBAVUTIL_VERSION_MINOR 1
|
||||||
#define LIBAVUTIL_VERSION_MICRO 100
|
#define LIBAVUTIL_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
|
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
|
||||||
|
@ -17,6 +17,12 @@ binary_size=4
|
|||||||
num64=1
|
num64=1
|
||||||
flt=0.333333
|
flt=0.333333
|
||||||
dbl=0.333333
|
dbl=0.333333
|
||||||
|
array_str[0]=str0
|
||||||
|
array_str[1]=str|1
|
||||||
|
array_str[2]=str\2
|
||||||
|
array_dict[0]: k00 v\00
|
||||||
|
array_dict[0]: k01 v,01
|
||||||
|
array_dict[1]: k10 v=1:0
|
||||||
TestContext AVOptions:
|
TestContext AVOptions:
|
||||||
-num <int> E.......... set num (from 0 to 100) (default 0)
|
-num <int> E.......... set num (from 0 to 100) (default 0)
|
||||||
-toggle <int> E.......... set toggle (from 0 to 1) (default 1)
|
-toggle <int> E.......... set toggle (from 0 to 1) (default 1)
|
||||||
@ -45,6 +51,9 @@ TestContext AVOptions:
|
|||||||
-bool3 <boolean> E.......... set boolean value (default false)
|
-bool3 <boolean> E.......... set boolean value (default false)
|
||||||
-dict1 <dictionary> E.......... set dictionary value
|
-dict1 <dictionary> E.......... set dictionary value
|
||||||
-dict2 <dictionary> E.......... set dictionary value (default "happy=':-)'")
|
-dict2 <dictionary> E.......... set dictionary value (default "happy=':-)'")
|
||||||
|
-array_int [<int> ].........T. array of ints
|
||||||
|
-array_str [<string> ].........T. array of strings (default str0|str\|1|str\\2)
|
||||||
|
-array_dict [<dictionary>].........T. array of dicts (default k00=v\\\\00:k01=v\,01,k10=v\\=1\\:0)
|
||||||
|
|
||||||
Testing av_opt_is_set_to_default()
|
Testing av_opt_is_set_to_default()
|
||||||
name: num default:1 error:
|
name: num default:1 error:
|
||||||
@ -74,6 +83,9 @@ name: bool2 default:0 error:
|
|||||||
name: bool3 default:1 error:
|
name: bool3 default:1 error:
|
||||||
name: dict1 default:1 error:
|
name: dict1 default:1 error:
|
||||||
name: dict2 default:0 error:
|
name: dict2 default:0 error:
|
||||||
|
name: array_int default:0 error:
|
||||||
|
name: array_str default:0 error:
|
||||||
|
name:array_dict default:0 error:
|
||||||
name: num default:1 error:
|
name: num default:1 error:
|
||||||
name: toggle default:1 error:
|
name: toggle default:1 error:
|
||||||
name: rational default:1 error:
|
name: rational default:1 error:
|
||||||
@ -101,6 +113,9 @@ name: bool2 default:1 error:
|
|||||||
name: bool3 default:1 error:
|
name: bool3 default:1 error:
|
||||||
name: dict1 default:1 error:
|
name: dict1 default:1 error:
|
||||||
name: dict2 default:1 error:
|
name: dict2 default:1 error:
|
||||||
|
name: array_int default:0 error:
|
||||||
|
name: array_str default:1 error:
|
||||||
|
name:array_dict default:1 error:
|
||||||
|
|
||||||
Testing av_opt_get/av_opt_set()
|
Testing av_opt_get/av_opt_set()
|
||||||
name: num get: 0 set: OK get: 0 OK
|
name: num get: 0 set: OK get: 0 OK
|
||||||
@ -127,9 +142,15 @@ name: bool2 get: true set: OK get: true
|
|||||||
name: bool3 get: false set: OK get: false OK
|
name: bool3 get: false set: OK get: false OK
|
||||||
name: dict1 get: set: OK get: OK
|
name: dict1 get: set: OK get: OK
|
||||||
name: dict2 get: happy=\:-) set: OK get: happy=\:-) OK
|
name: dict2 get: happy=\:-) set: OK get: happy=\:-) OK
|
||||||
|
name: array_int get: set: OK get: OK
|
||||||
|
name: array_str get: str0|str\|1|str\\2 set: OK get: str0|str\|1|str\\2 OK
|
||||||
|
name: array_dict get: k00=v\\\\00:k01=v\,01,k10=v\\=1\\:0 set: OK get: k00=v\\\\00:k01=v\,01,k10=v\\=1\\:0 OK
|
||||||
|
av_opt_set("array_dict", NULL) -> 0
|
||||||
|
array_dict=NULL; nb_array_dict=0
|
||||||
|
av_opt_get("array_dict") -> NULL
|
||||||
|
|
||||||
Test av_opt_serialize()
|
Test av_opt_serialize()
|
||||||
num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-)
|
num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-),array_int=,array_str=str0|str\\|1|str\\\\2,array_dict=k00\=v\\\\\\\\00:k01\=v\\\,01\,k10\=v\\\\\=1\\\\:0
|
||||||
Setting entry with key 'num' to value '0'
|
Setting entry with key 'num' to value '0'
|
||||||
Setting entry with key 'toggle' to value '1'
|
Setting entry with key 'toggle' to value '1'
|
||||||
Setting entry with key 'rational' to value '1/1'
|
Setting entry with key 'rational' to value '1/1'
|
||||||
@ -154,7 +175,10 @@ Setting entry with key 'bool2' to value 'true'
|
|||||||
Setting entry with key 'bool3' to value 'false'
|
Setting entry with key 'bool3' to value 'false'
|
||||||
Setting entry with key 'dict1' to value ''
|
Setting entry with key 'dict1' to value ''
|
||||||
Setting entry with key 'dict2' to value 'happy=\:-)'
|
Setting entry with key 'dict2' to value 'happy=\:-)'
|
||||||
num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-)
|
Setting entry with key 'array_int' to value ''
|
||||||
|
Setting entry with key 'array_str' to value 'str0|str\|1|str\\2'
|
||||||
|
Setting entry with key 'array_dict' to value 'k00=v\\\\00:k01=v\,01,k10=v\\=1\\:0'
|
||||||
|
num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-),array_int=,array_str=str0|str\\|1|str\\\\2,array_dict=k00\=v\\\\\\\\00:k01\=v\\\,01\,k10\=v\\\\\=1\\\\:0
|
||||||
|
|
||||||
Testing av_set_options_string()
|
Testing av_set_options_string()
|
||||||
Setting options string ''
|
Setting options string ''
|
||||||
@ -378,6 +402,13 @@ OK 'bool2=auto'
|
|||||||
Setting options string 'dict1='happy=\:-):sad=\:-(''
|
Setting options string 'dict1='happy=\:-):sad=\:-(''
|
||||||
Setting entry with key 'dict1' to value 'happy=\:-):sad=\:-('
|
Setting entry with key 'dict1' to value 'happy=\:-):sad=\:-('
|
||||||
OK 'dict1='happy=\:-):sad=\:-(''
|
OK 'dict1='happy=\:-):sad=\:-(''
|
||||||
|
Setting options string 'array_int=0,32,2147483647'
|
||||||
|
Setting entry with key 'array_int' to value '0,32,2147483647'
|
||||||
|
OK 'array_int=0,32,2147483647'
|
||||||
|
Setting options string 'array_int=2147483648'
|
||||||
|
Setting entry with key 'array_int' to value '2147483648'
|
||||||
|
Value 2147483648.000000 for parameter 'array_int' out of range [0 - 2.14748e+09]
|
||||||
|
Error 'array_int=2147483648'
|
||||||
|
|
||||||
Testing av_opt_set_from_string()
|
Testing av_opt_set_from_string()
|
||||||
Setting options string ''
|
Setting options string ''
|
||||||
|
Loading…
Reference in New Issue
Block a user