summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio/chmap_sel.c22
-rw-r--r--test/chmap_sel.c11
2 files changed, 22 insertions, 11 deletions
diff --git a/audio/chmap_sel.c b/audio/chmap_sel.c
index 8ddb7131e7..fa1941e6f6 100644
--- a/audio/chmap_sel.c
+++ b/audio/chmap_sel.c
@@ -274,19 +274,25 @@ static bool mp_chmap_is_better(struct mp_chmap *req, struct mp_chmap *old,
if (new_lost_r != old_lost_r)
return new_lost_r < old_lost_r;
+ struct mp_chmap old_p = *old, new_p = *new;
+ mp_chmap_remove_na(&old_p);
+ mp_chmap_remove_na(&new_p);
+
+ // If the situation is equal with replaced speakers, but the replacement is
+ // perfect for only one of them, let the better one win. This prefers
+ // inexact equivalents over exact supersets.
+ bool perfect_r_new = !new_lost_r && new_p.num <= old_p.num;
+ bool perfect_r_old = !old_lost_r && old_p.num <= new_p.num;
+ if (perfect_r_new != perfect_r_old)
+ return perfect_r_new;
+
int old_lost = mp_chmap_diffn(req, old);
int new_lost = mp_chmap_diffn(req, new);
-
- // If the situation is equal with replaced speakers, but one of them loses
- // less if no replacements are performed, pick the better one, even if it
- // means an upmix. This prefers exact supersets over inexact equivalents.
+ // If the situation is equal with replaced speakers, pick the better one,
+ // even if it means an upmix.
if (new_lost != old_lost)
return new_lost < old_lost;
- struct mp_chmap old_p = *old, new_p = *new;
- mp_chmap_remove_na(&old_p);
- mp_chmap_remove_na(&new_p);
-
// Some kind of upmix. If it's perfect, prefer the smaller one. Even if not,
// both have equal loss, so also prefer the smaller one.
// Drop padding channels (NA) for the sake of this check, as the number of
diff --git a/test/chmap_sel.c b/test/chmap_sel.c
index 0301045e23..38a5254073 100644
--- a/test/chmap_sel.c
+++ b/test/chmap_sel.c
@@ -52,6 +52,10 @@ static void test_mp_chmap_sel_fallback_use_replacements(void **state) {
test_sel("5.1", "7.1(rear)", LAYOUTS("7.1(rear)"));
}
+static void test_mp_chmap_sel_fallback_inexact_equivalent(void **state) {
+ test_sel("5.1(side)", "5.1", LAYOUTS("5.1", "7.1"));
+}
+
static void test_mp_chmap_sel_fallback_works_on_alsa_chmaps(void **state) {
test_sel("5.1", "7.1(alsa)", LAYOUTS("7.1(alsa)"));
}
@@ -89,11 +93,11 @@ static void test_mp_chmap_sel_fallback_reject_unknown(void **state) {
static void test_mp_chmap_sel_fallback_more_replacements(void **state) {
test_sel("quad", "quad(side)", LAYOUTS("quad(side)", "stereo"));
- test_sel("quad", "7.0", LAYOUTS("quad(side)", "7.0"));
- test_sel("quad", "7.0", LAYOUTS("7.0", "quad(side)"));
+ test_sel("quad", "quad(side)", LAYOUTS("quad(side)", "7.0"));
+ test_sel("quad", "quad(side)", LAYOUTS("7.0", "quad(side)"));
test_sel("quad", "7.1(wide-side)", LAYOUTS("7.1(wide-side)", "stereo"));
test_sel("quad", "7.1(wide-side)", LAYOUTS("stereo", "7.1(wide-side)"));
- test_sel("quad", "fl-fr-fc-bl-br",
+ test_sel("quad", "fl-fr-sl-sr",
LAYOUTS("fl-fr-fc-bl-br", "fl-fr-sl-sr"));
test_sel("quad", "fl-fr-bl-br-na-na-na-na",
LAYOUTS("fl-fr-bl-br-na-na-na-na", "quad(side)", "stereo"));
@@ -118,6 +122,7 @@ int main(void) {
cmocka_unit_test(test_mp_chmap_sel_fallback_prefer_compatible),
cmocka_unit_test(test_mp_chmap_sel_fallback_prefer_closest_upmix),
cmocka_unit_test(test_mp_chmap_sel_fallback_use_replacements),
+ cmocka_unit_test(test_mp_chmap_sel_fallback_inexact_equivalent),
cmocka_unit_test(test_mp_chmap_sel_fallback_works_on_alsa_chmaps),
cmocka_unit_test(test_mp_chmap_sel_fallback_mono_to_stereo),
cmocka_unit_test(test_mp_chmap_sel_fallback_stereo_to_stereo),