diff options
-rw-r--r-- | audio/chmap_sel.c | 22 | ||||
-rw-r--r-- | test/chmap_sel.c | 11 |
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), |