1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-17 04:15:13 +00:00
mpv/test/chmap_sel.c
wm4 fd1194de3c audio: fix channel map fallback selection (again)
The speaker replacement nonsense sometimes made blatantly incorrect
decisions. In this case, it prefered a 7.1(rear) upmix over outputting
5.1(side) as 5.1, which makes no sense at all. This happened because 5.1
and 7.1(rear) appeared equivalent to the final selection, as both of
them lose the sl-sr channels. The old code was too stupid to select the
one with the lower number of channels as well.

Redo this. There's really no reason why there should be a separate final
decision, so move the speaker replacement logic into the
mp_chmap_is_better() function.

Improve some other details. For example, we never should compare the
plain number of channels for deciding upmix/downmix, because due to NA
channels this is essentially meaningless. Remove the NA channels when
doing this comparison. Also, explicitly handle exact matches.
Conceptually this is not necessary, but it avoids that we have to
needlessly shuffle audio data around.
2015-06-25 17:32:00 +02:00

132 lines
5.2 KiB
C

#include "test_helpers.h"
#include "audio/chmap_sel.h"
#define LAYOUTS(...) (char*[]){__VA_ARGS__, NULL}
static void test_sel(const char *input, const char *expected_selection,
char **layouts)
{
struct mp_chmap_sel s = {0};
struct mp_chmap input_map;
struct mp_chmap expected_map;
assert_true(mp_chmap_from_str(&input_map, bstr0(input)));
assert_true(mp_chmap_from_str(&expected_map, bstr0(expected_selection)));
for (int n = 0; layouts[n]; n++) {
struct mp_chmap tmp;
assert_true(mp_chmap_from_str(&tmp, bstr0(layouts[n])));
int count = s.num_chmaps;
mp_chmap_sel_add_map(&s, &tmp);
assert_true(s.num_chmaps > count); // assure validity and max. count
}
assert_true(mp_chmap_sel_fallback(&s, &input_map));
// We convert expected_map to a chmap and then back to a string to avoid
// problems with ambiguous layouts.
assert_string_equal(mp_chmap_to_str(&input_map),
mp_chmap_to_str(&expected_map));
}
static void test_mp_chmap_sel_fallback_upmix(void **state) {
test_sel("5.1", "7.1", LAYOUTS("7.1"));
}
static void test_mp_chmap_sel_fallback_downmix(void **state) {
test_sel("7.1", "5.1", LAYOUTS("5.1"));
}
static void test_mp_chmap_sel_fallback_incompatible(void **state) {
test_sel("7.1(wide-side)", "7.1", LAYOUTS("7.1"));
}
static void test_mp_chmap_sel_fallback_prefer_compatible(void **state) {
test_sel("7.1(wide-side)", "5.1(side)", LAYOUTS("7.1", "5.1(side)"));
}
static void test_mp_chmap_sel_fallback_prefer_closest_upmix(void **state) {
test_sel("3.1", "5.1", LAYOUTS("7.1", "5.1", "2.1", "stereo", "mono"));
}
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_works_on_alsa_chmaps(void **state) {
test_sel("5.1", "7.1(alsa)", LAYOUTS("7.1(alsa)"));
}
static void test_mp_chmap_sel_fallback_mono_to_stereo(void **state) {
test_sel("mono", "stereo", LAYOUTS("stereo", "5.1"));
}
static void test_mp_chmap_sel_fallback_stereo_to_stereo(void **state) {
test_sel("stereo", "stereo", LAYOUTS("stereo", "5.1"));
}
static void test_mp_chmap_sel_fallback_no_downmix(void **state) {
test_sel("5.1(side)", "7.1(rear)", LAYOUTS("stereo", "7.1(rear)"));
}
static void test_mp_chmap_sel_fallback_minimal_downmix(void **state) {
test_sel("7.1", "fl-fr-lfe-fc-bl-br-flc-frc",
LAYOUTS("fl-fr-lfe-fc-bl-br-flc-frc", "3.0(back)"));
}
static void test_mp_chmap_sel_fallback_reject_unknown(void **state) {
struct mp_chmap a;
struct mp_chmap b;
struct mp_chmap_sel s = {0};
mp_chmap_set_unknown(&a, 2);
mp_chmap_from_str(&b, bstr0("5.1"));
mp_chmap_sel_add_map(&s, &a);
assert_false(mp_chmap_sel_fallback(&s, &b));
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"));
test_sel("fl-fr-fc-lfe-sl-sr", "fl-fr-lfe-fc-bl-br-na-na",
LAYOUTS("fl-fr-lfe-fc-bl-br-na-na", "fl-fr-lfe-fc-bl-br-sdl-sdr"));
test_sel("fl-fr-fc-lfe-sl-sr", "fl-fr-lfe-fc-bl-br-na-na",
LAYOUTS("fl-fr-lfe-fc-bl-br-sdl-sdr", "fl-fr-lfe-fc-bl-br-na-na"));
}
static void test_mp_chmap_sel_fallback_na_channels(void **state) {
test_sel("na-fl-fr", "na-fl-fr", LAYOUTS("na-fl-fr-na", "fl-na-fr", "na-fl-fr",
"fl-fr-na-na", "na-na-fl-fr"));
}
int main(void) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_mp_chmap_sel_fallback_upmix),
cmocka_unit_test(test_mp_chmap_sel_fallback_downmix),
cmocka_unit_test(test_mp_chmap_sel_fallback_incompatible),
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_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),
cmocka_unit_test(test_mp_chmap_sel_fallback_no_downmix),
cmocka_unit_test(test_mp_chmap_sel_fallback_minimal_downmix),
cmocka_unit_test(test_mp_chmap_sel_fallback_reject_unknown),
cmocka_unit_test(test_mp_chmap_sel_fallback_more_replacements),
cmocka_unit_test(test_mp_chmap_sel_fallback_na_channels),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}