aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2015-08-16 14:59:18 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2015-08-16 14:59:58 +0200
commit0cb87cd7d4cf253ae7299b9fae4176b9bd8ef058 (patch)
treead27f54db71aa91a9e21408f67dc1ce90d422bdd
parentb4b2717ffe89940999eeca7317190f729b27f472 (diff)
downloadffmpeg-0cb87cd7d4cf253ae7299b9fae4176b9bd8ef058.tar.gz
avfilter/avfiltergraph: Implement and use find_best_sample_fmt_of_2()
Similar to the pixel format code Fixes Ticket3847 Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r--libavfilter/avfiltergraph.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index bac0da18a4..bd3853f0b7 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -631,6 +631,40 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
return 0;
}
+static int get_fmt_score(enum AVSampleFormat dst_fmt, enum AVSampleFormat src_fmt)
+{
+ int score = 0;
+
+ if (av_sample_fmt_is_planar(dst_fmt) != av_sample_fmt_is_planar(src_fmt))
+ score ++;
+
+ if (av_get_bytes_per_sample(dst_fmt) < av_get_bytes_per_sample(src_fmt)) {
+ score += 100 * (av_get_bytes_per_sample(src_fmt) - av_get_bytes_per_sample(dst_fmt));
+ }else
+ score += 10 * (av_get_bytes_per_sample(dst_fmt) - av_get_bytes_per_sample(src_fmt));
+
+ if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_S32 &&
+ av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_FLT)
+ score += 20;
+
+ if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_FLT &&
+ av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_S32)
+ score += 2;
+
+ return score;
+}
+
+static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt1, enum AVSampleFormat dst_fmt2,
+ enum AVSampleFormat src_fmt)
+{
+ int score1, score2;
+
+ score1 = get_fmt_score(dst_fmt1, src_fmt);
+ score2 = get_fmt_score(dst_fmt2, src_fmt);
+
+ return score1 < score2 ? dst_fmt1 : dst_fmt2;
+}
+
static int pick_format(AVFilterLink *link, AVFilterLink *ref)
{
if (!link || !link->in_formats)
@@ -650,6 +684,19 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref)
av_get_pix_fmt_name(ref->format), has_alpha);
link->in_formats->formats[0] = best;
}
+ } else if (link->type == AVMEDIA_TYPE_AUDIO) {
+ if(ref && ref->type == AVMEDIA_TYPE_AUDIO){
+ enum AVSampleFormat best= AV_SAMPLE_FMT_NONE;
+ int i;
+ for (i=0; i<link->in_formats->nb_formats; i++) {
+ enum AVSampleFormat p = link->in_formats->formats[i];
+ best = find_best_sample_fmt_of_2(best, p, ref->format);
+ }
+ av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s\n",
+ av_get_sample_fmt_name(best), link->in_formats->nb_formats,
+ av_get_sample_fmt_name(ref->format));
+ link->in_formats->formats[0] = best;
+ }
}
link->in_formats->nb_formats = 1;