diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-05-30 21:04:14 +0200 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2016-03-24 10:34:15 +0200 |
commit | 564b4591bbe223bdc5f36a1131eaef103f23f5d0 (patch) | |
tree | 75f56f2edb540eaa6bbeecdedef6b8b4fe6561b4 /libavutil | |
parent | 8833f1508b7b6afc3172a8017934a7a54428c686 (diff) | |
download | ffmpeg-streaming-564b4591bbe223bdc5f36a1131eaef103f23f5d0.zip ffmpeg-streaming-564b4591bbe223bdc5f36a1131eaef103f23f5d0.tar.gz |
opt: Add av_opt_copy()
This includes documentation and other modifications by
Lukasz Marek and Martin Storsjö.
Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/opt.c | 66 | ||||
-rw-r--r-- | libavutil/opt.h | 13 | ||||
-rw-r--r-- | libavutil/version.h | 4 |
3 files changed, 81 insertions, 2 deletions
diff --git a/libavutil/opt.c b/libavutil/opt.c index c5a1933..0150243 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -757,6 +757,72 @@ const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *pre return NULL; } +static int opt_size(enum AVOptionType type) +{ + switch(type) { + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_FLAGS: return sizeof(int); + case AV_OPT_TYPE_INT64: return sizeof(int64_t); + case AV_OPT_TYPE_DOUBLE: return sizeof(double); + case AV_OPT_TYPE_FLOAT: return sizeof(float); + case AV_OPT_TYPE_STRING: return sizeof(uint8_t*); + case AV_OPT_TYPE_RATIONAL: return sizeof(AVRational); + case AV_OPT_TYPE_BINARY: return sizeof(uint8_t*) + sizeof(int); + } + return AVERROR(EINVAL); +} + +int av_opt_copy(void *dst, const void *src) +{ + const AVOption *o = NULL; + const AVClass *c; + int ret = 0; + + if (!src) + return AVERROR(EINVAL); + + c = *(AVClass**)src; + if (!c || c != *(AVClass**)dst) + return AVERROR(EINVAL); + + while ((o = av_opt_next(src, o))) { + void *field_dst = ((uint8_t*)dst) + o->offset; + void *field_src = ((uint8_t*)src) + o->offset; + uint8_t **field_dst8 = (uint8_t**)field_dst; + uint8_t **field_src8 = (uint8_t**)field_src; + + if (o->type == AV_OPT_TYPE_STRING) { + set_string(dst, o, *field_src8, field_dst8); + if (*field_src8 && !*field_dst8) + ret = AVERROR(ENOMEM); + } else if (o->type == AV_OPT_TYPE_BINARY) { + int len = *(int*)(field_src8 + 1); + if (*field_dst8 != *field_src8) + av_freep(field_dst8); + if (len) { + *field_dst8 = av_malloc(len); + if (!*field_dst8) { + ret = AVERROR(ENOMEM); + len = 0; + } + memcpy(*field_dst8, *field_src8, len); + } else { + *field_dst8 = NULL; + } + *(int*)(field_dst8 + 1) = len; + } else if (o->type == AV_OPT_TYPE_CONST) { + // do nothing + } else { + int size = opt_size(o->type); + if (size < 0) + ret = size; + else + memcpy(field_dst, field_src, size); + } + } + return ret; +} + #ifdef TEST typedef struct TestContext diff --git a/libavutil/opt.h b/libavutil/opt.h index 99d727c..906b869 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -530,6 +530,19 @@ int av_opt_get_q (void *obj, const char *name, int search_flags, AVRationa * 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); + +/** + * Copy options from src object into dest object. + * + * Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object. + * Original memory allocated for such options is freed unless both src and dest options points to the same memory. + * + * @param dest Object to copy from + * @param src Object to copy into + * @return 0 on success, negative on error + */ +int av_opt_copy(void *dest, const void *src); + /** * @} * @} diff --git a/libavutil/version.h b/libavutil/version.h index 235cdfd..186ebd8 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,8 +54,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 9 -#define LIBAVUTIL_VERSION_MICRO 1 +#define LIBAVUTIL_VERSION_MINOR 10 +#define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ |