From afdc060bb3d2558130e48a76a0a342be034e294c Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 12 Jun 2015 19:23:46 +0200 Subject: chmap_sel: improve speaker replacement handling This didn't really work since the last time the channel map fallback code was touched. In some cases, quite bad results were selected. --- audio/chmap_sel.c | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) (limited to 'audio/chmap_sel.c') diff --git a/audio/chmap_sel.c b/audio/chmap_sel.c index 855d0dc683..d1f6f2eee0 100644 --- a/audio/chmap_sel.c +++ b/audio/chmap_sel.c @@ -234,29 +234,45 @@ bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map) return true; } - struct mp_chmap best = {0}; + struct mp_chmap best_of_best = {0}; + + for (int i = -1; i < (int)MP_ARRAY_SIZE(speaker_replacements); i++) { + struct mp_chmap best = {0}; + struct mp_chmap t = *map; + + if (i >= 0) { + struct mp_chmap *r = (struct mp_chmap *)speaker_replacements[i]; + if (!replace_speakers(&t, r)) + continue; + } + + for (int n = 0; n < s->num_chmaps; n++) { + struct mp_chmap e = s->chmaps[n]; + + if (mp_chmap_is_unknown(&e)) + continue; - for (int n = 0; n < s->num_chmaps; n++) { - struct mp_chmap e = s->chmaps[n]; - - if (mp_chmap_is_unknown(&e)) - continue; - - // in case we didn't match any fallback retry after replacing speakers - for (int i = -1; i < (int)MP_ARRAY_SIZE(speaker_replacements); i++) { - struct mp_chmap t = *map; - if (i >= 0) { - struct mp_chmap *r = (struct mp_chmap *)speaker_replacements[i]; - if (!replace_speakers(&t, r)) - continue; - } if (mp_chmap_is_better(&t, &best, &e)) best = e; } + + if (best.num) { + if (best_of_best.num) { + // If best (without replacements) is not worse, but is actually + // better with replacements applied, pick it. + int bbest_lost = mp_chmap_diffn(map, &best_of_best); + int best_lost = mp_chmap_diffn(map, &best); + int repl_lost = mp_chmap_diffn(&t, &best); + if (best_lost <= bbest_lost && repl_lost < bbest_lost) + best_of_best = best; + } else { + best_of_best = best; + } + } } - if (best.num) { - *map = best; + if (best_of_best.num) { + *map = best_of_best; return true; } -- cgit v1.2.3