mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
55624a70ee
commit
afdc060bb3
|
@ -234,29 +234,45 @@ bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mp_chmap best = {0};
|
struct mp_chmap best_of_best = {0};
|
||||||
|
|
||||||
for (int n = 0; n < s->num_chmaps; n++) {
|
for (int i = -1; i < (int)MP_ARRAY_SIZE(speaker_replacements); i++) {
|
||||||
struct mp_chmap e = s->chmaps[n];
|
struct mp_chmap best = {0};
|
||||||
|
struct mp_chmap t = *map;
|
||||||
|
|
||||||
if (mp_chmap_is_unknown(&e))
|
if (i >= 0) {
|
||||||
continue;
|
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;
|
||||||
|
|
||||||
// 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))
|
if (mp_chmap_is_better(&t, &best, &e))
|
||||||
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) {
|
if (best_of_best.num) {
|
||||||
*map = best;
|
*map = best_of_best;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,20 @@ static void test_mp_chmap_sel_fallback_reject_unknown(void **state) {
|
||||||
assert_string_equal(mp_chmap_to_str(&b), "5.1");
|
assert_string_equal(mp_chmap_to_str(&b), "5.1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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", "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",
|
||||||
|
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"));
|
||||||
|
test_sel("quad", "fl-fr-bl-br-na-na-na-na",
|
||||||
|
LAYOUTS("stereo", "quad(side)", "fl-fr-bl-br-na-na-na-na"));
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
const UnitTest tests[] = {
|
const UnitTest tests[] = {
|
||||||
unit_test(test_mp_chmap_sel_fallback_upmix),
|
unit_test(test_mp_chmap_sel_fallback_upmix),
|
||||||
|
@ -101,6 +115,7 @@ int main(void) {
|
||||||
unit_test(test_mp_chmap_sel_fallback_no_downmix),
|
unit_test(test_mp_chmap_sel_fallback_no_downmix),
|
||||||
unit_test(test_mp_chmap_sel_fallback_minimal_downmix),
|
unit_test(test_mp_chmap_sel_fallback_minimal_downmix),
|
||||||
unit_test(test_mp_chmap_sel_fallback_reject_unknown),
|
unit_test(test_mp_chmap_sel_fallback_reject_unknown),
|
||||||
|
unit_test(test_mp_chmap_sel_fallback_more_replacements),
|
||||||
};
|
};
|
||||||
return run_tests(tests);
|
return run_tests(tests);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue