summaryrefslogtreecommitdiff
path: root/libavutil
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-10-11 02:39:50 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-10-11 03:42:43 +0200
commit41f55277fafeec4f1b3202967bd0ab120948dd69 (patch)
treef239ff85401c38aa12a243384bdaf2ad48afaffb /libavutil
parentfbb8468f205aa118b3701db56b134f3f173a13ad (diff)
parent4c7a232fc81fdbdee279ab819a255f624a22b083 (diff)
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.c218
-rw-r--r--libavutil/opt.h4
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