Similar to the pixel format code Fixes Ticket3847
Unified · Split
| @@ -631,6 +631,40 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 630 unmodified lines | ||
| 631 | 631 | return 0; |
| 632 | 632 | } |
| 633 | 633 | |
| 634 | +static int get_fmt_score(enum AVSampleFormat dst_fmt, enum AVSampleFormat src_fmt) | |
| 635 | +{ | |
| 636 | + int score = 0; | |
| 637 | + | |
| 638 | + if (av_sample_fmt_is_planar(dst_fmt) != av_sample_fmt_is_planar(src_fmt)) | |
| 639 | + score ++; | |
| 640 | + | |
| 641 | + if (av_get_bytes_per_sample(dst_fmt) < av_get_bytes_per_sample(src_fmt)) { | |
| 642 | + score += 100 * (av_get_bytes_per_sample(src_fmt) - av_get_bytes_per_sample(dst_fmt)); | |
| 643 | + }else | |
| 644 | + score += 10 * (av_get_bytes_per_sample(dst_fmt) - av_get_bytes_per_sample(src_fmt)); | |
| 645 | + | |
| 646 | + if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_S32 && | |
| 647 | + av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_FLT) | |
| 648 | + score += 20; | |
| 649 | + | |
| 650 | + if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_FLT && | |
| 651 | + av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_S32) | |
| 652 | + score += 2; | |
| 653 | + | |
| 654 | + return score; | |
| 655 | +} | |
| 656 | + | |
| 657 | +static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt1, enum AVSampleFormat dst_fmt2, | |
| 658 | + enum AVSampleFormat src_fmt) | |
| 659 | +{ | |
| 660 | + int score1, score2; | |
| 661 | + | |
| 662 | + score1 = get_fmt_score(dst_fmt1, src_fmt); | |
| 663 | + score2 = get_fmt_score(dst_fmt2, src_fmt); | |
| 664 | + | |
| 665 | + return score1 < score2 ? dst_fmt1 : dst_fmt2; | |
| 666 | +} | |
| 667 | + | |
| 634 | 668 | static int pick_format(AVFilterLink *link, AVFilterLink *ref) |
| 635 | 669 | { |
| 636 | 670 | if (!link || !link->in_formats) |
| @@ -650,6 +684,19 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 13 unmodified lines | ||
| 650 | 684 | av_get_pix_fmt_name(ref->format), has_alpha); |
| 651 | 685 | link->in_formats->formats[0] = best; |
| 652 | 686 | } |
| 687 | + } else if (link->type == AVMEDIA_TYPE_AUDIO) { | |
| 688 | + if(ref && ref->type == AVMEDIA_TYPE_AUDIO){ | |
| 689 | + enum AVSampleFormat best= AV_SAMPLE_FMT_NONE; | |
| 690 | + int i; | |
| 691 | + for (i=0; i<link->in_formats->nb_formats; i++) { | |
| 692 | + enum AVSampleFormat p = link->in_formats->formats[i]; | |
| 693 | + best = find_best_sample_fmt_of_2(best, p, ref->format); | |
| 694 | + } | |
| 695 | + av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s\n", | |
| 696 | + av_get_sample_fmt_name(best), link->in_formats->nb_formats, | |
| 697 | + av_get_sample_fmt_name(ref->format)); | |
| 698 | + link->in_formats->formats[0] = best; | |
| 699 | + } | |
| 653 | 700 | } |
| 654 | 701 | |
| 655 | 702 | link->in_formats->nb_formats = 1; |