00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "avutil.h"
00029 #include "avstring.h"
00030 #include "common.h"
00031 #include "opt.h"
00032 #include "eval.h"
00033 #include "dict.h"
00034 #include "log.h"
00035 #include "parseutils.h"
00036 #include "pixdesc.h"
00037 #include "mathematics.h"
00038
00039 #if FF_API_FIND_OPT
00040
00041 const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
00042 {
00043 const AVOption *o = NULL;
00044
00045 while ((o = av_next_option(v, o))) {
00046 if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags)
00047 return o;
00048 }
00049 return NULL;
00050 }
00051 #endif
00052
00053 #if FF_API_OLD_AVOPTIONS
00054 const AVOption *av_next_option(void *obj, const AVOption *last)
00055 {
00056 return av_opt_next(obj, last);
00057 }
00058 #endif
00059
00060 const AVOption *av_opt_next(void *obj, const AVOption *last)
00061 {
00062 AVClass *class = *(AVClass**)obj;
00063 if (!last && class->option && class->option[0].name)
00064 return class->option;
00065 if (last && last[1].name) return ++last;
00066 return NULL;
00067 }
00068
00069 static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum)
00070 {
00071 switch (o->type) {
00072 case AV_OPT_TYPE_FLAGS: *intnum = *(unsigned int*)dst;return 0;
00073 case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0;
00074 case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0;
00075 case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0;
00076 case AV_OPT_TYPE_DOUBLE: *num = *(double *)dst;return 0;
00077 case AV_OPT_TYPE_RATIONAL: *intnum = ((AVRational*)dst)->num;
00078 *den = ((AVRational*)dst)->den;
00079 return 0;
00080 case AV_OPT_TYPE_CONST: *num = o->default_val.dbl; return 0;
00081 }
00082 return AVERROR(EINVAL);
00083 }
00084
00085 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
00086 {
00087 if (o->max*den < num*intnum || o->min*den > num*intnum) {
00088 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range\n",
00089 num*intnum/den, o->name);
00090 return AVERROR(ERANGE);
00091 }
00092
00093 switch (o->type) {
00094 case AV_OPT_TYPE_FLAGS:
00095 case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break;
00096 case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break;
00097 case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break;
00098 case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break;
00099 case AV_OPT_TYPE_RATIONAL:
00100 if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
00101 else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
00102 break;
00103 default:
00104 return AVERROR(EINVAL);
00105 }
00106 return 0;
00107 }
00108
00109 static const double const_values[] = {
00110 M_PI,
00111 M_E,
00112 FF_QP2LAMBDA,
00113 0
00114 };
00115
00116 static const char * const const_names[] = {
00117 "PI",
00118 "E",
00119 "QP2LAMBDA",
00120 0
00121 };
00122
00123 static int hexchar2int(char c) {
00124 if (c >= '0' && c <= '9') return c - '0';
00125 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
00126 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
00127 return -1;
00128 }
00129
00130 static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
00131 {
00132 int *lendst = (int *)(dst + 1);
00133 uint8_t *bin, *ptr;
00134 int len = strlen(val);
00135
00136 av_freep(dst);
00137 *lendst = 0;
00138
00139 if (len & 1)
00140 return AVERROR(EINVAL);
00141 len /= 2;
00142
00143 ptr = bin = av_malloc(len);
00144 while (*val) {
00145 int a = hexchar2int(*val++);
00146 int b = hexchar2int(*val++);
00147 if (a < 0 || b < 0) {
00148 av_free(bin);
00149 return AVERROR(EINVAL);
00150 }
00151 *ptr++ = (a << 4) | b;
00152 }
00153 *dst = bin;
00154 *lendst = len;
00155
00156 return 0;
00157 }
00158
00159 static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
00160 {
00161 av_freep(dst);
00162 *dst = av_strdup(val);
00163 return 0;
00164 }
00165
00166 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
00167 opt->type == AV_OPT_TYPE_CONST || \
00168 opt->type == AV_OPT_TYPE_FLAGS || \
00169 opt->type == AV_OPT_TYPE_INT) ? \
00170 opt->default_val.i64 : opt->default_val.dbl)
00171
00172 static int set_string_number(void *obj, const AVOption *o, const char *val, void *dst)
00173 {
00174 int ret = 0, notfirst = 0;
00175 for (;;) {
00176 int i, den = 1;
00177 char buf[256];
00178 int cmd = 0;
00179 double d, num = 1;
00180 int64_t intnum = 1;
00181
00182 if (*val == '+' || *val == '-')
00183 cmd = *(val++);
00184
00185 for (i = 0; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
00186 buf[i] = val[i];
00187 buf[i] = 0;
00188
00189 {
00190 const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
00191 if (o_named && o_named->type == AV_OPT_TYPE_CONST)
00192 d = DEFAULT_NUMVAL(o_named);
00193 else if (!strcmp(buf, "default")) d = DEFAULT_NUMVAL(o);
00194 else if (!strcmp(buf, "max" )) d = o->max;
00195 else if (!strcmp(buf, "min" )) d = o->min;
00196 else if (!strcmp(buf, "none" )) d = 0;
00197 else if (!strcmp(buf, "all" )) d = ~0;
00198 else {
00199 int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
00200 if (res < 0) {
00201 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
00202 return res;
00203 }
00204 }
00205 }
00206 if (o->type == AV_OPT_TYPE_FLAGS) {
00207 read_number(o, dst, NULL, NULL, &intnum);
00208 if (cmd == '+') d = intnum | (int64_t)d;
00209 else if (cmd == '-') d = intnum &~(int64_t)d;
00210 } else {
00211 read_number(o, dst, &num, &den, &intnum);
00212 if (cmd == '+') d = notfirst*num*intnum/den + d;
00213 else if (cmd == '-') d = notfirst*num*intnum/den - d;
00214 }
00215
00216 if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
00217 return ret;
00218 val += i;
00219 if (!*val)
00220 return 0;
00221 notfirst = 1;
00222 }
00223
00224 return 0;
00225 }
00226
00227 #if FF_API_OLD_AVOPTIONS
00228 int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
00229 {
00230 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
00231 if (o_out)
00232 *o_out = o;
00233 return av_opt_set(obj, name, val, 0);
00234 }
00235 #endif
00236
00237 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
00238 {
00239 int ret;
00240 void *dst, *target_obj;
00241 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
00242 if (!o || !target_obj)
00243 return AVERROR_OPTION_NOT_FOUND;
00244 if (!val && (o->type != AV_OPT_TYPE_STRING && o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_IMAGE_SIZE))
00245 return AVERROR(EINVAL);
00246
00247 dst = ((uint8_t*)target_obj) + o->offset;
00248 switch (o->type) {
00249 case AV_OPT_TYPE_STRING: return set_string(obj, o, val, dst);
00250 case AV_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst);
00251 case AV_OPT_TYPE_FLAGS:
00252 case AV_OPT_TYPE_INT:
00253 case AV_OPT_TYPE_INT64:
00254 case AV_OPT_TYPE_FLOAT:
00255 case AV_OPT_TYPE_DOUBLE:
00256 case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst);
00257 case AV_OPT_TYPE_IMAGE_SIZE:
00258 if (!val || !strcmp(val, "none")) {
00259 *(int *)dst = *((int *)dst + 1) = 0;
00260 return 0;
00261 }
00262 ret = av_parse_video_size(dst, ((int *)dst) + 1, val);
00263 if (ret < 0)
00264 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
00265 return ret;
00266 case AV_OPT_TYPE_PIXEL_FMT:
00267 if (!val || !strcmp(val, "none"))
00268 ret = PIX_FMT_NONE;
00269 else {
00270 ret = av_get_pix_fmt(val);
00271 if (ret == PIX_FMT_NONE) {
00272 char *tail;
00273 ret = strtol(val, &tail, 0);
00274 if (*tail || (unsigned)ret >= PIX_FMT_NB) {
00275 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as pixel format\n", val);
00276 return AVERROR(EINVAL);
00277 }
00278 }
00279 }
00280 *(enum PixelFormat *)dst = ret;
00281 return 0;
00282 }
00283
00284 av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
00285 return AVERROR(EINVAL);
00286 }
00287
00288 #define OPT_EVAL_NUMBER(name, opttype, vartype)\
00289 int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
00290 {\
00291 if (!o || o->type != opttype)\
00292 return AVERROR(EINVAL);\
00293 return set_string_number(obj, o, val, name ## _out);\
00294 }
00295
00296 OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int)
00297 OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int)
00298 OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t)
00299 OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float)
00300 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double)
00301 OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational)
00302
00303 static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
00304 int search_flags)
00305 {
00306 void *dst, *target_obj;
00307 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
00308
00309 if (!o || !target_obj)
00310 return AVERROR_OPTION_NOT_FOUND;
00311
00312 dst = ((uint8_t*)target_obj) + o->offset;
00313 return write_number(obj, o, dst, num, den, intnum);
00314 }
00315
00316 #if FF_API_OLD_AVOPTIONS
00317 const AVOption *av_set_double(void *obj, const char *name, double n)
00318 {
00319 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
00320 if (set_number(obj, name, n, 1, 1, 0) < 0)
00321 return NULL;
00322 return o;
00323 }
00324
00325 const AVOption *av_set_q(void *obj, const char *name, AVRational n)
00326 {
00327 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
00328 if (set_number(obj, name, n.num, n.den, 1, 0) < 0)
00329 return NULL;
00330 return o;
00331 }
00332
00333 const AVOption *av_set_int(void *obj, const char *name, int64_t n)
00334 {
00335 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
00336 if (set_number(obj, name, 1, 1, n, 0) < 0)
00337 return NULL;
00338 return o;
00339 }
00340 #endif
00341
00342 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
00343 {
00344 return set_number(obj, name, 1, 1, val, search_flags);
00345 }
00346
00347 int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
00348 {
00349 return set_number(obj, name, val, 1, 1, search_flags);
00350 }
00351
00352 int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
00353 {
00354 return set_number(obj, name, val.num, val.den, 1, search_flags);
00355 }
00356
00357 int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
00358 {
00359 void *target_obj;
00360 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
00361 uint8_t *ptr;
00362 uint8_t **dst;
00363 int *lendst;
00364
00365 if (!o || !target_obj)
00366 return AVERROR_OPTION_NOT_FOUND;
00367
00368 if (o->type != AV_OPT_TYPE_BINARY)
00369 return AVERROR(EINVAL);
00370
00371 ptr = av_malloc(len);
00372 if (!ptr)
00373 return AVERROR(ENOMEM);
00374
00375 dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
00376 lendst = (int *)(dst + 1);
00377
00378 av_free(*dst);
00379 *dst = ptr;
00380 *lendst = len;
00381 memcpy(ptr, val, len);
00382
00383 return 0;
00384 }
00385
00386 #if FF_API_OLD_AVOPTIONS
00387
00392 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len)
00393 {
00394 const AVOption *o = av_opt_find(obj, name, NULL, 0, AV_OPT_SEARCH_CHILDREN);
00395 void *dst;
00396 uint8_t *bin;
00397 int len, i;
00398 if (!o)
00399 return NULL;
00400 if (o->type != AV_OPT_TYPE_STRING && (!buf || !buf_len))
00401 return NULL;
00402
00403 dst= ((uint8_t*)obj) + o->offset;
00404 if (o_out) *o_out= o;
00405
00406 switch (o->type) {
00407 case AV_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
00408 case AV_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
00409 case AV_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
00410 case AV_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
00411 case AV_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
00412 case AV_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
00413 case AV_OPT_TYPE_CONST: snprintf(buf, buf_len, "%f" , o->default_val.dbl);break;
00414 case AV_OPT_TYPE_STRING: return *(void**)dst;
00415 case AV_OPT_TYPE_BINARY:
00416 len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
00417 if (len >= (buf_len + 1)/2) return NULL;
00418 bin = *(uint8_t**)dst;
00419 for (i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]);
00420 break;
00421 default: return NULL;
00422 }
00423 return buf;
00424 }
00425 #endif
00426
00427 int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
00428 {
00429 void *dst, *target_obj;
00430 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
00431 uint8_t *bin, buf[128];
00432 int len, i, ret;
00433
00434 if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
00435 return AVERROR_OPTION_NOT_FOUND;
00436
00437 dst = (uint8_t*)target_obj + o->offset;
00438
00439 buf[0] = 0;
00440 switch (o->type) {
00441 case AV_OPT_TYPE_FLAGS: ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);break;
00442 case AV_OPT_TYPE_INT: ret = snprintf(buf, sizeof(buf), "%d" , *(int *)dst);break;
00443 case AV_OPT_TYPE_INT64: ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break;
00444 case AV_OPT_TYPE_FLOAT: ret = snprintf(buf, sizeof(buf), "%f" , *(float *)dst);break;
00445 case AV_OPT_TYPE_DOUBLE: ret = snprintf(buf, sizeof(buf), "%f" , *(double *)dst);break;
00446 case AV_OPT_TYPE_RATIONAL: ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
00447 case AV_OPT_TYPE_CONST: ret = snprintf(buf, sizeof(buf), "%f" , o->default_val.dbl);break;
00448 case AV_OPT_TYPE_STRING:
00449 if (*(uint8_t**)dst)
00450 *out_val = av_strdup(*(uint8_t**)dst);
00451 else
00452 *out_val = av_strdup("");
00453 return 0;
00454 case AV_OPT_TYPE_BINARY:
00455 len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
00456 if ((uint64_t)len*2 + 1 > INT_MAX)
00457 return AVERROR(EINVAL);
00458 if (!(*out_val = av_malloc(len*2 + 1)))
00459 return AVERROR(ENOMEM);
00460 bin = *(uint8_t**)dst;
00461 for (i = 0; i < len; i++)
00462 snprintf(*out_val + i*2, 3, "%02X", bin[i]);
00463 return 0;
00464 case AV_OPT_TYPE_IMAGE_SIZE:
00465 ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
00466 break;
00467 case AV_OPT_TYPE_PIXEL_FMT:
00468 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum PixelFormat *)dst), "none"));
00469 break;
00470 default:
00471 return AVERROR(EINVAL);
00472 }
00473
00474 if (ret >= sizeof(buf))
00475 return AVERROR(EINVAL);
00476 *out_val = av_strdup(buf);
00477 return 0;
00478 }
00479
00480 static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
00481 int search_flags)
00482 {
00483 void *dst, *target_obj;
00484 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
00485 if (!o || !target_obj)
00486 goto error;
00487
00488 dst = ((uint8_t*)target_obj) + o->offset;
00489
00490 if (o_out) *o_out= o;
00491
00492 return read_number(o, dst, num, den, intnum);
00493
00494 error:
00495 *den=*intnum=0;
00496 return -1;
00497 }
00498
00499 #if FF_API_OLD_AVOPTIONS
00500 double av_get_double(void *obj, const char *name, const AVOption **o_out)
00501 {
00502 int64_t intnum=1;
00503 double num=1;
00504 int den=1;
00505
00506 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
00507 return NAN;
00508 return num*intnum/den;
00509 }
00510
00511 AVRational av_get_q(void *obj, const char *name, const AVOption **o_out)
00512 {
00513 int64_t intnum=1;
00514 double num=1;
00515 int den=1;
00516
00517 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
00518 return (AVRational){0, 0};
00519 if (num == 1.0 && (int)intnum == intnum)
00520 return (AVRational){intnum, den};
00521 else
00522 return av_d2q(num*intnum/den, 1<<24);
00523 }
00524
00525 int64_t av_get_int(void *obj, const char *name, const AVOption **o_out)
00526 {
00527 int64_t intnum=1;
00528 double num=1;
00529 int den=1;
00530
00531 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
00532 return -1;
00533 return num*intnum/den;
00534 }
00535 #endif
00536
00537 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
00538 {
00539 int64_t intnum = 1;
00540 double num = 1;
00541 int ret, den = 1;
00542
00543 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
00544 return ret;
00545 *out_val = num*intnum/den;
00546 return 0;
00547 }
00548
00549 int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
00550 {
00551 int64_t intnum = 1;
00552 double num = 1;
00553 int ret, den = 1;
00554
00555 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
00556 return ret;
00557 *out_val = num*intnum/den;
00558 return 0;
00559 }
00560
00561 int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
00562 {
00563 int64_t intnum = 1;
00564 double num = 1;
00565 int ret, den = 1;
00566
00567 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
00568 return ret;
00569
00570 if (num == 1.0 && (int)intnum == intnum)
00571 *out_val = (AVRational){intnum, den};
00572 else
00573 *out_val = av_d2q(num*intnum/den, 1<<24);
00574 return 0;
00575 }
00576
00577 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
00578 {
00579 const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
00580 const AVOption *flag = av_opt_find(obj, flag_name,
00581 field ? field->unit : NULL, 0, 0);
00582 int64_t res;
00583
00584 if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
00585 av_opt_get_int(obj, field_name, 0, &res) < 0)
00586 return 0;
00587 return res & flag->default_val.i64;
00588 }
00589
00590 static void opt_list(void *obj, void *av_log_obj, const char *unit,
00591 int req_flags, int rej_flags)
00592 {
00593 const AVOption *opt=NULL;
00594
00595 while ((opt = av_opt_next(obj, opt))) {
00596 if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
00597 continue;
00598
00599
00600
00601
00602
00603 if (!unit && opt->type==AV_OPT_TYPE_CONST)
00604 continue;
00605 else if (unit && opt->type!=AV_OPT_TYPE_CONST)
00606 continue;
00607 else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
00608 continue;
00609 else if (unit && opt->type == AV_OPT_TYPE_CONST)
00610 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
00611 else
00612 av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name);
00613
00614 switch (opt->type) {
00615 case AV_OPT_TYPE_FLAGS:
00616 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>");
00617 break;
00618 case AV_OPT_TYPE_INT:
00619 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<int>");
00620 break;
00621 case AV_OPT_TYPE_INT64:
00622 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>");
00623 break;
00624 case AV_OPT_TYPE_DOUBLE:
00625 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<double>");
00626 break;
00627 case AV_OPT_TYPE_FLOAT:
00628 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<float>");
00629 break;
00630 case AV_OPT_TYPE_STRING:
00631 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<string>");
00632 break;
00633 case AV_OPT_TYPE_RATIONAL:
00634 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>");
00635 break;
00636 case AV_OPT_TYPE_BINARY:
00637 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<binary>");
00638 break;
00639 case AV_OPT_TYPE_IMAGE_SIZE:
00640 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<image_size>");
00641 break;
00642 case AV_OPT_TYPE_PIXEL_FMT:
00643 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<pix_fmt>");
00644 break;
00645 case AV_OPT_TYPE_CONST:
00646 default:
00647 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "");
00648 break;
00649 }
00650 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
00651 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
00652 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.');
00653 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.');
00654 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.');
00655 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
00656
00657 if (opt->help)
00658 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
00659 av_log(av_log_obj, AV_LOG_INFO, "\n");
00660 if (opt->unit && opt->type != AV_OPT_TYPE_CONST) {
00661 opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
00662 }
00663 }
00664 }
00665
00666 int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
00667 {
00668 if (!obj)
00669 return -1;
00670
00671 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
00672
00673 opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
00674
00675 return 0;
00676 }
00677
00678 void av_opt_set_defaults(void *s)
00679 {
00680 #if FF_API_OLD_AVOPTIONS
00681 av_opt_set_defaults2(s, 0, 0);
00682 }
00683
00684 void av_opt_set_defaults2(void *s, int mask, int flags)
00685 {
00686 #endif
00687 const AVOption *opt = NULL;
00688 while ((opt = av_opt_next(s, opt)) != NULL) {
00689 #if FF_API_OLD_AVOPTIONS
00690 if ((opt->flags & mask) != flags)
00691 continue;
00692 #endif
00693 switch (opt->type) {
00694 case AV_OPT_TYPE_CONST:
00695
00696 break;
00697 case AV_OPT_TYPE_FLAGS:
00698 case AV_OPT_TYPE_INT:
00699 case AV_OPT_TYPE_INT64:
00700 av_opt_set_int(s, opt->name, opt->default_val.i64, 0);
00701 break;
00702 case AV_OPT_TYPE_DOUBLE:
00703 case AV_OPT_TYPE_FLOAT: {
00704 double val;
00705 val = opt->default_val.dbl;
00706 av_opt_set_double(s, opt->name, val, 0);
00707 }
00708 break;
00709 case AV_OPT_TYPE_RATIONAL: {
00710 AVRational val;
00711 val = av_d2q(opt->default_val.dbl, INT_MAX);
00712 av_opt_set_q(s, opt->name, val, 0);
00713 }
00714 break;
00715 case AV_OPT_TYPE_STRING:
00716 case AV_OPT_TYPE_IMAGE_SIZE:
00717 case AV_OPT_TYPE_PIXEL_FMT:
00718 av_opt_set(s, opt->name, opt->default_val.str, 0);
00719 break;
00720 case AV_OPT_TYPE_BINARY:
00721
00722 break;
00723 default:
00724 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
00725 }
00726 }
00727 }
00728
00746 static int parse_key_value_pair(void *ctx, const char **buf,
00747 const char *key_val_sep, const char *pairs_sep)
00748 {
00749 char *key = av_get_token(buf, key_val_sep);
00750 char *val;
00751 int ret;
00752
00753 if (*key && strspn(*buf, key_val_sep)) {
00754 (*buf)++;
00755 val = av_get_token(buf, pairs_sep);
00756 } else {
00757 av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
00758 av_free(key);
00759 return AVERROR(EINVAL);
00760 }
00761
00762 av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
00763
00764 ret = av_opt_set(ctx, key, val, 0);
00765 if (ret == AVERROR_OPTION_NOT_FOUND)
00766 av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
00767
00768 av_free(key);
00769 av_free(val);
00770 return ret;
00771 }
00772
00773 int av_set_options_string(void *ctx, const char *opts,
00774 const char *key_val_sep, const char *pairs_sep)
00775 {
00776 int ret, count = 0;
00777
00778 if (!opts)
00779 return 0;
00780
00781 while (*opts) {
00782 if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
00783 return ret;
00784 count++;
00785
00786 if (*opts)
00787 opts++;
00788 }
00789
00790 return count;
00791 }
00792
00793 void av_opt_free(void *obj)
00794 {
00795 const AVOption *o = NULL;
00796 while ((o = av_opt_next(obj, o)))
00797 if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY)
00798 av_freep((uint8_t *)obj + o->offset);
00799 }
00800
00801 int av_opt_set_dict(void *obj, AVDictionary **options)
00802 {
00803 AVDictionaryEntry *t = NULL;
00804 AVDictionary *tmp = NULL;
00805 int ret = 0;
00806
00807 while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
00808 ret = av_opt_set(obj, t->key, t->value, 0);
00809 if (ret == AVERROR_OPTION_NOT_FOUND)
00810 av_dict_set(&tmp, t->key, t->value, 0);
00811 else if (ret < 0) {
00812 av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
00813 break;
00814 }
00815 ret = 0;
00816 }
00817 av_dict_free(options);
00818 *options = tmp;
00819 return ret;
00820 }
00821
00822 const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
00823 int opt_flags, int search_flags)
00824 {
00825 return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
00826 }
00827
00828 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
00829 int opt_flags, int search_flags, void **target_obj)
00830 {
00831 const AVClass *c;
00832 const AVOption *o = NULL;
00833
00834 if(!obj)
00835 return NULL;
00836
00837 c= *(AVClass**)obj;
00838
00839 if (search_flags & AV_OPT_SEARCH_CHILDREN) {
00840 if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
00841 const AVClass *child = NULL;
00842 while (child = av_opt_child_class_next(c, child))
00843 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
00844 return o;
00845 } else {
00846 void *child = NULL;
00847 while (child = av_opt_child_next(obj, child))
00848 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
00849 return o;
00850 }
00851 }
00852
00853 while (o = av_opt_next(obj, o)) {
00854 if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
00855 ((!unit && o->type != AV_OPT_TYPE_CONST) ||
00856 (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
00857 if (target_obj) {
00858 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
00859 *target_obj = obj;
00860 else
00861 *target_obj = NULL;
00862 }
00863 return o;
00864 }
00865 }
00866 return NULL;
00867 }
00868
00869 void *av_opt_child_next(void *obj, void *prev)
00870 {
00871 const AVClass *c = *(AVClass**)obj;
00872 if (c->child_next)
00873 return c->child_next(obj, prev);
00874 return NULL;
00875 }
00876
00877 const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
00878 {
00879 if (parent->child_class_next)
00880 return parent->child_class_next(prev);
00881 return NULL;
00882 }
00883
00884 void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
00885 {
00886 const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
00887 if(!opt)
00888 return NULL;
00889 return (uint8_t*)obj + opt->offset;
00890 }
00891
00892 #ifdef TEST
00893
00894 #undef printf
00895
00896 typedef struct TestContext
00897 {
00898 const AVClass *class;
00899 int num;
00900 int toggle;
00901 char *string;
00902 int flags;
00903 AVRational rational;
00904 int w, h;
00905 enum PixelFormat pix_fmt;
00906 } TestContext;
00907
00908 #define OFFSET(x) offsetof(TestContext, x)
00909
00910 #define TEST_FLAG_COOL 01
00911 #define TEST_FLAG_LAME 02
00912 #define TEST_FLAG_MU 04
00913
00914 static const AVOption test_options[]= {
00915 {"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100 },
00916 {"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1 },
00917 {"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10 },
00918 {"string", "set string", OFFSET(string), AV_OPT_TYPE_STRING, {0}, CHAR_MIN, CHAR_MAX },
00919 {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
00920 {"cool", "set cool flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_COOL}, INT_MIN, INT_MAX, 0, "flags" },
00921 {"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" },
00922 {"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" },
00923 {"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{0}, 0, 0 },
00924 {"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT,{0}, 0, 0 },
00925 {NULL},
00926 };
00927
00928 static const char *test_get_name(void *ctx)
00929 {
00930 return "test";
00931 }
00932
00933 static const AVClass test_class = {
00934 "TestContext",
00935 test_get_name,
00936 test_options
00937 };
00938
00939 int main(void)
00940 {
00941 int i;
00942
00943 printf("\nTesting av_set_options_string()\n");
00944 {
00945 TestContext test_ctx = { 0 };
00946 const char *options[] = {
00947 "",
00948 ":",
00949 "=",
00950 "foo=:",
00951 ":=foo",
00952 "=foo",
00953 "foo=",
00954 "foo",
00955 "foo=val",
00956 "foo==val",
00957 "toggle=:",
00958 "string=:",
00959 "toggle=1 : foo",
00960 "toggle=100",
00961 "toggle==1",
00962 "flags=+mu-lame : num=42: toggle=0",
00963 "num=42 : string=blahblah",
00964 "rational=0 : rational=1/2 : rational=1/-1",
00965 "rational=-1/0",
00966 "size=1024x768",
00967 "size=pal",
00968 "size=bogus",
00969 "pix_fmt=yuv420p",
00970 "pix_fmt=2",
00971 "pix_fmt=bogus",
00972 };
00973
00974 test_ctx.class = &test_class;
00975 av_opt_set_defaults(&test_ctx);
00976 test_ctx.string = av_strdup("default");
00977
00978 av_log_set_level(AV_LOG_DEBUG);
00979
00980 for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
00981 av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
00982 if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0)
00983 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
00984 printf("\n");
00985 }
00986 av_freep(&test_ctx.string);
00987 }
00988
00989 return 0;
00990 }
00991
00992 #endif