From 3bbb94077d47879703d796e2dc220fc23a092579 Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Mon, 29 Sep 2025 20:10:52 -0500 Subject: [PATCH] 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. --- test/libmpv_common.h | 76 +++++++++++++++++++++++++----- test/libmpv_encode.c | 14 +++--- test/libmpv_test_file_loading.c | 4 +- test/libmpv_test_lavfi_complex.c | 10 ++-- test/libmpv_test_options.c | 20 ++++---- test/libmpv_test_sdh_filter.c | 10 ++-- test/libmpv_test_track_selection.c | 60 +++++++++++------------ 7 files changed, 123 insertions(+), 71 deletions(-) diff --git a/test/libmpv_common.h b/test/libmpv_common.h index bf70bfc9cf..841386e195 100644 --- a/test/libmpv_common.h +++ b/test/libmpv_common.h @@ -26,6 +26,15 @@ #include "osdep/compiler.h" +#define command(cmd) command_impl(__FILE__, __LINE__, (cmd)) +#define command_string(cmd) command_string_impl(__FILE__, __LINE__, (cmd)) +#define get_property(property, format, result) \ + get_property_impl(__FILE__, __LINE__, (property), (format), (result)) +#define set_option_or_property(property, format, value, option) \ + set_option_or_property_impl(__FILE__, __LINE__, (property), (format), (value), (option)) +#define set_property_string(property, value) \ + set_property_string_impl(__FILE__, __LINE__, (property), (value)) + // Global handle. static mpv_handle *ctx; MP_NORETURN PRINTF_ATTRIBUTE(1, 2) @@ -65,16 +74,55 @@ static inline mpv_event *wrap_wait_event(void) } } -static inline void check_api_error(int status) +static inline void command_impl(const char *file, int line, const char *cmd[]) { - if (status < 0) - fail("mpv API error: %s\n", mpv_error_string(status)); + int ret = mpv_command(ctx, cmd); + if (ret < 0) + fail("mpv API error while running command '%s' at %s:%d (%s)\n", + cmd[0], file, line, mpv_error_string(ret)); +} + +static inline void command_string_impl(const char *file, int line, const char *cmd) +{ + int ret = mpv_command_string(ctx, cmd); + if (ret < 0) + fail("mpv API error while running command '%s' at %s:%d (%s)\n", + cmd, file, line, mpv_error_string(ret)); +} + +static inline void get_property_impl(const char *file, int line, const char *property, + int format, void *result) +{ + int ret = mpv_get_property(ctx, property, format, result); + if (ret < 0) + fail("mpv API error while getting property '%s' at %s:%d (%s)\n", + property, file, line, mpv_error_string(ret)); +} + +static inline void set_option_or_property_impl(const char *file, int line, const char *property, + int format, void *value, bool option) +{ + int ret = option ? mpv_set_option(ctx, property, format, value) : + mpv_set_property(ctx, property, format, value); + if (ret < 0) + fail("mpv API while setting %s '%s' at %s:%d (%s)\n", option ? "option" : "property", + property, file, line, mpv_error_string(ret)); + +} + +static inline void set_property_string_impl(const char *file, int line, const char *property, + const char *value) +{ + int ret = mpv_set_property_string(ctx, property, value); + if (ret < 0) + fail("mpv API error while setting property '%s' to '%s' at %s:%d (%s)\n", + property, value, file, line, mpv_error_string(ret)); } MP_UNUSED static void check_double(const char *property, double expect) { double result_double; - check_api_error(mpv_get_property(ctx, property, MPV_FORMAT_DOUBLE, &result_double)); + get_property(property, MPV_FORMAT_DOUBLE, &result_double); if (expect != result_double) fail("Double: expected '%f' but got '%f'!\n", expect, result_double); } @@ -82,7 +130,7 @@ MP_UNUSED static void check_double(const char *property, double expect) MP_UNUSED static void check_flag(const char *property, int expect) { int result_flag; - check_api_error(mpv_get_property(ctx, property, MPV_FORMAT_FLAG, &result_flag)); + get_property(property, MPV_FORMAT_FLAG, &result_flag); if (expect != result_flag) fail("Flag: expected '%d' but got '%d'!\n", expect, result_flag); } @@ -90,7 +138,7 @@ MP_UNUSED static void check_flag(const char *property, int expect) MP_UNUSED static void check_int(const char *property, int64_t expect) { int64_t result_int; - check_api_error(mpv_get_property(ctx, property, MPV_FORMAT_INT64, &result_int)); + get_property(property, MPV_FORMAT_INT64, &result_int); if (expect != result_int) fail("Int: expected '%" PRId64 "' but got '%" PRId64 "'!\n", expect, result_int); } @@ -98,7 +146,7 @@ MP_UNUSED static void check_int(const char *property, int64_t expect) MP_UNUSED static inline void check_string(const char *property, const char *expect) { char *result_string; - check_api_error(mpv_get_property(ctx, property, MPV_FORMAT_STRING, &result_string)); + get_property(property, MPV_FORMAT_STRING, &result_string); if (strcmp(expect, result_string) != 0) fail("String: expected '%s' but got '%s'!\n", expect, result_string); mpv_free(result_string); @@ -106,16 +154,20 @@ MP_UNUSED static inline void check_string(const char *property, const char *expe static inline void initialize(void) { - check_api_error(mpv_set_option_string(ctx, "vo", "null")); - check_api_error(mpv_set_option_string(ctx, "ao", "null")); - check_api_error(mpv_request_log_messages(ctx, "debug")); - check_api_error(mpv_initialize(ctx)); + set_property_string("vo", "null"); + set_property_string("ao", "null"); + int ret = mpv_request_log_messages(ctx, "debug"); + if (ret < 0) + fail("mpv API error while setting log level to debug: %s\n", mpv_error_string(ret)); + ret = mpv_initialize(ctx); + if (ret < 0) + fail("mpv API error while initializing mpv: %s\n", mpv_error_string(ret)); } static inline void reload_file(const char *path) { const char *cmd[] = {"loadfile", path, NULL}; - check_api_error(mpv_command(ctx, cmd)); + command(cmd); bool loaded = false; while (!loaded) { mpv_event *event = wrap_wait_event(); diff --git a/test/libmpv_encode.c b/test/libmpv_encode.c index e28f06fb8b..861b9d2537 100644 --- a/test/libmpv_encode.c +++ b/test/libmpv_encode.c @@ -93,19 +93,19 @@ int main(int argc, char *argv[]) out_path = path; #endif - check_api_error(mpv_set_option_string(ctx, "o", out_path)); - check_api_error(mpv_set_option_string(ctx, "of", "matroska")); - check_api_error(mpv_set_option_string(ctx, "end", "1.5")); - check_api_error(mpv_set_option_string(ctx, "terminal", "yes")); - check_api_error(mpv_set_option_string(ctx, "msg-level", "all=v")); + set_property_string("o", out_path); + set_property_string("of", "matroska"); + set_property_string("end", "1.5"); + set_property_string("terminal", "yes"); + set_property_string("msg-level", "all=v"); if (mpv_initialize(ctx) != 0) return 1; - check_api_error(mpv_set_option_string(ctx, "idle", "once")); + set_property_string("idle", "once"); const char *cmd[] = {"loadfile", "av://lavfi:testsrc", NULL}; - check_api_error(mpv_command(ctx, cmd)); + command(cmd); wait_done(); mpv_destroy(ctx); diff --git a/test/libmpv_test_file_loading.c b/test/libmpv_test_file_loading.c index e839c244ad..4be326fb57 100644 --- a/test/libmpv_test_file_loading.c +++ b/test/libmpv_test_file_loading.c @@ -20,7 +20,7 @@ static void test_file_loading(char *file) { const char *cmd[] = {"loadfile", file, NULL}; - check_api_error(mpv_command(ctx, cmd)); + command(cmd); bool loaded = false; bool finished = false; while (!finished) { @@ -58,7 +58,7 @@ int main(int argc, char *argv[]) test_file_loading(argv[1]); printf("================ SHUTDOWN ================\n"); - mpv_command_string(ctx, "quit"); + command_string("quit"); while (wrap_wait_event()->event_id != MPV_EVENT_SHUTDOWN) {} return 0; diff --git a/test/libmpv_test_lavfi_complex.c b/test/libmpv_test_lavfi_complex.c index 1614fd81f7..e4ffd4fed2 100644 --- a/test/libmpv_test_lavfi_complex.c +++ b/test/libmpv_test_lavfi_complex.c @@ -20,7 +20,7 @@ static void test_lavfi_complex(char *file) { const char *cmd[] = {"loadfile", file, NULL}; - check_api_error(mpv_command(ctx, cmd)); + command(cmd); bool finished = false; bool loaded = false; while (!finished) { @@ -29,10 +29,10 @@ static void test_lavfi_complex(char *file) case MPV_EVENT_FILE_LOADED: // Add file as external and toggle lavfi-complex on. if (!loaded) { - check_api_error(mpv_set_property_string(ctx, "external-files", file)); + set_property_string("external-files", file); const char *add_cmd[] = {"video-add", file, "auto", NULL}; - check_api_error(mpv_command(ctx, add_cmd)); - check_api_error(mpv_set_property_string(ctx, "lavfi-complex", "[vid1] [vid2] vstack [vo]")); + command(add_cmd); + set_property_string("lavfi-complex", "[vid1] [vid2] vstack [vo]"); } loaded = true; break; @@ -64,7 +64,7 @@ int main(int argc, char *argv[]) test_lavfi_complex(argv[1]); printf("================ SHUTDOWN ================\n"); - mpv_command_string(ctx, "quit"); + command_string("quit"); while (wrap_wait_event()->event_id != MPV_EVENT_SHUTDOWN) {} return 0; diff --git a/test/libmpv_test_options.c b/test/libmpv_test_options.c index f194fee270..8066638548 100644 --- a/test/libmpv_test_options.c +++ b/test/libmpv_test_options.c @@ -49,20 +49,20 @@ static void set_options_and_properties(const char *options[], const char *proper for (int i = 0; options[i]; i++) { switch (formats[i]) { case MPV_FORMAT_STRING: - check_api_error(mpv_set_option(ctx, options[i], formats[i], &str)); - check_api_error(mpv_set_property(ctx, properties[i], formats[i], &str)); + set_option_or_property(options[i], formats[i], &str, true); + set_option_or_property(properties[i], formats[i], &str, false); break; case MPV_FORMAT_FLAG: - check_api_error(mpv_set_option(ctx, options[i], formats[i], &flag)); - check_api_error(mpv_set_property(ctx, properties[i], formats[i], &flag)); + set_option_or_property(options[i], formats[i], &flag, true); + set_option_or_property(properties[i], formats[i], &flag, false); break; case MPV_FORMAT_INT64: - check_api_error(mpv_set_option(ctx, options[i], formats[i], &int_)); - check_api_error(mpv_set_property(ctx, properties[i], formats[i], &int_)); + set_option_or_property(options[i], formats[i], &int_, true); + set_option_or_property(properties[i], formats[i], &int_, false); break; case MPV_FORMAT_DOUBLE: - check_api_error(mpv_set_option(ctx, options[i], formats[i], &double_)); - check_api_error(mpv_set_property(ctx, properties[i], formats[i], &double_)); + set_option_or_property(options[i], formats[i], &double_, true); + set_option_or_property(properties[i], formats[i], &double_, false); break; } } @@ -105,7 +105,7 @@ static void test_options_and_properties(void) // Ensure the format is still MPV_FORMAT_FLAG for these property types. mpv_node result_node; - check_api_error(mpv_get_property(ctx, "idle-active", MPV_FORMAT_NODE, &result_node)); + get_property("idle-active", MPV_FORMAT_NODE, &result_node); if (result_node.format != MPV_FORMAT_FLAG) fail("Node: expected mpv format '%d' but got '%d'!\n", MPV_FORMAT_FLAG, result_node.format); @@ -132,7 +132,7 @@ int main(int argc, char *argv[]) test_options_and_properties(); printf("================ SHUTDOWN ================\n"); - mpv_command_string(ctx, "quit"); + command_string("quit"); while (wrap_wait_event()->event_id != MPV_EVENT_SHUTDOWN) {} return 0; diff --git a/test/libmpv_test_sdh_filter.c b/test/libmpv_test_sdh_filter.c index bbad7da6a7..662108becc 100644 --- a/test/libmpv_test_sdh_filter.c +++ b/test/libmpv_test_sdh_filter.c @@ -33,9 +33,9 @@ static void test_sdh_filter(char *file, char *path, char *harder) if (ret) fail("Test file, '%s', was not found!\n", path); - check_api_error(mpv_set_property_string(ctx, "sub-filter-sdh", "yes")); + set_property_string("sub-filter-sdh", "yes"); if (harder) - check_api_error(mpv_set_property_string(ctx, "sub-filter-sdh-harder", "yes")); + set_property_string("sub-filter-sdh-harder", "yes"); char *expect = ""; if (strcmp(file, "sdh_default") == 0 && harder) { @@ -91,13 +91,13 @@ int main(int argc, char *argv[]) const char *fmt = "================ TEST: %s %s ================\n"; printf(fmt, "test_sdh_filter", argv[1]); // Set pause and start from 1 second to ensure the subtitle is loaded. - mpv_set_property_string(ctx, "pause", "yes"); - mpv_set_property_string(ctx, "start", "1"); + set_property_string("pause", "yes"); + set_property_string("start", "1"); mpv_observe_property(ctx, 0, "sub-text", MPV_FORMAT_STRING); test_sdh_filter(argv[1], argv[2], argv[3]); printf("================ SHUTDOWN ================\n"); - mpv_command_string(ctx, "quit"); + command_string("quit"); while (wrap_wait_event()->event_id != MPV_EVENT_SHUTDOWN) {} return 0; diff --git a/test/libmpv_test_track_selection.c b/test/libmpv_test_track_selection.c index 1b8f9d4c2c..8775669d00 100644 --- a/test/libmpv_test_track_selection.c +++ b/test/libmpv_test_track_selection.c @@ -106,12 +106,12 @@ static void test_track_selection(char *file, char *path) check_string("current-tracks/sub/selected", "yes"); // --subs-falback=no - check_api_error(mpv_set_property_string(ctx, "subs-fallback", "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 - check_api_error(mpv_set_property_string(ctx, "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 || @@ -125,7 +125,7 @@ static void test_track_selection(char *file, char *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 - check_api_error(mpv_set_property_string(ctx, "subs-fallback-forced", "always")); + 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) { @@ -134,7 +134,7 @@ static void test_track_selection(char *file, char *path) check_string("track-list/2/selected", "no"); // --subs-fallback=yes - check_api_error(mpv_set_property_string(ctx, "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) { @@ -143,26 +143,26 @@ static void test_track_selection(char *file, char *path) check_string("current-tracks/sub/lang", "eng"); // default german subs - check_api_error(mpv_set_property_string(ctx, "subs-match-os-language", "no")); + 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 - check_api_error(mpv_set_property_string(ctx, "alang", "jpn")); + 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 - check_api_error(mpv_set_property_string(ctx, "alang", "pol")); + 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 - check_api_error(mpv_set_property_string(ctx, "alang", "eng")); - check_api_error(mpv_set_property_string(ctx, "slang", "eng")); - check_api_error(mpv_set_property_string(ctx, "subs-with-matching-audio", "no")); + 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"); @@ -171,65 +171,65 @@ static void test_track_selection(char *file, char *path) check_string("track-list/8/selected", "no"); // --subs-with-matching-audio=forced checks - check_api_error(mpv_set_property_string(ctx, "subs-with-matching-audio", "forced")); + 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 - check_api_error(mpv_set_property_string(ctx, "alang", "jpn")); - check_api_error(mpv_set_property_string(ctx, "slang", "jpn")); + 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 - check_api_error(mpv_set_property_string(ctx, "alang", "ger")); - check_api_error(mpv_set_property_string(ctx, "slang", "ger")); + 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 - check_api_error(mpv_set_property_string(ctx, "alang", "it")); - check_api_error(mpv_set_property_string(ctx, "slang", "pt,it,pol,ger")); + 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 - check_api_error(mpv_set_property_string(ctx, "alang", "ger")); - check_api_error(mpv_set_property_string(ctx, "slang", "jpn,pol")); - check_api_error(mpv_set_property_string(ctx, "subs-with-matching-audio", "yes")); - check_api_error(mpv_set_property_string(ctx, "subs-fallback-forced", "always")); + 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 - check_api_error(mpv_set_property_string(ctx, "subs-match-os-language", "no")); - check_api_error(mpv_set_property_string(ctx, "alang", "jpn")); + 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 - check_api_error(mpv_set_property_string(ctx, "alang", "eng")); + set_property_string("alang", "eng"); reload_file(path); check_string("track-list/4/selected", "yes"); // default jpn subs - check_api_error(mpv_set_property_string(ctx, "subs-fallback-forced", "no")); + set_property_string("subs-fallback-forced", "no"); reload_file(path); check_string("track-list/3/selected", "yes"); // default eng subs - check_api_error(mpv_set_property_string(ctx, "slang", "eng")); + set_property_string("slang", "eng"); reload_file(path); check_string("track-list/6/selected", "yes"); // no subs - check_api_error(mpv_set_property_string(ctx, "slang", "")); - check_api_error(mpv_set_property_string(ctx, "subs-fallback", "no")); + 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"); @@ -237,7 +237,7 @@ static void test_track_selection(char *file, char *path) check_string("track-list/6/selected", "no"); // untagged eng subs - check_api_error(mpv_set_property_string(ctx, "sid", "3")); + set_property_string("sid", "3"); reload_file(path); check_string("track-list/5/selected", "yes"); } @@ -266,7 +266,7 @@ int main(int argc, char *argv[]) test_track_selection(argv[1], argv[2]); printf("================ SHUTDOWN ================\n"); - mpv_command_string(ctx, "quit"); + command_string("quit"); while (wrap_wait_event()->event_id != MPV_EVENT_SHUTDOWN) {} return 0;