summaryrefslogtreecommitdiffstats
path: root/audio/chmap_sel.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-06-12 19:23:46 +0200
committerwm4 <wm4@nowhere>2015-06-12 19:23:46 +0200
commitafdc060bb3d2558130e48a76a0a342be034e294c (patch)
tree6e03432533fae076d61983918345d7f097693e76 /audio/chmap_sel.c
parent55624a70eeac79d6a5a208a078458f1fe07b833a (diff)
downloadmpv-afdc060bb3d2558130e48a76a0a342be034e294c.tar.bz2
mpv-afdc060bb3d2558130e48a76a0a342be034e294c.tar.xz
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.
Diffstat (limited to 'audio/chmap_sel.c')
-rw-r--r--audio/chmap_sel.c50
1 files changed, 33 insertions, 17 deletions
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;
}