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 "common.h" 33#include "dict.h" 34#include "eval.h" 35#include "log.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 46const AVOption *av_opt_next(const void *obj, const AVOption *last) 47{ 48 const AVClass *class; 49 if (!obj) 50 return NULL; 51 class = *(const AVClass**)obj; 52 if (!last && class && class->option && class->option[0].name) 53 return class->option; 54 if (last && last[1].name) 55 return ++last; 56 return NULL; 57} 58 59static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum) 60{ 61 switch (o->type) { 62 case AV_OPT_TYPE_FLAGS: 63 *intnum = *(unsigned int*)dst; 64 return 0; 65 case AV_OPT_TYPE_PIXEL_FMT: 66 *intnum = *(enum AVPixelFormat *)dst; 67 return 0; 68 case AV_OPT_TYPE_SAMPLE_FMT: 69 *intnum = *(enum AVSampleFormat *)dst; 70 return 0; 71 case AV_OPT_TYPE_BOOL: 72 case AV_OPT_TYPE_INT: 73 *intnum = *(int *)dst; 74 return 0; 75#if FF_API_OLD_CHANNEL_LAYOUT 76FF_DISABLE_DEPRECATION_WARNINGS 77 case AV_OPT_TYPE_CHANNEL_LAYOUT: 78FF_ENABLE_DEPRECATION_WARNINGS 79#endif 80 case AV_OPT_TYPE_DURATION: 81 case AV_OPT_TYPE_INT64: 82 case AV_OPT_TYPE_UINT64: 83 *intnum = *(int64_t *)dst; 84 return 0; 85 case AV_OPT_TYPE_FLOAT: 86 *num = *(float *)dst; 87 return 0; 88 case AV_OPT_TYPE_DOUBLE: 89 *num = *(double *)dst; 90 return 0; 91 case AV_OPT_TYPE_RATIONAL: 92 *intnum = ((AVRational *)dst)->num; 93 *den = ((AVRational *)dst)->den; 94 return 0; 95 case AV_OPT_TYPE_CONST: 96 *num = o->default_val.dbl; 97 return 0; 98 } 99 return AVERROR(EINVAL); 100} 101 102static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) 103{ 104 if (o->type != AV_OPT_TYPE_FLAGS && 105 (!den || o->max * den < num * intnum || o->min * den > num * intnum)) { 106 num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN); 107 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", 108 num, o->name, o->min, o->max); 109 return AVERROR(ERANGE); 110 } 111 if (o->type == AV_OPT_TYPE_FLAGS) { 112 double d = num*intnum/den; 113 if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) { 114 av_log(obj, AV_LOG_ERROR, 115 "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n", 116 num*intnum/den, o->name); 117 return AVERROR(ERANGE); 118 } 119 } 120 121 switch (o->type) { 122 case AV_OPT_TYPE_PIXEL_FMT: 123 *(enum AVPixelFormat *)dst = llrint(num / den) * intnum; 124 break; 125 case AV_OPT_TYPE_SAMPLE_FMT: 126 *(enum AVSampleFormat *)dst = llrint(num / den) * intnum; 127 break; 128 case AV_OPT_TYPE_BOOL: 129 case AV_OPT_TYPE_FLAGS: 130 case AV_OPT_TYPE_INT: 131 *(int *)dst = llrint(num / den) * intnum; 132 break; 133 case AV_OPT_TYPE_DURATION: 134#if FF_API_OLD_CHANNEL_LAYOUT 135FF_DISABLE_DEPRECATION_WARNINGS 136 case AV_OPT_TYPE_CHANNEL_LAYOUT: 137FF_ENABLE_DEPRECATION_WARNINGS 138#endif 139 case AV_OPT_TYPE_INT64:{ 140 double d = num / den; 141 if (intnum == 1 && d == (double)INT64_MAX) { 142 *(int64_t *)dst = INT64_MAX; 143 } else 144 *(int64_t *)dst = llrint(d) * intnum; 145 break;} 146 case AV_OPT_TYPE_UINT64:{ 147 double d = num / den; 148 // We must special case uint64_t here as llrint() does not support values 149 // outside the int64_t range and there is no portable function which does 150 // "INT64_MAX + 1ULL" is used as it is representable exactly as IEEE double 151 // while INT64_MAX is not 152 if (intnum == 1 && d == (double)UINT64_MAX) { 153 *(uint64_t *)dst = UINT64_MAX; 154 } else if (d > INT64_MAX + 1ULL) { 155 *(uint64_t *)dst = (llrint(d - (INT64_MAX + 1ULL)) + (INT64_MAX + 1ULL))*intnum; 156 } else { 157 *(uint64_t *)dst = llrint(d) * intnum; 158 } 159 break;} 160 case AV_OPT_TYPE_FLOAT: 161 *(float *)dst = num * intnum / den; 162 break; 163 case AV_OPT_TYPE_DOUBLE: 164 *(double *)dst = num * intnum / den; 165 break; 166 case AV_OPT_TYPE_RATIONAL: 167 case AV_OPT_TYPE_VIDEO_RATE: 168 if ((int) num == num) 169 *(AVRational *)dst = (AVRational) { num *intnum, den }; 170 else 171 *(AVRational *)dst = av_d2q(num * intnum / den, 1 << 24); 172 break; 173 default: 174 return AVERROR(EINVAL); 175 } 176 return 0; 177} 178 179static int hexchar2int(char c) { 180 if (c >= '0' && c <= '9') 181 return c - '0'; 182 if (c >= 'a' && c <= 'f') 183 return c - 'a' + 10; 184 if (c >= 'A' && c <= 'F') 185 return c - 'A' + 10; 186 return -1; 187} 188 189static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst) 190{ 191 int *lendst = (int *)(dst + 1); 192 uint8_t *bin, *ptr; 193 int len; 194 195 av_freep(dst); 196 *lendst = 0; 197 198 if (!val || !(len = strlen(val))) 199 return 0; 200 201 if (len & 1) 202 return AVERROR(EINVAL); 203 len /= 2; 204 205 ptr = bin = av_malloc(len); 206 if (!ptr) 207 return AVERROR(ENOMEM); 208 while (*val) { 209 int a = hexchar2int(*val++); 210 int b = hexchar2int(*val++); 211 if (a < 0 || b < 0) { 212 av_free(bin); 213 return AVERROR(EINVAL); 214 } 215 *ptr++ = (a << 4) | b; 216 } 217 *dst = bin; 218 *lendst = len; 219 220 return 0; 221} 222 223static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst) 224{ 225 av_freep(dst); 226 *dst = av_strdup(val); 227 return *dst ? 0 : AVERROR(ENOMEM); 228} 229 230#define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \ 231 opt->type == AV_OPT_TYPE_UINT64 || \ 232 opt->type == AV_OPT_TYPE_CONST || \ 233 opt->type == AV_OPT_TYPE_FLAGS || \ 234 opt->type == AV_OPT_TYPE_INT) \ 235 ? opt->default_val.i64 \ 236 : opt->default_val.dbl) 237 238static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst) 239{ 240 int ret = 0; 241 242 if (o->type == AV_OPT_TYPE_RATIONAL || o->type == AV_OPT_TYPE_VIDEO_RATE) { 243 int num, den; 244 char c; 245 if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) { 246 if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0) 247 return ret; 248 ret = 0; 249 } 250 } 251 252 for (;;) { 253 int i = 0; 254 char buf[256]; 255 int cmd = 0; 256 double d; 257 int64_t intnum = 1; 258 259 if (o->type == AV_OPT_TYPE_FLAGS) { 260 if (*val == '+' || *val == '-') 261 cmd = *(val++); 262 for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++) 263 buf[i] = val[i]; 264 buf[i] = 0; 265 } 266 267 { 268 int res; 269 int ci = 0; 270 double const_values[64]; 271 const char * const_names[64]; 272 int search_flags = (o->flags & AV_OPT_FLAG_CHILD_CONSTS) ? AV_OPT_SEARCH_CHILDREN : 0; 273 const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, search_flags); 274 if (o_named && o_named->type == AV_OPT_TYPE_CONST) { 275 d = DEFAULT_NUMVAL(o_named); 276 if (o_named->flags & AV_OPT_FLAG_DEPRECATED) 277 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", 278 o_named->name, o_named->help); 279 } else { 280 if (o->unit) { 281 for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) { 282 if (o_named->type == AV_OPT_TYPE_CONST && 283 o_named->unit && 284 !strcmp(o_named->unit, o->unit)) { 285 if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) { 286 av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit); 287 return AVERROR_PATCHWELCOME; 288 } 289 const_names [ci ] = o_named->name; 290 const_values[ci++] = DEFAULT_NUMVAL(o_named); 291 } 292 } 293 } 294 const_names [ci ] = "default"; 295 const_values[ci++] = DEFAULT_NUMVAL(o); 296 const_names [ci ] = "max"; 297 const_values[ci++] = o->max; 298 const_names [ci ] = "min"; 299 const_values[ci++] = o->min; 300 const_names [ci ] = "none"; 301 const_values[ci++] = 0; 302 const_names [ci ] = "all"; 303 const_values[ci++] = ~0; 304 const_names [ci] = NULL; 305 const_values[ci] = 0; 306 307 res = av_expr_parse_and_eval(&d, i ? buf : val, const_names, 308 const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); 309 if (res < 0) { 310 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); 311 return res; 312 } 313 } 314 } 315 if (o->type == AV_OPT_TYPE_FLAGS) { 316 read_number(o, dst, NULL, NULL, &intnum); 317 if (cmd == '+') 318 d = intnum | (int64_t)d; 319 else if (cmd == '-') 320 d = intnum &~(int64_t)d; 321 } 322 323 if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0) 324 return ret; 325 val += i; 326 if (!i || !*val) 327 return 0; 328 } 329} 330 331static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst) 332{ 333 int ret; 334 335 if (!val || !strcmp(val, "none")) { 336 dst[0] = 337 dst[1] = 0; 338 return 0; 339 } 340 ret = av_parse_video_size(dst, dst + 1, val); 341 if (ret < 0) 342 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val); 343 return ret; 344} 345 346static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst) 347{ 348 int ret = av_parse_video_rate(dst, val); 349 if (ret < 0) 350 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); 351 return ret; 352} 353 354static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst) 355{ 356 int ret; 357 358 if (!val) { 359 return 0; 360 } else { 361 ret = av_parse_color(dst, val, -1, obj); 362 if (ret < 0) 363 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val); 364 return ret; 365 } 366 return 0; 367} 368 369static const char *get_bool_name(int val) 370{ 371 if (val < 0) 372 return "auto"; 373 return val ? "true" : "false"; 374} 375 376static int set_string_bool(void *obj, const AVOption *o, const char *val, int *dst) 377{ 378 int n; 379 380 if (!val) 381 return 0; 382 383 if (!strcmp(val, "auto")) { 384 n = -1; 385 } else if (av_match_name(val, "true,y,yes,enable,enabled,on")) { 386 n = 1; 387 } else if (av_match_name(val, "false,n,no,disable,disabled,off")) { 388 n = 0; 389 } else { 390 char *end = NULL; 391 n = strtol(val, &end, 10); 392 if (val + strlen(val) != end) 393 goto fail; 394 } 395 396 if (n < o->min || n > o->max) 397 goto fail; 398 399 *dst = n; 400 return 0; 401 402fail: 403 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as boolean\n", val); 404 return AVERROR(EINVAL); 405} 406 407static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst, 408 int fmt_nb, int ((*get_fmt)(const char *)), const char *desc) 409{ 410 int fmt, min, max; 411 412 if (!val || !strcmp(val, "none")) { 413 fmt = -1; 414 } else { 415 fmt = get_fmt(val); 416 if (fmt == -1) { 417 char *tail; 418 fmt = strtol(val, &tail, 0); 419 if (*tail || (unsigned)fmt >= fmt_nb) { 420 av_log(obj, AV_LOG_ERROR, 421 "Unable to parse option value \"%s\" as %s\n", val, desc); 422 return AVERROR(EINVAL); 423 } 424 } 425 } 426 427 min = FFMAX(o->min, -1); 428 max = FFMIN(o->max, fmt_nb-1); 429 430 // hack for compatibility with old ffmpeg 431 if(min == 0 && max == 0) { 432 min = -1; 433 max = fmt_nb-1; 434 } 435 436 if (fmt < min || fmt > max) { 437 av_log(obj, AV_LOG_ERROR, 438 "Value %d for parameter '%s' out of %s format range [%d - %d]\n", 439 fmt, o->name, desc, min, max); 440 return AVERROR(ERANGE); 441 } 442 443 *(int *)dst = fmt; 444 return 0; 445} 446 447static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) 448{ 449 return set_string_fmt(obj, o, val, dst, 450 AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format"); 451} 452 453static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) 454{ 455 return set_string_fmt(obj, o, val, dst, 456 AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format"); 457} 458 459static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_t **dst) 460{ 461 AVDictionary *options = NULL; 462 463 if (val) { 464 int ret = av_dict_parse_string(&options, val, "=", ":", 0); 465 if (ret < 0) { 466 av_dict_free(&options); 467 return ret; 468 } 469 } 470 471 av_dict_free((AVDictionary **)dst); 472 *dst = (uint8_t *)options; 473 474 return 0; 475} 476 477static int set_string_channel_layout(void *obj, const AVOption *o, 478 const char *val, void *dst) 479{ 480 AVChannelLayout *channel_layout = dst; 481 av_channel_layout_uninit(channel_layout); 482 if (!val) 483 return 0; 484 return av_channel_layout_from_string(channel_layout, val); 485} 486 487int av_opt_set(void *obj, const char *name, const char *val, int search_flags) 488{ 489 int ret = 0; 490 void *dst, *target_obj; 491 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 492 if (!o || !target_obj) 493 return AVERROR_OPTION_NOT_FOUND; 494FF_DISABLE_DEPRECATION_WARNINGS 495 if (!val && (o->type != AV_OPT_TYPE_STRING && 496 o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT && 497 o->type != AV_OPT_TYPE_IMAGE_SIZE && 498 o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR && 499#if FF_API_OLD_CHANNEL_LAYOUT 500 o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && 501#endif 502 o->type != AV_OPT_TYPE_BOOL)) 503 return AVERROR(EINVAL); 504FF_ENABLE_DEPRECATION_WARNINGS 505 506 if (o->flags & AV_OPT_FLAG_READONLY) 507 return AVERROR(EINVAL); 508 509 if (o->flags & AV_OPT_FLAG_DEPRECATED) 510 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help); 511 512 dst = ((uint8_t *)target_obj) + o->offset; 513 switch (o->type) { 514 case AV_OPT_TYPE_BOOL: 515 return set_string_bool(obj, o, val, dst); 516 case AV_OPT_TYPE_STRING: 517 return set_string(obj, o, val, dst); 518 case AV_OPT_TYPE_BINARY: 519 return set_string_binary(obj, o, val, dst); 520 case AV_OPT_TYPE_FLAGS: 521 case AV_OPT_TYPE_INT: 522 case AV_OPT_TYPE_INT64: 523 case AV_OPT_TYPE_UINT64: 524 case AV_OPT_TYPE_FLOAT: 525 case AV_OPT_TYPE_DOUBLE: 526 case AV_OPT_TYPE_RATIONAL: 527 return set_string_number(obj, target_obj, o, val, dst); 528 case AV_OPT_TYPE_IMAGE_SIZE: 529 return set_string_image_size(obj, o, val, dst); 530 case AV_OPT_TYPE_VIDEO_RATE: { 531 AVRational tmp; 532 ret = set_string_video_rate(obj, o, val, &tmp); 533 if (ret < 0) 534 return ret; 535 return write_number(obj, o, dst, 1, tmp.den, tmp.num); 536 } 537 case AV_OPT_TYPE_PIXEL_FMT: 538 return set_string_pixel_fmt(obj, o, val, dst); 539 case AV_OPT_TYPE_SAMPLE_FMT: 540 return set_string_sample_fmt(obj, o, val, dst); 541 case AV_OPT_TYPE_DURATION: 542 { 543 int64_t usecs = 0; 544 if (val) { 545 if ((ret = av_parse_time(&usecs, val, 1)) < 0) { 546 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val); 547 return ret; 548 } 549 } 550 if (usecs < o->min || usecs > o->max) { 551 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", 552 usecs / 1000000.0, o->name, o->min / 1000000.0, o->max / 1000000.0); 553 return AVERROR(ERANGE); 554 } 555 *(int64_t *)dst = usecs; 556 return 0; 557 } 558 case AV_OPT_TYPE_COLOR: 559 return set_string_color(obj, o, val, dst); 560#if FF_API_OLD_CHANNEL_LAYOUT 561FF_DISABLE_DEPRECATION_WARNINGS 562 case AV_OPT_TYPE_CHANNEL_LAYOUT: 563 if (!val || !strcmp(val, "none")) { 564 *(int64_t *)dst = 0; 565 } else { 566 int64_t cl = av_get_channel_layout(val); 567 if (!cl) { 568 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); 569 ret = AVERROR(EINVAL); 570 } 571 *(int64_t *)dst = cl; 572 return ret; 573 } 574 break; 575FF_ENABLE_DEPRECATION_WARNINGS 576#endif 577 case AV_OPT_TYPE_CHLAYOUT: 578 ret = set_string_channel_layout(obj, o, val, dst); 579 if (ret < 0) { 580 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); 581 ret = AVERROR(EINVAL); 582 } 583 return ret; 584 case AV_OPT_TYPE_DICT: 585 return set_string_dict(obj, o, val, dst); 586 } 587 588 av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); 589 return AVERROR(EINVAL); 590} 591 592#define OPT_EVAL_NUMBER(name, opttype, vartype) \ 593int av_opt_eval_ ## name(void *obj, const AVOption *o, \ 594 const char *val, vartype *name ## _out) \ 595{ \ 596 if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY) \ 597 return AVERROR(EINVAL); \ 598 return set_string_number(obj, obj, o, val, name ## _out); \ 599} 600 601OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int) 602OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int) 603OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t) 604OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float) 605OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double) 606OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational) 607 608static int set_number(void *obj, const char *name, double num, int den, int64_t intnum, 609 int search_flags) 610{ 611 void *dst, *target_obj; 612 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 613 614 if (!o || !target_obj) 615 return AVERROR_OPTION_NOT_FOUND; 616 617 if (o->flags & AV_OPT_FLAG_READONLY) 618 return AVERROR(EINVAL); 619 620 dst = ((uint8_t *)target_obj) + o->offset; 621 return write_number(obj, o, dst, num, den, intnum); 622} 623 624int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags) 625{ 626 return set_number(obj, name, 1, 1, val, search_flags); 627} 628 629int av_opt_set_double(void *obj, const char *name, double val, int search_flags) 630{ 631 return set_number(obj, name, val, 1, 1, search_flags); 632} 633 634int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags) 635{ 636 return set_number(obj, name, val.num, val.den, 1, search_flags); 637} 638 639int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags) 640{ 641 void *target_obj; 642 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 643 uint8_t *ptr; 644 uint8_t **dst; 645 int *lendst; 646 647 if (!o || !target_obj) 648 return AVERROR_OPTION_NOT_FOUND; 649 650 if (o->type != AV_OPT_TYPE_BINARY || o->flags & AV_OPT_FLAG_READONLY) 651 return AVERROR(EINVAL); 652 653 ptr = len ? av_malloc(len) : NULL; 654 if (len && !ptr) 655 return AVERROR(ENOMEM); 656 657 dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset); 658 lendst = (int *)(dst + 1); 659 660 av_free(*dst); 661 *dst = ptr; 662 *lendst = len; 663 if (len) 664 memcpy(ptr, val, len); 665 666 return 0; 667} 668 669int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags) 670{ 671 void *target_obj; 672 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 673 674 if (!o || !target_obj) 675 return AVERROR_OPTION_NOT_FOUND; 676 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) { 677 av_log(obj, AV_LOG_ERROR, 678 "The value set by option '%s' is not an image size.\n", o->name); 679 return AVERROR(EINVAL); 680 } 681 if (w<0 || h<0) { 682 av_log(obj, AV_LOG_ERROR, 683 "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name); 684 return AVERROR(EINVAL); 685 } 686 *(int *)(((uint8_t *)target_obj) + o->offset) = w; 687 *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h; 688 return 0; 689} 690 691int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags) 692{ 693 void *target_obj; 694 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 695 696 if (!o || !target_obj) 697 return AVERROR_OPTION_NOT_FOUND; 698 if (o->type != AV_OPT_TYPE_VIDEO_RATE) { 699 av_log(obj, AV_LOG_ERROR, 700 "The value set by option '%s' is not a video rate.\n", o->name); 701 return AVERROR(EINVAL); 702 } 703 if (val.num <= 0 || val.den <= 0) 704 return AVERROR(EINVAL); 705 return set_number(obj, name, val.num, val.den, 1, search_flags); 706} 707 708static int set_format(void *obj, const char *name, int fmt, int search_flags, 709 enum AVOptionType type, const char *desc, int nb_fmts) 710{ 711 void *target_obj; 712 const AVOption *o = av_opt_find2(obj, name, NULL, 0, 713 search_flags, &target_obj); 714 int min, max; 715 716 if (!o || !target_obj) 717 return AVERROR_OPTION_NOT_FOUND; 718 if (o->type != type) { 719 av_log(obj, AV_LOG_ERROR, 720 "The value set by option '%s' is not a %s format", name, desc); 721 return AVERROR(EINVAL); 722 } 723 724 min = FFMAX(o->min, -1); 725 max = FFMIN(o->max, nb_fmts-1); 726 727 if (fmt < min || fmt > max) { 728 av_log(obj, AV_LOG_ERROR, 729 "Value %d for parameter '%s' out of %s format range [%d - %d]\n", 730 fmt, name, desc, min, max); 731 return AVERROR(ERANGE); 732 } 733 *(int *)(((uint8_t *)target_obj) + o->offset) = fmt; 734 return 0; 735} 736 737int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags) 738{ 739 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB); 740} 741 742int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags) 743{ 744 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB); 745} 746 747#if FF_API_OLD_CHANNEL_LAYOUT 748FF_DISABLE_DEPRECATION_WARNINGS 749int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags) 750{ 751 void *target_obj; 752 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 753 754 if (!o || !target_obj) 755 return AVERROR_OPTION_NOT_FOUND; 756 if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { 757 av_log(obj, AV_LOG_ERROR, 758 "The value set by option '%s' is not a channel layout.\n", o->name); 759 return AVERROR(EINVAL); 760 } 761 *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl; 762 return 0; 763} 764FF_ENABLE_DEPRECATION_WARNINGS 765#endif 766 767int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, 768 int search_flags) 769{ 770 void *target_obj; 771 AVDictionary **dst; 772 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 773 774 if (!o || !target_obj) 775 return AVERROR_OPTION_NOT_FOUND; 776 if (o->flags & AV_OPT_FLAG_READONLY) 777 return AVERROR(EINVAL); 778 779 dst = (AVDictionary **)(((uint8_t *)target_obj) + o->offset); 780 av_dict_free(dst); 781 av_dict_copy(dst, val, 0); 782 783 return 0; 784} 785 786int av_opt_set_chlayout(void *obj, const char *name, 787 const AVChannelLayout *channel_layout, 788 int search_flags) 789{ 790 void *target_obj; 791 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 792 AVChannelLayout *dst; 793 794 if (!o || !target_obj) 795 return AVERROR_OPTION_NOT_FOUND; 796 797 dst = (AVChannelLayout*)((uint8_t*)target_obj + o->offset); 798 799 return av_channel_layout_copy(dst, channel_layout); 800} 801 802static void format_duration(char *buf, size_t size, int64_t d) 803{ 804 char *e; 805 806 av_assert0(size >= 25); 807 if (d < 0 && d != INT64_MIN) { 808 *(buf++) = '-'; 809 size--; 810 d = -d; 811 } 812 if (d == INT64_MAX) 813 snprintf(buf, size, "INT64_MAX"); 814 else if (d == INT64_MIN) 815 snprintf(buf, size, "INT64_MIN"); 816 else if (d > (int64_t)3600*1000000) 817 snprintf(buf, size, "%"PRId64":%02d:%02d.%06d", d / 3600000000, 818 (int)((d / 60000000) % 60), 819 (int)((d / 1000000) % 60), 820 (int)(d % 1000000)); 821 else if (d > 60*1000000) 822 snprintf(buf, size, "%d:%02d.%06d", 823 (int)(d / 60000000), 824 (int)((d / 1000000) % 60), 825 (int)(d % 1000000)); 826 else 827 snprintf(buf, size, "%d.%06d", 828 (int)(d / 1000000), 829 (int)(d % 1000000)); 830 e = buf + strlen(buf); 831 while (e > buf && e[-1] == '0') 832 *(--e) = 0; 833 if (e > buf && e[-1] == '.') 834 *(--e) = 0; 835} 836 837int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) 838{ 839 void *dst, *target_obj; 840 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 841 uint8_t *bin, buf[128]; 842 int len, i, ret; 843 int64_t i64; 844 845 if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST)) 846 return AVERROR_OPTION_NOT_FOUND; 847 848 if (o->flags & AV_OPT_FLAG_DEPRECATED) 849 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help); 850 851 dst = (uint8_t *)target_obj + o->offset; 852 853 buf[0] = 0; 854 switch (o->type) { 855 case AV_OPT_TYPE_BOOL: 856 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(get_bool_name(*(int *)dst), "invalid")); 857 break; 858 case AV_OPT_TYPE_FLAGS: 859 ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst); 860 break; 861 case AV_OPT_TYPE_INT: 862 ret = snprintf(buf, sizeof(buf), "%d", *(int *)dst); 863 break; 864 case AV_OPT_TYPE_INT64: 865 ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t *)dst); 866 break; 867 case AV_OPT_TYPE_UINT64: 868 ret = snprintf(buf, sizeof(buf), "%"PRIu64, *(uint64_t *)dst); 869 break; 870 case AV_OPT_TYPE_FLOAT: 871 ret = snprintf(buf, sizeof(buf), "%f", *(float *)dst); 872 break; 873 case AV_OPT_TYPE_DOUBLE: 874 ret = snprintf(buf, sizeof(buf), "%f", *(double *)dst); 875 break; 876 case AV_OPT_TYPE_VIDEO_RATE: 877 case AV_OPT_TYPE_RATIONAL: 878 ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den); 879 break; 880 case AV_OPT_TYPE_CONST: 881 ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl); 882 break; 883 case AV_OPT_TYPE_STRING: 884 if (*(uint8_t **)dst) { 885 *out_val = av_strdup(*(uint8_t **)dst); 886 } else if (search_flags & AV_OPT_ALLOW_NULL) { 887 *out_val = NULL; 888 return 0; 889 } else { 890 *out_val = av_strdup(""); 891 } 892 return *out_val ? 0 : AVERROR(ENOMEM); 893 case AV_OPT_TYPE_BINARY: 894 if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) { 895 *out_val = NULL; 896 return 0; 897 } 898 len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *)); 899 if ((uint64_t)len * 2 + 1 > INT_MAX) 900 return AVERROR(EINVAL); 901 if (!(*out_val = av_malloc(len * 2 + 1))) 902 return AVERROR(ENOMEM); 903 if (!len) { 904 *out_val[0] = '\0'; 905 return 0; 906 } 907 bin = *(uint8_t **)dst; 908 for (i = 0; i < len; i++) 909 snprintf(*out_val + i * 2, 3, "%02X", bin[i]); 910 return 0; 911 case AV_OPT_TYPE_IMAGE_SIZE: 912 ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]); 913 break; 914 case AV_OPT_TYPE_PIXEL_FMT: 915 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none")); 916 break; 917 case AV_OPT_TYPE_SAMPLE_FMT: 918 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none")); 919 break; 920 case AV_OPT_TYPE_DURATION: 921 i64 = *(int64_t *)dst; 922 format_duration(buf, sizeof(buf), i64); 923 ret = strlen(buf); // no overflow possible, checked by an assert 924 break; 925 case AV_OPT_TYPE_COLOR: 926 ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", 927 (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1], 928 (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]); 929 break; 930#if FF_API_OLD_CHANNEL_LAYOUT 931FF_DISABLE_DEPRECATION_WARNINGS 932 case AV_OPT_TYPE_CHANNEL_LAYOUT: 933 934 i64 = *(int64_t *)dst; 935 ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64); 936 break; 937FF_ENABLE_DEPRECATION_WARNINGS 938#endif 939 case AV_OPT_TYPE_CHLAYOUT: 940 ret = av_channel_layout_describe(dst, buf, sizeof(buf)); 941 break; 942 case AV_OPT_TYPE_DICT: 943 if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) { 944 *out_val = NULL; 945 return 0; 946 } 947 return av_dict_get_string(*(AVDictionary **)dst, (char **)out_val, '=', ':'); 948 default: 949 return AVERROR(EINVAL); 950 } 951 952 if (ret >= sizeof(buf)) 953 return AVERROR(EINVAL); 954 *out_val = av_strdup(buf); 955 return *out_val ? 0 : AVERROR(ENOMEM); 956} 957 958static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum, 959 int search_flags) 960{ 961 void *dst, *target_obj; 962 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 963 if (!o || !target_obj) 964 goto error; 965 966 dst = ((uint8_t *)target_obj) + o->offset; 967 968 if (o_out) *o_out= o; 969 970 return read_number(o, dst, num, den, intnum); 971 972error: 973 *den = 974 *intnum = 0; 975 return -1; 976} 977 978int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val) 979{ 980 int64_t intnum = 1; 981 double num = 1; 982 int ret, den = 1; 983 984 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) 985 return ret; 986 if (num == den) 987 *out_val = intnum; 988 else 989 *out_val = num * intnum / den; 990 return 0; 991} 992 993int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val) 994{ 995 int64_t intnum = 1; 996 double num = 1; 997 int ret, den = 1; 998 999 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) 1000 return ret; 1001 *out_val = num * intnum / den; 1002 return 0; 1003} 1004 1005int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val) 1006{ 1007 int64_t intnum = 1; 1008 double num = 1; 1009 int ret, den = 1; 1010 1011 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) 1012 return ret; 1013 1014 if (num == 1.0 && (int)intnum == intnum) 1015 *out_val = (AVRational){intnum, den}; 1016 else 1017 *out_val = av_d2q(num*intnum/den, 1<<24); 1018 return 0; 1019} 1020 1021int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out) 1022{ 1023 void *dst, *target_obj; 1024 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1025 if (!o || !target_obj) 1026 return AVERROR_OPTION_NOT_FOUND; 1027 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) { 1028 av_log(obj, AV_LOG_ERROR, 1029 "The value for option '%s' is not an image size.\n", name); 1030 return AVERROR(EINVAL); 1031 } 1032 1033 dst = ((uint8_t*)target_obj) + o->offset; 1034 if (w_out) *w_out = *(int *)dst; 1035 if (h_out) *h_out = *((int *)dst+1); 1036 return 0; 1037} 1038 1039int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val) 1040{ 1041 int64_t intnum = 1; 1042 double num = 1; 1043 int ret, den = 1; 1044 1045 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) 1046 return ret; 1047 1048 if (num == 1.0 && (int)intnum == intnum) 1049 *out_val = (AVRational) { intnum, den }; 1050 else 1051 *out_val = av_d2q(num * intnum / den, 1 << 24); 1052 return 0; 1053} 1054 1055static int get_format(void *obj, const char *name, int search_flags, int *out_fmt, 1056 enum AVOptionType type, const char *desc) 1057{ 1058 void *dst, *target_obj; 1059 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1060 if (!o || !target_obj) 1061 return AVERROR_OPTION_NOT_FOUND; 1062 if (o->type != type) { 1063 av_log(obj, AV_LOG_ERROR, 1064 "The value for option '%s' is not a %s format.\n", desc, name); 1065 return AVERROR(EINVAL); 1066 } 1067 1068 dst = ((uint8_t*)target_obj) + o->offset; 1069 *out_fmt = *(int *)dst; 1070 return 0; 1071} 1072 1073int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt) 1074{ 1075 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel"); 1076} 1077 1078int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt) 1079{ 1080 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample"); 1081} 1082 1083#if FF_API_OLD_CHANNEL_LAYOUT 1084FF_DISABLE_DEPRECATION_WARNINGS 1085int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl) 1086{ 1087 void *dst, *target_obj; 1088 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1089 if (!o || !target_obj) 1090 return AVERROR_OPTION_NOT_FOUND; 1091 if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { 1092 av_log(obj, AV_LOG_ERROR, 1093 "The value for option '%s' is not a channel layout.\n", name); 1094 return AVERROR(EINVAL); 1095 } 1096 1097 dst = ((uint8_t*)target_obj) + o->offset; 1098 *cl = *(int64_t *)dst; 1099 return 0; 1100} 1101FF_ENABLE_DEPRECATION_WARNINGS 1102#endif 1103 1104int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *cl) 1105{ 1106 void *dst, *target_obj; 1107 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1108 if (!o || !target_obj) 1109 return AVERROR_OPTION_NOT_FOUND; 1110 if (o->type != AV_OPT_TYPE_CHLAYOUT) { 1111 av_log(obj, AV_LOG_ERROR, 1112 "The value for option '%s' is not a channel layout.\n", name); 1113 return AVERROR(EINVAL); 1114 } 1115 1116 dst = ((uint8_t*)target_obj) + o->offset; 1117 return av_channel_layout_copy(cl, dst); 1118} 1119 1120int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val) 1121{ 1122 void *target_obj; 1123 AVDictionary *src; 1124 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); 1125 1126 if (!o || !target_obj) 1127 return AVERROR_OPTION_NOT_FOUND; 1128 if (o->type != AV_OPT_TYPE_DICT) 1129 return AVERROR(EINVAL); 1130 1131 src = *(AVDictionary **)(((uint8_t *)target_obj) + o->offset); 1132 av_dict_copy(out_val, src, 0); 1133 1134 return 0; 1135} 1136 1137int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) 1138{ 1139 const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); 1140 const AVOption *flag = av_opt_find(obj, flag_name, 1141 field ? field->unit : NULL, 0, 0); 1142 int64_t res; 1143 1144 if (!field || !flag || flag->type != AV_OPT_TYPE_CONST || 1145 av_opt_get_int(obj, field_name, 0, &res) < 0) 1146 return 0; 1147 return res & flag->default_val.i64; 1148} 1149 1150static void log_int_value(void *av_log_obj, int level, int64_t i) 1151{ 1152 if (i == INT_MAX) { 1153 av_log(av_log_obj, level, "INT_MAX"); 1154 } else if (i == INT_MIN) { 1155 av_log(av_log_obj, level, "INT_MIN"); 1156 } else if (i == UINT32_MAX) { 1157 av_log(av_log_obj, level, "UINT32_MAX"); 1158 } else if (i == INT64_MAX) { 1159 av_log(av_log_obj, level, "I64_MAX"); 1160 } else if (i == INT64_MIN) { 1161 av_log(av_log_obj, level, "I64_MIN"); 1162 } else { 1163 av_log(av_log_obj, level, "%"PRId64, i); 1164 } 1165} 1166 1167static void log_value(void *av_log_obj, int level, double d) 1168{ 1169 if (d == INT_MAX) { 1170 av_log(av_log_obj, level, "INT_MAX"); 1171 } else if (d == INT_MIN) { 1172 av_log(av_log_obj, level, "INT_MIN"); 1173 } else if (d == UINT32_MAX) { 1174 av_log(av_log_obj, level, "UINT32_MAX"); 1175 } else if (d == (double)INT64_MAX) { 1176 av_log(av_log_obj, level, "I64_MAX"); 1177 } else if (d == INT64_MIN) { 1178 av_log(av_log_obj, level, "I64_MIN"); 1179 } else if (d == FLT_MAX) { 1180 av_log(av_log_obj, level, "FLT_MAX"); 1181 } else if (d == FLT_MIN) { 1182 av_log(av_log_obj, level, "FLT_MIN"); 1183 } else if (d == -FLT_MAX) { 1184 av_log(av_log_obj, level, "-FLT_MAX"); 1185 } else if (d == -FLT_MIN) { 1186 av_log(av_log_obj, level, "-FLT_MIN"); 1187 } else if (d == DBL_MAX) { 1188 av_log(av_log_obj, level, "DBL_MAX"); 1189 } else if (d == DBL_MIN) { 1190 av_log(av_log_obj, level, "DBL_MIN"); 1191 } else if (d == -DBL_MAX) { 1192 av_log(av_log_obj, level, "-DBL_MAX"); 1193 } else if (d == -DBL_MIN) { 1194 av_log(av_log_obj, level, "-DBL_MIN"); 1195 } else { 1196 av_log(av_log_obj, level, "%g", d); 1197 } 1198} 1199 1200static const char *get_opt_const_name(void *obj, const char *unit, int64_t value) 1201{ 1202 const AVOption *opt = NULL; 1203 1204 if (!unit) 1205 return NULL; 1206 while ((opt = av_opt_next(obj, opt))) 1207 if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) && 1208 opt->default_val.i64 == value) 1209 return opt->name; 1210 return NULL; 1211} 1212 1213static char *get_opt_flags_string(void *obj, const char *unit, int64_t value) 1214{ 1215 const AVOption *opt = NULL; 1216 char flags[512]; 1217 1218 flags[0] = 0; 1219 if (!unit) 1220 return NULL; 1221 while ((opt = av_opt_next(obj, opt))) { 1222 if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) && 1223 opt->default_val.i64 & value) { 1224 if (flags[0]) 1225 av_strlcatf(flags, sizeof(flags), "+"); 1226 av_strlcatf(flags, sizeof(flags), "%s", opt->name); 1227 } 1228 } 1229 if (flags[0]) 1230 return av_strdup(flags); 1231 return NULL; 1232} 1233 1234static void opt_list(void *obj, void *av_log_obj, const char *unit, 1235 int req_flags, int rej_flags, enum AVOptionType parent_type) 1236{ 1237 const AVOption *opt = NULL; 1238 AVOptionRanges *r; 1239 int i; 1240 1241 while ((opt = av_opt_next(obj, opt))) { 1242 if (!(opt->flags & req_flags) || (opt->flags & rej_flags)) 1243 continue; 1244 1245 /* Don't print CONST's on level one. 1246 * Don't print anything but CONST's on level two. 1247 * Only print items from the requested unit. 1248 */ 1249 if (!unit && opt->type == AV_OPT_TYPE_CONST) 1250 continue; 1251 else if (unit && opt->type != AV_OPT_TYPE_CONST) 1252 continue; 1253 else if (unit && opt->type == AV_OPT_TYPE_CONST && strcmp(unit, opt->unit)) 1254 continue; 1255 else if (unit && opt->type == AV_OPT_TYPE_CONST) 1256 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); 1257 else 1258 av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ", 1259 (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? " " : "-", 1260 opt->name); 1261 1262 switch (opt->type) { 1263 case AV_OPT_TYPE_FLAGS: 1264 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>"); 1265 break; 1266 case AV_OPT_TYPE_INT: 1267 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>"); 1268 break; 1269 case AV_OPT_TYPE_INT64: 1270 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>"); 1271 break; 1272 case AV_OPT_TYPE_UINT64: 1273 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<uint64>"); 1274 break; 1275 case AV_OPT_TYPE_DOUBLE: 1276 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>"); 1277 break; 1278 case AV_OPT_TYPE_FLOAT: 1279 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>"); 1280 break; 1281 case AV_OPT_TYPE_STRING: 1282 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>"); 1283 break; 1284 case AV_OPT_TYPE_RATIONAL: 1285 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>"); 1286 break; 1287 case AV_OPT_TYPE_BINARY: 1288 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>"); 1289 break; 1290 case AV_OPT_TYPE_DICT: 1291 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<dictionary>"); 1292 break; 1293 case AV_OPT_TYPE_IMAGE_SIZE: 1294 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>"); 1295 break; 1296 case AV_OPT_TYPE_VIDEO_RATE: 1297 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>"); 1298 break; 1299 case AV_OPT_TYPE_PIXEL_FMT: 1300 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>"); 1301 break; 1302 case AV_OPT_TYPE_SAMPLE_FMT: 1303 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>"); 1304 break; 1305 case AV_OPT_TYPE_DURATION: 1306 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>"); 1307 break; 1308 case AV_OPT_TYPE_COLOR: 1309 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>"); 1310 break; 1311 case AV_OPT_TYPE_CHLAYOUT: 1312#if FF_API_OLD_CHANNEL_LAYOUT 1313FF_DISABLE_DEPRECATION_WARNINGS 1314 case AV_OPT_TYPE_CHANNEL_LAYOUT: 1315FF_ENABLE_DEPRECATION_WARNINGS 1316#endif 1317 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>"); 1318 break; 1319 case AV_OPT_TYPE_BOOL: 1320 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<boolean>"); 1321 break; 1322 case AV_OPT_TYPE_CONST: 1323 if (parent_type == AV_OPT_TYPE_INT) 1324 av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", opt->default_val.i64); 1325 else 1326 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); 1327 break; 1328 default: 1329 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); 1330 break; 1331 } 1332 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.'); 1333 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.'); 1334 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.'); 1335 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); 1336 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); 1337 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); 1338 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.'); 1339 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.'); 1340 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.'); 1341 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_RUNTIME_PARAM) ? 'T' : '.'); 1342 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DEPRECATED) ? 'P' : '.'); 1343 1344 if (opt->help) 1345 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); 1346 1347 if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) { 1348 switch (opt->type) { 1349 case AV_OPT_TYPE_INT: 1350 case AV_OPT_TYPE_INT64: 1351 case AV_OPT_TYPE_UINT64: 1352 case AV_OPT_TYPE_DOUBLE: 1353 case AV_OPT_TYPE_FLOAT: 1354 case AV_OPT_TYPE_RATIONAL: 1355 for (i = 0; i < r->nb_ranges; i++) { 1356 av_log(av_log_obj, AV_LOG_INFO, " (from "); 1357 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min); 1358 av_log(av_log_obj, AV_LOG_INFO, " to "); 1359 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max); 1360 av_log(av_log_obj, AV_LOG_INFO, ")"); 1361 } 1362 break; 1363 } 1364 av_opt_freep_ranges(&r); 1365 } 1366 1367 if (opt->type != AV_OPT_TYPE_CONST && 1368 opt->type != AV_OPT_TYPE_BINARY && 1369 !((opt->type == AV_OPT_TYPE_COLOR || 1370 opt->type == AV_OPT_TYPE_IMAGE_SIZE || 1371 opt->type == AV_OPT_TYPE_STRING || 1372 opt->type == AV_OPT_TYPE_DICT || 1373 opt->type == AV_OPT_TYPE_CHLAYOUT || 1374 opt->type == AV_OPT_TYPE_VIDEO_RATE) && 1375 !opt->default_val.str)) { 1376 av_log(av_log_obj, AV_LOG_INFO, " (default "); 1377 switch (opt->type) { 1378 case AV_OPT_TYPE_BOOL: 1379 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(get_bool_name(opt->default_val.i64), "invalid")); 1380 break; 1381 case AV_OPT_TYPE_FLAGS: { 1382 char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64); 1383 if (def_flags) { 1384 av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags); 1385 av_freep(&def_flags); 1386 } else { 1387 av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64); 1388 } 1389 break; 1390 } 1391 case AV_OPT_TYPE_DURATION: { 1392 char buf[25]; 1393 format_duration(buf, sizeof(buf), opt->default_val.i64); 1394 av_log(av_log_obj, AV_LOG_INFO, "%s", buf); 1395 break; 1396 } 1397 case AV_OPT_TYPE_INT: 1398 case AV_OPT_TYPE_UINT64: 1399 case AV_OPT_TYPE_INT64: { 1400 const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64); 1401 if (def_const) 1402 av_log(av_log_obj, AV_LOG_INFO, "%s", def_const); 1403 else 1404 log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64); 1405 break; 1406 } 1407 case AV_OPT_TYPE_DOUBLE: 1408 case AV_OPT_TYPE_FLOAT: 1409 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl); 1410 break; 1411 case AV_OPT_TYPE_RATIONAL: { 1412 AVRational q = av_d2q(opt->default_val.dbl, INT_MAX); 1413 av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); } 1414 break; 1415 case AV_OPT_TYPE_PIXEL_FMT: 1416 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none")); 1417 break; 1418 case AV_OPT_TYPE_SAMPLE_FMT: 1419 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none")); 1420 break; 1421 case AV_OPT_TYPE_COLOR: 1422 case AV_OPT_TYPE_IMAGE_SIZE: 1423 case AV_OPT_TYPE_STRING: 1424 case AV_OPT_TYPE_DICT: 1425 case AV_OPT_TYPE_VIDEO_RATE: 1426 case AV_OPT_TYPE_CHLAYOUT: 1427 av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str); 1428 break; 1429#if FF_API_OLD_CHANNEL_LAYOUT 1430FF_DISABLE_DEPRECATION_WARNINGS 1431 case AV_OPT_TYPE_CHANNEL_LAYOUT: 1432 av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64); 1433 break; 1434FF_ENABLE_DEPRECATION_WARNINGS 1435#endif 1436 } 1437 av_log(av_log_obj, AV_LOG_INFO, ")"); 1438 } 1439 1440 av_log(av_log_obj, AV_LOG_INFO, "\n"); 1441 if (opt->unit && opt->type != AV_OPT_TYPE_CONST) 1442 opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags, opt->type); 1443 } 1444} 1445 1446int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags) 1447{ 1448 if (!obj) 1449 return -1; 1450 1451 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name); 1452 1453 opt_list(obj, av_log_obj, NULL, req_flags, rej_flags, -1); 1454 1455 return 0; 1456} 1457 1458void av_opt_set_defaults(void *s) 1459{ 1460 av_opt_set_defaults2(s, 0, 0); 1461} 1462 1463void av_opt_set_defaults2(void *s, int mask, int flags) 1464{ 1465 const AVOption *opt = NULL; 1466 while ((opt = av_opt_next(s, opt))) { 1467 void *dst = ((uint8_t*)s) + opt->offset; 1468 1469 if ((opt->flags & mask) != flags) 1470 continue; 1471 1472 if (opt->flags & AV_OPT_FLAG_READONLY) 1473 continue; 1474 1475 switch (opt->type) { 1476 case AV_OPT_TYPE_CONST: 1477 /* Nothing to be done here */ 1478 break; 1479 case AV_OPT_TYPE_BOOL: 1480 case AV_OPT_TYPE_FLAGS: 1481 case AV_OPT_TYPE_INT: 1482 case AV_OPT_TYPE_INT64: 1483 case AV_OPT_TYPE_UINT64: 1484 case AV_OPT_TYPE_DURATION: 1485#if FF_API_OLD_CHANNEL_LAYOUT 1486FF_DISABLE_DEPRECATION_WARNINGS 1487 case AV_OPT_TYPE_CHANNEL_LAYOUT: 1488FF_ENABLE_DEPRECATION_WARNINGS 1489#endif 1490 case AV_OPT_TYPE_PIXEL_FMT: 1491 case AV_OPT_TYPE_SAMPLE_FMT: 1492 write_number(s, opt, dst, 1, 1, opt->default_val.i64); 1493 break; 1494 case AV_OPT_TYPE_DOUBLE: 1495 case AV_OPT_TYPE_FLOAT: { 1496 double val; 1497 val = opt->default_val.dbl; 1498 write_number(s, opt, dst, val, 1, 1); 1499 } 1500 break; 1501 case AV_OPT_TYPE_RATIONAL: { 1502 AVRational val; 1503 val = av_d2q(opt->default_val.dbl, INT_MAX); 1504 write_number(s, opt, dst, 1, val.den, val.num); 1505 } 1506 break; 1507 case AV_OPT_TYPE_COLOR: 1508 set_string_color(s, opt, opt->default_val.str, dst); 1509 break; 1510 case AV_OPT_TYPE_STRING: 1511 set_string(s, opt, opt->default_val.str, dst); 1512 break; 1513 case AV_OPT_TYPE_IMAGE_SIZE: 1514 set_string_image_size(s, opt, opt->default_val.str, dst); 1515 break; 1516 case AV_OPT_TYPE_VIDEO_RATE: 1517 set_string_video_rate(s, opt, opt->default_val.str, dst); 1518 break; 1519 case AV_OPT_TYPE_BINARY: 1520 set_string_binary(s, opt, opt->default_val.str, dst); 1521 break; 1522 case AV_OPT_TYPE_CHLAYOUT: 1523 set_string_channel_layout(s, opt, opt->default_val.str, dst); 1524 break; 1525 case AV_OPT_TYPE_DICT: 1526 set_string_dict(s, opt, opt->default_val.str, dst); 1527 break; 1528 default: 1529 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", 1530 opt->type, opt->name); 1531 } 1532 } 1533} 1534 1535/** 1536 * Store the value in the field in ctx that is named like key. 1537 * ctx must be an AVClass context, storing is done using AVOptions. 1538 * 1539 * @param buf the string to parse, buf will be updated to point at the 1540 * separator just after the parsed key/value pair 1541 * @param key_val_sep a 0-terminated list of characters used to 1542 * separate key from value 1543 * @param pairs_sep a 0-terminated list of characters used to separate 1544 * two pairs from each other 1545 * @return 0 if the key/value pair has been successfully parsed and 1546 * set, or a negative value corresponding to an AVERROR code in case 1547 * of error: 1548 * AVERROR(EINVAL) if the key/value pair cannot be parsed, 1549 * the error code issued by av_opt_set() if the key/value pair 1550 * cannot be set 1551 */ 1552static int parse_key_value_pair(void *ctx, const char **buf, 1553 const char *key_val_sep, const char *pairs_sep) 1554{ 1555 char *key = av_get_token(buf, key_val_sep); 1556 char *val; 1557 int ret; 1558 1559 if (!key) 1560 return AVERROR(ENOMEM); 1561 1562 if (*key && strspn(*buf, key_val_sep)) { 1563 (*buf)++; 1564 val = av_get_token(buf, pairs_sep); 1565 if (!val) { 1566 av_freep(&key); 1567 return AVERROR(ENOMEM); 1568 } 1569 } else { 1570 av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); 1571 av_free(key); 1572 return AVERROR(EINVAL); 1573 } 1574 1575 av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val); 1576 1577 ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN); 1578 if (ret == AVERROR_OPTION_NOT_FOUND) 1579 av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); 1580 1581 av_free(key); 1582 av_free(val); 1583 return ret; 1584} 1585 1586int av_set_options_string(void *ctx, const char *opts, 1587 const char *key_val_sep, const char *pairs_sep) 1588{ 1589 int ret, count = 0; 1590 1591 if (!opts) 1592 return 0; 1593 1594 while (*opts) { 1595 if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) 1596 return ret; 1597 count++; 1598 1599 if (*opts) 1600 opts++; 1601 } 1602 1603 return count; 1604} 1605 1606#define WHITESPACES " \n\t\r" 1607 1608static int is_key_char(char c) 1609{ 1610 return (unsigned)((c | 32) - 'a') < 26 || 1611 (unsigned)(c - '0') < 10 || 1612 c == '-' || c == '_' || c == '/' || c == '.'; 1613} 1614 1615/** 1616 * Read a key from a string. 1617 * 1618 * The key consists of is_key_char characters and must be terminated by a 1619 * character from the delim string; spaces are ignored. 1620 * 1621 * @return 0 for success (even with ellipsis), <0 for failure 1622 */ 1623static int get_key(const char **ropts, const char *delim, char **rkey) 1624{ 1625 const char *opts = *ropts; 1626 const char *key_start, *key_end; 1627 1628 key_start = opts += strspn(opts, WHITESPACES); 1629 while (is_key_char(*opts)) 1630 opts++; 1631 key_end = opts; 1632 opts += strspn(opts, WHITESPACES); 1633 if (!*opts || !strchr(delim, *opts)) 1634 return AVERROR(EINVAL); 1635 opts++; 1636 if (!(*rkey = av_malloc(key_end - key_start + 1))) 1637 return AVERROR(ENOMEM); 1638 memcpy(*rkey, key_start, key_end - key_start); 1639 (*rkey)[key_end - key_start] = 0; 1640 *ropts = opts; 1641 return 0; 1642} 1643 1644int av_opt_get_key_value(const char **ropts, 1645 const char *key_val_sep, const char *pairs_sep, 1646 unsigned flags, 1647 char **rkey, char **rval) 1648{ 1649 int ret; 1650 char *key = NULL, *val; 1651 const char *opts = *ropts; 1652 1653 if ((ret = get_key(&opts, key_val_sep, &key)) < 0 && 1654 !(flags & AV_OPT_FLAG_IMPLICIT_KEY)) 1655 return AVERROR(EINVAL); 1656 if (!(val = av_get_token(&opts, pairs_sep))) { 1657 av_free(key); 1658 return AVERROR(ENOMEM); 1659 } 1660 *ropts = opts; 1661 *rkey = key; 1662 *rval = val; 1663 return 0; 1664} 1665 1666int av_opt_set_from_string(void *ctx, const char *opts, 1667 const char *const *shorthand, 1668 const char *key_val_sep, const char *pairs_sep) 1669{ 1670 int ret, count = 0; 1671 const char *dummy_shorthand = NULL; 1672 char *av_uninit(parsed_key), *av_uninit(value); 1673 const char *key; 1674 1675 if (!opts) 1676 return 0; 1677 if (!shorthand) 1678 shorthand = &dummy_shorthand; 1679 1680 while (*opts) { 1681 ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep, 1682 *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0, 1683 &parsed_key, &value); 1684 if (ret < 0) { 1685 if (ret == AVERROR(EINVAL)) 1686 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts); 1687 else 1688 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts, 1689 av_err2str(ret)); 1690 return ret; 1691 } 1692 if (*opts) 1693 opts++; 1694 if (parsed_key) { 1695 key = parsed_key; 1696 while (*shorthand) /* discard all remaining shorthand */ 1697 shorthand++; 1698 } else { 1699 key = *(shorthand++); 1700 } 1701 1702 av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value); 1703 if ((ret = av_opt_set(ctx, key, value, 0)) < 0) { 1704 if (ret == AVERROR_OPTION_NOT_FOUND) 1705 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); 1706 av_free(value); 1707 av_free(parsed_key); 1708 return ret; 1709 } 1710 1711 av_free(value); 1712 av_free(parsed_key); 1713 count++; 1714 } 1715 return count; 1716} 1717 1718void av_opt_free(void *obj) 1719{ 1720 const AVOption *o = NULL; 1721 while ((o = av_opt_next(obj, o))) { 1722 switch (o->type) { 1723 case AV_OPT_TYPE_STRING: 1724 case AV_OPT_TYPE_BINARY: 1725 av_freep((uint8_t *)obj + o->offset); 1726 break; 1727 1728 case AV_OPT_TYPE_DICT: 1729 av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset)); 1730 break; 1731 1732 case AV_OPT_TYPE_CHLAYOUT: 1733 av_channel_layout_uninit((AVChannelLayout *)(((uint8_t *)obj) + o->offset)); 1734 break; 1735 1736 default: 1737 break; 1738 } 1739 } 1740} 1741 1742int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags) 1743{ 1744 AVDictionaryEntry *t = NULL; 1745 AVDictionary *tmp = NULL; 1746 int ret; 1747 1748 if (!options) 1749 return 0; 1750 1751 while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) { 1752 ret = av_opt_set(obj, t->key, t->value, search_flags); 1753 if (ret == AVERROR_OPTION_NOT_FOUND) 1754 ret = av_dict_set(&tmp, t->key, t->value, 0); 1755 if (ret < 0) { 1756 av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value); 1757 av_dict_free(&tmp); 1758 return ret; 1759 } 1760 } 1761 av_dict_free(options); 1762 *options = tmp; 1763 return 0; 1764} 1765 1766int av_opt_set_dict(void *obj, AVDictionary **options) 1767{ 1768 return av_opt_set_dict2(obj, options, 0); 1769} 1770 1771const AVOption *av_opt_find(void *obj, const char *name, const char *unit, 1772 int opt_flags, int search_flags) 1773{ 1774 return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL); 1775} 1776 1777const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, 1778 int opt_flags, int search_flags, void **target_obj) 1779{ 1780 const AVClass *c; 1781 const AVOption *o = NULL; 1782 1783 if(!obj) 1784 return NULL; 1785 1786 c= *(AVClass**)obj; 1787 1788 if (!c) 1789 return NULL; 1790 1791 if (search_flags & AV_OPT_SEARCH_CHILDREN) { 1792 if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { 1793 void *iter = NULL; 1794 const AVClass *child; 1795 while (child = av_opt_child_class_iterate(c, &iter)) 1796 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) 1797 return o; 1798 } else { 1799 void *child = NULL; 1800 while (child = av_opt_child_next(obj, child)) 1801 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj)) 1802 return o; 1803 } 1804 } 1805 1806 while (o = av_opt_next(obj, o)) { 1807 if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags && 1808 ((!unit && o->type != AV_OPT_TYPE_CONST) || 1809 (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) { 1810 if (target_obj) { 1811 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ)) 1812 *target_obj = obj; 1813 else 1814 *target_obj = NULL; 1815 } 1816 return o; 1817 } 1818 } 1819 return NULL; 1820} 1821 1822void *av_opt_child_next(void *obj, void *prev) 1823{ 1824 const AVClass *c = *(AVClass **)obj; 1825 if (c->child_next) 1826 return c->child_next(obj, prev); 1827 return NULL; 1828} 1829 1830const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter) 1831{ 1832 if (parent->child_class_iterate) 1833 return parent->child_class_iterate(iter); 1834 return NULL; 1835} 1836 1837void *av_opt_ptr(const AVClass *class, void *obj, const char *name) 1838{ 1839 const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL); 1840 if(!opt) 1841 return NULL; 1842 return (uint8_t*)obj + opt->offset; 1843} 1844 1845static int opt_size(enum AVOptionType type) 1846{ 1847 switch(type) { 1848 case AV_OPT_TYPE_BOOL: 1849 case AV_OPT_TYPE_INT: 1850 case AV_OPT_TYPE_FLAGS: 1851 return sizeof(int); 1852 case AV_OPT_TYPE_DURATION: 1853#if FF_API_OLD_CHANNEL_LAYOUT 1854FF_DISABLE_DEPRECATION_WARNINGS 1855 case AV_OPT_TYPE_CHANNEL_LAYOUT: 1856FF_ENABLE_DEPRECATION_WARNINGS 1857#endif 1858 case AV_OPT_TYPE_INT64: 1859 case AV_OPT_TYPE_UINT64: 1860 return sizeof(int64_t); 1861 case AV_OPT_TYPE_DOUBLE: 1862 return sizeof(double); 1863 case AV_OPT_TYPE_FLOAT: 1864 return sizeof(float); 1865 case AV_OPT_TYPE_STRING: 1866 return sizeof(uint8_t*); 1867 case AV_OPT_TYPE_VIDEO_RATE: 1868 case AV_OPT_TYPE_RATIONAL: 1869 return sizeof(AVRational); 1870 case AV_OPT_TYPE_BINARY: 1871 return sizeof(uint8_t*) + sizeof(int); 1872 case AV_OPT_TYPE_IMAGE_SIZE: 1873 return sizeof(int[2]); 1874 case AV_OPT_TYPE_PIXEL_FMT: 1875 return sizeof(enum AVPixelFormat); 1876 case AV_OPT_TYPE_SAMPLE_FMT: 1877 return sizeof(enum AVSampleFormat); 1878 case AV_OPT_TYPE_COLOR: 1879 return 4; 1880 } 1881 return AVERROR(EINVAL); 1882} 1883 1884int av_opt_copy(void *dst, const void *src) 1885{ 1886 const AVOption *o = NULL; 1887 const AVClass *c; 1888 int ret = 0; 1889 1890 if (!src) 1891 return AVERROR(EINVAL); 1892 1893 c = *(AVClass **)src; 1894 if (!c || c != *(AVClass **)dst) 1895 return AVERROR(EINVAL); 1896 1897 while ((o = av_opt_next(src, o))) { 1898 void *field_dst = (uint8_t *)dst + o->offset; 1899 void *field_src = (uint8_t *)src + o->offset; 1900 uint8_t **field_dst8 = (uint8_t **)field_dst; 1901 uint8_t **field_src8 = (uint8_t **)field_src; 1902 1903 if (o->type == AV_OPT_TYPE_STRING) { 1904 if (*field_dst8 != *field_src8) 1905 av_freep(field_dst8); 1906 *field_dst8 = av_strdup(*field_src8); 1907 if (*field_src8 && !*field_dst8) 1908 ret = AVERROR(ENOMEM); 1909 } else if (o->type == AV_OPT_TYPE_BINARY) { 1910 int len = *(int *)(field_src8 + 1); 1911 if (*field_dst8 != *field_src8) 1912 av_freep(field_dst8); 1913 *field_dst8 = av_memdup(*field_src8, len); 1914 if (len && !*field_dst8) { 1915 ret = AVERROR(ENOMEM); 1916 len = 0; 1917 } 1918 *(int *)(field_dst8 + 1) = len; 1919 } else if (o->type == AV_OPT_TYPE_CONST) { 1920 // do nothing 1921 } else if (o->type == AV_OPT_TYPE_DICT) { 1922 AVDictionary **sdict = (AVDictionary **) field_src; 1923 AVDictionary **ddict = (AVDictionary **) field_dst; 1924 int ret2; 1925 if (*sdict != *ddict) 1926 av_dict_free(ddict); 1927 *ddict = NULL; 1928 ret2 = av_dict_copy(ddict, *sdict, 0); 1929 if (ret2 < 0) 1930 ret = ret2; 1931 } else if (o->type == AV_OPT_TYPE_CHLAYOUT) { 1932 if (field_dst != field_src) 1933 ret = av_channel_layout_copy(field_dst, field_src); 1934 } else { 1935 int size = opt_size(o->type); 1936 if (size < 0) 1937 ret = size; 1938 else 1939 memcpy(field_dst, field_src, size); 1940 } 1941 } 1942 return ret; 1943} 1944 1945int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) 1946{ 1947 int ret; 1948 const AVClass *c = *(AVClass**)obj; 1949 int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = c->query_ranges; 1950 1951 if (!callback) 1952 callback = av_opt_query_ranges_default; 1953 1954 ret = callback(ranges_arg, obj, key, flags); 1955 if (ret >= 0) { 1956 if (!(flags & AV_OPT_MULTI_COMPONENT_RANGE)) 1957 ret = 1; 1958 (*ranges_arg)->nb_components = ret; 1959 } 1960 return ret; 1961} 1962 1963int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) 1964{ 1965 AVOptionRanges *ranges = av_mallocz(sizeof(*ranges)); 1966 AVOptionRange **range_array = av_mallocz(sizeof(void*)); 1967 AVOptionRange *range = av_mallocz(sizeof(*range)); 1968 const AVOption *field = av_opt_find(obj, key, NULL, 0, flags); 1969 int ret; 1970 1971 *ranges_arg = NULL; 1972 1973 if (!ranges || !range || !range_array || !field) { 1974 ret = AVERROR(ENOMEM); 1975 goto fail; 1976 } 1977 1978 ranges->range = range_array; 1979 ranges->range[0] = range; 1980 ranges->nb_ranges = 1; 1981 ranges->nb_components = 1; 1982 range->is_range = 1; 1983 range->value_min = field->min; 1984 range->value_max = field->max; 1985 1986 switch (field->type) { 1987 case AV_OPT_TYPE_BOOL: 1988 case AV_OPT_TYPE_INT: 1989 case AV_OPT_TYPE_INT64: 1990 case AV_OPT_TYPE_UINT64: 1991 case AV_OPT_TYPE_PIXEL_FMT: 1992 case AV_OPT_TYPE_SAMPLE_FMT: 1993 case AV_OPT_TYPE_FLOAT: 1994 case AV_OPT_TYPE_DOUBLE: 1995 case AV_OPT_TYPE_DURATION: 1996 case AV_OPT_TYPE_COLOR: 1997#if FF_API_OLD_CHANNEL_LAYOUT 1998FF_DISABLE_DEPRECATION_WARNINGS 1999 case AV_OPT_TYPE_CHANNEL_LAYOUT: 2000FF_ENABLE_DEPRECATION_WARNINGS 2001#endif 2002 break; 2003 case AV_OPT_TYPE_STRING: 2004 range->component_min = 0; 2005 range->component_max = 0x10FFFF; // max unicode value 2006 range->value_min = -1; 2007 range->value_max = INT_MAX; 2008 break; 2009 case AV_OPT_TYPE_RATIONAL: 2010 range->component_min = INT_MIN; 2011 range->component_max = INT_MAX; 2012 break; 2013 case AV_OPT_TYPE_IMAGE_SIZE: 2014 range->component_min = 0; 2015 range->component_max = INT_MAX/128/8; 2016 range->value_min = 0; 2017 range->value_max = INT_MAX/8; 2018 break; 2019 case AV_OPT_TYPE_VIDEO_RATE: 2020 range->component_min = 1; 2021 range->component_max = INT_MAX; 2022 range->value_min = 1; 2023 range->value_max = INT_MAX; 2024 break; 2025 default: 2026 ret = AVERROR(ENOSYS); 2027 goto fail; 2028 } 2029 2030 *ranges_arg = ranges; 2031 return 1; 2032fail: 2033 av_free(ranges); 2034 av_free(range); 2035 av_free(range_array); 2036 return ret; 2037} 2038 2039void av_opt_freep_ranges(AVOptionRanges **rangesp) 2040{ 2041 int i; 2042 AVOptionRanges *ranges = *rangesp; 2043 2044 if (!ranges) 2045 return; 2046 2047 for (i = 0; i < ranges->nb_ranges * ranges->nb_components; i++) { 2048 AVOptionRange *range = ranges->range[i]; 2049 if (range) { 2050 av_freep(&range->str); 2051 av_freep(&ranges->range[i]); 2052 } 2053 } 2054 av_freep(&ranges->range); 2055 av_freep(rangesp); 2056} 2057 2058int av_opt_is_set_to_default(void *obj, const AVOption *o) 2059{ 2060 int64_t i64; 2061 double d, d2; 2062 float f; 2063 AVRational q; 2064 int ret, w, h; 2065 char *str; 2066 void *dst; 2067 2068 if (!o || !obj) 2069 return AVERROR(EINVAL); 2070 2071 dst = ((uint8_t*)obj) + o->offset; 2072 2073 switch (o->type) { 2074 case AV_OPT_TYPE_CONST: 2075 return 1; 2076 case AV_OPT_TYPE_BOOL: 2077 case AV_OPT_TYPE_FLAGS: 2078 case AV_OPT_TYPE_PIXEL_FMT: 2079 case AV_OPT_TYPE_SAMPLE_FMT: 2080 case AV_OPT_TYPE_INT: 2081#if FF_API_OLD_CHANNEL_LAYOUT 2082FF_DISABLE_DEPRECATION_WARNINGS 2083 case AV_OPT_TYPE_CHANNEL_LAYOUT: 2084FF_ENABLE_DEPRECATION_WARNINGS 2085#endif 2086 case AV_OPT_TYPE_DURATION: 2087 case AV_OPT_TYPE_INT64: 2088 case AV_OPT_TYPE_UINT64: 2089 read_number(o, dst, NULL, NULL, &i64); 2090 return o->default_val.i64 == i64; 2091 case AV_OPT_TYPE_CHLAYOUT: { 2092 AVChannelLayout ch_layout = { 0 }; 2093 if (o->default_val.str) { 2094 if ((ret = av_channel_layout_from_string(&ch_layout, o->default_val.str)) < 0) 2095 return ret; 2096 } 2097 return !av_channel_layout_compare((AVChannelLayout *)dst, &ch_layout); 2098 } 2099 case AV_OPT_TYPE_STRING: 2100 str = *(char **)dst; 2101 if (str == o->default_val.str) //2 NULLs 2102 return 1; 2103 if (!str || !o->default_val.str) //1 NULL 2104 return 0; 2105 return !strcmp(str, o->default_val.str); 2106 case AV_OPT_TYPE_DOUBLE: 2107 read_number(o, dst, &d, NULL, NULL); 2108 return o->default_val.dbl == d; 2109 case AV_OPT_TYPE_FLOAT: 2110 read_number(o, dst, &d, NULL, NULL); 2111 f = o->default_val.dbl; 2112 d2 = f; 2113 return d2 == d; 2114 case AV_OPT_TYPE_RATIONAL: 2115 q = av_d2q(o->default_val.dbl, INT_MAX); 2116 return !av_cmp_q(*(AVRational*)dst, q); 2117 case AV_OPT_TYPE_BINARY: { 2118 struct { 2119 uint8_t *data; 2120 int size; 2121 } tmp = {0}; 2122 int opt_size = *(int *)((void **)dst + 1); 2123 void *opt_ptr = *(void **)dst; 2124 if (!opt_size && (!o->default_val.str || !strlen(o->default_val.str))) 2125 return 1; 2126 if (!opt_size || !o->default_val.str || !strlen(o->default_val.str )) 2127 return 0; 2128 if (opt_size != strlen(o->default_val.str) / 2) 2129 return 0; 2130 ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data); 2131 if (!ret) 2132 ret = !memcmp(opt_ptr, tmp.data, tmp.size); 2133 av_free(tmp.data); 2134 return ret; 2135 } 2136 case AV_OPT_TYPE_DICT: { 2137 AVDictionary *dict1 = NULL; 2138 AVDictionary *dict2 = *(AVDictionary **)dst; 2139 AVDictionaryEntry *en1 = NULL; 2140 AVDictionaryEntry *en2 = NULL; 2141 ret = av_dict_parse_string(&dict1, o->default_val.str, "=", ":", 0); 2142 if (ret < 0) { 2143 av_dict_free(&dict1); 2144 return ret; 2145 } 2146 do { 2147 en1 = av_dict_get(dict1, "", en1, AV_DICT_IGNORE_SUFFIX); 2148 en2 = av_dict_get(dict2, "", en2, AV_DICT_IGNORE_SUFFIX); 2149 } while (en1 && en2 && !strcmp(en1->key, en2->key) && !strcmp(en1->value, en2->value)); 2150 av_dict_free(&dict1); 2151 return (!en1 && !en2); 2152 } 2153 case AV_OPT_TYPE_IMAGE_SIZE: 2154 if (!o->default_val.str || !strcmp(o->default_val.str, "none")) 2155 w = h = 0; 2156 else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0) 2157 return ret; 2158 return (w == *(int *)dst) && (h == *((int *)dst+1)); 2159 case AV_OPT_TYPE_VIDEO_RATE: 2160 q = (AVRational){0, 0}; 2161 if (o->default_val.str) { 2162 if ((ret = av_parse_video_rate(&q, o->default_val.str)) < 0) 2163 return ret; 2164 } 2165 return !av_cmp_q(*(AVRational*)dst, q); 2166 case AV_OPT_TYPE_COLOR: { 2167 uint8_t color[4] = {0, 0, 0, 0}; 2168 if (o->default_val.str) { 2169 if ((ret = av_parse_color(color, o->default_val.str, -1, NULL)) < 0) 2170 return ret; 2171 } 2172 return !memcmp(color, dst, sizeof(color)); 2173 } 2174 default: 2175 av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name); 2176 break; 2177 } 2178 return AVERROR_PATCHWELCOME; 2179} 2180 2181int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags) 2182{ 2183 const AVOption *o; 2184 void *target; 2185 if (!obj) 2186 return AVERROR(EINVAL); 2187 o = av_opt_find2(obj, name, NULL, 0, search_flags, &target); 2188 if (!o) 2189 return AVERROR_OPTION_NOT_FOUND; 2190 return av_opt_is_set_to_default(target, o); 2191} 2192 2193int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, 2194 const char key_val_sep, const char pairs_sep) 2195{ 2196 const AVOption *o = NULL; 2197 uint8_t *buf; 2198 AVBPrint bprint; 2199 int ret, cnt = 0; 2200 const char special_chars[] = {pairs_sep, key_val_sep, '\0'}; 2201 2202 if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep || 2203 pairs_sep == '\\' || key_val_sep == '\\') { 2204 av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found."); 2205 return AVERROR(EINVAL); 2206 } 2207 2208 if (!obj || !buffer) 2209 return AVERROR(EINVAL); 2210 2211 *buffer = NULL; 2212 av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); 2213 2214 while (o = av_opt_next(obj, o)) { 2215 if (o->type == AV_OPT_TYPE_CONST) 2216 continue; 2217 if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags) 2218 continue; 2219 else if (((o->flags & opt_flags) != opt_flags)) 2220 continue; 2221 if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0) 2222 continue; 2223 if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) { 2224 av_bprint_finalize(&bprint, NULL); 2225 return ret; 2226 } 2227 if (buf) { 2228 if (cnt++) 2229 av_bprint_append_data(&bprint, &pairs_sep, 1); 2230 av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); 2231 av_bprint_append_data(&bprint, &key_val_sep, 1); 2232 av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); 2233 av_freep(&buf); 2234 } 2235 } 2236 ret = av_bprint_finalize(&bprint, buffer); 2237 if (ret < 0) 2238 return ret; 2239 return 0; 2240} 2241