summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2014-12-28 09:38:22 +0100
committerStefano Pigozzi <stefano.pigozzi@gmail.com>2014-12-29 17:56:53 +0100
commit54aea7d5de13735bad291c0f1d9ba93b17a6321e (patch)
tree13ca20a462a71329f59f9463c0620df9a620ed70 /test
parent461ba50ed6e8227da034e4ebcb4316f34a720274 (diff)
downloadmpv-54aea7d5de13735bad291c0f1d9ba93b17a6321e.tar.bz2
mpv-54aea7d5de13735bad291c0f1d9ba93b17a6321e.tar.xz
chmap_sel: add multichannel fallback heuristic
Instead of just failing during channel map selection, try to select a close layout that makes most sense and upmix/downmix to that instead of failing AO initialization. The heuristic is rather simple, and uses the following steps: 1) If mono is required always prefer stereo to a multichannel upmix. 2) Search for an upmix that is an exact superset of the required channel map. 3) Search for a downmix that is the exact subset of the required channel map. 4) Search for either an upmix or downmix that is the closest (minimum difference of channels) to the required channel map.
Diffstat (limited to 'test')
-rw-r--r--test/chmap.c56
-rw-r--r--test/chmap_sel.c162
-rw-r--r--test/test_helpers.h11
3 files changed, 229 insertions, 0 deletions
diff --git a/test/chmap.c b/test/chmap.c
new file mode 100644
index 0000000000..f0e8a1802d
--- /dev/null
+++ b/test/chmap.c
@@ -0,0 +1,56 @@
+#include "test_helpers.h"
+#include "audio/chmap.h"
+
+static void test_mp_chmap_diff(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+ struct mp_chmap diff;
+
+ mp_chmap_from_str(&a, bstr0("3.1"));
+ mp_chmap_from_str(&b, bstr0("2.1"));
+
+ mp_chmap_diff(&a, &b, &diff);
+ assert_int_equal(diff.num, 1);
+ assert_int_equal(diff.speaker[0], MP_SPEAKER_ID_FC);
+
+ mp_chmap_from_str(&b, bstr0("6.1(back)"));
+ mp_chmap_diff(&a, &b, &diff);
+ assert_int_equal(diff.num, 0);
+
+ mp_chmap_diff(&b, &a, &diff);
+ assert_int_equal(diff.num, 3);
+ assert_int_equal(diff.speaker[0], MP_SPEAKER_ID_BL);
+ assert_int_equal(diff.speaker[1], MP_SPEAKER_ID_BR);
+ assert_int_equal(diff.speaker[2], MP_SPEAKER_ID_BC);
+}
+
+static void test_mp_chmap_contains_with_related_chmaps(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+
+ mp_chmap_from_str(&a, bstr0("3.1"));
+ mp_chmap_from_str(&b, bstr0("2.1"));
+
+ assert_true(mp_chmap_contains(&a, &b));
+ assert_false(mp_chmap_contains(&b, &a));
+}
+
+static void test_mp_chmap_contains_with_unrelated_chmaps(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+
+ mp_chmap_from_str(&a, bstr0("mono"));
+ mp_chmap_from_str(&b, bstr0("stereo"));
+
+ assert_false(mp_chmap_contains(&a, &b));
+ assert_false(mp_chmap_contains(&b, &a));
+}
+
+int main(void) {
+ const UnitTest tests[] = {
+ unit_test(test_mp_chmap_diff),
+ unit_test(test_mp_chmap_contains_with_related_chmaps),
+ unit_test(test_mp_chmap_contains_with_unrelated_chmaps),
+ };
+ return run_tests(tests);
+}
diff --git a/test/chmap_sel.c b/test/chmap_sel.c
new file mode 100644
index 0000000000..c315d2f9a1
--- /dev/null
+++ b/test/chmap_sel.c
@@ -0,0 +1,162 @@
+#include "test_helpers.h"
+#include "audio/chmap_sel.h"
+
+static void test_mp_chmap_sel_fallback_upmix(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+ struct mp_chmap_sel s = {0};
+
+ mp_chmap_from_str(&a, bstr0("7.1"));
+ mp_chmap_from_str(&b, bstr0("5.1"));
+
+ mp_chmap_sel_add_map(&s, &a);
+ assert_true(mp_chmap_sel_fallback(&s, &b));
+ assert_string_equal(mp_chmap_to_str(&b), "7.1");
+}
+
+static void test_mp_chmap_sel_fallback_downmix(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+ struct mp_chmap_sel s = {0};
+
+ mp_chmap_from_str(&a, bstr0("5.1"));
+ mp_chmap_from_str(&b, bstr0("7.1"));
+
+ mp_chmap_sel_add_map(&s, &a);
+ assert_true(mp_chmap_sel_fallback(&s, &b));
+ assert_string_equal(mp_chmap_to_str(&b), "5.1");
+}
+
+static void test_mp_chmap_sel_fallback_incompatible(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+ struct mp_chmap_sel s = {0};
+
+ mp_chmap_from_str(&a, bstr0("7.1"));
+ mp_chmap_from_str(&b, bstr0("7.1(wide-side)"));
+
+ mp_chmap_sel_add_map(&s, &a);
+ assert_true(mp_chmap_sel_fallback(&s, &b));
+ assert_string_equal(mp_chmap_to_str(&b), "7.1");
+}
+
+static void test_mp_chmap_sel_fallback_prefer_compatible(void **state) {
+ struct mp_chmap a, b, c;
+ struct mp_chmap_sel s = {0};
+
+ mp_chmap_from_str(&a, bstr0("7.1"));
+ mp_chmap_from_str(&b, bstr0("5.1(side)"));
+ mp_chmap_from_str(&c, bstr0("7.1(wide-side)"));
+
+ mp_chmap_sel_add_map(&s, &a);
+ mp_chmap_sel_add_map(&s, &b);
+
+ assert_true(mp_chmap_sel_fallback(&s, &c));
+ assert_string_equal(mp_chmap_to_str(&b), "5.1(side)");
+}
+
+static void test_mp_chmap_sel_fallback_prefer_closest_upmix(void **state) {
+ struct mp_chmap_sel s = {0};
+
+ char *maps[] = { "7.1", "5.1", "2.1", "stereo", "mono", NULL };
+ for (int i = 0; maps[i]; i++) {
+ struct mp_chmap m;
+ mp_chmap_from_str(&m, bstr0(maps[i]));
+ mp_chmap_sel_add_map(&s, &m);
+ }
+
+ struct mp_chmap c;
+ mp_chmap_from_str(&c, bstr0("3.1"));
+ assert_true(mp_chmap_sel_fallback(&s, &c));
+ assert_string_equal(mp_chmap_to_str(&c), "5.1");
+}
+
+static void test_mp_chmap_sel_fallback_use_replacements(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+ struct mp_chmap_sel s = {0};
+
+ mp_chmap_from_str(&a, bstr0("7.1(rear)"));
+ mp_chmap_from_str(&b, bstr0("5.1"));
+
+ mp_chmap_sel_add_map(&s, &a);
+ assert_true(mp_chmap_sel_fallback(&s, &b));
+ assert_string_equal(mp_chmap_to_str(&b), "7.1(rear)");
+}
+
+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};
+
+ a.num = 2;
+ a.speaker[0] = MP_SPEAKER_ID_UNKNOWN0;
+ a.speaker[1] = MP_SPEAKER_ID_UNKNOWN0 + 1;
+
+ 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_works_on_alsa_chmaps(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+ struct mp_chmap_sel s = {0};
+
+ mp_chmap_from_str(&a, bstr0("7.1(alsa)"));
+ mp_chmap_from_str(&b, bstr0("5.1"));
+
+ mp_chmap_sel_add_map(&s, &a);
+ assert_true(mp_chmap_sel_fallback(&s, &b));
+ assert_string_equal(mp_chmap_to_str(&b), "7.1(alsa)");
+}
+
+static void test_mp_chmap_sel_fallback_mono_to_stereo(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+ struct mp_chmap c;
+ struct mp_chmap_sel s = {0};
+
+ mp_chmap_from_str(&a, bstr0("stereo"));
+ mp_chmap_from_str(&b, bstr0("5.1"));
+ mp_chmap_from_str(&c, bstr0("mono"));
+
+ mp_chmap_sel_add_map(&s, &a);
+ mp_chmap_sel_add_map(&s, &b);
+ assert_true(mp_chmap_sel_fallback(&s, &c));
+ assert_string_equal(mp_chmap_to_str(&c), "stereo");
+}
+
+static void test_mp_chmap_sel_fallback_stereo_to_stereo(void **state) {
+ struct mp_chmap a;
+ struct mp_chmap b;
+ struct mp_chmap c;
+ struct mp_chmap_sel s = {0};
+
+ mp_chmap_from_str(&a, bstr0("stereo"));
+ mp_chmap_from_str(&b, bstr0("5.1"));
+ mp_chmap_from_str(&c, bstr0("stereo"));
+
+ mp_chmap_sel_add_map(&s, &a);
+ mp_chmap_sel_add_map(&s, &b);
+ assert_true(mp_chmap_sel_fallback(&s, &c));
+ assert_string_equal(mp_chmap_to_str(&c), "stereo");
+}
+
+int main(void) {
+ const UnitTest tests[] = {
+ unit_test(test_mp_chmap_sel_fallback_upmix),
+ unit_test(test_mp_chmap_sel_fallback_downmix),
+ unit_test(test_mp_chmap_sel_fallback_incompatible),
+ unit_test(test_mp_chmap_sel_fallback_prefer_compatible),
+ unit_test(test_mp_chmap_sel_fallback_prefer_closest_upmix),
+ unit_test(test_mp_chmap_sel_fallback_use_replacements),
+ unit_test(test_mp_chmap_sel_fallback_reject_unknown),
+ unit_test(test_mp_chmap_sel_fallback_works_on_alsa_chmaps),
+ unit_test(test_mp_chmap_sel_fallback_mono_to_stereo),
+ unit_test(test_mp_chmap_sel_fallback_stereo_to_stereo),
+ };
+ return run_tests(tests);
+}
diff --git a/test/test_helpers.h b/test/test_helpers.h
new file mode 100644
index 0000000000..3dfe08fdbe
--- /dev/null
+++ b/test/test_helpers.h
@@ -0,0 +1,11 @@
+#ifndef MP_TESTS_H
+#define MP_TESTS_H
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <stdio.h>
+
+#endif