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 | return 0; | 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 | static int pick_format(AVFilterLink *link, AVFilterLink *ref) | 668 | static int pick_format(AVFilterLink *link, AVFilterLink *ref) |
| 635 | { | 669 | { |
| 636 | if (!link || !link->in_formats) | 670 | if (!link || !link->in_formats) |
| @@ -650,6 +684,19 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 13 unmodified lines | |||
| 650 | av_get_pix_fmt_name(ref->format), has_alpha); | 684 | av_get_pix_fmt_name(ref->format), has_alpha); |
| 651 | link->in_formats->formats[0] = best; | 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 | link->in_formats->nb_formats = 1; | 702 | link->in_formats->nb_formats = 1; |