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 | return NULL; | 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 | static int filter_query_formats(AVFilterContext *ctx) | 203 | static int filter_query_formats(AVFilterContext *ctx) |
| 189 | { | 204 | { |
| 190 | int ret; | 205 | int ret, i; |
| 191 | AVFilterFormats *formats; | 206 | AVFilterFormats *formats; |
| 192 | AVFilterChannelLayouts *chlayouts; | 207 | AVFilterChannelLayouts *chlayouts; |
| 193 | AVFilterFormats *samplerates; | 208 | AVFilterFormats *samplerates; |
| @@ -201,6 +216,11 @@ static int filter_query_formats(AVFilterContext *ctx) · 7 unmodified lines | |||
| 201 | return ret; | 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 | formats = ff_all_formats(type); | 224 | formats = ff_all_formats(type); |
| 205 | if (!formats) | 225 | if (!formats) |
| 206 | return AVERROR(ENOMEM); | 226 | return AVERROR(ENOMEM); |
| @@ -470,7 +490,7 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 263 unmodified lines | |||
| 470 | link->in_samplerates->format_count = 1; | 490 | link->in_samplerates->format_count = 1; |
| 471 | link->sample_rate = link->in_samplerates->formats[0]; | 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 | av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for" | 494 | av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for" |
| 475 | "the link between filters %s and %s.\n", link->src->name, | 495 | "the link between filters %s and %s.\n", link->src->name, |
| 476 | link->dst->name); | 496 | link->dst->name); |
| @@ -478,7 +498,10 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 1 unmodified line | |||
| 478 | } | 498 | } |
| 479 | link->in_channel_layouts->nb_channel_layouts = 1; | 499 | link->in_channel_layouts->nb_channel_layouts = 1; |
| 480 | link->channel_layout = link->in_channel_layouts->channel_layouts[0]; | 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 | ff_formats_unref(&link->in_formats); | 507 | ff_formats_unref(&link->in_formats); |
| @@ -534,8 +557,42 @@ static int reduce_formats_on_filter(AVFilterContext *filter) · 49 unmodified lines | |||
| 534 | format_count, ff_add_format); | 557 | format_count, ff_add_format); |
| 535 | REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, | 558 | REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, |
| 536 | format_count, ff_add_format); | 559 | format_count, ff_add_format); |
| 537 | REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts, | 560 | |
| 538 | channel_layouts, nb_channel_layouts, ff_add_channel_layout); | 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 | return ret; | 597 | return ret; |
| 541 | } | 598 | } |
| @@ -663,7 +720,23 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) · 121 unmodified lines | |||
| 663 | int out_channels = av_get_channel_layout_nb_channels(out_chlayout); | 720 | int out_channels = av_get_channel_layout_nb_channels(out_chlayout); |
| 664 | int count_diff = out_channels - in_channels; | 721 | int count_diff = out_channels - in_channels; |
| 665 | int matched_channels, extra_channels; | 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 | /* channel substitution */ | 741 | /* channel substitution */ |
| 669 | for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) { | 742 | for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) { |