| 499 | } |
| 500 | |
| 501 | int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used, |
| 502 | void *logctx, int decode) |
| 503 | { |
| 504 | const AVClass *class = avcodec_get_class(); |
| 505 | const AVClass *fclass = avformat_get_class(); |
| 506 | |
| 507 | const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM : |
| 508 | AV_OPT_FLAG_ENCODING_PARAM; |
| 509 | const AVDictionaryEntry *e = NULL; |
| 510 | |
| 511 | while ((e = av_dict_iterate(opts, e))) { |
| 512 | const AVOption *option, *foption; |
| 513 | char *optname, *p; |
| 514 | |
| 515 | if (av_dict_get(opts_used, e->key, NULL, 0)) |
| 516 | continue; |
| 517 | |
| 518 | optname = av_strdup(e->key); |
| 519 | if (!optname) |
| 520 | return AVERROR(ENOMEM); |
| 521 | |
| 522 | p = strchr(optname, ':'); |
| 523 | if (p) |
| 524 | *p = 0; |
| 525 | |
| 526 | option = av_opt_find(&class, optname, NULL, 0, |
| 527 | AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); |
| 528 | foption = av_opt_find(&fclass, optname, NULL, 0, |
| 529 | AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); |
| 530 | av_freep(&optname); |
| 531 | if (!option || foption) |
| 532 | continue; |
| 533 | |
| 534 | if (!(option->flags & flag)) { |
| 535 | av_log(logctx, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a %s " |
| 536 | "option.\n", e->key, option->help ? option->help : "", |
| 537 | decode ? "decoding" : "encoding"); |
| 538 | return AVERROR(EINVAL); |
| 539 | } |
| 540 | |
| 541 | av_log(logctx, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used " |
| 542 | "for any stream. The most likely reason is either wrong type " |
| 543 | "(e.g. a video option with no video streams) or that it is a " |
| 544 | "private option of some decoder which was not actually used " |
| 545 | "for any stream.\n", e->key, option->help ? option->help : ""); |
| 546 | } |
| 547 | |
| 548 | return 0; |
| 549 | } |
| 550 | |
| 551 | void update_benchmark(const char *fmt, ...) |
| 552 | { |
no test coverage detected