1/* 2 * AVOptions 3 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * AVOptions 25 * @author Michael Niedermayer <michaelni@gmx.at> 26 */ 27 28#include "avutil.h" 29#include "avstring.h" 30#include "channel_layout.h" 31#include "common.h" 32#include "opt.h" 33#include "eval.h" 34#include "dict.h" 35#include "log.h" 36#include "parseutils.h" 37#include "pixdesc.h" 38#include "mathematics.h" 39#include "samplefmt.h" 40 41#include <float.h> 42 43#if FF_API_FIND_OPT 44//FIXME order them and do a bin search 45const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags) 46{ 47 const AVOption *o = NULL; 48 49 while ((o = av_next_option(v, o))) { 50 if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags) 51 return o; 52 } 53 return NULL; 54} 55#endif 56 57#if FF_API_OLD_AVOPTIONS 58const AVOption *av_next_option(void *obj, const AVOption *last) 59{ 60 return av_opt_next(obj, last); 61} 62#endif 63 64const AVOption *av_opt_next(void *obj, const AVOption *last) 65{ 66 AVClass *class = *(AVClass**)obj; 67 if (!last && class && class->option && class->option[0].name) 68 return class->option; 69 if (last && last[1].name) 70 return ++last; 71 return NULL; 72} 73 74static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum) 75{ 76 switch (o->type) { 77 case AV_OPT_TYPE_FLAGS: *intnum = *(unsigned int*)dst;return 0; 78 case AV_OPT_TYPE_PIXEL_FMT: 79 case AV_OPT_TYPE_SAMPLE_FMT: 80 case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0; 81 case AV_OPT_TYPE_CHANNEL_LAYOUT: 82 case AV_OPT_TYPE_DURATION: 83 case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0; 84 case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0; 85 case AV_OPT_TYPE_DOUBLE: *num = *(double *)dst;return 0; 86 case AV_OPT_TYPE_RATIONAL: *intnum = ((AVRational*)dst)->num; 87 *den = ((AVRational*)dst)->den; 88 return 0; 89 case AV_OPT_TYPE_CONST: *num = o->default_val.dbl; return 0; 90 } 91 return AVERROR(EINVAL); 92} 93 94static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) 95{ 96 if (o->type != AV_OPT_TYPE_FLAGS && 97 (o->max * den < num * intnum || o->min * den > num * intnum)) { 98 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", 99 num*intnum/den, o->name, o->min, o->max); 100 return AVERROR(ERANGE); 101 } 102 if (o->type == AV_OPT_TYPE_FLAGS) { 103 double d = num*intnum/den; 104 if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) { 105 av_log(obj, AV_LOG_ERROR, 106 "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n", 107 num*intnum/den, o->name); 108 return AVERROR(ERANGE); 109 } 110 } 111 112 switch (o->type) { 113 case AV_OPT_TYPE_FLAGS: 114 case AV_OPT_TYPE_PIXEL_FMT: 115 case AV_OPT_TYPE_SAMPLE_FMT: 116 case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break; 117 case AV_OPT_TYPE_DURATION: 118 case AV_OPT_TYPE_CHANNEL_LAYOUT: 119 case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break; 120 case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; 121 case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; 122 case AV_OPT_TYPE_RATIONAL: 123 if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den}; 124 else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); 125 break; 126 default: 127 return AVERROR(EINVAL); 128 } 129 return 0; 130} 131 132static const double const_values[] = { 133 M_PI, 134 M_E, 135 FF_QP2LAMBDA, 136 0 137}; 138 139static const char * const const_names[] = { 140 "PI", 141 "E", 142 "QP2LAMBDA", 143 0 144}; 145 146static int hexchar2int(char c) { 147 if (c >= '0' && c <= '9') return c - '0'; 148 if (c >= 'a' && c <= 'f') return c - 'a' + 10; 149 if (c >= 'A' && c <= 'F') return c - 'A' + 10; 150 return -1; 151} 152 153static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst) 154{ 155 int *lendst = (int *)(dst + 1); 156 uint8_t *bin, *ptr; 157 int len = strlen(val); 158 159 av_freep(dst); 160 *lendst = 0; 161 162 if (len & 1) 163 return AVERROR(EINVAL); 164 len /= 2; 165 166 ptr = bin = av_malloc(len); 167 while (*val) { 168 int a = hexchar2int(*val++); 169 int b = hexchar2int(*val++); 170 if (a < 0 || b < 0) { 171 av_free(bin); 172 return AVERROR(EINVAL); 173 } 174 *ptr++ = (a << 4) | b; 175 } 176 *dst = bin; 177 *lendst = len; 178 179 return 0; 180} 181 182static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst) 183{ 184 av_freep(dst); 185 *dst = av_strdup(val); 186 return 0; 187} 188 189#define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \ 190 opt->type == AV_OPT_TYPE_CONST || \ 191 opt->type == AV_OPT_TYPE_FLAGS || \ 192 opt->type == AV_OPT_TYPE_INT) ? \ 193 opt->default_val.i64 : opt->default_val.dbl) 194 195static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst) 196{ 197 int ret = 0, notfirst = 0; 198 int num, den; 199 char c; 200 201 if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) { 202 if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0) 203 return ret; 204 ret = 0; 205 } 206 207 for (;;) { 208 int i, den = 1; 209 char buf[256]; 210 int cmd = 0; 211 double d, num = 1; 212 int64_t intnum = 1; 213 214 i = 0; 215 if (*val == '+' || *val == '-') { 216 if (o->type == AV_OPT_TYPE_FLAGS) 217 cmd = *(val++); 218 else if (!notfirst) 219 buf[i++] = *val; 220 } 221 222 for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++) 223 buf[i] = val[i]; 224 buf[i] = 0; 225 226 { 227 const AVOption *o_named = av_opt_find(target_obj, buf, o->unit, 0, 0); 228 if (o_named && o_named->type == AV_OPT_TYPE_CONST) 229 d = DEFAULT_NUMVAL(o_named); 230 else if (!strcmp(buf, "default")) d = DEFAULT_NUMVAL(o); 231 else if (!strcmp(buf, "max" )) d = o->max; 232 else if (!strcmp(buf, "min" )) d = o->min; 233 else if (!strcmp(buf, "none" )) d = 0; 234 else if (!strcmp(buf, "all" )) d = ~0; 235 else { 236 int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); 237 if (res < 0) { 238 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); 239 return res; 240 } 241 } 242 } 243 if (o->type == AV_OPT_TYPE_FLAGS) { 244 read_number(o, dst, NULL, NULL, &intnum); 245 if (cmd == '+') d = intnum | (int64_t)d; 246 else if (cmd == '-') d = intnum &~(int64_t)d; 247 } else { 248 read_number(o, dst, &num, &den, &intnum); 249 if (cmd == '+') d = notfirst*num*intnum/den + d; 250 else if (cmd == '-') d = notfirst*num*intnum/den - d; 251 } 252 253 if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0) 254 return ret; 255 val += i; 256 if (!*val) 257 return 0; 258 notfirst = 1; 259 } 260 261 return 0; 262} 263 264static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst) 265{ 266 int ret; 267 268 if (!val || !strcmp(val, "none")) { 269 dst[0] = 270 dst[1] = 0; 271 return 0; 272 } 273 ret = av_parse_video_size(dst, dst + 1, val); 274 if (ret < 0) 275 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val); 276 return ret; 277} 278 279static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst) 280{ 281 int ret; 282 if (!val) { 283 ret = AVERROR(EINVAL); 284 } else { 285 ret = av_parse_video_rate(dst, val); 286 } 287 if (ret < 0) 288 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); 289 return ret; 290} 291 292static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst) 293{ 294 int ret; 295 296 if (!val) { 297 return 0; 298 } else { 299 ret = av_parse_color(dst, val, -1, obj); 300 if (ret < 0) 301 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val); 302 return ret; 303 } 304 return 0; 305} 306 307static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst, 308 int fmt_nb, int ((*get_fmt)(const char *)), const char *desc) 309{ 310 int fmt, min, max; 311 312 if (!val || !strcmp(val, "none")) { 313 fmt = -1; 314 } else { 315 fmt = get_fmt(val); 316 if (fmt == -1) { 317 char *tail; 318 fmt = strtol(val, &tail, 0); 319 if (*tail || (unsigned)fmt >= fmt_nb) { 320 av_log(obj, AV_LOG_ERROR, 321 "Unable to parse option value \"%s\" as %s\n", val, desc); 322 return AVERROR(EINVAL); 323 } 324 } 325 } 326 327 min = FFMAX(o->min, -1); 328 max = FFMIN(o->max, fmt_nb-1); 329 330 // hack for compatibility with old ffmpeg 331 if(min == 0 && max == 0) { 332 min = -1; 333 max = fmt_nb-1; 334 } 335 336 if (fmt < min || fmt > max) { 337 av_log(obj, AV_LOG_ERROR, 338 "Value %d for parameter '%s' out of %s format range [%d - %d]\n", 339 fmt, o->name, desc, min, max); 340 return AVERROR(ERANGE); 341 } 342 343 *(int *)dst = fmt; 344 return 0; 345} 346 347static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) 348{ 349 return set_string_fmt(obj, o, val, dst, 350 AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format"); 351} 352 353static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) 354{ 355 return set_string_fmt(obj, o, val, dst, 356 AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format"); 357} 358 359#if FF_API_OLD_AVOPTIONS 360int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) 361{ 362 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); 363 if (o_out) 364 *o_out = o; 365 return av_opt_set(obj, name, val, 0); 366} 367#endif 368 369int av_opt_set(void *obj, const char *name, const char *val, int search_flags) 370{ 371 int ret = 0; 372 void *dst, *target_obj; 373 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 374 if (!o || !target_obj) 375 return AVERROR_OPTION_NOT_FOUND; 376 if (!val && (o->type != AV_OPT_TYPE_STRING && 377 o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT && 378 o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE && 379 o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR && 380 o->type != AV_OPT_TYPE_CHANNEL_LAYOUT)) 381 return AVERROR(EINVAL); 382 383 if (o->flags & AV_OPT_FLAG_READONLY) 384 return AVERROR(EINVAL); 385 386 dst = ((uint8_t*)target_obj) + o->offset; 387 switch (o->type) { 388 case AV_OPT_TYPE_STRING: return set_string(obj, o, val, dst); 389 case AV_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst); 390 case AV_OPT_TYPE_FLAGS: 391 case AV_OPT_TYPE_INT: 392 case AV_OPT_TYPE_INT64: 393 case AV_OPT_TYPE_FLOAT: 394 case AV_OPT_TYPE_DOUBLE: 395 case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, target_obj, o, val, dst); 396 case AV_OPT_TYPE_IMAGE_SIZE: return set_string_image_size(obj, o, val, dst); 397 case AV_OPT_TYPE_VIDEO_RATE: return set_string_video_rate(obj, o, val, dst); 398 case AV_OPT_TYPE_PIXEL_FMT: return set_string_pixel_fmt(obj, o, val, dst); 399 case AV_OPT_TYPE_SAMPLE_FMT: return set_string_sample_fmt(obj, o, val, dst); 400 case AV_OPT_TYPE_DURATION: 401 if (!val) { 402 *(int64_t *)dst = 0; 403 return 0; 404 } else { 405 if ((ret = av_parse_time(dst, val, 1)) < 0) 406 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val); 407 return ret; 408 } 409 break; 410 case AV_OPT_TYPE_COLOR: return set_string_color(obj, o, val, dst); 411 case AV_OPT_TYPE_CHANNEL_LAYOUT: 412 if (!val || !strcmp(val, "none")) { 413 *(int64_t *)dst = 0; 414 } else { 415#if FF_API_GET_CHANNEL_LAYOUT_COMPAT 416 int64_t cl = ff_get_channel_layout(val, 0); 417#else 418 int64_t cl = av_get_channel_layout(val); 419#endif 420 if (!cl) { 421 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); 422 ret = AVERROR(EINVAL); 423 } 424 *(int64_t *)dst = cl; 425 return ret; 426 } 427 break; 428 } 429 430 av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); 431 return AVERROR(EINVAL); 432} 433 434#define OPT_EVAL_NUMBER(name, opttype, vartype)\ 435 int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\ 436 {\ 437 if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY)\ 438 return AVERROR(EINVAL);\ 439 return set_string_number(obj, obj, o, val, name ## _out);\ 440 } 441 442OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int) 443OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int) 444OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t) 445OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float) 446OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double) 447OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational) 448 449static int set_number(void *obj, const char *name, double num, int den, int64_t intnum, 450 int search_flags) 451{ 452 void *dst, *target_obj; 453 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 454 455 if (!o || !target_obj) 456 return AVERROR_OPTION_NOT_FOUND; 457 458 if (o->flags & AV_OPT_FLAG_READONLY) 459 return AVERROR(EINVAL); 460 461 dst = ((uint8_t*)target_obj) + o->offset; 462 return write_number(obj, o, dst, num, den, intnum); 463} 464 465#if FF_API_OLD_AVOPTIONS 466const AVOption *av_set_double(void *obj, const char *name, double n) 467{ 468 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); 469 if (set_number(obj, name, n, 1, 1, 0) < 0) 470 return NULL; 471 return o; 472} 473 474const AVOption *av_set_q(void *obj, const char *name, AVRational n) 475{ 476 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); 477 if (set_number(obj, name, n.num, n.den, 1, 0) < 0) 478 return NULL; 479 return o; 480} 481 482const AVOption *av_set_int(void *obj, const char *name, int64_t n) 483{ 484 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); 485 if (set_number(obj, name, 1, 1, n, 0) < 0) 486 return NULL; 487 return o; 488} 489#endif 490 491int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags) 492{ 493 return set_number(obj, name, 1, 1, val, search_flags); 494} 495 496int av_opt_set_double(void *obj, const char *name, double val, int search_flags) 497{ 498 return set_number(obj, name, val, 1, 1, search_flags); 499} 500 501int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags) 502{ 503 return set_number(obj, name, val.num, val.den, 1, search_flags); 504} 505 506int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags) 507{ 508 void *target_obj; 509 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 510 uint8_t *ptr; 511 uint8_t **dst; 512 int *lendst; 513 514 if (!o || !target_obj) 515 return AVERROR_OPTION_NOT_FOUND; 516 517 if (o->type != AV_OPT_TYPE_BINARY || o->flags & AV_OPT_FLAG_READONLY) 518 return AVERROR(EINVAL); 519 520 ptr = len ? av_malloc(len) : NULL; 521 if (len && !ptr) 522 return AVERROR(ENOMEM); 523 524 dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset); 525 lendst = (int *)(dst + 1); 526 527 av_free(*dst); 528 *dst = ptr; 529 *lendst = len; 530 if (len) 531 memcpy(ptr, val, len); 532 533 return 0; 534} 535 536int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags) 537{ 538 void *target_obj; 539 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 540 541 if (!o || !target_obj) 542 return AVERROR_OPTION_NOT_FOUND; 543 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) { 544 av_log(obj, AV_LOG_ERROR, 545 "The value set by option '%s' is not an image size.\n", o->name); 546 return AVERROR(EINVAL); 547 } 548 if (w<0 || h<0) { 549 av_log(obj, AV_LOG_ERROR, 550 "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name); 551 return AVERROR(EINVAL); 552 } 553 *(int *)(((uint8_t *)target_obj) + o->offset) = w; 554 *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h; 555 return 0; 556} 557 558int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags) 559{ 560 void *target_obj; 561 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 562 563 if (!o || !target_obj) 564 return AVERROR_OPTION_NOT_FOUND; 565 if (o->type != AV_OPT_TYPE_VIDEO_RATE) { 566 av_log(obj, AV_LOG_ERROR, 567 "The value set by option '%s' is not a video rate.\n", o->name); 568 return AVERROR(EINVAL); 569 } 570 if (val.num <= 0 || val.den <= 0) 571 return AVERROR(EINVAL); 572 return set_number(obj, name, val.num, val.den, 1, search_flags); 573} 574 575static int set_format(void *obj, const char *name, int fmt, int search_flags, 576 enum AVOptionType type, const char *desc, int nb_fmts) 577{ 578 void *target_obj; 579 const AVOption *o = av_opt_find2(obj, name, NULL, 0, 580 search_flags, &target_obj); 581 int min, max; 582 const AVClass *class = *(AVClass **)obj; 583 584 if (!o || !target_obj) 585 return AVERROR_OPTION_NOT_FOUND; 586 if (o->type != type) { 587 av_log(obj, AV_LOG_ERROR, 588 "The value set by option '%s' is not a %s format", name, desc); 589 return AVERROR(EINVAL); 590 } 591 592#if LIBAVUTIL_VERSION_MAJOR < 54 593 if (class->version && class->version < AV_VERSION_INT(52, 11, 100)) { 594 min = -1; 595 max = nb_fmts-1; 596 } else 597#endif 598 { 599 min = FFMAX(o->min, -1); 600 max = FFMIN(o->max, nb_fmts-1); 601 } 602 if (fmt < min || fmt > max) { 603 av_log(obj, AV_LOG_ERROR, 604 "Value %d for parameter '%s' out of %s format range [%d - %d]\n", 605 fmt, name, desc, min, max); 606 return AVERROR(ERANGE); 607 } 608 *(int *)(((uint8_t *)target_obj) + o->offset) = fmt; 609 return 0; 610} 611 612int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags) 613{ 614 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB); 615} 616 617int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags) 618{ 619 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB); 620} 621 622int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags) 623{ 624 void *target_obj; 625 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 626 627 if (!o || !target_obj) 628 return AVERROR_OPTION_NOT_FOUND; 629 if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { 630 av_log(obj, AV_LOG_ERROR, 631 "The value set by option '%s' is not a channel layout.\n", o->name); 632 return AVERROR(EINVAL); 633 } 634 *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl; 635 return 0; 636} 637 638#if FF_API_OLD_AVOPTIONS 639/** 640 * 641 * @param buf a buffer which is used for returning non string values as strings, can be NULL 642 * @param buf_len allocated length in bytes of buf 643 */ 644const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len) 645{ 646 const AVOption *o = av_opt_find(obj, name, NULL, 0, AV_OPT_SEARCH_CHILDREN); 647 void *dst; 648 uint8_t *bin; 649 int len, i; 650 if (!o) 651 return NULL; 652 if (o->type != AV_OPT_TYPE_STRING && (!buf || !buf_len)) 653 return NULL; 654 655 dst= ((uint8_t*)obj) + o->offset; 656 if (o_out) *o_out= o; 657 658 switch (o->type) { 659 case AV_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break; 660 case AV_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break; 661 case AV_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break; 662 case AV_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break; 663 case AV_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break; 664 case AV_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; 665 case AV_OPT_TYPE_CONST: snprintf(buf, buf_len, "%f" , o->default_val.dbl);break; 666 case AV_OPT_TYPE_STRING: return *(void**)dst; 667 case AV_OPT_TYPE_BINARY: 668 len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *)); 669 if (len >= (buf_len + 1)/2) return NULL; 670 bin = *(uint8_t**)dst; 671 for (i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]); 672 break; 673 default: return NULL; 674 } 675 return buf; 676} 677#endif 678 679int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) 680{ 681 void *dst, *target_obj; 682 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 683 uint8_t *bin, buf[128]; 684 int len, i, ret; 685 int64_t i64; 686 687 if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST)) 688 return AVERROR_OPTION_NOT_FOUND; 689 690 dst = (uint8_t*)target_obj + o->offset; 691 692 buf[0] = 0; 693 switch (o->type) { 694 case AV_OPT_TYPE_FLAGS: ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);break; 695 case AV_OPT_TYPE_INT: ret = snprintf(buf, sizeof(buf), "%d" , *(int *)dst);break; 696 case AV_OPT_TYPE_INT64: ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break; 697 case AV_OPT_TYPE_FLOAT: ret = snprintf(buf, sizeof(buf), "%f" , *(float *)dst);break; 698 case AV_OPT_TYPE_DOUBLE: ret = snprintf(buf, sizeof(buf), "%f" , *(double *)dst);break; 699 case AV_OPT_TYPE_VIDEO_RATE: 700 case AV_OPT_TYPE_RATIONAL: ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; 701 case AV_OPT_TYPE_CONST: ret = snprintf(buf, sizeof(buf), "%f" , o->default_val.dbl);break; 702 case AV_OPT_TYPE_STRING: 703 if (*(uint8_t**)dst) 704 *out_val = av_strdup(*(uint8_t**)dst); 705 else 706 *out_val = av_strdup(""); 707 return 0; 708 case AV_OPT_TYPE_BINARY: 709 len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *)); 710 if ((uint64_t)len*2 + 1 > INT_MAX) 711 return AVERROR(EINVAL); 712 if (!(*out_val = av_malloc(len*2 + 1))) 713 return AVERROR(ENOMEM); 714 bin = *(uint8_t**)dst; 715 for (i = 0; i < len; i++) 716 snprintf(*out_val + i*2, 3, "%02X", bin[i]); 717 return 0; 718 case AV_OPT_TYPE_IMAGE_SIZE: 719 ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]); 720 break; 721 case AV_OPT_TYPE_PIXEL_FMT: 722 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none")); 723 break; 724 case AV_OPT_TYPE_SAMPLE_FMT: 725 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none")); 726 break; 727 case AV_OPT_TYPE_DURATION: 728 i64 = *(int64_t *)dst; 729 ret = snprintf(buf, sizeof(buf), "%"PRIi64"d:%02d:%02d.%06d", 730 i64 / 3600000000, (int)((i64 / 60000000) % 60), 731 (int)((i64 / 1000000) % 60), (int)(i64 % 1000000)); 732 break; 733 case AV_OPT_TYPE_COLOR: 734 ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]); 735 break; 736 case AV_OPT_TYPE_CHANNEL_LAYOUT: 737 i64 = *(int64_t *)dst; 738 ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64); 739 break; 740 default: 741 return AVERROR(EINVAL); 742 } 743 744 if (ret >= sizeof(buf)) 745 return AVERROR(EINVAL); 746 *out_val = av_strdup(buf); 747 return 0; 748} 749 750static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum, 751 int search_flags) 752{ 753 void *dst, *target_obj; 754 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 755 if (!o || !target_obj) 756 goto error; 757 758 dst = ((uint8_t*)target_obj) + o->offset; 759 760 if (o_out) *o_out= o; 761 762 return read_number(o, dst, num, den, intnum); 763 764error: 765 *den=*intnum=0; 766 return -1; 767} 768 769#if FF_API_OLD_AVOPTIONS 770double av_get_double(void *obj, const char *name, const AVOption **o_out) 771{ 772 int64_t intnum=1; 773 double num=1; 774 int den=1; 775 776 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0) 777 return NAN; 778 return num*intnum/den; 779} 780 781AVRational av_get_q(void *obj, const char *name, const AVOption **o_out) 782{ 783 int64_t intnum=1; 784 double num=1; 785 int den=1; 786 787 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0) 788 return (AVRational){0, 0}; 789 if (num == 1.0 && (int)intnum == intnum) 790 return (AVRational){intnum, den}; 791 else 792 return av_d2q(num*intnum/den, 1<<24); 793} 794 795int64_t av_get_int(void *obj, const char *name, const AVOption **o_out) 796{ 797 int64_t intnum=1; 798 double num=1; 799 int den=1; 800 801 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0) 802 return -1; 803 return num*intnum/den; 804} 805#endif 806 807int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val) 808{ 809 int64_t intnum = 1; 810 double num = 1; 811 int ret, den = 1; 812 813 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) 814 return ret; 815 *out_val = num*intnum/den; 816 return 0; 817} 818 819int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val) 820{ 821 int64_t intnum = 1; 822 double num = 1; 823 int ret, den = 1; 824 825 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) 826 return ret; 827 *out_val = num*intnum/den; 828 return 0; 829} 830 831int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val) 832{ 833 int64_t intnum = 1; 834 double num = 1; 835 int ret, den = 1; 836 837 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) 838 return ret; 839 840 if (num == 1.0 && (int)intnum == intnum) 841 *out_val = (AVRational){intnum, den}; 842 else 843 *out_val = av_d2q(num*intnum/den, 1<<24); 844 return 0; 845} 846 847int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out) 848{ 849 void *dst, *target_obj; 850 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 851 if (!o || !target_obj) 852 return AVERROR_OPTION_NOT_FOUND; 853 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) { 854 av_log(obj, AV_LOG_ERROR, 855 "The value for option '%s' is not an image size.\n", name); 856 return AVERROR(EINVAL); 857 } 858 859 dst = ((uint8_t*)target_obj) + o->offset; 860 if (w_out) *w_out = *(int *)dst; 861 if (h_out) *h_out = *((int *)dst+1); 862 return 0; 863} 864 865int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val) 866{ 867 int64_t intnum = 1; 868 double num = 1; 869 int ret, den = 1; 870 871 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) 872 return ret; 873 874 if (num == 1.0 && (int)intnum == intnum) 875 *out_val = (AVRational){intnum, den}; 876 else 877 *out_val = av_d2q(num*intnum/den, 1<<24); 878 return 0; 879} 880 881static int get_format(void *obj, const char *name, int search_flags, int *out_fmt, 882 enum AVOptionType type, const char *desc) 883{ 884 void *dst, *target_obj; 885 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 886 if (!o || !target_obj) 887 return AVERROR_OPTION_NOT_FOUND; 888 if (o->type != type) { 889 av_log(obj, AV_LOG_ERROR, 890 "The value for option '%s' is not a %s format.\n", desc, name); 891 return AVERROR(EINVAL); 892 } 893 894 dst = ((uint8_t*)target_obj) + o->offset; 895 *out_fmt = *(int *)dst; 896 return 0; 897} 898 899int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt) 900{ 901 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel"); 902} 903 904int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt) 905{ 906 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample"); 907} 908 909int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl) 910{ 911 void *dst, *target_obj; 912 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 913 if (!o || !target_obj) 914 return AVERROR_OPTION_NOT_FOUND; 915 if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { 916 av_log(obj, AV_LOG_ERROR, 917 "The value for option '%s' is not a channel layout.\n", name); 918 return AVERROR(EINVAL); 919 } 920 921 dst = ((uint8_t*)target_obj) + o->offset; 922 *cl = *(int64_t *)dst; 923 return 0; 924} 925 926int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) 927{ 928 const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); 929 const AVOption *flag = av_opt_find(obj, flag_name, 930 field ? field->unit : NULL, 0, 0); 931 int64_t res; 932 933 if (!field || !flag || flag->type != AV_OPT_TYPE_CONST || 934 av_opt_get_int(obj, field_name, 0, &res) < 0) 935 return 0; 936 return res & flag->default_val.i64; 937} 938 939static void log_value(void *av_log_obj, int level, double d) 940{ 941 if (d == INT_MAX) { 942 av_log(av_log_obj, level, "INT_MAX"); 943 } else if (d == INT_MIN) { 944 av_log(av_log_obj, level, "INT_MIN"); 945 } else if (d == UINT32_MAX) { 946 av_log(av_log_obj, level, "UINT32_MAX"); 947 } else if (d == (double)INT64_MAX) { 948 av_log(av_log_obj, level, "I64_MAX"); 949 } else if (d == INT64_MIN) { 950 av_log(av_log_obj, level, "I64_MIN"); 951 } else if (d == FLT_MAX) { 952 av_log(av_log_obj, level, "FLT_MAX"); 953 } else if (d == FLT_MIN) { 954 av_log(av_log_obj, level, "FLT_MIN"); 955 } else if (d == -FLT_MAX) { 956 av_log(av_log_obj, level, "-FLT_MAX"); 957 } else if (d == -FLT_MIN) { 958 av_log(av_log_obj, level, "-FLT_MIN"); 959 } else if (d == DBL_MAX) { 960 av_log(av_log_obj, level, "DBL_MAX"); 961 } else if (d == DBL_MIN) { 962 av_log(av_log_obj, level, "DBL_MIN"); 963 } else if (d == -DBL_MAX) { 964 av_log(av_log_obj, level, "-DBL_MAX"); 965 } else if (d == -DBL_MIN) { 966 av_log(av_log_obj, level, "-DBL_MIN"); 967 } else { 968 av_log(av_log_obj, level, "%g", d); 969 } 970} 971 972static void opt_list(void *obj, void *av_log_obj, const char *unit, 973 int req_flags, int rej_flags) 974{ 975 const AVOption *opt=NULL; 976 AVOptionRanges *r; 977 int i; 978 979 while ((opt = av_opt_next(obj, opt))) { 980 if (!(opt->flags & req_flags) || (opt->flags & rej_flags)) 981 continue; 982 983 /* Don't print CONST's on level one. 984 * Don't print anything but CONST's on level two. 985 * Only print items from the requested unit. 986 */ 987 if (!unit && opt->type==AV_OPT_TYPE_CONST) 988 continue; 989 else if (unit && opt->type!=AV_OPT_TYPE_CONST) 990 continue; 991 else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit)) 992 continue; 993 else if (unit && opt->type == AV_OPT_TYPE_CONST) 994 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); 995 else 996 av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ", 997 (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? "" : "-", 998 opt->name); 999 1000 switch (opt->type) { 1001 case AV_OPT_TYPE_FLAGS: 1002 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>"); 1003 break; 1004 case AV_OPT_TYPE_INT: 1005 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>"); 1006 break; 1007 case AV_OPT_TYPE_INT64: 1008 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>"); 1009 break; 1010 case AV_OPT_TYPE_DOUBLE: 1011 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>"); 1012 break; 1013 case AV_OPT_TYPE_FLOAT: 1014 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>"); 1015 break; 1016 case AV_OPT_TYPE_STRING: 1017 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>"); 1018 break; 1019 case AV_OPT_TYPE_RATIONAL: 1020 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>"); 1021 break; 1022 case AV_OPT_TYPE_BINARY: 1023 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>"); 1024 break; 1025 case AV_OPT_TYPE_IMAGE_SIZE: 1026 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>"); 1027 break; 1028 case AV_OPT_TYPE_VIDEO_RATE: 1029 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>"); 1030 break; 1031 case AV_OPT_TYPE_PIXEL_FMT: 1032 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>"); 1033 break; 1034 case AV_OPT_TYPE_SAMPLE_FMT: 1035 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>"); 1036 break; 1037 case AV_OPT_TYPE_DURATION: 1038 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>"); 1039 break; 1040 case AV_OPT_TYPE_COLOR: 1041 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>"); 1042 break; 1043 case AV_OPT_TYPE_CHANNEL_LAYOUT: 1044 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>"); 1045 break; 1046 case AV_OPT_TYPE_CONST: 1047 default: 1048 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); 1049 break; 1050 } 1051 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.'); 1052 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.'); 1053 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.'); 1054 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); 1055 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); 1056 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); 1057 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.'); 1058 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.'); 1059 1060 if (opt->help) 1061 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); 1062 1063 if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) { 1064 switch (opt->type) { 1065 case AV_OPT_TYPE_INT: 1066 case AV_OPT_TYPE_INT64: 1067 case AV_OPT_TYPE_DOUBLE: 1068 case AV_OPT_TYPE_FLOAT: 1069 case AV_OPT_TYPE_RATIONAL: 1070 for (i = 0; i < r->nb_ranges; i++) { 1071 av_log(av_log_obj, AV_LOG_INFO, " (from "); 1072 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min); 1073 av_log(av_log_obj, AV_LOG_INFO, " to "); 1074 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max); 1075 av_log(av_log_obj, AV_LOG_INFO, ")"); 1076 } 1077 break; 1078 } 1079 av_opt_freep_ranges(&r); 1080 } 1081 1082 if (opt->type != AV_OPT_TYPE_CONST && 1083 opt->type != AV_OPT_TYPE_BINARY && 1084 !((opt->type == AV_OPT_TYPE_COLOR || 1085 opt->type == AV_OPT_TYPE_IMAGE_SIZE || 1086 opt->type == AV_OPT_TYPE_STRING || 1087 opt->type == AV_OPT_TYPE_VIDEO_RATE) && 1088 !opt->default_val.str)) { 1089 av_log(av_log_obj, AV_LOG_INFO, " (default "); 1090 switch (opt->type) { 1091 case AV_OPT_TYPE_FLAGS: 1092 av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64); 1093 break; 1094 case AV_OPT_TYPE_DURATION: 1095 case AV_OPT_TYPE_INT: 1096 case AV_OPT_TYPE_INT64: 1097 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64); 1098 break; 1099 case AV_OPT_TYPE_DOUBLE: 1100 case AV_OPT_TYPE_FLOAT: 1101 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl); 1102 break; 1103 case AV_OPT_TYPE_RATIONAL: { 1104 AVRational q = av_d2q(opt->default_val.dbl, INT_MAX); 1105 av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); } 1106 break; 1107 case AV_OPT_TYPE_PIXEL_FMT: 1108 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none")); 1109 break; 1110 case AV_OPT_TYPE_SAMPLE_FMT: 1111 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none")); 1112 break; 1113 case AV_OPT_TYPE_COLOR: 1114 case AV_OPT_TYPE_IMAGE_SIZE: 1115 case AV_OPT_TYPE_STRING: 1116 case AV_OPT_TYPE_VIDEO_RATE: 1117 av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str); 1118 break; 1119 case AV_OPT_TYPE_CHANNEL_LAYOUT: 1120 av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64); 1121 break; 1122 } 1123 av_log(av_log_obj, AV_LOG_INFO, ")"); 1124 } 1125 1126 av_log(av_log_obj, AV_LOG_INFO, "\n"); 1127 if (opt->unit && opt->type != AV_OPT_TYPE_CONST) { 1128 opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags); 1129 } 1130 } 1131} 1132 1133int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags) 1134{ 1135 if (!obj) 1136 return -1; 1137 1138 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name); 1139 1140 opt_list(obj, av_log_obj, NULL, req_flags, rej_flags); 1141 1142 return 0; 1143} 1144 1145void av_opt_set_defaults(void *s) 1146{ 1147#if FF_API_OLD_AVOPTIONS 1148 av_opt_set_defaults2(s, 0, 0); 1149} 1150 1151void av_opt_set_defaults2(void *s, int mask, int flags) 1152{ 1153#endif 1154 const AVClass *class = *(AVClass **)s; 1155 const AVOption *opt = NULL; 1156 while ((opt = av_opt_next(s, opt)) != NULL) { 1157 void *dst = ((uint8_t*)s) + opt->offset; 1158#if FF_API_OLD_AVOPTIONS 1159 if ((opt->flags & mask) != flags) 1160 continue; 1161#endif 1162 1163 if (opt->flags & AV_OPT_FLAG_READONLY) 1164 continue; 1165 1166 switch (opt->type) { 1167 case AV_OPT_TYPE_CONST: 1168 /* Nothing to be done here */ 1169 break; 1170 case AV_OPT_TYPE_FLAGS: 1171 case AV_OPT_TYPE_INT: 1172 case AV_OPT_TYPE_INT64: 1173 case AV_OPT_TYPE_DURATION: 1174 case AV_OPT_TYPE_CHANNEL_LAYOUT: 1175 write_number(s, opt, dst, 1, 1, opt->default_val.i64); 1176 break; 1177 case AV_OPT_TYPE_DOUBLE: 1178 case AV_OPT_TYPE_FLOAT: { 1179 double val; 1180 val = opt->default_val.dbl; 1181 write_number(s, opt, dst, val, 1, 1); 1182 } 1183 break; 1184 case AV_OPT_TYPE_RATIONAL: { 1185 AVRational val; 1186 val = av_d2q(opt->default_val.dbl, INT_MAX); 1187 write_number(s, opt, dst, 1, val.den, val.num); 1188 } 1189 break; 1190 case AV_OPT_TYPE_COLOR: 1191 set_string_color(s, opt, opt->default_val.str, dst); 1192 break; 1193 case AV_OPT_TYPE_STRING: 1194 set_string(s, opt, opt->default_val.str, dst); 1195 break; 1196 case AV_OPT_TYPE_IMAGE_SIZE: 1197 set_string_image_size(s, opt, opt->default_val.str, dst); 1198 break; 1199 case AV_OPT_TYPE_VIDEO_RATE: 1200 set_string_video_rate(s, opt, opt->default_val.str, dst); 1201 break; 1202 case AV_OPT_TYPE_PIXEL_FMT: 1203#if LIBAVUTIL_VERSION_MAJOR < 54 1204 if (class->version && class->version < AV_VERSION_INT(52, 10, 100)) 1205 av_opt_set(s, opt->name, opt->default_val.str, 0); 1206 else 1207#endif 1208 write_number(s, opt, dst, 1, 1, opt->default_val.i64); 1209 break; 1210 case AV_OPT_TYPE_SAMPLE_FMT: 1211#if LIBAVUTIL_VERSION_MAJOR < 54 1212 if (class->version && class->version < AV_VERSION_INT(52, 10, 100)) 1213 av_opt_set(s, opt->name, opt->default_val.str, 0); 1214 else 1215#endif 1216 write_number(s, opt, dst, 1, 1, opt->default_val.i64); 1217 break; 1218 case AV_OPT_TYPE_BINARY: 1219 /* Cannot set default for binary */ 1220 break; 1221 default: 1222 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name); 1223 } 1224 } 1225} 1226 1227/** 1228 * Store the value in the field in ctx that is named like key. 1229 * ctx must be an AVClass context, storing is done using AVOptions. 1230 * 1231 * @param buf the string to parse, buf will be updated to point at the 1232 * separator just after the parsed key/value pair 1233 * @param key_val_sep a 0-terminated list of characters used to 1234 * separate key from value 1235 * @param pairs_sep a 0-terminated list of characters used to separate 1236 * two pairs from each other 1237 * @return 0 if the key/value pair has been successfully parsed and 1238 * set, or a negative value corresponding to an AVERROR code in case 1239 * of error: 1240 * AVERROR(EINVAL) if the key/value pair cannot be parsed, 1241 * the error code issued by av_opt_set() if the key/value pair 1242 * cannot be set 1243 */ 1244static int parse_key_value_pair(void *ctx, const char **buf, 1245 const char *key_val_sep, const char *pairs_sep) 1246{ 1247 char *key = av_get_token(buf, key_val_sep); 1248 char *val; 1249 int ret; 1250 1251 if (!key) 1252 return AVERROR(ENOMEM); 1253 1254 if (*key && strspn(*buf, key_val_sep)) { 1255 (*buf)++; 1256 val = av_get_token(buf, pairs_sep); 1257 if (!val) { 1258 av_freep(&key); 1259 return AVERROR(ENOMEM); 1260 } 1261 } else { 1262 av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); 1263 av_free(key); 1264 return AVERROR(EINVAL); 1265 } 1266 1267 av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val); 1268 1269 ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN); 1270 if (ret == AVERROR_OPTION_NOT_FOUND) 1271 av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); 1272 1273 av_free(key); 1274 av_free(val); 1275 return ret; 1276} 1277 1278int av_set_options_string(void *ctx, const char *opts, 1279 const char *key_val_sep, const char *pairs_sep) 1280{ 1281 int ret, count = 0; 1282 1283 if (!opts) 1284 return 0; 1285 1286 while (*opts) { 1287 if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) 1288 return ret; 1289 count++; 1290 1291 if (*opts) 1292 opts++; 1293 } 1294 1295 return count; 1296} 1297 1298#define WHITESPACES " \n\t" 1299 1300static int is_key_char(char c) 1301{ 1302 return (unsigned)((c | 32) - 'a') < 26 || 1303 (unsigned)(c - '0') < 10 || 1304 c == '-' || c == '_' || c == '/' || c == '.'; 1305} 1306 1307/** 1308 * Read a key from a string. 1309 * 1310 * The key consists of is_key_char characters and must be terminated by a 1311 * character from the delim string; spaces are ignored. 1312 * 1313 * @return 0 for success (even with ellipsis), <0 for failure 1314 */ 1315static int get_key(const char **ropts, const char *delim, char **rkey) 1316{ 1317 const char *opts = *ropts; 1318 const char *key_start, *key_end; 1319 1320 key_start = opts += strspn(opts, WHITESPACES); 1321 while (is_key_char(*opts)) 1322 opts++; 1323 key_end = opts; 1324 opts += strspn(opts, WHITESPACES); 1325 if (!*opts || !strchr(delim, *opts)) 1326 return AVERROR(EINVAL); 1327 opts++; 1328 if (!(*rkey = av_malloc(key_end - key_start + 1))) 1329 return AVERROR(ENOMEM); 1330 memcpy(*rkey, key_start, key_end - key_start); 1331 (*rkey)[key_end - key_start] = 0; 1332 *ropts = opts; 1333 return 0; 1334} 1335 1336int av_opt_get_key_value(const char **ropts, 1337 const char *key_val_sep, const char *pairs_sep, 1338 unsigned flags, 1339 char **rkey, char **rval) 1340{ 1341 int ret; 1342 char *key = NULL, *val; 1343 const char *opts = *ropts; 1344 1345 if ((ret = get_key(&opts, key_val_sep, &key)) < 0 && 1346 !(flags & AV_OPT_FLAG_IMPLICIT_KEY)) 1347 return AVERROR(EINVAL); 1348 if (!(val = av_get_token(&opts, pairs_sep))) { 1349 av_free(key); 1350 return AVERROR(ENOMEM); 1351 } 1352 *ropts = opts; 1353 *rkey = key; 1354 *rval = val; 1355 return 0; 1356} 1357 1358int av_opt_set_from_string(void *ctx, const char *opts, 1359 const char *const *shorthand, 1360 const char *key_val_sep, const char *pairs_sep) 1361{ 1362 int ret, count = 0; 1363 const char *dummy_shorthand = NULL; 1364 char *av_uninit(parsed_key), *av_uninit(value); 1365 const char *key; 1366 1367 if (!opts) 1368 return 0; 1369 if (!shorthand) 1370 shorthand = &dummy_shorthand; 1371 1372 while (*opts) { 1373 ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep, 1374 *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0, 1375 &parsed_key, &value); 1376 if (ret < 0) { 1377 if (ret == AVERROR(EINVAL)) 1378 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts); 1379 else 1380 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts, 1381 av_err2str(ret)); 1382 return ret; 1383 } 1384 if (*opts) 1385 opts++; 1386 if (parsed_key) { 1387 key = parsed_key; 1388 while (*shorthand) /* discard all remaining shorthand */ 1389 shorthand++; 1390 } else { 1391 key = *(shorthand++); 1392 } 1393 1394 av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value); 1395 if ((ret = av_opt_set(ctx, key, value, 0)) < 0) { 1396 if (ret == AVERROR_OPTION_NOT_FOUND) 1397 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); 1398 av_free(value); 1399 av_free(parsed_key); 1400 return ret; 1401 } 1402 1403 av_free(value); 1404 av_free(parsed_key); 1405 count++; 1406 } 1407 return count; 1408} 1409 1410void av_opt_free(void *obj) 1411{ 1412 const AVOption *o = NULL; 1413 while ((o = av_opt_next(obj, o))) 1414 if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY) 1415 av_freep((uint8_t *)obj + o->offset); 1416} 1417 1418int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags) 1419{ 1420 AVDictionaryEntry *t = NULL; 1421 AVDictionary *tmp = NULL; 1422 int ret = 0; 1423 1424 if (!options) 1425 return 0; 1426 1427 while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) { 1428 ret = av_opt_set(obj, t->key, t->value, search_flags); 1429 if (ret == AVERROR_OPTION_NOT_FOUND) 1430 av_dict_set(&tmp, t->key, t->value, 0); 1431 else if (ret < 0) { 1432 av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value); 1433 break; 1434 } 1435 ret = 0; 1436 } 1437 av_dict_free(options); 1438 *options = tmp; 1439 return ret; 1440} 1441 1442int av_opt_set_dict(void *obj, AVDictionary **options) 1443{ 1444 return av_opt_set_dict2(obj, options, 0); 1445} 1446 1447const AVOption *av_opt_find(void *obj, const char *name, const char *unit, 1448 int opt_flags, int search_flags) 1449{ 1450 return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL); 1451} 1452 1453const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, 1454 int opt_flags, int search_flags, void **target_obj) 1455{ 1456 const AVClass *c; 1457 const AVOption *o = NULL; 1458 1459 if(!obj) 1460 return NULL; 1461 1462 c= *(AVClass**)obj; 1463 1464 if (!c) 1465 return NULL; 1466 1467 if (search_flags & AV_OPT_SEARCH_CHILDREN) { 1468 if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { 1469 const AVClass *child = NULL; 1470 while (child = av_opt_child_class_next(c, child)) 1471 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) 1472 return o; 1473 } else { 1474 void *child = NULL; 1475 while (child = av_opt_child_next(obj, child)) 1476 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj)) 1477 return o; 1478 } 1479 } 1480 1481 while (o = av_opt_next(obj, o)) { 1482 if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags && 1483 ((!unit && o->type != AV_OPT_TYPE_CONST) || 1484 (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) { 1485 if (target_obj) { 1486 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ)) 1487 *target_obj = obj; 1488 else 1489 *target_obj = NULL; 1490 } 1491 return o; 1492 } 1493 } 1494 return NULL; 1495} 1496 1497void *av_opt_child_next(void *obj, void *prev) 1498{ 1499 const AVClass *c = *(AVClass**)obj; 1500 if (c->child_next) 1501 return c->child_next(obj, prev); 1502 return NULL; 1503} 1504 1505const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev) 1506{ 1507 if (parent->child_class_next) 1508 return parent->child_class_next(prev); 1509 return NULL; 1510} 1511 1512void *av_opt_ptr(const AVClass *class, void *obj, const char *name) 1513{ 1514 const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL); 1515 if(!opt) 1516 return NULL; 1517 return (uint8_t*)obj + opt->offset; 1518} 1519 1520static int opt_size(enum AVOptionType type) 1521{ 1522 switch(type) { 1523 case AV_OPT_TYPE_INT: 1524 case AV_OPT_TYPE_FLAGS: return sizeof(int); 1525 case AV_OPT_TYPE_DURATION: 1526 case AV_OPT_TYPE_CHANNEL_LAYOUT: 1527 case AV_OPT_TYPE_INT64: return sizeof(int64_t); 1528 case AV_OPT_TYPE_DOUBLE: return sizeof(double); 1529 case AV_OPT_TYPE_FLOAT: return sizeof(float); 1530 case AV_OPT_TYPE_STRING: return sizeof(uint8_t*); 1531 case AV_OPT_TYPE_VIDEO_RATE: 1532 case AV_OPT_TYPE_RATIONAL: return sizeof(AVRational); 1533 case AV_OPT_TYPE_BINARY: return sizeof(uint8_t*) + sizeof(int); 1534 case AV_OPT_TYPE_IMAGE_SIZE:return sizeof(int[2]); 1535 case AV_OPT_TYPE_PIXEL_FMT: return sizeof(enum AVPixelFormat); 1536 case AV_OPT_TYPE_SAMPLE_FMT:return sizeof(enum AVSampleFormat); 1537 case AV_OPT_TYPE_COLOR: return 4; 1538 } 1539 return 0; 1540} 1541 1542int av_opt_copy(void *dst, void *src) 1543{ 1544 const AVOption *o = NULL; 1545 const AVClass *c; 1546 int ret = 0; 1547 1548 if (!src) 1549 return 0; 1550 1551 c = *(AVClass**)src; 1552 if (*(AVClass**)dst && c != *(AVClass**)dst) 1553 return AVERROR(EINVAL); 1554 1555 while ((o = av_opt_next(src, o))) { 1556 void *field_dst = ((uint8_t*)dst) + o->offset; 1557 void *field_src = ((uint8_t*)src) + o->offset; 1558 uint8_t **field_dst8 = (uint8_t**)field_dst; 1559 uint8_t **field_src8 = (uint8_t**)field_src; 1560 1561 if (o->type == AV_OPT_TYPE_STRING) { 1562 set_string(dst, o, *field_src8, field_dst8); 1563 if (*field_src8 && !*field_dst8) 1564 ret = AVERROR(ENOMEM); 1565 } else if (o->type == AV_OPT_TYPE_BINARY) { 1566 int len = *(int*)(field_src8 + 1); 1567 if (*field_dst8 != *field_src8) 1568 av_freep(field_dst8); 1569 *field_dst8 = av_memdup(*field_src8, len); 1570 if (len && !*field_dst8) { 1571 ret = AVERROR(ENOMEM); 1572 len = 0; 1573 } 1574 *(int*)(field_dst8 + 1) = len; 1575 } else if (o->type == AV_OPT_TYPE_CONST) { 1576 // do nothing 1577 } else { 1578 memcpy(field_dst, field_src, opt_size(o->type)); 1579 } 1580 } 1581 return ret; 1582} 1583 1584int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) 1585{ 1586 int ret; 1587 const AVClass *c = *(AVClass**)obj; 1588 int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL; 1589 1590 if (c->version > (52 << 16 | 11 << 8)) 1591 callback = c->query_ranges; 1592 1593 if (!callback) 1594 callback = av_opt_query_ranges_default; 1595 1596 ret = callback(ranges_arg, obj, key, flags); 1597 if (ret >= 0) { 1598 if (!(flags & AV_OPT_MULTI_COMPONENT_RANGE)) 1599 ret = 1; 1600 (*ranges_arg)->nb_components = ret; 1601 } 1602 return ret; 1603} 1604 1605int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) 1606{ 1607 AVOptionRanges *ranges = av_mallocz(sizeof(*ranges)); 1608 AVOptionRange **range_array = av_mallocz(sizeof(void*)); 1609 AVOptionRange *range = av_mallocz(sizeof(*range)); 1610 const AVOption *field = av_opt_find(obj, key, NULL, 0, flags); 1611 int ret; 1612 1613 *ranges_arg = NULL; 1614 1615 if (!ranges || !range || !range_array || !field) { 1616 ret = AVERROR(ENOMEM); 1617 goto fail; 1618 } 1619 1620 ranges->range = range_array; 1621 ranges->range[0] = range; 1622 ranges->nb_ranges = 1; 1623 ranges->nb_components = 1; 1624 range->is_range = 1; 1625 range->value_min = field->min; 1626 range->value_max = field->max; 1627 1628 switch (field->type) { 1629 case AV_OPT_TYPE_INT: 1630 case AV_OPT_TYPE_INT64: 1631 case AV_OPT_TYPE_PIXEL_FMT: 1632 case AV_OPT_TYPE_SAMPLE_FMT: 1633 case AV_OPT_TYPE_FLOAT: 1634 case AV_OPT_TYPE_DOUBLE: 1635 case AV_OPT_TYPE_DURATION: 1636 case AV_OPT_TYPE_COLOR: 1637 case AV_OPT_TYPE_CHANNEL_LAYOUT: 1638 break; 1639 case AV_OPT_TYPE_STRING: 1640 range->component_min = 0; 1641 range->component_max = 0x10FFFF; // max unicode value 1642 range->value_min = -1; 1643 range->value_max = INT_MAX; 1644 break; 1645 case AV_OPT_TYPE_RATIONAL: 1646 range->component_min = INT_MIN; 1647 range->component_max = INT_MAX; 1648 break; 1649 case AV_OPT_TYPE_IMAGE_SIZE: 1650 range->component_min = 0; 1651 range->component_max = INT_MAX/128/8; 1652 range->value_min = 0; 1653 range->value_max = INT_MAX/8; 1654 break; 1655 case AV_OPT_TYPE_VIDEO_RATE: 1656 range->component_min = 1; 1657 range->component_max = INT_MAX; 1658 range->value_min = 1; 1659 range->value_max = INT_MAX; 1660 break; 1661 default: 1662 ret = AVERROR(ENOSYS); 1663 goto fail; 1664 } 1665 1666 *ranges_arg = ranges; 1667 return 1; 1668fail: 1669 av_free(ranges); 1670 av_free(range); 1671 av_free(range_array); 1672 return ret; 1673} 1674 1675void av_opt_freep_ranges(AVOptionRanges **rangesp) 1676{ 1677 int i; 1678 AVOptionRanges *ranges = *rangesp; 1679 1680 if (!ranges) 1681 return; 1682 1683 for (i = 0; i < ranges->nb_ranges * ranges->nb_components; i++) { 1684 AVOptionRange *range = ranges->range[i]; 1685 if (range) { 1686 av_freep(&range->str); 1687 av_freep(&ranges->range[i]); 1688 } 1689 } 1690 av_freep(&ranges->range); 1691 av_freep(rangesp); 1692} 1693 1694#ifdef TEST 1695 1696typedef struct TestContext 1697{ 1698 const AVClass *class; 1699 int num; 1700 int toggle; 1701 char *string; 1702 int flags; 1703 AVRational rational; 1704 AVRational video_rate; 1705 int w, h; 1706 enum AVPixelFormat pix_fmt; 1707 enum AVSampleFormat sample_fmt; 1708 int64_t duration; 1709 uint8_t color[4]; 1710 int64_t channel_layout; 1711} TestContext; 1712 1713#define OFFSET(x) offsetof(TestContext, x) 1714 1715#define TEST_FLAG_COOL 01 1716#define TEST_FLAG_LAME 02 1717#define TEST_FLAG_MU 04 1718 1719static const AVOption test_options[]= { 1720{"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100 }, 1721{"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1 }, 1722{"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10 }, 1723{"string", "set string", OFFSET(string), AV_OPT_TYPE_STRING, {.str = "default"}, CHAR_MIN, CHAR_MAX }, 1724{"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" }, 1725{"cool", "set cool flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_COOL}, INT_MIN, INT_MAX, 0, "flags" }, 1726{"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" }, 1727{"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" }, 1728{"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{0}, 0, 0 }, 1729{"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX}, 1730{"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, INT_MAX}, 1731{"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0 }, 1732{"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX}, 1733{"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0}, 1734{"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = AV_CH_LAYOUT_HEXAGONAL}, 0, INT64_MAX}, 1735{NULL}, 1736}; 1737 1738static const char *test_get_name(void *ctx) 1739{ 1740 return "test"; 1741} 1742 1743static const AVClass test_class = { 1744 "TestContext", 1745 test_get_name, 1746 test_options 1747}; 1748 1749int main(void) 1750{ 1751 int i; 1752 1753 printf("\nTesting av_set_options_string()\n"); 1754 { 1755 TestContext test_ctx = { 0 }; 1756 static const char * const options[] = { 1757 "", 1758 ":", 1759 "=", 1760 "foo=:", 1761 ":=foo", 1762 "=foo", 1763 "foo=", 1764 "foo", 1765 "foo=val", 1766 "foo==val", 1767 "toggle=:", 1768 "string=:", 1769 "toggle=1 : foo", 1770 "toggle=100", 1771 "toggle==1", 1772 "flags=+mu-lame : num=42: toggle=0", 1773 "num=42 : string=blahblah", 1774 "rational=0 : rational=1/2 : rational=1/-1", 1775 "rational=-1/0", 1776 "size=1024x768", 1777 "size=pal", 1778 "size=bogus", 1779 "pix_fmt=yuv420p", 1780 "pix_fmt=2", 1781 "pix_fmt=bogus", 1782 "sample_fmt=s16", 1783 "sample_fmt=2", 1784 "sample_fmt=bogus", 1785 "video_rate=pal", 1786 "video_rate=25", 1787 "video_rate=30000/1001", 1788 "video_rate=30/1.001", 1789 "video_rate=bogus", 1790 "duration=bogus", 1791 "duration=123.45", 1792 "duration=1\\:23\\:45.67", 1793 "color=blue", 1794 "color=0x223300", 1795 "color=0x42FF07AA", 1796 "cl=stereo+downmix", 1797 "cl=foo", 1798 }; 1799 1800 test_ctx.class = &test_class; 1801 av_opt_set_defaults(&test_ctx); 1802 1803 av_log_set_level(AV_LOG_DEBUG); 1804 1805 for (i=0; i < FF_ARRAY_ELEMS(options); i++) { 1806 av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]); 1807 if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0) 1808 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); 1809 printf("\n"); 1810 } 1811 av_opt_free(&test_ctx); 1812 } 1813 1814 printf("\nTesting av_opt_set_from_string()\n"); 1815 { 1816 TestContext test_ctx = { 0 }; 1817 static const char * const options[] = { 1818 "", 1819 "5", 1820 "5:hello", 1821 "5:hello:size=pal", 1822 "5:size=pal:hello", 1823 ":", 1824 "=", 1825 " 5 : hello : size = pal ", 1826 "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42" 1827 }; 1828 static const char * const shorthand[] = { "num", "string", NULL }; 1829 1830 test_ctx.class = &test_class; 1831 av_opt_set_defaults(&test_ctx); 1832 1833 av_log_set_level(AV_LOG_DEBUG); 1834 1835 for (i=0; i < FF_ARRAY_ELEMS(options); i++) { 1836 av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]); 1837 if (av_opt_set_from_string(&test_ctx, options[i], shorthand, "=", ":") < 0) 1838 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); 1839 printf("\n"); 1840 } 1841 av_opt_free(&test_ctx); 1842 } 1843 1844 return 0; 1845} 1846 1847#endif 1848