diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-10-11 02:39:50 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-10-11 03:42:43 +0200 |
commit | 41f55277fafeec4f1b3202967bd0ab120948dd69 (patch) | |
tree | f239ff85401c38aa12a243384bdaf2ad48afaffb /libavutil | |
parent | fbb8468f205aa118b3701db56b134f3f173a13ad (diff) | |
parent | 4c7a232fc81fdbdee279ab819a255f624a22b083 (diff) | |
download | ffmpeg-41f55277fafeec4f1b3202967bd0ab120948dd69.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (34 commits)
h264: reset h->ref_count in case of errors in ff_h264_decode_ref_pic_list_reordering()
error_resilience: fix the check for missing references in ff_er_frame_end() for H264
4xm: prevent NULL dereference with invalid huffman table
4xmdemux: prevent use of uninitialized memory
4xm: clear FF_INPUT_BUFFER_PADDING_SIZE bytes in temporary buffers
ptx: check for out of bound reads
tiffdec: fix out of bound reads/writes
eacmv: check for out of bound reads
eacmv: fix potential pointer arithmetic overflows
adpcm: fix out of bound reads due to integer overflow
anm: prevent infinite loop
avsdemux: check for out of bound writes
avs: check for out of bound reads
avsdemux: check for corrupted data
AVOptions: refactor set_number/write_number
AVOptions: cosmetics, rename static av_set_number2() to write_number().
AVOptions: cosmetics, move and rename static av_set_number().
AVOptions: split av_set_string3 into opt type-specific functions
avidec: fix signed overflow in avi_sync()
mxfdec: Fix some buffer overreads caused by the misuse of AVPacket related functions.
...
Conflicts:
Changelog
configure
libavcodec/ptx.c
libavcodec/ra144.c
libavcodec/vaapi_vc1.c
libavcodec/vc1.c
libavcodec/version.h
libavformat/4xm.c
libavformat/avidec.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/opt.c | 218 | ||||
-rw-r--r-- | libavutil/opt.h | 4 |
2 files changed, 120 insertions, 102 deletions
diff --git a/libavutil/opt.c b/libavutil/opt.c index d749259c08..c425cfefbd 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -53,22 +53,13 @@ const AVOption *av_next_option(void *obj, const AVOption *last) else return (*(AVClass**)obj)->option; } -static int av_set_number2(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out) +static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) { - const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); - void *dst; - if (o_out) - *o_out= o; - if (!o) - return AVERROR_OPTION_NOT_FOUND; - if (o->max*den < num*intnum || o->min*den > num*intnum) { - av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, name); + av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, o->name); return AVERROR(ERANGE); } - dst= ((uint8_t*)obj) + o->offset; - switch (o->type) { case FF_OPT_TYPE_FLAGS: case FF_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break; @@ -85,15 +76,6 @@ static int av_set_number2(void *obj, const char *name, double num, int den, int6 return 0; } -static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum) -{ - const AVOption *o = NULL; - if (av_set_number2(obj, name, num, den, intnum, &o) < 0) - return NULL; - else - return o; -} - static const double const_values[] = { M_PI, M_E, @@ -115,10 +97,98 @@ static int hexchar2int(char c) { return -1; } +static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst) +{ + int *lendst = (int *)(dst + 1); + uint8_t *bin, *ptr; + int len = strlen(val); + + av_freep(dst); + *lendst = 0; + + if (len & 1) + return AVERROR(EINVAL); + len /= 2; + + ptr = bin = av_malloc(len); + while (*val) { + int a = hexchar2int(*val++); + int b = hexchar2int(*val++); + if (a < 0 || b < 0) { + av_free(bin); + return AVERROR(EINVAL); + } + *ptr++ = (a << 4) | b; + } + *dst = bin; + *lendst = len; + + return 0; +} + +static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst) +{ + av_freep(dst); + *dst = av_strdup(val); + return 0; +} + +static int set_string_number(void *obj, const AVOption *o, const char *val, void *dst) +{ + int ret = 0, notfirst = 0; + for (;;) { + int i; + char buf[256]; + int cmd = 0; + double d; + + if (*val == '+' || *val == '-') + cmd = *(val++); + + for (i = 0; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++) + buf[i] = val[i]; + buf[i] = 0; + + { + const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0); + if (o_named && o_named->type == FF_OPT_TYPE_CONST) + d = o_named->default_val.dbl; + else if (!strcmp(buf, "default")) d = o->default_val.dbl; + else if (!strcmp(buf, "max" )) d = o->max; + else if (!strcmp(buf, "min" )) d = o->min; + else if (!strcmp(buf, "none" )) d = 0; + else if (!strcmp(buf, "all" )) d = ~0; + else { + int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); + if (res < 0) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); + return res; + } + } + } + if (o->type == FF_OPT_TYPE_FLAGS) { + if (cmd == '+') d = av_get_int(obj, o->name, NULL) | (int64_t)d; + else if (cmd == '-') d = av_get_int(obj, o->name, NULL) &~(int64_t)d; + } else { + if (cmd == '+') d = notfirst*av_get_double(obj, o->name, NULL) + d; + else if (cmd == '-') d = notfirst*av_get_double(obj, o->name, NULL) - d; + } + + if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0) + return ret; + val += i; + if (!*val) + return 0; + notfirst = 1; + } + + return 0; +} + int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) { - int ret; const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); + void *dst; if (o_out) *o_out = o; if (!o) @@ -126,100 +196,50 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons if (!val && o->type != FF_OPT_TYPE_STRING) return AVERROR(EINVAL); - if (o->type == FF_OPT_TYPE_BINARY) { - uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset); - int *lendst = (int *)(dst + 1); - uint8_t *bin, *ptr; - int len = strlen(val); - av_freep(dst); - *lendst = 0; - if (len & 1) return AVERROR(EINVAL); - len /= 2; - ptr = bin = av_malloc(len); - while (*val) { - int a = hexchar2int(*val++); - int b = hexchar2int(*val++); - if (a < 0 || b < 0) { - av_free(bin); - return AVERROR(EINVAL); - } - *ptr++ = (a << 4) | b; - } - *dst = bin; - *lendst = len; - return 0; + dst = ((uint8_t*)obj) + o->offset; + switch (o->type) { + case FF_OPT_TYPE_STRING: return set_string(obj, o, val, dst); + case FF_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst); + case FF_OPT_TYPE_FLAGS: + case FF_OPT_TYPE_INT: + case FF_OPT_TYPE_INT64: + case FF_OPT_TYPE_FLOAT: + case FF_OPT_TYPE_DOUBLE: + case FF_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst); } - if (o->type != FF_OPT_TYPE_STRING) { - int notfirst=0; - for (;;) { - int i; - char buf[256]; - int cmd=0; - double d; - - if (*val == '+' || *val == '-') - cmd= *(val++); - - for (i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++) - buf[i]= val[i]; - buf[i]=0; - - { - const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0); - if (o_named && o_named->type == FF_OPT_TYPE_CONST) - d= o_named->default_val.dbl; - else if (!strcmp(buf, "default")) d= o->default_val.dbl; - else if (!strcmp(buf, "max" )) d= o->max; - else if (!strcmp(buf, "min" )) d= o->min; - else if (!strcmp(buf, "none" )) d= 0; - else if (!strcmp(buf, "all" )) d= ~0; - else { - int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); - if (res < 0) { - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); - return res; - } - } - } - if (o->type == FF_OPT_TYPE_FLAGS) { - if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; - else if (cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; - } else { - if (cmd=='+') d= notfirst*av_get_double(obj, name, NULL) + d; - else if (cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d; - } - if ((ret = av_set_number2(obj, name, d, 1, 1, o_out)) < 0) - return ret; - val+= i; - if (!*val) - return 0; - notfirst=1; - } - } + av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); + return AVERROR(EINVAL); +} - if (alloc) { - av_free(*(void**)(((uint8_t*)obj) + o->offset)); - val= av_strdup(val); - } +static const AVOption *set_number(void *obj, const char *name, double num, int den, int64_t intnum) +{ + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); + void *dst; - memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val)); - return 0; + if (!o) + return NULL; + + dst = ((uint8_t*)obj) + o->offset; + if (write_number(obj, o, dst, num, den, intnum) < 0) + return NULL; + else + return o; } const AVOption *av_set_double(void *obj, const char *name, double n) { - return av_set_number(obj, name, n, 1, 1); + return set_number(obj, name, n, 1, 1); } const AVOption *av_set_q(void *obj, const char *name, AVRational n) { - return av_set_number(obj, name, n.num, n.den, 1); + return set_number(obj, name, n.num, n.den, 1); } const AVOption *av_set_int(void *obj, const char *name, int64_t n) { - return av_set_number(obj, name, 1, 1, n); + return set_number(obj, name, 1, 1, n); } /** diff --git a/libavutil/opt.h b/libavutil/opt.h index 95ce12c6a7..06dea7de4c 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -129,9 +129,7 @@ const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int m * similarly, '-' unsets a flag. * @param[out] o_out if non-NULL put here a pointer to the AVOption * found - * @param alloc when 1 then the old value will be av_freed() and the - * new av_strduped() - * when 0 then no av_free() nor av_strdup() will be used + * @param alloc this parameter is currently ignored * @return 0 if the value has been set, or an AVERROR code in case of * error: * AVERROR_OPTION_NOT_FOUND if no matching option exists |