mirror of https://github.com/mpv-player/mpv
chmap_sel: prefer inexact equivalents over perfect upmix
Given 5.1(side), this lets it pick 5.1 from [5.1, 7.1]. Which was probably the original intention of this replacement stuff. Until now, the opposite was done in some cases. Keep the old heuristic if the replacement is not perfect. This would mean that a subset of the channel layout is an inexact equivalent, but not all of it. (My conclusion is that audio output APIs should be designed to simply take any channel layout, like the PulseAudio API does.)
This commit is contained in:
parent
cb8b0cc329
commit
dac5b598f5
|
@ -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)
|
if (new_lost_r != old_lost_r)
|
||||||
return new_lost_r < old_lost_r;
|
return new_lost_r < old_lost_r;
|
||||||
|
|
||||||
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 (new_lost != old_lost)
|
|
||||||
return new_lost < old_lost;
|
|
||||||
|
|
||||||
struct mp_chmap old_p = *old, new_p = *new;
|
struct mp_chmap old_p = *old, new_p = *new;
|
||||||
mp_chmap_remove_na(&old_p);
|
mp_chmap_remove_na(&old_p);
|
||||||
mp_chmap_remove_na(&new_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, pick the better one,
|
||||||
|
// even if it means an upmix.
|
||||||
|
if (new_lost != old_lost)
|
||||||
|
return new_lost < old_lost;
|
||||||
|
|
||||||
// Some kind of upmix. If it's perfect, prefer the smaller one. Even if not,
|
// 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.
|
// both have equal loss, so also prefer the smaller one.
|
||||||
// Drop padding channels (NA) for the sake of this check, as the number of
|
// Drop padding channels (NA) for the sake of this check, as the number of
|
||||||
|
|
|
@ -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)"));
|
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) {
|
static void test_mp_chmap_sel_fallback_works_on_alsa_chmaps(void **state) {
|
||||||
test_sel("5.1", "7.1(alsa)", LAYOUTS("7.1(alsa)"));
|
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) {
|
static void test_mp_chmap_sel_fallback_more_replacements(void **state) {
|
||||||
test_sel("quad", "quad(side)", LAYOUTS("quad(side)", "stereo"));
|
test_sel("quad", "quad(side)", LAYOUTS("quad(side)", "stereo"));
|
||||||
test_sel("quad", "7.0", LAYOUTS("quad(side)", "7.0"));
|
test_sel("quad", "quad(side)", LAYOUTS("quad(side)", "7.0"));
|
||||||
test_sel("quad", "7.0", LAYOUTS("7.0", "quad(side)"));
|
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("7.1(wide-side)", "stereo"));
|
||||||
test_sel("quad", "7.1(wide-side)", LAYOUTS("stereo", "7.1(wide-side)"));
|
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"));
|
LAYOUTS("fl-fr-fc-bl-br", "fl-fr-sl-sr"));
|
||||||
test_sel("quad", "fl-fr-bl-br-na-na-na-na",
|
test_sel("quad", "fl-fr-bl-br-na-na-na-na",
|
||||||
LAYOUTS("fl-fr-bl-br-na-na-na-na", "quad(side)", "stereo"));
|
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_compatible),
|
||||||
cmocka_unit_test(test_mp_chmap_sel_fallback_prefer_closest_upmix),
|
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_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_works_on_alsa_chmaps),
|
||||||
cmocka_unit_test(test_mp_chmap_sel_fallback_mono_to_stereo),
|
cmocka_unit_test(test_mp_chmap_sel_fallback_mono_to_stereo),
|
||||||
cmocka_unit_test(test_mp_chmap_sel_fallback_stereo_to_stereo),
|
cmocka_unit_test(test_mp_chmap_sel_fallback_stereo_to_stereo),
|
||||||
|
|
Loading…
Reference in New Issue