Files
mpv/test/libmpv_test_track_selection.c
Dudemanguy 3bbb94077d test/libmpv: use common wrappers for properties and commands
This is mainly for better, more descriptive logging when something goes
wrong and fails. Common operations that manipulate properties and
commands go through shared functions that do better detailed logging.
Also it means we don't need check_api_error around anymore so get rid of
that. libmpv_lifetime is left untouched since that one is a bit special
and works a little differently.
2025-10-02 15:15:48 +00:00

274 lines
9.0 KiB
C

/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifdef _WIN32
#include <assert.h>
#include <io.h>
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "libmpv_common.h"
#ifndef F_OK
#define F_OK 0
#endif
#ifdef _WIN32
static bool any_starts_with(const wchar_t *buffer, ULONG count, const wchar_t *str)
{
for (ULONG pos = 0, i = 0; i < count; ++i) {
assert(buffer[pos]);
if (wcsncmp(buffer + pos, str, wcslen(str)) == 0)
return true;
pos += wcslen(buffer + pos) + 1;
}
return false;
}
#endif
static bool have_english_locale(void)
{
#ifdef __APPLE__
CFArrayRef arr = CFLocaleCopyPreferredLanguages();
if (!arr)
return false;
CFIndex count = CFArrayGetCount(arr);
if (!count)
return false;
bool ret = false;
CFRange range = CFRangeMake(0, 2);
CFStringRef en = CFStringCreateWithCString(NULL, "en", kCFStringEncodingMacRoman);
for (CFIndex i = 0; i < count; i++) {
CFStringRef cfstr = CFArrayGetValueAtIndex(arr, i);
if (CFStringCompareWithOptions(cfstr, en, range, 0) == 0) {
ret = true;
break;
}
}
CFRelease(en);
return ret;
#endif
#ifdef _WIN32
wchar_t buf[1024];
ULONG size = _countof(buf);
ULONG count = 0;
if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &count, buf, &size))
fail("GetUserPreferredUILanguages failed: %#lx\n", GetLastError());
if (any_starts_with(buf, count, L"en"))
return true;
size = _countof(buf);
if (!GetSystemPreferredUILanguages(MUI_LANGUAGE_NAME, &count, buf, &size))
fail("GetSystemPreferredUILanguages failed: %#lx\n", GetLastError());
if (any_starts_with(buf, count, L"en"))
return true;
return false;
#endif
return true;
}
static void test_track_selection(char *file, char *path)
{
int ret = access(path, F_OK);
if (ret)
fail("Test file, '%s', was not found!\n", path);
if (strcmp(file, "eng_default.mkv") == 0) {
// --no-config
reload_file(path);
check_string("current-tracks/sub/selected", "yes");
// --subs-falback=no
set_property_string("subs-fallback", "no");
reload_file(path);
check_string("track-list/2/selected", "no");
} else if (strcmp(file, "eng_default_forced.mkv") == 0) {
// --subs-fallback-forced=no
set_property_string("subs-fallback-forced", "no");
reload_file(path);
check_string("current-tracks/sub/selected", "yes");
} else if (strcmp(file, "eng_forced_matching_audio.mkv") == 0 ||
(strcmp(file, "eng_forced_matching_audio_region.mkv") == 0)) {
// select forced track
reload_file(path);
check_string("current-tracks/sub/selected", "yes");
} else if (strcmp(file, "eng_forced_no_matching_audio.mkv") == 0) {
// forced track should not be selected
reload_file(path);
check_string("track-list/2/selected", "no");
} else if (strcmp(file, "eng_forced_always_audio.mkv") == 0) {
// forced track should be selected anyway despite no matching audio
set_property_string("subs-fallback-forced", "always");
reload_file(path);
check_string("current-tracks/sub/selected", "yes");
} else if (strcmp(file, "eng_no_default.mkv") == 0) {
// track should not be selected
reload_file(path);
check_string("track-list/2/selected", "no");
// --subs-fallback=yes
set_property_string("subs-fallback", "yes");
reload_file(path);
check_string("current-tracks/sub/selected", "yes");
} else if (strcmp(file, "locale.mkv") == 0) {
// default english subs
reload_file(path);
check_string("current-tracks/sub/lang", "eng");
// default german subs
set_property_string("subs-match-os-language", "no");
reload_file(path);
check_string("current-tracks/sub/lang", "ger");
} else if (strcmp(file, "multilang.mkv") == 0) {
// --alang=jpn should select forced jpn subs
set_property_string("alang", "jpn");
reload_file(path);
check_string("current-tracks/audio/lang", "jpn");
check_string("current-tracks/sub/lang", "jpn");
// --alang=pol should select default, non-forced ger subs
set_property_string("alang", "pol");
reload_file(path);
check_string("current-tracks/audio/lang", "pol");
check_string("current-tracks/sub/lang", "ger");
// --slang=eng and --subs-with-matching-audio should not pick any subs
set_property_string("alang", "eng");
set_property_string("slang", "eng");
set_property_string("subs-with-matching-audio", "no");
reload_file(path);
check_string("current-tracks/audio/lang", "eng");
check_string("track-list/5/selected", "no");
check_string("track-list/6/selected", "no");
check_string("track-list/7/selected", "no");
check_string("track-list/8/selected", "no");
// --subs-with-matching-audio=forced checks
set_property_string("subs-with-matching-audio", "forced");
reload_file(path);
check_string("current-tracks/audio/lang", "eng");
check_string("current-tracks/sub/lang", "eng");
// forced jpn subs should be selected
set_property_string("alang", "jpn");
set_property_string("slang", "jpn");
reload_file(path);
check_string("current-tracks/audio/lang", "jpn");
check_string("current-tracks/sub/lang", "jpn");
// default+forced eng subs should be selected
set_property_string("alang", "ger");
set_property_string("slang", "ger");
reload_file(path);
check_string("current-tracks/audio/lang", "ger");
check_string("current-tracks/sub/lang", "eng");
// eng audio and pol subs should be selected
set_property_string("alang", "it");
set_property_string("slang", "pt,it,pol,ger");
reload_file(path);
check_string("current-tracks/audio/lang", "eng");
check_string("current-tracks/sub/lang", "pol");
// forced jpn subs should be selected
set_property_string("alang", "ger");
set_property_string("slang", "jpn,pol");
set_property_string("subs-with-matching-audio", "yes");
set_property_string("subs-fallback-forced", "always");
reload_file(path);
check_string("current-tracks/audio/lang", "ger");
check_string("current-tracks/sub/lang", "jpn");
} else if (strcmp(file, "multilang2.mkv") == 0) {
// default jpn subs
set_property_string("subs-match-os-language", "no");
set_property_string("alang", "jpn");
reload_file(path);
check_string("track-list/3/selected", "yes");
// forced eng subs
set_property_string("alang", "eng");
reload_file(path);
check_string("track-list/4/selected", "yes");
// default jpn subs
set_property_string("subs-fallback-forced", "no");
reload_file(path);
check_string("track-list/3/selected", "yes");
// default eng subs
set_property_string("slang", "eng");
reload_file(path);
check_string("track-list/6/selected", "yes");
// no subs
set_property_string("slang", "");
set_property_string("subs-fallback", "no");
reload_file(path);
check_string("track-list/3/selected", "no");
check_string("track-list/4/selected", "no");
check_string("track-list/5/selected", "no");
check_string("track-list/6/selected", "no");
// untagged eng subs
set_property_string("sid", "3");
reload_file(path);
check_string("track-list/5/selected", "yes");
}
}
int main(int argc, char *argv[])
{
if (argc < 3)
return 1;
if (!strcmp(argv[1], "locale.mkv") && !have_english_locale()) {
printf("Non English language detected. Skipping locale test.\n");
return 77;
}
ctx = mpv_create();
if (!ctx)
return 1;
atexit(exit_cleanup);
initialize();
const char *fmt = "================ TEST: %s %s ================\n";
printf(fmt, "test_track_selection", argv[1]);
test_track_selection(argv[1], argv[2]);
printf("================ SHUTDOWN ================\n");
command_string("quit");
while (wrap_wait_event()->event_id != MPV_EVENT_SHUTDOWN) {}
return 0;
}