From 3b64bf908a9af3d9f3b56a3b7f57239cb3d1e54a Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 15 Apr 2024 18:35:44 +0200 Subject: [PATCH] test: add an encoding test with libmpv --- test/libmpv_encode.c | 138 +++++++++++++++++++++++++++++++++++++++++++ test/meson.build | 10 +++- 2 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 test/libmpv_encode.c diff --git a/test/libmpv_encode.c b/test/libmpv_encode.c new file mode 100644 index 0000000000..49ca166310 --- /dev/null +++ b/test/libmpv_encode.c @@ -0,0 +1,138 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +// Stolen from osdep/compiler.h +#ifdef __GNUC__ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format(printf, a1, a2))) +#define MP_NORETURN __attribute__((noreturn)) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#define MP_NORETURN +#endif + +// Broken crap with __USE_MINGW_ANSI_STDIO +#if defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__) +#undef PRINTF_ATTRIBUTE +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (gnu_printf, a1, a2))) +#endif + +// Global handle +static mpv_handle *ctx; +// Temporary output file +static const char *out_path; + +static void exit_cleanup(void) +{ + if (ctx) + mpv_destroy(ctx); + if (out_path) + unlink(out_path); +} + +MP_NORETURN PRINTF_ATTRIBUTE(1, 2) +static void fail(const char *fmt, ...) +{ + if (fmt) { + va_list va; + va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); + } + exit(1); +} + +static void check_api_error(int status) +{ + if (status < 0) + fail("libmpv error: %s\n", mpv_error_string(status)); +} + +static void wait_done(void) +{ + while (1) { + mpv_event *ev = mpv_wait_event(ctx, -1.0); + if (ev->event_id == MPV_EVENT_NONE) + continue; + printf("event: %s\n", mpv_event_name(ev->event_id)); + if (ev->event_id == MPV_EVENT_SHUTDOWN) + return; + } +} + +static void check_output(int fd) +{ + off_t size = lseek(fd, 0, SEEK_END); + if (size < 100) + fail("did not encode anything"); + + char magic[4] = {0}; + lseek(fd, 0, SEEK_SET); + read(fd, magic, sizeof(magic)); + static const char ebml_magic[] = {26, 69, 223, 163}; + if (memcmp(magic, ebml_magic, 4) != 0) + fail("output was not Matroska"); + + puts("output file ok"); +} + +int main(int argc, char *argv[]) +{ + atexit(exit_cleanup); + + ctx = mpv_create(); + if (!ctx) + return 1; + + int fd; + { + char path[] = "./testout.XXXXXX"; + fd = mkstemp(path); + if (fd == -1) + fail("mkstemp failed"); + out_path = strdup(path); + } + 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")); + + if (mpv_initialize(ctx) != 0) + return 1; + + check_api_error(mpv_set_option_string(ctx, "terminal", "yes")); + check_api_error(mpv_set_option_string(ctx, "msg-level", "all=v")); + check_api_error(mpv_set_option_string(ctx, "idle", "once")); + + const char *cmd[] = {"loadfile", "av://lavfi:testsrc", NULL}; + check_api_error(mpv_command(ctx, cmd)); + + wait_done(); + mpv_destroy(ctx); + ctx = NULL; + + check_output(fd); + close(fd); + + return 0; +} diff --git a/test/meson.build b/test/meson.build index 27b794d0a5..e34d72ca02 100644 --- a/test/meson.build +++ b/test/meson.build @@ -115,10 +115,14 @@ paths = executable('paths', 'paths.c', include_directories: incdir, test('paths', paths) if get_option('libmpv') - libmpv_test = executable('libmpv-test', 'libmpv_test.c', - include_directories: incdir, link_with: libmpv) + exe = executable('libmpv-test', 'libmpv_test.c', + include_directories: incdir, link_with: libmpv) file = join_paths(source_root, 'etc', 'mpv-icon-8bit-16x16.png') - test('libmpv', libmpv_test, args: file, timeout: 60) + test('libmpv', exe, args: file, timeout: 60) + + exe = executable('libmpv-encode', 'libmpv_encode.c', + include_directories: incdir, link_with: libmpv) + test('libmpv-encode', exe, timeout: 30) endif # Supported libavutil versions that work with these tests.