Showing the changes to libavfilter/avfiltergraph.c (1 of 5 files). Show all
Unified · Split
| @@ -185,9 +185,24 @@ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name) · 184 unmodified lines | ||
| 185 | 185 | return NULL; |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | +static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l) | |
| 189 | +{ | |
| 190 | + if (!l) | |
| 191 | + return; | |
| 192 | + if (l->nb_channel_layouts) { | |
| 193 | + if (l->all_layouts || l->all_counts) | |
| 194 | + av_log(log, AV_LOG_WARNING, "All layouts set on non-empty list\n"); | |
| 195 | + l->all_layouts = l->all_counts = 0; | |
| 196 | + } else { | |
| 197 | + if (l->all_counts && !l->all_layouts) | |
| 198 | + av_log(log, AV_LOG_WARNING, "All counts without all layouts\n"); | |
| 199 | + l->all_layouts = 1; | |
| 200 | + } | |
| 201 | +} | |
| 202 | + | |
| 188 | 203 | static int filter_query_formats(AVFilterContext *ctx) |
| 189 | 204 | { |
| 190 | − int ret; | |
| 205 | + int ret, i; | |
| 191 | 206 | AVFilterFormats *formats; |
| 192 | 207 | AVFilterChannelLayouts *chlayouts; |
| 193 | 208 | AVFilterFormats *samplerates; |
| @@ -201,6 +216,11 @@ static int filter_query_formats(AVFilterContext *ctx) · 7 unmodified lines | ||
| 201 | 216 | return ret; |
| 202 | 217 | } |
| 203 | 218 | |
| 219 | + for (i = 0; i < ctx->nb_inputs; i++) | |
| 220 | + sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts); | |
| 221 | + for (i = 0; i < ctx->nb_outputs; i++) | |
| 222 | + sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts); | |
| 223 | + | |
| 204 | 224 | formats = ff_all_formats(type); |
| 205 | 225 | if (!formats) |
| 206 | 226 | return AVERROR(ENOMEM); |
| @@ -470,7 +490,7 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 263 unmodified lines | ||
| 470 | 490 | link->in_samplerates->format_count = 1; |
| 471 | 491 | link->sample_rate = link->in_samplerates->formats[0]; |
| 472 | 492 | |
| 473 | − if (!link->in_channel_layouts->nb_channel_layouts) { | |
| 493 | + if (link->in_channel_layouts->all_layouts) { | |
| 474 | 494 | av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for" |
| 475 | 495 | "the link between filters %s and %s.\n", link->src->name, |
| 476 | 496 | link->dst->name); |
| @@ -478,7 +498,10 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 1 unmodified line | ||
| 478 | 498 | } |
| 479 | 499 | link->in_channel_layouts->nb_channel_layouts = 1; |
| 480 | 500 | link->channel_layout = link->in_channel_layouts->channel_layouts[0]; |
| 481 | − link->channels = av_get_channel_layout_nb_channels(link->channel_layout); | |
| 501 | + if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout))) | |
| 502 | + link->channel_layout = 0; | |
| 503 | + else | |
| 504 | + link->channels = av_get_channel_layout_nb_channels(link->channel_layout); | |
| 482 | 505 | } |
| 483 | 506 | |
| 484 | 507 | ff_formats_unref(&link->in_formats); |
| @@ -534,8 +557,42 @@ static int reduce_formats_on_filter(AVFilterContext *filter) · 49 unmodified lines | ||
| 534 | 557 | format_count, ff_add_format); |
| 535 | 558 | REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, |
| 536 | 559 | format_count, ff_add_format); |
| 537 | − REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts, | |
| 538 | − channel_layouts, nb_channel_layouts, ff_add_channel_layout); | |
| 560 | + | |
| 561 | + /* reduce channel layouts */ | |
| 562 | + for (i = 0; i < filter->nb_inputs; i++) { | |
| 563 | + AVFilterLink *inlink = filter->inputs[i]; | |
| 564 | + uint64_t fmt; | |
| 565 | + | |
| 566 | + if (!inlink->out_channel_layouts || | |
| 567 | + inlink->out_channel_layouts->nb_channel_layouts != 1) | |
| 568 | + continue; | |
| 569 | + fmt = inlink->out_channel_layouts->channel_layouts[0]; | |
| 570 | + | |
| 571 | + for (j = 0; j < filter->nb_outputs; j++) { | |
| 572 | + AVFilterLink *outlink = filter->outputs[j]; | |
| 573 | + AVFilterChannelLayouts *fmts; | |
| 574 | + | |
| 575 | + fmts = outlink->in_channel_layouts; | |
| 576 | + if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1) | |
| 577 | + continue; | |
| 578 | + | |
| 579 | + if (fmts->all_layouts) { | |
| 580 | + /* Turn the infinite list into a singleton */ | |
| 581 | + fmts->all_layouts = fmts->all_counts = 0; | |
| 582 | + ff_add_channel_layout(&outlink->in_channel_layouts, fmt); | |
| 583 | + break; | |
| 584 | + } | |
| 585 | + | |
| 586 | + for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) { | |
| 587 | + if (fmts->channel_layouts[k] == fmt) { | |
| 588 | + fmts->channel_layouts[0] = fmt; | |
| 589 | + fmts->nb_channel_layouts = 1; | |
| 590 | + ret = 1; | |
| 591 | + break; | |
| 592 | + } | |
| 593 | + } | |
| 594 | + } | |
| 595 | + } | |
| 539 | 596 | |
| 540 | 597 | return ret; |
| 541 | 598 | } |
| @@ -663,7 +720,23 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) · 121 unmodified lines | ||
| 663 | 720 | int out_channels = av_get_channel_layout_nb_channels(out_chlayout); |
| 664 | 721 | int count_diff = out_channels - in_channels; |
| 665 | 722 | int matched_channels, extra_channels; |
| 666 | − int score = 0; | |
| 723 | + int score = 100000; | |
| 724 | + | |
| 725 | + if (FF_LAYOUT2COUNT(in_chlayout) || FF_LAYOUT2COUNT(out_chlayout)) { | |
| 726 | + /* Compute score in case the input or output layout encodes | |
| 727 | + a channel count; in this case the score is not altered by | |
| 728 | + the computation afterwards, as in_chlayout and | |
| 729 | + out_chlayout have both been set to 0 */ | |
| 730 | + if (FF_LAYOUT2COUNT(in_chlayout)) | |
| 731 | + in_channels = FF_LAYOUT2COUNT(in_chlayout); | |
| 732 | + if (FF_LAYOUT2COUNT(out_chlayout)) | |
| 733 | + out_channels = FF_LAYOUT2COUNT(out_chlayout); | |
| 734 | + score -= 10000 + FFABS(out_channels - in_channels) + | |
| 735 | + (in_channels > out_channels ? 10000 : 0); | |
| 736 | + in_chlayout = out_chlayout = 0; | |
| 737 | + /* Let the remaining computation run, even if the score | |
| 738 | + value is not altered */ | |
| 739 | + } | |
| 667 | 740 | |
| 668 | 741 | /* channel substitution */ |
| 669 | 742 | for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) { |