* Perform one round of query_formats() and merging formats lists on the * filter graph. * @return >=0 if all links formats lists could be queried and merged; * AVERROR(EAGAIN) some progress was made in the queries or merging * and a later call may succeed; * AVERROR(EIO) (may be changed) plus a log message if no progress * was made and the negotiation is
| 524 | * a negative error code if some other error happened |
| 525 | */ |
| 526 | static int query_formats(AVFilterGraph *graph, void *log_ctx) |
| 527 | { |
| 528 | int i, j, k, ret; |
| 529 | int converter_count = 0; |
| 530 | int count_queried = 0; /* successful calls to query_formats() */ |
| 531 | int count_merged = 0; /* successful merge of formats lists */ |
| 532 | int count_already_merged = 0; /* lists already merged */ |
| 533 | int count_delayed = 0; /* lists that need to be merged later */ |
| 534 | |
| 535 | for (i = 0; i < graph->nb_filters; i++) { |
| 536 | AVFilterContext *f = graph->filters[i]; |
| 537 | if (formats_declared(f)) |
| 538 | continue; |
| 539 | ret = filter_query_formats(f); |
| 540 | if (ret < 0 && ret != AVERROR(EAGAIN)) |
| 541 | return ret; |
| 542 | /* note: EAGAIN could indicate a partial success, not counted yet */ |
| 543 | if (ret >= 0) { |
| 544 | print_filter_formats(log_ctx, AV_LOG_DEBUG, f); |
| 545 | count_queried++; |
| 546 | } |
| 547 | } |
| 548 | |
| 549 | /* go through and merge as many format lists as possible */ |
| 550 | retry: |
| 551 | for (i = 0; i < graph->nb_filters; i++) { |
| 552 | AVFilterContext *filter = graph->filters[i]; |
| 553 | |
| 554 | for (j = 0; j < filter->nb_inputs; j++) { |
| 555 | AVFilterLink *link = filter->inputs[j]; |
| 556 | const AVFilterNegotiation *neg; |
| 557 | AVFilterContext *conv[4]; |
| 558 | const AVFilterFormatsMerger *mergers[4]; /* triggered mergers */ |
| 559 | const char *conv_filters[4], *conv_opts[4] = {0}; |
| 560 | unsigned neg_step, num_conv = 0, num_mergers = 0; |
| 561 | |
| 562 | if (!link) |
| 563 | continue; |
| 564 | |
| 565 | neg = ff_filter_get_negotiation(link); |
| 566 | av_assert0(neg); |
| 567 | for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) { |
| 568 | const AVFilterFormatsMerger *m = &neg->mergers[neg_step]; |
| 569 | void *a = FF_FIELD_AT(void *, m->offset, link->incfg); |
| 570 | void *b = FF_FIELD_AT(void *, m->offset, link->outcfg); |
| 571 | if (a && b && a != b && !m->can_merge(a, b)) { |
| 572 | for (k = 0; k < num_conv; k++) { |
| 573 | if (!strcmp(conv_filters[k], m->conversion_filter)) |
| 574 | break; |
| 575 | } |
| 576 | if (k == num_conv) { |
| 577 | av_assert1(num_conv < FF_ARRAY_ELEMS(conv_filters)); |
| 578 | conv_filters[num_conv] = m->conversion_filter; |
| 579 | if (m->conversion_opts_offset) |
| 580 | conv_opts[num_conv] = FF_FIELD_AT(char *, m->conversion_opts_offset, *graph); |
| 581 | num_conv++; |
| 582 | } |
| 583 | av_assert1(num_mergers < FF_ARRAY_ELEMS(mergers)); |
no test coverage detected