opt.c (88061B)
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 "avassert.h" 30 #include "avstring.h" 31 #include "channel_layout.h" 32 #include "dict.h" 33 #include "eval.h" 34 #include "log.h" 35 #include "mem.h" 36 #include "parseutils.h" 37 #include "pixdesc.h" 38 #include "mathematics.h" 39 #include "opt.h" 40 #include "samplefmt.h" 41 #include "bprint.h" 42 #include "version.h" 43 44 #include <float.h> 45 46 #define TYPE_BASE(type) ((type) & ~AV_OPT_TYPE_FLAG_ARRAY) 47 48 const AVOption *av_opt_next(const void *obj, const AVOption *last) 49 { 50 const AVClass *class; 51 if (!obj) 52 return NULL; 53 class = *(const AVClass**)obj; 54 if (!last && class && class->option && class->option[0].name) 55 return class->option; 56 if (last && last[1].name) 57 return ++last; 58 return NULL; 59 } 60 61 static const struct { 62 size_t size; 63 const char *name; 64 } opt_type_desc[] = { 65 [AV_OPT_TYPE_FLAGS] = { sizeof(unsigned), "<flags>" }, 66 [AV_OPT_TYPE_INT] = { sizeof(int), "<int>" }, 67 [AV_OPT_TYPE_INT64] = { sizeof(int64_t), "<int64>" }, 68 [AV_OPT_TYPE_UINT] = { sizeof(unsigned), "<unsigned>" }, 69 [AV_OPT_TYPE_UINT64] = { sizeof(uint64_t), "<uint64>" }, 70 [AV_OPT_TYPE_DOUBLE] = { sizeof(double), "<double>" }, 71 [AV_OPT_TYPE_FLOAT] = { sizeof(float), "<float>" }, 72 [AV_OPT_TYPE_STRING] = { sizeof(char *), "<string>" }, 73 [AV_OPT_TYPE_RATIONAL] = { sizeof(AVRational), "<rational>" }, 74 [AV_OPT_TYPE_BINARY] = { sizeof(uint8_t *), "<binary>" }, 75 [AV_OPT_TYPE_DICT] = { sizeof(AVDictionary *), "<dictionary>" }, 76 [AV_OPT_TYPE_IMAGE_SIZE] = { sizeof(int[2]), "<image_size>" }, 77 [AV_OPT_TYPE_VIDEO_RATE] = { sizeof(AVRational), "<video_rate>" }, 78 [AV_OPT_TYPE_PIXEL_FMT] = { sizeof(int), "<pix_fmt>" }, 79 [AV_OPT_TYPE_SAMPLE_FMT] = { sizeof(int), "<sample_fmt>" }, 80 [AV_OPT_TYPE_DURATION] = { sizeof(int64_t), "<duration>" }, 81 [AV_OPT_TYPE_COLOR] = { sizeof(uint8_t[4]), "<color>" }, 82 [AV_OPT_TYPE_CHLAYOUT] = { sizeof(AVChannelLayout),"<channel_layout>" }, 83 [AV_OPT_TYPE_BOOL] = { sizeof(int), "<boolean>" }, 84 }; 85 86 // option is plain old data 87 static int opt_is_pod(enum AVOptionType type) 88 { 89 switch (type) { 90 case AV_OPT_TYPE_FLAGS: 91 case AV_OPT_TYPE_INT: 92 case AV_OPT_TYPE_INT64: 93 case AV_OPT_TYPE_DOUBLE: 94 case AV_OPT_TYPE_FLOAT: 95 case AV_OPT_TYPE_RATIONAL: 96 case AV_OPT_TYPE_UINT64: 97 case AV_OPT_TYPE_IMAGE_SIZE: 98 case AV_OPT_TYPE_PIXEL_FMT: 99 case AV_OPT_TYPE_SAMPLE_FMT: 100 case AV_OPT_TYPE_VIDEO_RATE: 101 case AV_OPT_TYPE_DURATION: 102 case AV_OPT_TYPE_COLOR: 103 case AV_OPT_TYPE_BOOL: 104 case AV_OPT_TYPE_UINT: 105 return 1; 106 } 107 return 0; 108 } 109 110 static uint8_t opt_array_sep(const AVOption *o) 111 { 112 const AVOptionArrayDef *d = o->default_val.arr; 113 av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY); 114 return (d && d->sep) ? d->sep : ','; 115 } 116 117 static void *opt_array_pelem(const AVOption *o, void *array, unsigned idx) 118 { 119 av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY); 120 return (uint8_t *)array + idx * opt_type_desc[TYPE_BASE(o->type)].size; 121 } 122 123 static unsigned *opt_array_pcount(const void *parray) 124 { 125 return (unsigned *)((const void * const *)parray + 1); 126 } 127 128 static void opt_free_elem(enum AVOptionType type, void *ptr) 129 { 130 switch (TYPE_BASE(type)) { 131 case AV_OPT_TYPE_STRING: 132 case AV_OPT_TYPE_BINARY: 133 av_freep(ptr); 134 break; 135 136 case AV_OPT_TYPE_DICT: 137 av_dict_free((AVDictionary **)ptr); 138 break; 139 140 case AV_OPT_TYPE_CHLAYOUT: 141 av_channel_layout_uninit((AVChannelLayout *)ptr); 142 break; 143 144 default: 145 break; 146 } 147 } 148 149 static void opt_free_array(const AVOption *o, void *parray, unsigned *count) 150 { 151 for (unsigned i = 0; i < *count; i++) 152 opt_free_elem(o->type, opt_array_pelem(o, *(void **)parray, i)); 153 154 av_freep(parray); 155 *count = 0; 156 } 157 158 /** 159 * Perform common setup for option-setting functions. 160 * 161 * @param require_type when non-0, require the option to be of this type 162 * @param ptgt target object is written here 163 * @param po the option is written here 164 * @param pdst pointer to option value is written here 165 */ 166 static int opt_set_init(void *obj, const char *name, int search_flags, 167 int require_type, 168 void **ptgt, const AVOption **po, void **pdst) 169 { 170 const AVOption *o; 171 void *tgt; 172 173 o = av_opt_find2(obj, name, NULL, 0, search_flags, &tgt); 174 if (!o || !tgt) 175 return AVERROR_OPTION_NOT_FOUND; 176 177 if (o->flags & AV_OPT_FLAG_READONLY) 178 return AVERROR(EINVAL); 179 180 if (require_type && (o->type != require_type)) { 181 av_log(obj, AV_LOG_ERROR, 182 "Tried to set option '%s' of type %s from value of type %s, " 183 "this is not supported\n", o->name, opt_type_desc[o->type].name, 184 opt_type_desc[require_type].name); 185 return AVERROR(EINVAL); 186 } 187 188 if (!(o->flags & AV_OPT_FLAG_RUNTIME_PARAM)) { 189 unsigned *state_flags = NULL; 190 const AVClass *class; 191 192 // try state flags first from the target (child), then from its parent 193 class = *(const AVClass**)tgt; 194 if ( 195 #if LIBAVUTIL_VERSION_MAJOR < 60 196 class->version >= AV_VERSION_INT(59, 41, 100) && 197 #endif 198 class->state_flags_offset) 199 state_flags = (unsigned*)((uint8_t*)tgt + class->state_flags_offset); 200 201 if (!state_flags && obj != tgt) { 202 class = *(const AVClass**)obj; 203 if ( 204 #if LIBAVUTIL_VERSION_MAJOR < 60 205 class->version >= AV_VERSION_INT(59, 41, 100) && 206 #endif 207 class->state_flags_offset) 208 state_flags = (unsigned*)((uint8_t*)obj + class->state_flags_offset); 209 } 210 211 if (state_flags && (*state_flags & AV_CLASS_STATE_INITIALIZED)) { 212 av_log(obj, AV_LOG_ERROR, "Option '%s' is not a runtime option and " 213 "so cannot be set after the object has been initialized\n", 214 o->name); 215 #if LIBAVUTIL_VERSION_MAJOR >= 60 216 return AVERROR(EINVAL); 217 #endif 218 } 219 } 220 221 if (o->flags & AV_OPT_FLAG_DEPRECATED) 222 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help); 223 224 if (po) 225 *po = o; 226 if (ptgt) 227 *ptgt = tgt; 228 if (pdst) 229 *pdst = ((uint8_t *)tgt) + o->offset; 230 231 return 0; 232 } 233 234 static AVRational double_to_rational(double d) 235 { 236 AVRational r = av_d2q(d, 1 << 24); 237 if ((!r.num || !r.den) && d) 238 r = av_d2q(d, INT_MAX); 239 return r; 240 } 241 242 static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum) 243 { 244 switch (TYPE_BASE(o->type)) { 245 case AV_OPT_TYPE_FLAGS: 246 *intnum = *(unsigned int*)dst; 247 return 0; 248 case AV_OPT_TYPE_PIXEL_FMT: 249 *intnum = *(enum AVPixelFormat *)dst; 250 return 0; 251 case AV_OPT_TYPE_SAMPLE_FMT: 252 *intnum = *(enum AVSampleFormat *)dst; 253 return 0; 254 case AV_OPT_TYPE_BOOL: 255 case AV_OPT_TYPE_INT: 256 *intnum = *(int *)dst; 257 return 0; 258 case AV_OPT_TYPE_UINT: 259 *intnum = *(unsigned int *)dst; 260 return 0; 261 case AV_OPT_TYPE_DURATION: 262 case AV_OPT_TYPE_INT64: 263 case AV_OPT_TYPE_UINT64: 264 *intnum = *(int64_t *)dst; 265 return 0; 266 case AV_OPT_TYPE_FLOAT: 267 *num = *(float *)dst; 268 return 0; 269 case AV_OPT_TYPE_DOUBLE: 270 *num = *(double *)dst; 271 return 0; 272 case AV_OPT_TYPE_RATIONAL: 273 *intnum = ((AVRational *)dst)->num; 274 *den = ((AVRational *)dst)->den; 275 return 0; 276 case AV_OPT_TYPE_CONST: 277 *intnum = o->default_val.i64; 278 return 0; 279 } 280 return AVERROR(EINVAL); 281 } 282 283 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) 284 { 285 const enum AVOptionType type = TYPE_BASE(o->type); 286 287 if (type != AV_OPT_TYPE_FLAGS && 288 (!den || o->max * den < num * intnum || o->min * den > num * intnum)) { 289 num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN); 290 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", 291 num, o->name, o->min, o->max); 292 return AVERROR(ERANGE); 293 } 294 if (type == AV_OPT_TYPE_FLAGS) { 295 double d = num*intnum/den; 296 if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) { 297 av_log(obj, AV_LOG_ERROR, 298 "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n", 299 num*intnum/den, o->name); 300 return AVERROR(ERANGE); 301 } 302 } 303 304 switch (type) { 305 case AV_OPT_TYPE_PIXEL_FMT: 306 *(enum AVPixelFormat *)dst = llrint(num / den) * intnum; 307 break; 308 case AV_OPT_TYPE_SAMPLE_FMT: 309 *(enum AVSampleFormat *)dst = llrint(num / den) * intnum; 310 break; 311 case AV_OPT_TYPE_BOOL: 312 case AV_OPT_TYPE_FLAGS: 313 case AV_OPT_TYPE_INT: 314 case AV_OPT_TYPE_UINT: 315 *(int *)dst = llrint(num / den) * intnum; 316 break; 317 case AV_OPT_TYPE_DURATION: 318 case AV_OPT_TYPE_INT64:{ 319 double d = num / den; 320 if (intnum == 1 && d == (double)INT64_MAX) { 321 *(int64_t *)dst = INT64_MAX; 322 } else 323 *(int64_t *)dst = llrint(d) * intnum; 324 break;} 325 case AV_OPT_TYPE_UINT64:{ 326 double d = num / den; 327 // We must special case uint64_t here as llrint() does not support values 328 // outside the int64_t range and there is no portable function which does 329 // "INT64_MAX + 1ULL" is used as it is representable exactly as IEEE double 330 // while INT64_MAX is not 331 if (intnum == 1 && d == (double)UINT64_MAX) { 332 *(uint64_t *)dst = UINT64_MAX; 333 } else if (d > INT64_MAX + 1ULL) { 334 *(uint64_t *)dst = (llrint(d - (INT64_MAX + 1ULL)) + (INT64_MAX + 1ULL))*intnum; 335 } else { 336 *(uint64_t *)dst = llrint(d) * intnum; 337 } 338 break;} 339 case AV_OPT_TYPE_FLOAT: 340 *(float *)dst = num * intnum / den; 341 break; 342 case AV_OPT_TYPE_DOUBLE: 343 *(double *)dst = num * intnum / den; 344 break; 345 case AV_OPT_TYPE_RATIONAL: 346 case AV_OPT_TYPE_VIDEO_RATE: 347 if ((int) num == num) 348 *(AVRational *)dst = (AVRational) { num *intnum, den }; 349 else 350 *(AVRational *)dst = double_to_rational(num * intnum / den); 351 break; 352 default: 353 return AVERROR(EINVAL); 354 } 355 return 0; 356 } 357 358 static int hexchar2int(char c) { 359 if (c >= '0' && c <= '9') 360 return c - '0'; 361 if (c >= 'a' && c <= 'f') 362 return c - 'a' + 10; 363 if (c >= 'A' && c <= 'F') 364 return c - 'A' + 10; 365 return -1; 366 } 367 368 static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst) 369 { 370 int *lendst = (int *)(dst + 1); 371 uint8_t *bin, *ptr; 372 int len; 373 374 av_freep(dst); 375 *lendst = 0; 376 377 if (!val || !(len = strlen(val))) 378 return 0; 379 380 if (len & 1) 381 return AVERROR(EINVAL); 382 len /= 2; 383 384 ptr = bin = av_malloc(len); 385 if (!ptr) 386 return AVERROR(ENOMEM); 387 while (*val) { 388 int a = hexchar2int(*val++); 389 int b = hexchar2int(*val++); 390 if (a < 0 || b < 0) { 391 av_free(bin); 392 return AVERROR(EINVAL); 393 } 394 *ptr++ = (a << 4) | b; 395 } 396 *dst = bin; 397 *lendst = len; 398 399 return 0; 400 } 401 402 static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst) 403 { 404 av_freep(dst); 405 if (!val) 406 return 0; 407 *dst = av_strdup(val); 408 return *dst ? 0 : AVERROR(ENOMEM); 409 } 410 411 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \ 412 opt->type == AV_OPT_TYPE_UINT64 || \ 413 opt->type == AV_OPT_TYPE_CONST || \ 414 opt->type == AV_OPT_TYPE_FLAGS || \ 415 opt->type == AV_OPT_TYPE_UINT || \ 416 opt->type == AV_OPT_TYPE_INT) \ 417 ? opt->default_val.i64 \ 418 : opt->default_val.dbl) 419 420 static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst) 421 { 422 const enum AVOptionType type = TYPE_BASE(o->type); 423 int ret = 0; 424 425 if (type == AV_OPT_TYPE_RATIONAL || type == AV_OPT_TYPE_VIDEO_RATE) { 426 int num, den; 427 char c; 428 if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) { 429 if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0) 430 return ret; 431 ret = 0; 432 } 433 } 434 435 for (;;) { 436 int i = 0; 437 char buf[256]; 438 int cmd = 0; 439 double d; 440 int64_t intnum = 1; 441 442 if (type == AV_OPT_TYPE_FLAGS) { 443 if (*val == '+' || *val == '-') 444 cmd = *(val++); 445 for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++) 446 buf[i] = val[i]; 447 buf[i] = 0; 448 } 449 450 { 451 int res; 452 int ci = 0; 453 double const_values[64]; 454 const char * const_names[64]; 455 int search_flags = (o->flags & AV_OPT_FLAG_CHILD_CONSTS) ? AV_OPT_SEARCH_CHILDREN : 0; 456 const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, search_flags); 457 if (o_named && o_named->type == AV_OPT_TYPE_CONST) { 458 d = DEFAULT_NUMVAL(o_named); 459 if (o_named->flags & AV_OPT_FLAG_DEPRECATED) 460 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", 461 o_named->name, o_named->help); 462 } else { 463 if (o->unit) { 464 for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) { 465 if (o_named->type == AV_OPT_TYPE_CONST && 466 o_named->unit && 467 !strcmp(o_named->unit, o->unit)) { 468 if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) { 469 av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit); 470 return AVERROR_PATCHWELCOME; 471 } 472 const_names [ci ] = o_named->name; 473 const_values[ci++] = DEFAULT_NUMVAL(o_named); 474 } 475 } 476 } 477 const_names [ci ] = "default"; 478 const_values[ci++] = DEFAULT_NUMVAL(o); 479 const_names [ci ] = "max"; 480 const_values[ci++] = o->max; 481 const_names [ci ] = "min"; 482 const_values[ci++] = o->min; 483 const_names [ci ] = "none"; 484 const_values[ci++] = 0; 485 const_names [ci ] = "all"; 486 const_values[ci++] = ~0; 487 const_names [ci] = NULL; 488 const_values[ci] = 0; 489 490 res = av_expr_parse_and_eval(&d, i ? buf : val, const_names, 491 const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); 492 if (res < 0) { 493 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); 494 return res; 495 } 496 } 497 } 498 if (type == AV_OPT_TYPE_FLAGS) { 499 intnum = *(unsigned int*)dst; 500 if (cmd == '+') 501 d = intnum | (int64_t)d; 502 else if (cmd == '-') 503 d = intnum &~(int64_t)d; 504 } 505 506 if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0) 507 return ret; 508 val += i; 509 if (!i || !*val) 510 return 0; 511 } 512 } 513 514 static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst) 515 { 516 int ret; 517 518 if (!val || !strcmp(val, "none")) { 519 dst[0] = 520 dst[1] = 0; 521 return 0; 522 } 523 ret = av_parse_video_size(dst, dst + 1, val); 524 if (ret < 0) 525 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val); 526 return ret; 527 } 528 529 static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst) 530 { 531 int ret = av_parse_video_rate(dst, val); 532 if (ret < 0) 533 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); 534 return ret; 535 } 536 537 static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst) 538 { 539 int ret; 540 541 if (!val) { 542 return 0; 543 } else { 544 ret = av_parse_color(dst, val, -1, obj); 545 if (ret < 0) 546 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val); 547 return ret; 548 } 549 return 0; 550 } 551 552 static const char *get_bool_name(int val) 553 { 554 if (val < 0) 555 return "auto"; 556 return val ? "true" : "false"; 557 } 558 559 static int set_string_bool(void *obj, const AVOption *o, const char *val, int *dst) 560 { 561 int n; 562 563 if (!val) 564 return 0; 565 566 if (!strcmp(val, "auto")) { 567 n = -1; 568 } else if (av_match_name(val, "true,y,yes,enable,enabled,on")) { 569 n = 1; 570 } else if (av_match_name(val, "false,n,no,disable,disabled,off")) { 571 n = 0; 572 } else { 573 char *end = NULL; 574 n = strtol(val, &end, 10); 575 if (val + strlen(val) != end) 576 goto fail; 577 } 578 579 if (n < o->min || n > o->max) 580 goto fail; 581 582 *dst = n; 583 return 0; 584 585 fail: 586 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as boolean\n", val); 587 return AVERROR(EINVAL); 588 } 589 590 static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst, 591 int fmt_nb, int ((*get_fmt)(const char *)), const char *desc) 592 { 593 int fmt, min, max; 594 595 if (!val || !strcmp(val, "none")) { 596 fmt = -1; 597 } else { 598 fmt = get_fmt(val); 599 if (fmt == -1) { 600 char *tail; 601 fmt = strtol(val, &tail, 0); 602 if (*tail || (unsigned)fmt >= fmt_nb) { 603 av_log(obj, AV_LOG_ERROR, 604 "Unable to parse option value \"%s\" as %s\n", val, desc); 605 return AVERROR(EINVAL); 606 } 607 } 608 } 609 610 min = FFMAX(o->min, -1); 611 max = FFMIN(o->max, fmt_nb-1); 612 613 // hack for compatibility with old ffmpeg 614 if(min == 0 && max == 0) { 615 min = -1; 616 max = fmt_nb-1; 617 } 618 619 if (fmt < min || fmt > max) { 620 av_log(obj, AV_LOG_ERROR, 621 "Value %d for parameter '%s' out of %s format range [%d - %d]\n", 622 fmt, o->name, desc, min, max); 623 return AVERROR(ERANGE); 624 } 625 626 *(int *)dst = fmt; 627 return 0; 628 } 629 630 static int get_pix_fmt(const char *name) 631 { 632 return av_get_pix_fmt(name); 633 } 634 635 static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) 636 { 637 return set_string_fmt(obj, o, val, dst, 638 AV_PIX_FMT_NB, get_pix_fmt, "pixel format"); 639 } 640 641 static int get_sample_fmt(const char *name) 642 { 643 return av_get_sample_fmt(name); 644 } 645 646 static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) 647 { 648 return set_string_fmt(obj, o, val, dst, 649 AV_SAMPLE_FMT_NB, get_sample_fmt, "sample format"); 650 } 651 652 static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_t **dst) 653 { 654 AVDictionary *options = NULL; 655 656 if (val) { 657 int ret = av_dict_parse_string(&options, val, "=", ":", 0); 658 if (ret < 0) { 659 av_dict_free(&options); 660 return ret; 661 } 662 } 663 664 av_dict_free((AVDictionary **)dst); 665 *dst = (uint8_t *)options; 666 667 return 0; 668 } 669 670 static int set_string_channel_layout(void *obj, const AVOption *o, 671 const char *val, void *dst) 672 { 673 AVChannelLayout *channel_layout = dst; 674 av_channel_layout_uninit(channel_layout); 675 if (!val) 676 return 0; 677 return av_channel_layout_from_string(channel_layout, val); 678 } 679 680 static int opt_set_elem(void *obj, void *target_obj, const AVOption *o, 681 const char *val, void *dst) 682 { 683 const enum AVOptionType type = TYPE_BASE(o->type); 684 int ret; 685 686 if (!val && (type != AV_OPT_TYPE_STRING && 687 type != AV_OPT_TYPE_PIXEL_FMT && type != AV_OPT_TYPE_SAMPLE_FMT && 688 type != AV_OPT_TYPE_IMAGE_SIZE && 689 type != AV_OPT_TYPE_DURATION && type != AV_OPT_TYPE_COLOR && 690 type != AV_OPT_TYPE_BOOL)) 691 return AVERROR(EINVAL); 692 693 switch (type) { 694 case AV_OPT_TYPE_BOOL: 695 return set_string_bool(obj, o, val, dst); 696 case AV_OPT_TYPE_STRING: 697 return set_string(obj, o, val, dst); 698 case AV_OPT_TYPE_BINARY: 699 return set_string_binary(obj, o, val, dst); 700 case AV_OPT_TYPE_FLAGS: 701 case AV_OPT_TYPE_INT: 702 case AV_OPT_TYPE_UINT: 703 case AV_OPT_TYPE_INT64: 704 case AV_OPT_TYPE_UINT64: 705 case AV_OPT_TYPE_FLOAT: 706 case AV_OPT_TYPE_DOUBLE: 707 case AV_OPT_TYPE_RATIONAL: 708 return set_string_number(obj, target_obj, o, val, dst); 709 case AV_OPT_TYPE_IMAGE_SIZE: 710 return set_string_image_size(obj, o, val, dst); 711 case AV_OPT_TYPE_VIDEO_RATE: { 712 AVRational tmp; 713 ret = set_string_video_rate(obj, o, val, &tmp); 714 if (ret < 0) 715 return ret; 716 return write_number(obj, o, dst, 1, tmp.den, tmp.num); 717 } 718 case AV_OPT_TYPE_PIXEL_FMT: 719 return set_string_pixel_fmt(obj, o, val, dst); 720 case AV_OPT_TYPE_SAMPLE_FMT: 721 return set_string_sample_fmt(obj, o, val, dst); 722 case AV_OPT_TYPE_DURATION: 723 { 724 int64_t usecs = 0; 725 if (val) { 726 if ((ret = av_parse_time(&usecs, val, 1)) < 0) { 727 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val); 728 return ret; 729 } 730 } 731 if (usecs < o->min || usecs > o->max) { 732 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", 733 usecs / 1000000.0, o->name, o->min / 1000000.0, o->max / 1000000.0); 734 return AVERROR(ERANGE); 735 } 736 *(int64_t *)dst = usecs; 737 return 0; 738 } 739 case AV_OPT_TYPE_COLOR: 740 return set_string_color(obj, o, val, dst); 741 case AV_OPT_TYPE_CHLAYOUT: 742 ret = set_string_channel_layout(obj, o, val, dst); 743 if (ret < 0) { 744 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); 745 ret = AVERROR(EINVAL); 746 } 747 return ret; 748 case AV_OPT_TYPE_DICT: 749 return set_string_dict(obj, o, val, dst); 750 } 751 752 av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); 753 return AVERROR(EINVAL); 754 } 755 756 static int opt_set_array(void *obj, void *target_obj, const AVOption *o, 757 const char *val, void *dst) 758 { 759 const AVOptionArrayDef *arr = o->default_val.arr; 760 const size_t elem_size = opt_type_desc[TYPE_BASE(o->type)].size; 761 const uint8_t sep = opt_array_sep(o); 762 uint8_t *str = NULL; 763 764 void *elems = NULL; 765 unsigned nb_elems = 0; 766 int ret; 767 768 if (val && *val) { 769 str = av_malloc(strlen(val) + 1); 770 if (!str) 771 return AVERROR(ENOMEM); 772 } 773 774 // split and unescape the string 775 while (val && *val) { 776 uint8_t *p = str; 777 void *tmp; 778 779 if (arr && arr->size_max && nb_elems >= arr->size_max) { 780 av_log(obj, AV_LOG_ERROR, 781 "Cannot assign more than %u elements to array option %s\n", 782 arr->size_max, o->name); 783 ret = AVERROR(EINVAL); 784 goto fail; 785 } 786 787 for (; *val; val++, p++) { 788 if (*val == '\\' && val[1]) 789 val++; 790 else if (*val == sep) { 791 val++; 792 break; 793 } 794 *p = *val; 795 } 796 *p = 0; 797 798 tmp = av_realloc_array(elems, nb_elems + 1, elem_size); 799 if (!tmp) { 800 ret = AVERROR(ENOMEM); 801 goto fail; 802 } 803 elems = tmp; 804 805 tmp = opt_array_pelem(o, elems, nb_elems); 806 memset(tmp, 0, elem_size); 807 808 ret = opt_set_elem(obj, target_obj, o, str, tmp); 809 if (ret < 0) 810 goto fail; 811 nb_elems++; 812 } 813 av_freep(&str); 814 815 opt_free_array(o, dst, opt_array_pcount(dst)); 816 817 if (arr && nb_elems < arr->size_min) { 818 av_log(obj, AV_LOG_ERROR, 819 "Cannot assign fewer than %u elements to array option %s\n", 820 arr->size_min, o->name); 821 ret = AVERROR(EINVAL); 822 goto fail; 823 } 824 825 *((void **)dst) = elems; 826 *opt_array_pcount(dst) = nb_elems; 827 828 return 0; 829 fail: 830 av_freep(&str); 831 opt_free_array(o, &elems, &nb_elems); 832 return ret; 833 } 834 835 int av_opt_set(void *obj, const char *name, const char *val, int search_flags) 836 { 837 void *dst, *target_obj; 838 const AVOption *o; 839 int ret; 840 841 ret = opt_set_init(obj, name, search_flags, 0, &target_obj, &o, &dst); 842 if (ret < 0) 843 return ret; 844 845 return ((o->type & AV_OPT_TYPE_FLAG_ARRAY) ? 846 opt_set_array : opt_set_elem)(obj, target_obj, o, val, dst); 847 } 848 849 #define OPT_EVAL_NUMBER(name, opttype, vartype) \ 850 int av_opt_eval_ ## name(void *obj, const AVOption *o, \ 851 const char *val, vartype *name ## _out) \ 852 { \ 853 if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY) \ 854 return AVERROR(EINVAL); \ 855 return set_string_number(obj, obj, o, val, name ## _out); \ 856 } 857 858 OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int) 859 OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int) 860 OPT_EVAL_NUMBER(uint, AV_OPT_TYPE_UINT, unsigned) 861 OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t) 862 OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float) 863 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double) 864 OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational) 865 866 static int set_number(void *obj, const char *name, double num, int den, int64_t intnum, 867 int search_flags, int require_type) 868 { 869 void *dst; 870 const AVOption *o; 871 int ret; 872 873 ret = opt_set_init(obj, name, search_flags, require_type, NULL, &o, &dst); 874 if (ret < 0) 875 return ret; 876 877 return write_number(obj, o, dst, num, den, intnum); 878 } 879 880 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags) 881 { 882 return set_number(obj, name, 1, 1, val, search_flags, 0); 883 } 884 885 int av_opt_set_double(void *obj, const char *name, double val, int search_flags) 886 { 887 return set_number(obj, name, val, 1, 1, search_flags, 0); 888 } 889 890 int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags) 891 { 892 return set_number(obj, name, val.num, val.den, 1, search_flags, 0); 893 } 894 895 int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags) 896 { 897 uint8_t *ptr; 898 uint8_t **dst; 899 int *lendst; 900 int ret; 901 902 ret = opt_set_init(obj, name, search_flags, AV_OPT_TYPE_BINARY, 903 NULL, NULL, (void**)&dst); 904 if (ret < 0) 905 return ret; 906 907 ptr = len ? av_malloc(len) : NULL; 908 if (len && !ptr) 909 return AVERROR(ENOMEM); 910 911 lendst = (int *)(dst + 1); 912 913 av_free(*dst); 914 *dst = ptr; 915 *lendst = len; 916 if (len) 917 memcpy(ptr, val, len); 918 919 return 0; 920 } 921 922 int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags) 923 { 924 const AVOption *o; 925 int *dst; 926 int ret; 927 928 ret = opt_set_init(obj, name, search_flags, AV_OPT_TYPE_IMAGE_SIZE, 929 NULL, &o, (void**)&dst); 930 if (ret < 0) 931 return ret; 932 933 if (w<0 || h<0) { 934 av_log(obj, AV_LOG_ERROR, 935 "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name); 936 return AVERROR(EINVAL); 937 } 938 939 dst[0] = w; 940 dst[1] = h; 941 942 return 0; 943 } 944 945 int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags) 946 { 947 return set_number(obj, name, val.num, val.den, 1, search_flags, AV_OPT_TYPE_VIDEO_RATE); 948 } 949 950 static int set_format(void *obj, const char *name, int fmt, int search_flags, 951 enum AVOptionType type, const char *desc, int nb_fmts) 952 { 953 const AVOption *o; 954 int *dst; 955 int min, max, ret; 956 957 ret = opt_set_init(obj, name, search_flags, type, NULL, &o, (void**)&dst); 958 if (ret < 0) 959 return ret; 960 961 min = FFMAX(o->min, -1); 962 max = FFMIN(o->max, nb_fmts-1); 963 964 if (fmt < min || fmt > max) { 965 av_log(obj, AV_LOG_ERROR, 966 "Value %d for parameter '%s' out of %s format range [%d - %d]\n", 967 fmt, name, desc, min, max); 968 return AVERROR(ERANGE); 969 } 970 *dst = fmt; 971 return 0; 972 } 973 974 int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags) 975 { 976 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB); 977 } 978 979 int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags) 980 { 981 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB); 982 } 983 984 int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, 985 int search_flags) 986 { 987 AVDictionary **dst; 988 int ret; 989 990 ret = opt_set_init(obj, name, search_flags, AV_OPT_TYPE_DICT, NULL, NULL, 991 (void**)&dst); 992 if (ret < 0) 993 return ret; 994 995 av_dict_free(dst); 996 997 return av_dict_copy(dst, val, 0); 998 } 999 1000 int av_opt_set_chlayout(void *obj, const char *name, 1001 const AVChannelLayout *channel_layout, 1002 int search_flags) 1003 { 1004 AVChannelLayout *dst; 1005 int ret; 1006 1007 ret = opt_set_init(obj, name, search_flags, AV_OPT_TYPE_CHLAYOUT, NULL, NULL, 1008 (void**)&dst); 1009 if (ret < 0) 1010 return ret; 1011 1012 return av_channel_layout_copy(dst, channel_layout); 1013 } 1014 1015 static void format_duration(char *buf, size_t size, int64_t d) 1016 { 1017 char *e; 1018 1019 av_assert0(size >= 25); 1020 if (d < 0 && d != INT64_MIN) { 1021 *(buf++) = '-'; 1022 size--; 1023 d = -d; 1024 } 1025 if (d == INT64_MAX) 1026 snprintf(buf, size, "INT64_MAX"); 1027 else if (d == INT64_MIN) 1028 snprintf(buf, size, "INT64_MIN"); 1029 else if (d > (int64_t)3600*1000000) 1030 snprintf(buf, size, "%"PRId64":%02d:%02d.%06d", d / 3600000000, 1031 (int)((d / 60000000) % 60), 1032 (int)((d / 1000000) % 60), 1033 (int)(d % 1000000)); 1034 else if (d > 60*1000000) 1035 snprintf(buf, size, "%d:%02d.%06d", 1036 (int)(d / 60000000), 1037 (int)((d / 1000000) % 60), 1038 (int)(d % 1000000)); 1039 else 1040 snprintf(buf, size, "%d.%06d", 1041 (int)(d / 1000000), 1042 (int)(d % 1000000)); 1043 e = buf + strlen(buf); 1044 while (e > buf && e[-1] == '0') 1045 *(--e) = 0; 1046 if (e > buf && e[-1] == '.') 1047 *(--e) = 0; 1048 } 1049 1050 static int opt_get_elem(const AVOption *o, uint8_t **pbuf, size_t buf_len, 1051 const void *dst, int search_flags) 1052 { 1053 int ret; 1054 1055 switch (TYPE_BASE(o->type)) { 1056 case AV_OPT_TYPE_BOOL: 1057 ret = snprintf(*pbuf, buf_len, "%s", get_bool_name(*(int *)dst)); 1058 break; 1059 case AV_OPT_TYPE_FLAGS: 1060 ret = snprintf(*pbuf, buf_len, "0x%08X", *(int *)dst); 1061 break; 1062 case AV_OPT_TYPE_INT: 1063 ret = snprintf(*pbuf, buf_len, "%d", *(int *)dst); 1064 break; 1065 case AV_OPT_TYPE_UINT: 1066 ret = snprintf(*pbuf, buf_len, "%u", *(unsigned *)dst); 1067 break; 1068 case AV_OPT_TYPE_INT64: 1069 ret = snprintf(*pbuf, buf_len, "%"PRId64, *(int64_t *)dst); 1070 break; 1071 case AV_OPT_TYPE_UINT64: 1072 ret = snprintf(*pbuf, buf_len, "%"PRIu64, *(uint64_t *)dst); 1073 break; 1074 case AV_OPT_TYPE_FLOAT: 1075 ret = snprintf(*pbuf, buf_len, "%f", *(float *)dst); 1076 break; 1077 case AV_OPT_TYPE_DOUBLE: 1078 ret = snprintf(*pbuf, buf_len, "%f", *(double *)dst); 1079 break; 1080 case AV_OPT_TYPE_VIDEO_RATE: 1081 case AV_OPT_TYPE_RATIONAL: 1082 ret = snprintf(*pbuf, buf_len, "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den); 1083 break; 1084 case AV_OPT_TYPE_CONST: 1085 ret = snprintf(*pbuf, buf_len, "%"PRId64, o->default_val.i64); 1086 break; 1087 case AV_OPT_TYPE_STRING: 1088 if (*(uint8_t **)dst) { 1089 *pbuf = av_strdup(*(uint8_t **)dst); 1090 } else if (search_flags & AV_OPT_ALLOW_NULL) { 1091 *pbuf = NULL; 1092 return 0; 1093 } else { 1094 *pbuf = av_strdup(""); 1095 } 1096 return *pbuf ? 0 : AVERROR(ENOMEM); 1097 case AV_OPT_TYPE_BINARY: { 1098 const uint8_t *bin; 1099 int len; 1100 1101 if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) { 1102 *pbuf = NULL; 1103 return 0; 1104 } 1105 len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *)); 1106 if ((uint64_t)len * 2 + 1 > INT_MAX) 1107 return AVERROR(EINVAL); 1108 if (!(*pbuf = av_malloc(len * 2 + 1))) 1109 return AVERROR(ENOMEM); 1110 if (!len) { 1111 *pbuf[0] = '\0'; 1112 return 0; 1113 } 1114 bin = *(uint8_t **)dst; 1115 for (int i = 0; i < len; i++) 1116 snprintf(*pbuf + i * 2, 3, "%02X", bin[i]); 1117 return 0; 1118 } 1119 case AV_OPT_TYPE_IMAGE_SIZE: 1120 ret = snprintf(*pbuf, buf_len, "%dx%d", ((int *)dst)[0], ((int *)dst)[1]); 1121 break; 1122 case AV_OPT_TYPE_PIXEL_FMT: 1123 ret = snprintf(*pbuf, buf_len, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none")); 1124 break; 1125 case AV_OPT_TYPE_SAMPLE_FMT: 1126 ret = snprintf(*pbuf, buf_len, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none")); 1127 break; 1128 case AV_OPT_TYPE_DURATION: { 1129 int64_t i64 = *(int64_t *)dst; 1130 format_duration(*pbuf, buf_len, i64); 1131 ret = strlen(*pbuf); // no overflow possible, checked by an assert 1132 break; 1133 } 1134 case AV_OPT_TYPE_COLOR: 1135 ret = snprintf(*pbuf, buf_len, "0x%02x%02x%02x%02x", 1136 (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1], 1137 (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]); 1138 break; 1139 case AV_OPT_TYPE_CHLAYOUT: 1140 ret = av_channel_layout_describe(dst, *pbuf, buf_len); 1141 break; 1142 case AV_OPT_TYPE_DICT: 1143 if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) { 1144 *pbuf = NULL; 1145 return 0; 1146 } 1147 return av_dict_get_string(*(AVDictionary **)dst, (char **)pbuf, '=', ':'); 1148 default: 1149 return AVERROR(EINVAL); 1150 } 1151 1152 return ret; 1153 } 1154 1155 static int opt_get_array(const AVOption *o, void *dst, uint8_t **out_val) 1156 { 1157 const unsigned count = *opt_array_pcount(dst); 1158 const uint8_t sep = opt_array_sep(o); 1159 1160 uint8_t *str = NULL; 1161 size_t str_len = 0; 1162 int ret; 1163 1164 *out_val = NULL; 1165 1166 for (unsigned i = 0; i < count; i++) { 1167 uint8_t buf[128], *out = buf; 1168 size_t out_len; 1169 1170 ret = opt_get_elem(o, &out, sizeof(buf), 1171 opt_array_pelem(o, *(void **)dst, i), 0); 1172 if (ret < 0) 1173 goto fail; 1174 1175 out_len = strlen(out); 1176 if (out_len > SIZE_MAX / 2 - !!i || 1177 !!i + out_len * 2 > SIZE_MAX - str_len - 1) { 1178 ret = AVERROR(ERANGE); 1179 goto fail; 1180 } 1181 1182 // terminator escaping separator 1183 // ↓ ↓ ↓ 1184 ret = av_reallocp(&str, str_len + 1 + out_len * 2 + !!i); 1185 if (ret < 0) 1186 goto fail; 1187 1188 // add separator if needed 1189 if (i) 1190 str[str_len++] = sep; 1191 1192 // escape the element 1193 for (unsigned j = 0; j < out_len; j++) { 1194 uint8_t val = out[j]; 1195 if (val == sep || val == '\\') 1196 str[str_len++] = '\\'; 1197 str[str_len++] = val; 1198 } 1199 str[str_len] = 0; 1200 1201 fail: 1202 if (out != buf) 1203 av_freep(&out); 1204 if (ret < 0) { 1205 av_freep(&str); 1206 return ret; 1207 } 1208 } 1209 1210 *out_val = str; 1211 1212 return 0; 1213 } 1214 1215 int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) 1216 { 1217 void *dst, *target_obj; 1218 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1219 uint8_t *out, buf[128]; 1220 int ret; 1221 1222 if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST)) 1223 return AVERROR_OPTION_NOT_FOUND; 1224 1225 if (o->flags & AV_OPT_FLAG_DEPRECATED) 1226 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help); 1227 1228 dst = (uint8_t *)target_obj + o->offset; 1229 1230 if (o->type & AV_OPT_TYPE_FLAG_ARRAY) { 1231 ret = opt_get_array(o, dst, out_val); 1232 if (ret < 0) 1233 return ret; 1234 if (!*out_val && !(search_flags & AV_OPT_ALLOW_NULL)) { 1235 *out_val = av_strdup(""); 1236 if (!*out_val) 1237 return AVERROR(ENOMEM); 1238 } 1239 return 0; 1240 } 1241 1242 buf[0] = 0; 1243 out = buf; 1244 ret = opt_get_elem(o, &out, sizeof(buf), dst, search_flags); 1245 if (ret < 0) 1246 return ret; 1247 if (out != buf) { 1248 *out_val = out; 1249 return 0; 1250 } 1251 1252 if (ret >= sizeof(buf)) 1253 return AVERROR(EINVAL); 1254 *out_val = av_strdup(out); 1255 return *out_val ? 0 : AVERROR(ENOMEM); 1256 } 1257 1258 static int get_number(void *obj, const char *name, double *num, int *den, int64_t *intnum, 1259 int search_flags) 1260 { 1261 void *dst, *target_obj; 1262 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1263 if (!o || !target_obj) 1264 return AVERROR_OPTION_NOT_FOUND; 1265 if (o->type & AV_OPT_TYPE_FLAG_ARRAY) 1266 return AVERROR(EINVAL); 1267 1268 dst = ((uint8_t *)target_obj) + o->offset; 1269 1270 return read_number(o, dst, num, den, intnum); 1271 } 1272 1273 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val) 1274 { 1275 int64_t intnum = 1; 1276 double num = 1; 1277 int ret, den = 1; 1278 1279 if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0) 1280 return ret; 1281 if (num == den) 1282 *out_val = intnum; 1283 else 1284 *out_val = num * intnum / den; 1285 return 0; 1286 } 1287 1288 int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val) 1289 { 1290 int64_t intnum = 1; 1291 double num = 1; 1292 int ret, den = 1; 1293 1294 if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0) 1295 return ret; 1296 *out_val = num * intnum / den; 1297 return 0; 1298 } 1299 1300 int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val) 1301 { 1302 int64_t intnum = 1; 1303 double num = 1; 1304 int ret, den = 1; 1305 1306 if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0) 1307 return ret; 1308 1309 if (num == 1.0 && (int)intnum == intnum) 1310 *out_val = (AVRational){intnum, den}; 1311 else 1312 *out_val = double_to_rational(num*intnum/den); 1313 return 0; 1314 } 1315 1316 int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out) 1317 { 1318 void *dst, *target_obj; 1319 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1320 if (!o || !target_obj) 1321 return AVERROR_OPTION_NOT_FOUND; 1322 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) { 1323 av_log(obj, AV_LOG_ERROR, 1324 "The value for option '%s' is not a image size.\n", name); 1325 return AVERROR(EINVAL); 1326 } 1327 1328 dst = ((uint8_t*)target_obj) + o->offset; 1329 if (w_out) *w_out = *(int *)dst; 1330 if (h_out) *h_out = *((int *)dst+1); 1331 return 0; 1332 } 1333 1334 int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val) 1335 { 1336 return av_opt_get_q(obj, name, search_flags, out_val); 1337 } 1338 1339 static int get_format(void *obj, const char *name, int search_flags, int *out_fmt, 1340 enum AVOptionType type, const char *desc) 1341 { 1342 void *dst, *target_obj; 1343 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1344 if (!o || !target_obj) 1345 return AVERROR_OPTION_NOT_FOUND; 1346 if (o->type != type) { 1347 av_log(obj, AV_LOG_ERROR, 1348 "The value for option '%s' is not a %s format.\n", desc, name); 1349 return AVERROR(EINVAL); 1350 } 1351 1352 dst = ((uint8_t*)target_obj) + o->offset; 1353 *out_fmt = *(int *)dst; 1354 return 0; 1355 } 1356 1357 int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt) 1358 { 1359 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel"); 1360 } 1361 1362 int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt) 1363 { 1364 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample"); 1365 } 1366 1367 int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *cl) 1368 { 1369 void *dst, *target_obj; 1370 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1371 if (!o || !target_obj) 1372 return AVERROR_OPTION_NOT_FOUND; 1373 if (o->type != AV_OPT_TYPE_CHLAYOUT) { 1374 av_log(obj, AV_LOG_ERROR, 1375 "The value for option '%s' is not a channel layout.\n", name); 1376 return AVERROR(EINVAL); 1377 } 1378 1379 dst = ((uint8_t*)target_obj) + o->offset; 1380 return av_channel_layout_copy(cl, dst); 1381 } 1382 1383 int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val) 1384 { 1385 void *target_obj; 1386 AVDictionary *src; 1387 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1388 1389 if (!o || !target_obj) 1390 return AVERROR_OPTION_NOT_FOUND; 1391 if (o->type != AV_OPT_TYPE_DICT) 1392 return AVERROR(EINVAL); 1393 1394 src = *(AVDictionary **)(((uint8_t *)target_obj) + o->offset); 1395 1396 return av_dict_copy(out_val, src, 0); 1397 } 1398 1399 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) 1400 { 1401 const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); 1402 const AVOption *flag = av_opt_find(obj, flag_name, 1403 field ? field->unit : NULL, 0, 0); 1404 int64_t res; 1405 1406 if (!field || !flag || flag->type != AV_OPT_TYPE_CONST || 1407 av_opt_get_int(obj, field_name, 0, &res) < 0) 1408 return 0; 1409 return res & flag->default_val.i64; 1410 } 1411 1412 static void log_int_value(void *av_log_obj, int level, int64_t i) 1413 { 1414 if (i == INT_MAX) { 1415 av_log(av_log_obj, level, "INT_MAX"); 1416 } else if (i == INT_MIN) { 1417 av_log(av_log_obj, level, "INT_MIN"); 1418 } else if (i == UINT32_MAX) { 1419 av_log(av_log_obj, level, "UINT32_MAX"); 1420 } else if (i == INT64_MAX) { 1421 av_log(av_log_obj, level, "I64_MAX"); 1422 } else if (i == INT64_MIN) { 1423 av_log(av_log_obj, level, "I64_MIN"); 1424 } else { 1425 av_log(av_log_obj, level, "%"PRId64, i); 1426 } 1427 } 1428 1429 static void log_value(void *av_log_obj, int level, double d) 1430 { 1431 if (d == INT_MAX) { 1432 av_log(av_log_obj, level, "INT_MAX"); 1433 } else if (d == INT_MIN) { 1434 av_log(av_log_obj, level, "INT_MIN"); 1435 } else if (d == UINT32_MAX) { 1436 av_log(av_log_obj, level, "UINT32_MAX"); 1437 } else if (d == (double)INT64_MAX) { 1438 av_log(av_log_obj, level, "I64_MAX"); 1439 } else if (d == INT64_MIN) { 1440 av_log(av_log_obj, level, "I64_MIN"); 1441 } else if (d == FLT_MAX) { 1442 av_log(av_log_obj, level, "FLT_MAX"); 1443 } else if (d == FLT_MIN) { 1444 av_log(av_log_obj, level, "FLT_MIN"); 1445 } else if (d == -FLT_MAX) { 1446 av_log(av_log_obj, level, "-FLT_MAX"); 1447 } else if (d == -FLT_MIN) { 1448 av_log(av_log_obj, level, "-FLT_MIN"); 1449 } else if (d == DBL_MAX) { 1450 av_log(av_log_obj, level, "DBL_MAX"); 1451 } else if (d == DBL_MIN) { 1452 av_log(av_log_obj, level, "DBL_MIN"); 1453 } else if (d == -DBL_MAX) { 1454 av_log(av_log_obj, level, "-DBL_MAX"); 1455 } else if (d == -DBL_MIN) { 1456 av_log(av_log_obj, level, "-DBL_MIN"); 1457 } else { 1458 av_log(av_log_obj, level, "%g", d); 1459 } 1460 } 1461 1462 static const char *get_opt_const_name(void *obj, const char *unit, int64_t value) 1463 { 1464 const AVOption *opt = NULL; 1465 1466 if (!unit) 1467 return NULL; 1468 while ((opt = av_opt_next(obj, opt))) 1469 if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) && 1470 opt->default_val.i64 == value) 1471 return opt->name; 1472 return NULL; 1473 } 1474 1475 static char *get_opt_flags_string(void *obj, const char *unit, int64_t value) 1476 { 1477 const AVOption *opt = NULL; 1478 char flags[512]; 1479 1480 flags[0] = 0; 1481 if (!unit) 1482 return NULL; 1483 while ((opt = av_opt_next(obj, opt))) { 1484 if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) && 1485 opt->default_val.i64 & value) { 1486 if (flags[0]) 1487 av_strlcatf(flags, sizeof(flags), "+"); 1488 av_strlcatf(flags, sizeof(flags), "%s", opt->name); 1489 } 1490 } 1491 if (flags[0]) 1492 return av_strdup(flags); 1493 return NULL; 1494 } 1495 1496 static void log_type(void *av_log_obj, const AVOption *o, 1497 enum AVOptionType parent_type) 1498 { 1499 const enum AVOptionType type = TYPE_BASE(o->type); 1500 1501 if (o->type == AV_OPT_TYPE_CONST && TYPE_BASE(parent_type) == AV_OPT_TYPE_INT) 1502 av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", o->default_val.i64); 1503 else if (type < FF_ARRAY_ELEMS(opt_type_desc) && opt_type_desc[type].name) { 1504 if (o->type & AV_OPT_TYPE_FLAG_ARRAY) 1505 av_log(av_log_obj, AV_LOG_INFO, "[%-10s]", opt_type_desc[type].name); 1506 else 1507 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", opt_type_desc[type].name); 1508 } 1509 else 1510 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); 1511 } 1512 1513 static void log_default(void *obj, void *av_log_obj, const AVOption *opt) 1514 { 1515 if (opt->type == AV_OPT_TYPE_CONST || opt->type == AV_OPT_TYPE_BINARY) 1516 return; 1517 if ((opt->type == AV_OPT_TYPE_COLOR || 1518 opt->type == AV_OPT_TYPE_IMAGE_SIZE || 1519 opt->type == AV_OPT_TYPE_STRING || 1520 opt->type == AV_OPT_TYPE_DICT || 1521 opt->type == AV_OPT_TYPE_CHLAYOUT || 1522 opt->type == AV_OPT_TYPE_VIDEO_RATE) && 1523 !opt->default_val.str) 1524 return; 1525 1526 if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) { 1527 const AVOptionArrayDef *arr = opt->default_val.arr; 1528 if (arr && arr->def) 1529 av_log(av_log_obj, AV_LOG_INFO, " (default %s)", arr->def); 1530 return; 1531 } 1532 1533 av_log(av_log_obj, AV_LOG_INFO, " (default "); 1534 switch (opt->type) { 1535 case AV_OPT_TYPE_BOOL: 1536 av_log(av_log_obj, AV_LOG_INFO, "%s", get_bool_name(opt->default_val.i64)); 1537 break; 1538 case AV_OPT_TYPE_FLAGS: { 1539 char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64); 1540 if (def_flags) { 1541 av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags); 1542 av_freep(&def_flags); 1543 } else { 1544 av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64); 1545 } 1546 break; 1547 } 1548 case AV_OPT_TYPE_DURATION: { 1549 char buf[25]; 1550 format_duration(buf, sizeof(buf), opt->default_val.i64); 1551 av_log(av_log_obj, AV_LOG_INFO, "%s", buf); 1552 break; 1553 } 1554 case AV_OPT_TYPE_UINT: 1555 case AV_OPT_TYPE_INT: 1556 case AV_OPT_TYPE_UINT64: 1557 case AV_OPT_TYPE_INT64: { 1558 const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64); 1559 if (def_const) 1560 av_log(av_log_obj, AV_LOG_INFO, "%s", def_const); 1561 else 1562 log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64); 1563 break; 1564 } 1565 case AV_OPT_TYPE_DOUBLE: 1566 case AV_OPT_TYPE_FLOAT: 1567 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl); 1568 break; 1569 case AV_OPT_TYPE_RATIONAL: { 1570 AVRational q = av_d2q(opt->default_val.dbl, INT_MAX); 1571 av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); } 1572 break; 1573 case AV_OPT_TYPE_PIXEL_FMT: 1574 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none")); 1575 break; 1576 case AV_OPT_TYPE_SAMPLE_FMT: 1577 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none")); 1578 break; 1579 case AV_OPT_TYPE_COLOR: 1580 case AV_OPT_TYPE_IMAGE_SIZE: 1581 case AV_OPT_TYPE_STRING: 1582 case AV_OPT_TYPE_DICT: 1583 case AV_OPT_TYPE_VIDEO_RATE: 1584 case AV_OPT_TYPE_CHLAYOUT: 1585 av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str); 1586 break; 1587 } 1588 av_log(av_log_obj, AV_LOG_INFO, ")"); 1589 } 1590 1591 static void opt_list(void *obj, void *av_log_obj, const char *unit, 1592 int req_flags, int rej_flags, enum AVOptionType parent_type) 1593 { 1594 const AVOption *opt = NULL; 1595 AVOptionRanges *r; 1596 int i; 1597 1598 while ((opt = av_opt_next(obj, opt))) { 1599 if (!(opt->flags & req_flags) || (opt->flags & rej_flags)) 1600 continue; 1601 1602 /* Don't print CONST's on level one. 1603 * Don't print anything but CONST's on level two. 1604 * Only print items from the requested unit. 1605 */ 1606 if (!unit && opt->type == AV_OPT_TYPE_CONST) 1607 continue; 1608 else if (unit && opt->type != AV_OPT_TYPE_CONST) 1609 continue; 1610 else if (unit && opt->type == AV_OPT_TYPE_CONST && strcmp(unit, opt->unit)) 1611 continue; 1612 else if (unit && opt->type == AV_OPT_TYPE_CONST) 1613 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); 1614 else 1615 av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ", 1616 (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? " " : "-", 1617 opt->name); 1618 1619 log_type(av_log_obj, opt, parent_type); 1620 1621 av_log(av_log_obj, AV_LOG_INFO, "%c%c%c%c%c%c%c%c%c%c%c", 1622 (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.', 1623 (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.', 1624 (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? 'F' : '.', 1625 (opt->flags & AV_OPT_FLAG_VIDEO_PARAM) ? 'V' : '.', 1626 (opt->flags & AV_OPT_FLAG_AUDIO_PARAM) ? 'A' : '.', 1627 (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.', 1628 (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.', 1629 (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.', 1630 (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.', 1631 (opt->flags & AV_OPT_FLAG_RUNTIME_PARAM) ? 'T' : '.', 1632 (opt->flags & AV_OPT_FLAG_DEPRECATED) ? 'P' : '.'); 1633 1634 if (opt->help) 1635 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); 1636 1637 if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) { 1638 switch (opt->type) { 1639 case AV_OPT_TYPE_INT: 1640 case AV_OPT_TYPE_UINT: 1641 case AV_OPT_TYPE_INT64: 1642 case AV_OPT_TYPE_UINT64: 1643 case AV_OPT_TYPE_DOUBLE: 1644 case AV_OPT_TYPE_FLOAT: 1645 case AV_OPT_TYPE_RATIONAL: 1646 for (i = 0; i < r->nb_ranges; i++) { 1647 av_log(av_log_obj, AV_LOG_INFO, " (from "); 1648 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min); 1649 av_log(av_log_obj, AV_LOG_INFO, " to "); 1650 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max); 1651 av_log(av_log_obj, AV_LOG_INFO, ")"); 1652 } 1653 break; 1654 } 1655 av_opt_freep_ranges(&r); 1656 } 1657 1658 log_default(obj, av_log_obj, opt); 1659 1660 av_log(av_log_obj, AV_LOG_INFO, "\n"); 1661 if (opt->unit && opt->type != AV_OPT_TYPE_CONST) 1662 opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags, opt->type); 1663 } 1664 } 1665 1666 int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags) 1667 { 1668 if (!obj) 1669 return -1; 1670 1671 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name); 1672 1673 opt_list(obj, av_log_obj, NULL, req_flags, rej_flags, -1); 1674 1675 return 0; 1676 } 1677 1678 void av_opt_set_defaults(void *s) 1679 { 1680 av_opt_set_defaults2(s, 0, 0); 1681 } 1682 1683 void av_opt_set_defaults2(void *s, int mask, int flags) 1684 { 1685 const AVOption *opt = NULL; 1686 while ((opt = av_opt_next(s, opt))) { 1687 void *dst = ((uint8_t*)s) + opt->offset; 1688 1689 if ((opt->flags & mask) != flags) 1690 continue; 1691 1692 if (opt->flags & AV_OPT_FLAG_READONLY) 1693 continue; 1694 1695 if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) { 1696 const AVOptionArrayDef *arr = opt->default_val.arr; 1697 const char sep = opt_array_sep(opt); 1698 1699 av_assert0(sep && sep != '\\' && 1700 (sep < 'a' || sep > 'z') && 1701 (sep < 'A' || sep > 'Z') && 1702 (sep < '0' || sep > '9')); 1703 1704 if (arr && arr->def) 1705 opt_set_array(s, s, opt, arr->def, dst); 1706 1707 continue; 1708 } 1709 1710 switch (opt->type) { 1711 case AV_OPT_TYPE_CONST: 1712 /* Nothing to be done here */ 1713 break; 1714 case AV_OPT_TYPE_BOOL: 1715 case AV_OPT_TYPE_FLAGS: 1716 case AV_OPT_TYPE_INT: 1717 case AV_OPT_TYPE_UINT: 1718 case AV_OPT_TYPE_INT64: 1719 case AV_OPT_TYPE_UINT64: 1720 case AV_OPT_TYPE_DURATION: 1721 case AV_OPT_TYPE_PIXEL_FMT: 1722 case AV_OPT_TYPE_SAMPLE_FMT: 1723 write_number(s, opt, dst, 1, 1, opt->default_val.i64); 1724 break; 1725 case AV_OPT_TYPE_DOUBLE: 1726 case AV_OPT_TYPE_FLOAT: { 1727 double val; 1728 val = opt->default_val.dbl; 1729 write_number(s, opt, dst, val, 1, 1); 1730 } 1731 break; 1732 case AV_OPT_TYPE_RATIONAL: { 1733 AVRational val; 1734 val = av_d2q(opt->default_val.dbl, INT_MAX); 1735 write_number(s, opt, dst, 1, val.den, val.num); 1736 } 1737 break; 1738 case AV_OPT_TYPE_COLOR: 1739 set_string_color(s, opt, opt->default_val.str, dst); 1740 break; 1741 case AV_OPT_TYPE_STRING: 1742 set_string(s, opt, opt->default_val.str, dst); 1743 break; 1744 case AV_OPT_TYPE_IMAGE_SIZE: 1745 set_string_image_size(s, opt, opt->default_val.str, dst); 1746 break; 1747 case AV_OPT_TYPE_VIDEO_RATE: 1748 set_string_video_rate(s, opt, opt->default_val.str, dst); 1749 break; 1750 case AV_OPT_TYPE_BINARY: 1751 set_string_binary(s, opt, opt->default_val.str, dst); 1752 break; 1753 case AV_OPT_TYPE_CHLAYOUT: 1754 set_string_channel_layout(s, opt, opt->default_val.str, dst); 1755 break; 1756 case AV_OPT_TYPE_DICT: 1757 set_string_dict(s, opt, opt->default_val.str, dst); 1758 break; 1759 default: 1760 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", 1761 opt->type, opt->name); 1762 } 1763 } 1764 } 1765 1766 /** 1767 * Store the value in the field in ctx that is named like key. 1768 * ctx must be an AVClass context, storing is done using AVOptions. 1769 * 1770 * @param buf the string to parse, buf will be updated to point at the 1771 * separator just after the parsed key/value pair 1772 * @param key_val_sep a 0-terminated list of characters used to 1773 * separate key from value 1774 * @param pairs_sep a 0-terminated list of characters used to separate 1775 * two pairs from each other 1776 * @return 0 if the key/value pair has been successfully parsed and 1777 * set, or a negative value corresponding to an AVERROR code in case 1778 * of error: 1779 * AVERROR(EINVAL) if the key/value pair cannot be parsed, 1780 * the error code issued by av_opt_set() if the key/value pair 1781 * cannot be set 1782 */ 1783 static int parse_key_value_pair(void *ctx, const char **buf, 1784 const char *key_val_sep, const char *pairs_sep) 1785 { 1786 char *key = av_get_token(buf, key_val_sep); 1787 char *val; 1788 int ret; 1789 1790 if (!key) 1791 return AVERROR(ENOMEM); 1792 1793 if (*key && strspn(*buf, key_val_sep)) { 1794 (*buf)++; 1795 val = av_get_token(buf, pairs_sep); 1796 if (!val) { 1797 av_freep(&key); 1798 return AVERROR(ENOMEM); 1799 } 1800 } else { 1801 av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); 1802 av_free(key); 1803 return AVERROR(EINVAL); 1804 } 1805 1806 av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val); 1807 1808 ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN); 1809 if (ret == AVERROR_OPTION_NOT_FOUND) 1810 av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); 1811 1812 av_free(key); 1813 av_free(val); 1814 return ret; 1815 } 1816 1817 int av_set_options_string(void *ctx, const char *opts, 1818 const char *key_val_sep, const char *pairs_sep) 1819 { 1820 int ret, count = 0; 1821 1822 if (!opts) 1823 return 0; 1824 1825 while (*opts) { 1826 if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) 1827 return ret; 1828 count++; 1829 1830 if (*opts) 1831 opts++; 1832 } 1833 1834 return count; 1835 } 1836 1837 #define WHITESPACES " \n\t\r" 1838 1839 static int is_key_char(char c) 1840 { 1841 return (unsigned)((c | 32) - 'a') < 26 || 1842 (unsigned)(c - '0') < 10 || 1843 c == '-' || c == '_' || c == '/' || c == '.'; 1844 } 1845 1846 /** 1847 * Read a key from a string. 1848 * 1849 * The key consists of is_key_char characters and must be terminated by a 1850 * character from the delim string; spaces are ignored. 1851 * 1852 * @return 0 for success (even with ellipsis), <0 for failure 1853 */ 1854 static int get_key(const char **ropts, const char *delim, char **rkey) 1855 { 1856 const char *opts = *ropts; 1857 const char *key_start, *key_end; 1858 1859 key_start = opts += strspn(opts, WHITESPACES); 1860 while (is_key_char(*opts)) 1861 opts++; 1862 key_end = opts; 1863 opts += strspn(opts, WHITESPACES); 1864 if (!*opts || !strchr(delim, *opts)) 1865 return AVERROR(EINVAL); 1866 opts++; 1867 if (!(*rkey = av_malloc(key_end - key_start + 1))) 1868 return AVERROR(ENOMEM); 1869 memcpy(*rkey, key_start, key_end - key_start); 1870 (*rkey)[key_end - key_start] = 0; 1871 *ropts = opts; 1872 return 0; 1873 } 1874 1875 int av_opt_get_key_value(const char **ropts, 1876 const char *key_val_sep, const char *pairs_sep, 1877 unsigned flags, 1878 char **rkey, char **rval) 1879 { 1880 int ret; 1881 char *key = NULL, *val; 1882 const char *opts = *ropts; 1883 1884 if ((ret = get_key(&opts, key_val_sep, &key)) < 0 && 1885 !(flags & AV_OPT_FLAG_IMPLICIT_KEY)) 1886 return AVERROR(EINVAL); 1887 if (!(val = av_get_token(&opts, pairs_sep))) { 1888 av_free(key); 1889 return AVERROR(ENOMEM); 1890 } 1891 *ropts = opts; 1892 *rkey = key; 1893 *rval = val; 1894 return 0; 1895 } 1896 1897 int av_opt_set_from_string(void *ctx, const char *opts, 1898 const char *const *shorthand, 1899 const char *key_val_sep, const char *pairs_sep) 1900 { 1901 int ret, count = 0; 1902 const char *dummy_shorthand = NULL; 1903 const char *key; 1904 1905 if (!opts) 1906 return 0; 1907 if (!shorthand) 1908 shorthand = &dummy_shorthand; 1909 1910 while (*opts) { 1911 char *parsed_key, *value; 1912 ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep, 1913 *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0, 1914 &parsed_key, &value); 1915 if (ret < 0) { 1916 if (ret == AVERROR(EINVAL)) 1917 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts); 1918 else 1919 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts, 1920 av_err2str(ret)); 1921 return ret; 1922 } 1923 if (*opts) 1924 opts++; 1925 if (parsed_key) { 1926 key = parsed_key; 1927 while (*shorthand) /* discard all remaining shorthand */ 1928 shorthand++; 1929 } else { 1930 key = *(shorthand++); 1931 } 1932 1933 av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value); 1934 if ((ret = av_opt_set(ctx, key, value, 0)) < 0) { 1935 if (ret == AVERROR_OPTION_NOT_FOUND) 1936 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); 1937 av_free(value); 1938 av_free(parsed_key); 1939 return ret; 1940 } 1941 1942 av_free(value); 1943 av_free(parsed_key); 1944 count++; 1945 } 1946 return count; 1947 } 1948 1949 void av_opt_free(void *obj) 1950 { 1951 const AVOption *o = NULL; 1952 while ((o = av_opt_next(obj, o))) { 1953 void *pitem = (uint8_t *)obj + o->offset; 1954 1955 if (o->type & AV_OPT_TYPE_FLAG_ARRAY) 1956 opt_free_array(o, pitem, opt_array_pcount(pitem)); 1957 else 1958 opt_free_elem(o->type, pitem); 1959 } 1960 } 1961 1962 int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags) 1963 { 1964 const AVDictionaryEntry *t = NULL; 1965 AVDictionary *tmp = NULL; 1966 int ret; 1967 1968 if (!options) 1969 return 0; 1970 1971 while ((t = av_dict_iterate(*options, t))) { 1972 ret = av_opt_set(obj, t->key, t->value, search_flags); 1973 if (ret == AVERROR_OPTION_NOT_FOUND) 1974 ret = av_dict_set(&tmp, t->key, t->value, AV_DICT_MULTIKEY); 1975 if (ret < 0) { 1976 av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value); 1977 av_dict_free(&tmp); 1978 return ret; 1979 } 1980 } 1981 av_dict_free(options); 1982 *options = tmp; 1983 return 0; 1984 } 1985 1986 int av_opt_set_dict(void *obj, AVDictionary **options) 1987 { 1988 return av_opt_set_dict2(obj, options, 0); 1989 } 1990 1991 const AVOption *av_opt_find(void *obj, const char *name, const char *unit, 1992 int opt_flags, int search_flags) 1993 { 1994 return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL); 1995 } 1996 1997 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, 1998 int opt_flags, int search_flags, void **target_obj) 1999 { 2000 const AVClass *c; 2001 const AVOption *o = NULL; 2002 2003 if(!obj) 2004 return NULL; 2005 2006 c= *(AVClass**)obj; 2007 2008 if (!c) 2009 return NULL; 2010 2011 if (search_flags & AV_OPT_SEARCH_CHILDREN) { 2012 if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { 2013 void *iter = NULL; 2014 const AVClass *child; 2015 while (child = av_opt_child_class_iterate(c, &iter)) 2016 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) 2017 return o; 2018 } else { 2019 void *child = NULL; 2020 while (child = av_opt_child_next(obj, child)) 2021 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj)) 2022 return o; 2023 } 2024 } 2025 2026 while (o = av_opt_next(obj, o)) { 2027 if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags && 2028 ((!unit && o->type != AV_OPT_TYPE_CONST) || 2029 (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) { 2030 if (target_obj) { 2031 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ)) 2032 *target_obj = obj; 2033 else 2034 *target_obj = NULL; 2035 } 2036 return o; 2037 } 2038 } 2039 return NULL; 2040 } 2041 2042 void *av_opt_child_next(void *obj, void *prev) 2043 { 2044 const AVClass *c = *(AVClass **)obj; 2045 if (c->child_next) 2046 return c->child_next(obj, prev); 2047 return NULL; 2048 } 2049 2050 const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter) 2051 { 2052 if (parent->child_class_iterate) 2053 return parent->child_class_iterate(iter); 2054 return NULL; 2055 } 2056 2057 #if FF_API_OPT_PTR 2058 void *av_opt_ptr(const AVClass *class, void *obj, const char *name) 2059 { 2060 const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL); 2061 2062 // no direct access to array-type options 2063 if (!opt || (opt->type & AV_OPT_TYPE_FLAG_ARRAY)) 2064 return NULL; 2065 return (uint8_t*)obj + opt->offset; 2066 } 2067 #endif 2068 2069 static int opt_copy_elem(void *logctx, enum AVOptionType type, 2070 void *dst, const void *src) 2071 { 2072 if (type == AV_OPT_TYPE_STRING) { 2073 const char *src_str = *(const char *const *)src; 2074 char **dstp = (char **)dst; 2075 if (*dstp != src_str) 2076 av_freep(dstp); 2077 if (src_str) { 2078 *dstp = av_strdup(src_str); 2079 if (!*dstp) 2080 return AVERROR(ENOMEM); 2081 } 2082 } else if (type == AV_OPT_TYPE_BINARY) { 2083 const uint8_t *const *src8 = (const uint8_t *const *)src; 2084 uint8_t **dst8 = (uint8_t **)dst; 2085 int len = *(const int *)(src8 + 1); 2086 if (*dst8 != *src8) 2087 av_freep(dst8); 2088 *dst8 = av_memdup(*src8, len); 2089 if (len && !*dst8) { 2090 *(int *)(dst8 + 1) = 0; 2091 return AVERROR(ENOMEM); 2092 } 2093 *(int *)(dst8 + 1) = len; 2094 } else if (type == AV_OPT_TYPE_CONST) { 2095 // do nothing 2096 } else if (type == AV_OPT_TYPE_DICT) { 2097 const AVDictionary *sdict = *(const AVDictionary * const *)src; 2098 AVDictionary **ddictp = (AVDictionary **)dst; 2099 if (sdict != *ddictp) 2100 av_dict_free(ddictp); 2101 *ddictp = NULL; 2102 return av_dict_copy(ddictp, sdict, 0); 2103 } else if (type == AV_OPT_TYPE_CHLAYOUT) { 2104 if (dst != src) 2105 return av_channel_layout_copy(dst, src); 2106 } else if (opt_is_pod(type)) { 2107 size_t size = opt_type_desc[type].size; 2108 memcpy(dst, src, size); 2109 } else { 2110 av_log(logctx, AV_LOG_ERROR, "Unhandled option type: %d\n", type); 2111 return AVERROR(EINVAL); 2112 } 2113 2114 return 0; 2115 } 2116 2117 static int opt_copy_array(void *logctx, const AVOption *o, 2118 void **pdst, const void * const *psrc) 2119 { 2120 unsigned nb_elems = *opt_array_pcount(psrc); 2121 void *dst = NULL; 2122 int ret; 2123 2124 if (*pdst == *psrc) { 2125 *pdst = NULL; 2126 *opt_array_pcount(pdst) = 0; 2127 } 2128 2129 opt_free_array(o, pdst, opt_array_pcount(pdst)); 2130 2131 dst = av_calloc(nb_elems, opt_type_desc[TYPE_BASE(o->type)].size); 2132 if (!dst) 2133 return AVERROR(ENOMEM); 2134 2135 for (unsigned i = 0; i < nb_elems; i++) { 2136 ret = opt_copy_elem(logctx, TYPE_BASE(o->type), 2137 opt_array_pelem(o, dst, i), 2138 opt_array_pelem(o, *(void**)psrc, i)); 2139 if (ret < 0) { 2140 opt_free_array(o, &dst, &nb_elems); 2141 return ret; 2142 } 2143 } 2144 2145 *pdst = dst; 2146 *opt_array_pcount(pdst) = nb_elems; 2147 2148 return 0; 2149 } 2150 2151 int av_opt_copy(void *dst, const void *src) 2152 { 2153 const AVOption *o = NULL; 2154 const AVClass *c; 2155 int ret = 0; 2156 2157 if (!src) 2158 return AVERROR(EINVAL); 2159 2160 c = *(AVClass **)src; 2161 if (!c || c != *(AVClass **)dst) 2162 return AVERROR(EINVAL); 2163 2164 while ((o = av_opt_next(src, o))) { 2165 void *field_dst = (uint8_t *)dst + o->offset; 2166 void *field_src = (uint8_t *)src + o->offset; 2167 2168 int err = (o->type & AV_OPT_TYPE_FLAG_ARRAY) ? 2169 opt_copy_array(dst, o, field_dst, field_src) : 2170 opt_copy_elem (dst, o->type, field_dst, field_src); 2171 if (err < 0) 2172 ret = err; 2173 } 2174 return ret; 2175 } 2176 2177 int av_opt_get_array_size(void *obj, const char *name, int search_flags, 2178 unsigned int *out_val) 2179 { 2180 void *target_obj, *parray; 2181 const AVOption *o; 2182 2183 o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 2184 if (!o || !target_obj) 2185 return AVERROR_OPTION_NOT_FOUND; 2186 if (!(o->type & AV_OPT_TYPE_FLAG_ARRAY)) 2187 return AVERROR(EINVAL); 2188 2189 parray = (uint8_t *)target_obj + o->offset; 2190 *out_val = *opt_array_pcount(parray); 2191 2192 return 0; 2193 } 2194 2195 int av_opt_get_array(void *obj, const char *name, int search_flags, 2196 unsigned int start_elem, unsigned int nb_elems, 2197 enum AVOptionType out_type, void *out_val) 2198 { 2199 const size_t elem_size_out = opt_type_desc[TYPE_BASE(out_type)].size; 2200 2201 const AVOption *o; 2202 void *target_obj; 2203 2204 const void *parray; 2205 unsigned array_size; 2206 2207 int ret; 2208 2209 o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 2210 if (!o || !target_obj) 2211 return AVERROR_OPTION_NOT_FOUND; 2212 if (!(o->type & AV_OPT_TYPE_FLAG_ARRAY) || 2213 (out_type & AV_OPT_TYPE_FLAG_ARRAY)) 2214 return AVERROR(EINVAL); 2215 2216 parray = (uint8_t *)target_obj + o->offset; 2217 array_size = *opt_array_pcount(parray); 2218 2219 if (start_elem >= array_size || 2220 array_size - start_elem < nb_elems) 2221 return AVERROR(EINVAL); 2222 2223 for (unsigned i = 0; i < nb_elems; i++) { 2224 const void *src = opt_array_pelem(o, *(void**)parray, start_elem + i); 2225 void *dst = (uint8_t*)out_val + i * elem_size_out; 2226 2227 if (out_type == TYPE_BASE(o->type)) { 2228 ret = opt_copy_elem(obj, out_type, dst, src); 2229 if (ret < 0) 2230 goto fail; 2231 } else if (out_type == AV_OPT_TYPE_STRING) { 2232 uint8_t buf[128], *out = buf; 2233 2234 ret = opt_get_elem(o, &out, sizeof(buf), src, search_flags); 2235 if (ret < 0) 2236 goto fail; 2237 2238 if (out == buf) { 2239 out = av_strdup(buf); 2240 if (!out) { 2241 ret = AVERROR(ENOMEM); 2242 goto fail; 2243 } 2244 } 2245 2246 *(uint8_t**)dst = out; 2247 } else if (out_type == AV_OPT_TYPE_INT64 || 2248 out_type == AV_OPT_TYPE_DOUBLE || 2249 out_type == AV_OPT_TYPE_RATIONAL) { 2250 double num = 1.0; 2251 int den = 1; 2252 int64_t intnum = 1; 2253 2254 ret = read_number(o, src, &num, &den, &intnum); 2255 if (ret < 0) 2256 goto fail; 2257 2258 switch (out_type) { 2259 case AV_OPT_TYPE_INT64: 2260 *(int64_t*)dst = (num == den) ? intnum : num * intnum / den; 2261 break; 2262 case AV_OPT_TYPE_DOUBLE: 2263 *(double*)dst = num * intnum / den; 2264 break; 2265 case AV_OPT_TYPE_RATIONAL: 2266 *(AVRational*)dst = (num == 1.0 && (int)intnum == intnum) ? 2267 (AVRational){ intnum, den } : 2268 double_to_rational(num * intnum / den); 2269 break; 2270 default: av_assert0(0); 2271 } 2272 } else 2273 return AVERROR(ENOSYS); 2274 } 2275 2276 return 0; 2277 fail: 2278 for (unsigned i = 0; i < nb_elems; i++) 2279 opt_free_elem(out_type, (uint8_t*)out_val + i * elem_size_out); 2280 return ret; 2281 } 2282 2283 int av_opt_set_array(void *obj, const char *name, int search_flags, 2284 unsigned int start_elem, unsigned int nb_elems, 2285 enum AVOptionType val_type, const void *val) 2286 { 2287 const size_t elem_size_val = opt_type_desc[TYPE_BASE(val_type)].size; 2288 2289 const AVOption *o; 2290 const AVOptionArrayDef *arr; 2291 void *target_obj; 2292 2293 void *parray; 2294 void *new_elems; 2295 unsigned *array_size, new_size; 2296 size_t elem_size; 2297 2298 int ret = 0; 2299 2300 ret = opt_set_init(obj, name, search_flags, 0, &target_obj, &o, &parray); 2301 if (ret < 0) 2302 return ret; 2303 2304 if (!(o->type & AV_OPT_TYPE_FLAG_ARRAY) || 2305 (val_type & AV_OPT_TYPE_FLAG_ARRAY)) 2306 return AVERROR(EINVAL); 2307 2308 arr = o->default_val.arr; 2309 array_size = opt_array_pcount(parray); 2310 elem_size = opt_type_desc[TYPE_BASE(o->type)].size; 2311 2312 if (start_elem > *array_size) 2313 return AVERROR(EINVAL); 2314 2315 // compute new array size 2316 if (!val) { 2317 if (*array_size - start_elem < nb_elems) 2318 return AVERROR(EINVAL); 2319 2320 new_size = *array_size - nb_elems; 2321 } else if (search_flags & AV_OPT_ARRAY_REPLACE) { 2322 if (start_elem >= UINT_MAX - nb_elems) 2323 return AVERROR(EINVAL); 2324 2325 new_size = FFMAX(*array_size, start_elem + nb_elems); 2326 } else { 2327 if (nb_elems >= UINT_MAX - *array_size) 2328 return AVERROR(EINVAL); 2329 2330 new_size = *array_size + nb_elems; 2331 } 2332 2333 if (arr && 2334 ((arr->size_max && new_size > arr->size_max) || 2335 (arr->size_min && new_size < arr->size_min))) 2336 return AVERROR(EINVAL); 2337 2338 // desired operation is shrinking the array 2339 if (!val) { 2340 void *array = *(void**)parray; 2341 2342 for (unsigned i = 0; i < nb_elems; i++) { 2343 opt_free_elem(o->type, 2344 opt_array_pelem(o, array, start_elem + i)); 2345 } 2346 2347 if (new_size > 0) { 2348 memmove(opt_array_pelem(o, array, start_elem), 2349 opt_array_pelem(o, array, start_elem + nb_elems), 2350 elem_size * (*array_size - start_elem - nb_elems)); 2351 2352 array = av_realloc_array(array, new_size, elem_size); 2353 if (!array) 2354 return AVERROR(ENOMEM); 2355 2356 *(void**)parray = array; 2357 } else 2358 av_freep(parray); 2359 2360 *array_size = new_size; 2361 2362 return 0; 2363 } 2364 2365 // otherwise, desired operation is insert/replace; 2366 // first, store new elements in a separate array to simplify 2367 // rollback on failure 2368 new_elems = av_calloc(nb_elems, elem_size); 2369 if (!new_elems) 2370 return AVERROR(ENOMEM); 2371 2372 // convert/validate each new element 2373 for (unsigned i = 0; i < nb_elems; i++) { 2374 void *dst = opt_array_pelem(o, new_elems, i); 2375 const void *src = (uint8_t*)val + i * elem_size_val; 2376 2377 double num = 1.0; 2378 int den = 1; 2379 int64_t intnum = 1; 2380 2381 if (val_type == TYPE_BASE(o->type)) { 2382 int err; 2383 2384 ret = opt_copy_elem(obj, val_type, dst, src); 2385 if (ret < 0) 2386 goto fail; 2387 2388 // validate the range for numeric options 2389 err = read_number(o, dst, &num, &den, &intnum); 2390 if (err >= 0 && TYPE_BASE(o->type) != AV_OPT_TYPE_FLAGS && 2391 (!den || o->max * den < num * intnum || o->min * den > num * intnum)) { 2392 num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN); 2393 av_log(obj, AV_LOG_ERROR, "Cannot set array element %u for " 2394 "parameter '%s': value %f out of range [%g - %g]\n", 2395 start_elem + i, o->name, num, o->min, o->max); 2396 ret = AVERROR(ERANGE); 2397 goto fail; 2398 } 2399 } else if (val_type == AV_OPT_TYPE_STRING) { 2400 ret = opt_set_elem(obj, target_obj, o, *(const char **)src, dst); 2401 if (ret < 0) 2402 goto fail; 2403 } else if (val_type == AV_OPT_TYPE_INT || 2404 val_type == AV_OPT_TYPE_INT64 || 2405 val_type == AV_OPT_TYPE_FLOAT || 2406 val_type == AV_OPT_TYPE_DOUBLE || 2407 val_type == AV_OPT_TYPE_RATIONAL) { 2408 2409 switch (val_type) { 2410 case AV_OPT_TYPE_INT: intnum = *(int*)src; break; 2411 case AV_OPT_TYPE_INT64: intnum = *(int64_t*)src; break; 2412 case AV_OPT_TYPE_FLOAT: num = *(float*)src; break; 2413 case AV_OPT_TYPE_DOUBLE: num = *(double*)src; break; 2414 case AV_OPT_TYPE_RATIONAL: intnum = ((AVRational*)src)->num; 2415 den = ((AVRational*)src)->den; break; 2416 default: av_assert0(0); 2417 } 2418 2419 ret = write_number(obj, o, dst, num, den, intnum); 2420 if (ret < 0) 2421 goto fail; 2422 } else { 2423 ret = AVERROR(ENOSYS); 2424 goto fail; 2425 } 2426 } 2427 2428 // commit new elements to the array 2429 if (start_elem == 0 && nb_elems == new_size) { 2430 // replacing the existing array entirely 2431 opt_free_array(o, parray, array_size); 2432 *(void**)parray = new_elems; 2433 *array_size = nb_elems; 2434 2435 new_elems = NULL; 2436 nb_elems = 0; 2437 } else { 2438 void *array = av_realloc_array(*(void**)parray, new_size, elem_size); 2439 if (!array) { 2440 ret = AVERROR(ENOMEM); 2441 goto fail; 2442 } 2443 2444 if (search_flags & AV_OPT_ARRAY_REPLACE) { 2445 // free the elements being overwritten 2446 for (unsigned i = start_elem; i < FFMIN(start_elem + nb_elems, *array_size); i++) 2447 opt_free_elem(o->type, opt_array_pelem(o, array, i)); 2448 } else { 2449 // shift existing elements to the end 2450 memmove(opt_array_pelem(o, array, start_elem + nb_elems), 2451 opt_array_pelem(o, array, start_elem), 2452 elem_size * (*array_size - start_elem)); 2453 } 2454 2455 memcpy((uint8_t*)array + elem_size * start_elem, new_elems, elem_size * nb_elems); 2456 2457 av_freep(&new_elems); 2458 nb_elems = 0; 2459 2460 *(void**)parray = array; 2461 *array_size = new_size; 2462 } 2463 2464 fail: 2465 opt_free_array(o, &new_elems, &nb_elems); 2466 2467 return ret; 2468 } 2469 2470 int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) 2471 { 2472 int ret; 2473 const AVClass *c = *(AVClass**)obj; 2474 int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = c->query_ranges; 2475 2476 if (!callback) 2477 callback = av_opt_query_ranges_default; 2478 2479 ret = callback(ranges_arg, obj, key, flags); 2480 if (ret >= 0) { 2481 if (!(flags & AV_OPT_MULTI_COMPONENT_RANGE)) 2482 ret = 1; 2483 (*ranges_arg)->nb_components = ret; 2484 } 2485 return ret; 2486 } 2487 2488 int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) 2489 { 2490 AVOptionRanges *ranges = av_mallocz(sizeof(*ranges)); 2491 AVOptionRange **range_array = av_mallocz(sizeof(void*)); 2492 AVOptionRange *range = av_mallocz(sizeof(*range)); 2493 const AVOption *field = av_opt_find(obj, key, NULL, 0, flags); 2494 int ret; 2495 2496 *ranges_arg = NULL; 2497 2498 if (!ranges || !range || !range_array || !field) { 2499 ret = AVERROR(ENOMEM); 2500 goto fail; 2501 } 2502 2503 ranges->range = range_array; 2504 ranges->range[0] = range; 2505 ranges->nb_ranges = 1; 2506 ranges->nb_components = 1; 2507 range->is_range = 1; 2508 range->value_min = field->min; 2509 range->value_max = field->max; 2510 2511 switch (field->type) { 2512 case AV_OPT_TYPE_BOOL: 2513 case AV_OPT_TYPE_INT: 2514 case AV_OPT_TYPE_UINT: 2515 case AV_OPT_TYPE_INT64: 2516 case AV_OPT_TYPE_UINT64: 2517 case AV_OPT_TYPE_PIXEL_FMT: 2518 case AV_OPT_TYPE_SAMPLE_FMT: 2519 case AV_OPT_TYPE_FLOAT: 2520 case AV_OPT_TYPE_DOUBLE: 2521 case AV_OPT_TYPE_DURATION: 2522 case AV_OPT_TYPE_COLOR: 2523 break; 2524 case AV_OPT_TYPE_STRING: 2525 range->component_min = 0; 2526 range->component_max = 0x10FFFF; // max unicode value 2527 range->value_min = -1; 2528 range->value_max = INT_MAX; 2529 break; 2530 case AV_OPT_TYPE_RATIONAL: 2531 range->component_min = INT_MIN; 2532 range->component_max = INT_MAX; 2533 break; 2534 case AV_OPT_TYPE_IMAGE_SIZE: 2535 range->component_min = 0; 2536 range->component_max = INT_MAX/128/8; 2537 range->value_min = 0; 2538 range->value_max = INT_MAX/8; 2539 break; 2540 case AV_OPT_TYPE_VIDEO_RATE: 2541 range->component_min = 1; 2542 range->component_max = INT_MAX; 2543 range->value_min = 1; 2544 range->value_max = INT_MAX; 2545 break; 2546 default: 2547 ret = AVERROR(ENOSYS); 2548 goto fail; 2549 } 2550 2551 *ranges_arg = ranges; 2552 return 1; 2553 fail: 2554 av_free(ranges); 2555 av_free(range); 2556 av_free(range_array); 2557 return ret; 2558 } 2559 2560 void av_opt_freep_ranges(AVOptionRanges **rangesp) 2561 { 2562 int i; 2563 AVOptionRanges *ranges = *rangesp; 2564 2565 if (!ranges) 2566 return; 2567 2568 for (i = 0; i < ranges->nb_ranges * ranges->nb_components; i++) { 2569 AVOptionRange *range = ranges->range[i]; 2570 if (range) { 2571 av_freep(&range->str); 2572 av_freep(&ranges->range[i]); 2573 } 2574 } 2575 av_freep(&ranges->range); 2576 av_freep(rangesp); 2577 } 2578 2579 int av_opt_is_set_to_default(void *obj, const AVOption *o) 2580 { 2581 int64_t i64; 2582 double d; 2583 AVRational q; 2584 int ret, w, h; 2585 char *str; 2586 void *dst; 2587 2588 if (!o || !obj) 2589 return AVERROR(EINVAL); 2590 2591 dst = ((uint8_t*)obj) + o->offset; 2592 2593 if (o->type & AV_OPT_TYPE_FLAG_ARRAY) { 2594 const char *def = o->default_val.arr ? o->default_val.arr->def : NULL; 2595 uint8_t *val; 2596 2597 ret = opt_get_array(o, dst, &val); 2598 if (ret < 0) 2599 return ret; 2600 2601 if (!!val != !!def) 2602 ret = 0; 2603 else if (val) 2604 ret = !strcmp(val, def); 2605 2606 av_freep(&val); 2607 2608 return ret; 2609 } 2610 2611 switch (o->type) { 2612 case AV_OPT_TYPE_CONST: 2613 return 1; 2614 case AV_OPT_TYPE_BOOL: 2615 case AV_OPT_TYPE_FLAGS: 2616 case AV_OPT_TYPE_PIXEL_FMT: 2617 case AV_OPT_TYPE_SAMPLE_FMT: 2618 case AV_OPT_TYPE_INT: 2619 case AV_OPT_TYPE_UINT: 2620 case AV_OPT_TYPE_DURATION: 2621 case AV_OPT_TYPE_INT64: 2622 case AV_OPT_TYPE_UINT64: 2623 read_number(o, dst, NULL, NULL, &i64); 2624 return o->default_val.i64 == i64; 2625 case AV_OPT_TYPE_CHLAYOUT: { 2626 AVChannelLayout ch_layout = { 0 }; 2627 if (o->default_val.str) { 2628 if ((ret = av_channel_layout_from_string(&ch_layout, o->default_val.str)) < 0) 2629 return ret; 2630 } 2631 ret = !av_channel_layout_compare((AVChannelLayout *)dst, &ch_layout); 2632 av_channel_layout_uninit(&ch_layout); 2633 return ret; 2634 } 2635 case AV_OPT_TYPE_STRING: 2636 str = *(char **)dst; 2637 if (str == o->default_val.str) //2 NULLs 2638 return 1; 2639 if (!str || !o->default_val.str) //1 NULL 2640 return 0; 2641 return !strcmp(str, o->default_val.str); 2642 case AV_OPT_TYPE_DOUBLE: 2643 d = *(double *)dst; 2644 return o->default_val.dbl == d; 2645 case AV_OPT_TYPE_FLOAT: 2646 d = *(float *)dst; 2647 return (float)o->default_val.dbl == d; 2648 case AV_OPT_TYPE_RATIONAL: 2649 q = av_d2q(o->default_val.dbl, INT_MAX); 2650 return !av_cmp_q(*(AVRational*)dst, q); 2651 case AV_OPT_TYPE_BINARY: { 2652 struct { 2653 uint8_t *data; 2654 int size; 2655 } tmp = {0}; 2656 int opt_size = *(int *)((void **)dst + 1); 2657 void *opt_ptr = *(void **)dst; 2658 if (!opt_size && (!o->default_val.str || !strlen(o->default_val.str))) 2659 return 1; 2660 if (!opt_size || !o->default_val.str || !strlen(o->default_val.str )) 2661 return 0; 2662 if (opt_size != strlen(o->default_val.str) / 2) 2663 return 0; 2664 ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data); 2665 if (!ret) 2666 ret = !memcmp(opt_ptr, tmp.data, tmp.size); 2667 av_free(tmp.data); 2668 return ret; 2669 } 2670 case AV_OPT_TYPE_DICT: { 2671 AVDictionary *dict1 = NULL; 2672 AVDictionary *dict2 = *(AVDictionary **)dst; 2673 const AVDictionaryEntry *en1 = NULL; 2674 const AVDictionaryEntry *en2 = NULL; 2675 ret = av_dict_parse_string(&dict1, o->default_val.str, "=", ":", 0); 2676 if (ret < 0) { 2677 av_dict_free(&dict1); 2678 return ret; 2679 } 2680 do { 2681 en1 = av_dict_iterate(dict1, en1); 2682 en2 = av_dict_iterate(dict2, en2); 2683 } while (en1 && en2 && !strcmp(en1->key, en2->key) && !strcmp(en1->value, en2->value)); 2684 av_dict_free(&dict1); 2685 return (!en1 && !en2); 2686 } 2687 case AV_OPT_TYPE_IMAGE_SIZE: 2688 if (!o->default_val.str || !strcmp(o->default_val.str, "none")) 2689 w = h = 0; 2690 else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0) 2691 return ret; 2692 return (w == *(int *)dst) && (h == *((int *)dst+1)); 2693 case AV_OPT_TYPE_VIDEO_RATE: 2694 q = (AVRational){0, 0}; 2695 if (o->default_val.str) { 2696 if ((ret = av_parse_video_rate(&q, o->default_val.str)) < 0) 2697 return ret; 2698 } 2699 return !av_cmp_q(*(AVRational*)dst, q); 2700 case AV_OPT_TYPE_COLOR: { 2701 uint8_t color[4] = {0, 0, 0, 0}; 2702 if (o->default_val.str) { 2703 if ((ret = av_parse_color(color, o->default_val.str, -1, NULL)) < 0) 2704 return ret; 2705 } 2706 return !memcmp(color, dst, sizeof(color)); 2707 } 2708 default: 2709 av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name); 2710 break; 2711 } 2712 return AVERROR_PATCHWELCOME; 2713 } 2714 2715 int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags) 2716 { 2717 const AVOption *o; 2718 void *target; 2719 if (!obj) 2720 return AVERROR(EINVAL); 2721 o = av_opt_find2(obj, name, NULL, 0, search_flags, &target); 2722 if (!o) 2723 return AVERROR_OPTION_NOT_FOUND; 2724 return av_opt_is_set_to_default(target, o); 2725 } 2726 2727 static int opt_serialize(void *obj, int opt_flags, int flags, int *cnt, 2728 AVBPrint *bprint, const char key_val_sep, const char pairs_sep) 2729 { 2730 const AVOption *o = NULL; 2731 void *child = NULL; 2732 uint8_t *buf; 2733 int ret; 2734 const char special_chars[] = {pairs_sep, key_val_sep, '\0'}; 2735 2736 if (flags & AV_OPT_SERIALIZE_SEARCH_CHILDREN) 2737 while (child = av_opt_child_next(obj, child)) { 2738 ret = opt_serialize(child, opt_flags, flags, cnt, bprint, 2739 key_val_sep, pairs_sep); 2740 if (ret < 0) 2741 return ret; 2742 } 2743 2744 while (o = av_opt_next(obj, o)) { 2745 if (o->type == AV_OPT_TYPE_CONST) 2746 continue; 2747 if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags) 2748 continue; 2749 else if (((o->flags & opt_flags) != opt_flags)) 2750 continue; 2751 if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0) 2752 continue; 2753 if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) { 2754 av_bprint_finalize(bprint, NULL); 2755 return ret; 2756 } 2757 if (buf) { 2758 if ((*cnt)++) 2759 av_bprint_append_data(bprint, &pairs_sep, 1); 2760 av_bprint_escape(bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); 2761 av_bprint_append_data(bprint, &key_val_sep, 1); 2762 av_bprint_escape(bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); 2763 av_freep(&buf); 2764 } 2765 } 2766 2767 return 0; 2768 } 2769 2770 int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, 2771 const char key_val_sep, const char pairs_sep) 2772 { 2773 AVBPrint bprint; 2774 int ret, cnt = 0; 2775 2776 if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep || 2777 pairs_sep == '\\' || key_val_sep == '\\') { 2778 av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found."); 2779 return AVERROR(EINVAL); 2780 } 2781 2782 if (!obj || !buffer) 2783 return AVERROR(EINVAL); 2784 2785 *buffer = NULL; 2786 av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); 2787 2788 ret = opt_serialize(obj, opt_flags, flags, &cnt, &bprint, 2789 key_val_sep, pairs_sep); 2790 if (ret < 0) 2791 return ret; 2792 2793 ret = av_bprint_finalize(&bprint, buffer); 2794 if (ret < 0) 2795 return ret; 2796 return 0; 2797 }