Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -461,6 +461,74 @@ static void swap_channel_layouts(AVFilterGraph *graph) · 460 unmodified lines | |||
| 461 | swap_channel_layouts_on_filter(graph->filters[i]); | 461 | swap_channel_layouts_on_filter(graph->filters[i]); |
| 462 | } | 462 | } |
| 463 | 463 | ||
| 464 | static void swap_sample_fmts_on_filter(AVFilterContext *filter) | ||
| 465 | { | ||
| 466 | AVFilterLink *link = NULL; | ||
| 467 | int format, bps; | ||
| 468 | int i, j; | ||
| 469 | |||
| 470 | for (i = 0; i < filter->input_count; i++) { | ||
| 471 | link = filter->inputs[i]; | ||
| 472 | |||
| 473 | if (link->type == AVMEDIA_TYPE_AUDIO && | ||
| 474 | link->out_formats->format_count == 1) | ||
| 475 | break; | ||
| 476 | } | ||
| 477 | if (i == filter->input_count) | ||
| 478 | return; | ||
| 479 | |||
| 480 | format = link->out_formats->formats[0]; | ||
| 481 | bps = av_get_bytes_per_sample(format); | ||
| 482 | |||
| 483 | for (i = 0; i < filter->output_count; i++) { | ||
| 484 | AVFilterLink *outlink = filter->outputs[i]; | ||
| 485 | int best_idx, best_score = INT_MIN; | ||
| 486 | |||
| 487 | if (outlink->type != AVMEDIA_TYPE_AUDIO || | ||
| 488 | outlink->in_formats->format_count < 2) | ||
| 489 | continue; | ||
| 490 | |||
| 491 | for (j = 0; j < outlink->in_formats->format_count; j++) { | ||
| 492 | int out_format = outlink->in_formats->formats[j]; | ||
| 493 | int out_bps = av_get_bytes_per_sample(out_format); | ||
| 494 | int score; | ||
| 495 | |||
| 496 | if (av_get_packed_sample_fmt(out_format) == format || | ||
| 497 | av_get_planar_sample_fmt(out_format) == format) { | ||
| 498 | best_idx = j; | ||
| 499 | break; | ||
| 500 | } | ||
| 501 | |||
| 502 | /* for s32 and float prefer double to prevent loss of information */ | ||
| 503 | if (bps == 4 && out_bps == 8) { | ||
| 504 | best_idx = j; | ||
| 505 | break; | ||
| 506 | } | ||
| 507 | |||
| 508 | /* prefer closest higher or equal bps */ | ||
| 509 | score = -abs(out_bps - bps); | ||
| 510 | if (out_bps >= bps) | ||
| 511 | score += INT_MAX/2; | ||
| 512 | |||
| 513 | if (score > best_score) { | ||
| 514 | best_score = score; | ||
| 515 | best_idx = j; | ||
| 516 | } | ||
| 517 | } | ||
| 518 | FFSWAP(int, outlink->in_formats->formats[0], | ||
| 519 | outlink->in_formats->formats[best_idx]); | ||
| 520 | } | ||
| 521 | } | ||
| 522 | |||
| 523 | static void swap_sample_fmts(AVFilterGraph *graph) | ||
| 524 | { | ||
| 525 | int i; | ||
| 526 | |||
| 527 | for (i = 0; i < graph->filter_count; i++) | ||
| 528 | swap_sample_fmts_on_filter(graph->filters[i]); | ||
| 529 | |||
| 530 | } | ||
| 531 | |||
| 464 | static int pick_formats(AVFilterGraph *graph) | 532 | static int pick_formats(AVFilterGraph *graph) |
| 465 | { | 533 | { |
| 466 | int i, j, ret; | 534 | int i, j, ret; |
| @@ -491,8 +559,9 @@ int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx) · 24 unmodified lines | |||
| 491 | * of format conversion inside filters */ | 559 | * of format conversion inside filters */ |
| 492 | reduce_formats(graph); | 560 | reduce_formats(graph); |
| 493 | 561 | ||
| 494 | /* for audio filters, ensure the best sample rate and channel layout | 562 | /* for audio filters, ensure the best format, sample rate and channel layout |
| 495 | * is selected */ | 563 | * is selected */ |
| 564 | swap_sample_fmts(graph); | ||
| 496 | swap_samplerates(graph); | 565 | swap_samplerates(graph); |
| 497 | swap_channel_layouts(graph); | 566 | swap_channel_layouts(graph); |
| 498 | 567 | ||