diff options
81 files changed, 1584 insertions, 736 deletions
@@ -5,7 +5,7 @@ build*/ compile_commands.json data/ docs/**/*.html -env/bin/ +env/msvc-root/ result src/portal/cpy/portal.c src/portal/cpy/portal.h @@ -13,6 +13,7 @@ src/portal/py/config.py src/portal/vendor/* subprojects/BLAKE3-*/ subprojects/SPIRV-Cross-*/ +subprojects/SPIRV-Tools-*/ subprojects/c89atomic-*/ subprojects/c89atomic.wrap subprojects/cairo.wrap @@ -60,6 +61,7 @@ subprojects/libxml2-*/ subprojects/libxml2.wrap subprojects/linmath.h-*/ subprojects/miniaudio-*/ +subprojects/msvc-wine/ subprojects/notcurses-*/ subprojects/packagecache/ subprojects/pcre2-*/ diff --git a/cross/i686-w64-mingw32.txt b/cross/i686-w64-mingw32.txt index e07fa49..159c662 100644 --- a/cross/i686-w64-mingw32.txt +++ b/cross/i686-w64-mingw32.txt @@ -1,15 +1,15 @@ [binaries] c = 'i686-w64-mingw32-gcc' cpp = 'i686-w64-mingw32-g++' -ar = 'i686-w64-mingw32-gcc-ar' +ar = 'i686-w64-mingw32-ar' strip = 'i686-w64-mingw32-strip' windres = 'i686-w64-mingw32-windres' dlltool = 'i686-w64-mingw32-dlltool' exe_wrapper = 'wine' [properties] -nm = 'i686-w64-mingw32-gcc-nm' -ar = 'i686-w64-mingw32-gcc-ar' +ar = 'i686-w64-mingw32-ar' +nm = 'i686-w64-mingw32-nm' needs_exe_wrapper = true [host_machine] diff --git a/cross/x86_64-w64-mingw32.txt b/cross/x86_64-w64-mingw32.txt index 37e4e24..2bc8756 100644 --- a/cross/x86_64-w64-mingw32.txt +++ b/cross/x86_64-w64-mingw32.txt @@ -3,15 +3,15 @@ [binaries] c = 'x86_64-w64-mingw32-gcc' cpp = 'x86_64-w64-mingw32-g++' -ar = 'x86_64-w64-mingw32-gcc-ar' +ar = 'x86_64-w64-mingw32-ar' strip = 'x86_64-w64-mingw32-strip' windres = 'x86_64-w64-mingw32-windres' dlltool = 'x86_64-w64-mingw32-dlltool' exe_wrapper = 'wine64' [properties] -nm = 'x86_64-w64-mingw32-gcc-nm' -ar = 'x86_64-w64-mingw32-gcc-ar' +ar = 'x86_64-w64-mingw32-ar' +nm = 'x86_64-w64-mingw32-nm' needs_exe_wrapper = true [host_machine] diff --git a/cross/x86_64-w64-msvc-clang.txt b/cross/x86_64-w64-msvc-clang.txt new file mode 100644 index 0000000..f269f63 --- /dev/null +++ b/cross/x86_64-w64-msvc-clang.txt @@ -0,0 +1,24 @@ +[binaries] +c = 'clang-cl' +c_ld = 'lld-link' +cpp = 'clang-cl' +cpp_ld = 'lld-link' +ar = 'llvm-lib' +nm = 'llvm-objdump' +dlltool = 'llvm-dlltool' +windres = 'llvm-rc' +pkg-config = '' +exe_wrapper = 'wine64' + +[properties] +c_args = ['--target=x86_64-windows-msvc', '-fuse-ld=lld'] +cpp_args = ['--target=x86_64-windows-msvc', '-fuse-ld=lld'] +ar = 'llvm-lib' +nm = 'llvm-objdump' +needs_exe_wrapper = true + +[host_machine] +system = 'windows' +cpu_family = 'x86_64' +cpu = 'x86_64' +endian = 'little' diff --git a/env/mingw_build.sh b/env/mingw_build.sh new file mode 100644 index 0000000..805c4f5 --- /dev/null +++ b/env/mingw_build.sh @@ -0,0 +1,12 @@ +#! /usr/bin/env sh +meson setup build-mingw64 -Drenderer-api=vulkan -Drenderer=libplacebo \ + -Dsink-only=false -Dserver=enabled -Dportal=disabled -Dclient=disabled \ + -Dcodecs=ffmpeg -Dcodec-hwaccel=enabled -Dsubtitles=enabled \ + -Dtests=disabled -Dwin32-compat=false --cross-file ./cross/x86_64-w64-mingw32.txt \ + --default-library=static --buildtype=release --optimization=2 -Ddebug=false --strip + +meson setup build-mingw32-min -Drenderer-api=gl -Drenderer=momo \ + -Dsink-only=false -Dserver=enabled -Dportal=disabled -Dclient=disabled \ + -Dcodecs=ffmpeg -Dcodec-hwaccel=disabled -Dsubtitles=enabled \ + -Dtests=disabled -Dwin32-compat=true --cross-file ./cross/i686-w64-mingw32.txt \ + --default-library=static --buildtype=release --optimization=s -Ddebug=false --strip diff --git a/env/msvc_build.sh b/env/msvc_build.sh new file mode 100644 index 0000000..ccc5625 --- /dev/null +++ b/env/msvc_build.sh @@ -0,0 +1,13 @@ +#! /usr/bin/env sh + +# meson subprojects download msvc-wine +# ./vsdownload.py --dest env/msvc-root +# ./install.sh env/msvc-root + +BIN=env/msvc-root/bin/x64 . subprojects/msvc-wine/msvcenv-native.sh +export INCLUDE="$HOME/c/camu/subprojects/vulkan-headers-1.4.313/include;/nix/store/jx7aqhh225lhxdxdbiw42mrf2awvpdsq-clang-19.1.7-lib/lib/clang/19/include;$INCLUDE" +CC=clang-cl CXX=clang-cl meson setup build-clang-cl -Drenderer-api=dx11 \ + -Dsink-only=false -Dserver=enabled -Dportal=disabled -Dclient=disabled \ + -Dcodecs=ffmpeg -Dcodec-hwaccel=enabled -Dsubtitles=enabled \ + -Dtests=disabled --cross-file ./cross/x86_64-w64-msvc-clang.txt --default-library=static --buildtype=release \ + --optimization=2 -Ddebug=false --strip -Db_vscrt=static_from_buildtype @@ -23,11 +23,11 @@ ] }, "locked": { - "lastModified": 1747279714, - "narHash": "sha256-UdxlE8yyrKiGq3bgGyJ78AdFwh+fuRAruKtyFY5Zq5I=", + "lastModified": 1748134483, + "narHash": "sha256-5PBK1nV8X39K3qUj8B477Aa2RdbLq3m7wRxUKRtggX4=", "owner": "nix-community", "repo": "home-manager", - "rev": "954615c510c9faa3ee7fb6607ff72e55905e69f2", + "rev": "c1e671036224089937e111e32ea899f59181c383", "type": "github" }, "original": { @@ -39,11 +39,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1747129300, - "narHash": "sha256-L3clA5YGeYCF47ghsI7Tcex+DnaaN/BbQ4dR2wzoiKg=", + "lastModified": 1747900541, + "narHash": "sha256-dn64Pg9xLETjblwZs9Euu/SsjW80pd6lr5qSiyLY1pg=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "e81fd167b33121269149c57806599045fd33eeed", + "rev": "11f2d9ea49c3e964315215d6baa73a8d42672f06", "type": "github" }, "original": { @@ -91,11 +91,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1747179050, - "narHash": "sha256-qhFMmDkeJX9KJwr5H32f1r7Prs7XbQWtO0h3V0a0rFY=", + "lastModified": 1748026106, + "narHash": "sha256-6m1Y3/4pVw1RWTsrkAK2VMYSzG4MMIj7sqUy7o8th1o=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "adaa24fbf46737f3f1b5497bf64bae750f82942e", + "rev": "063f43f2dbdef86376cc29ad646c45c46e93234c", "type": "github" }, "original": { @@ -18,7 +18,7 @@ outputs = { self, nixpkgs, nixos-hardware, nixos-wsl, home-manager }: let overlays = [ (self: super: { - libplacebo = super.libplacebo.overrideAttrs (old: { + libplacebo = super.libplacebo.overrideAttrs (oldAttrs: { patches = [ ./subprojects/packagefiles/libplacebo/cache_ref_rect.diff ./subprojects/packagefiles/libplacebo/compiler_warnings.diff @@ -27,7 +27,7 @@ ./subprojects/packagefiles/libplacebo/info_priv_hash.diff ]; }); - libcue = super.libcue.overrideAttrs (old: { + libcue = super.libcue.overrideAttrs (oldAttrs: { patches = [ ./subprojects/packagefiles/libcue/55.diff # https://github.com/lipnitsk/libcue/pull/4 @@ -52,13 +52,22 @@ "i686-linux" "aarch64-linux" ] (system: - function (import nixpkgs { + function (import (nixpkgs.legacyPackages.${system}.applyPatches { + src = nixpkgs; + name = "nixpkgs-camu"; + patches = [ ]; + }) { inherit system; config = { allowUnfree = true; android_sdk.accept_license = true; }; })); + buildWithFlags = (pkg: flags: + pkg.overrideAttrs (oldAttrs: { + env.NIX_CFLAGS_COMPILE = (oldAttrs.env.NIX_CFLAGS_COMPILE or "") + " ${flags}"; + }) + ); in rec { packages = forAllSupportedSystems (pkgs: { default = with pkgs; stdenv.mkDerivation { @@ -228,10 +237,11 @@ }; mingw64 = with pkgs; let - gcc = pkgsCross.ucrt64.buildPackages.wrapCC - (pkgsCross.ucrt64.buildPackages.gcc-unwrapped.override ({ + gcc = pkgsCross.ucrt64.buildPackages.wrapCCWith { + cc = (pkgsCross.ucrt64.buildPackages.gcc-unwrapped.override ({ threadsCross = { model = "win32"; package = null; }; })); + }; gccWin32Stdenv = overrideCC pkgsCross.ucrt64.stdenv gcc; in mkShell.override { stdenv = gccWin32Stdenv; } { # Note that `cc` has to invoke a native compiler not a cross compiler. @@ -251,6 +261,11 @@ cmake gdb wineWowPackages.staging + # clang-cl + clang + msitools + lld + libllvm # wine build flex bison @@ -270,16 +285,22 @@ ]; buildInputs = with pkgsCross.ucrt64; [ (zlib.override { static = true; shared = false; }) + (bzip2.override { enableStatic = true; enableShared = false; }) + #(shaderc.overrideAttrs (oldAttrs: { + # cmakeFlags = oldAttrs.cmakeFlags ++ [ "-DBUILD_STATIC_LIBS=ON" "-DBUILD_SHARED_LIBS=OFF" ]; + #})) (soxr.overrideAttrs (oldAttrs: { - cmakeFlags = [ "-DBUILD_STATIC_LIBS=ON" "-DBUILD_SHARED_LIBS=OFF" ]; + cmakeFlags = oldAttrs.cmakeFlags ++ [ "-DBUILD_STATIC_LIBS=ON" "-DBUILD_SHARED_LIBS=OFF" ]; })) (openssl.override { static = true; }) xxHash (libiconv.override { enableStatic = true; enableShared = false; }) vulkan-headers ]; + # https://old.reddit.com/r/NixOS/comments/1c4lc1n/how_to_run_this_minimal_python_script_with/kzpao62/ shellHook = '' export SHELL="${pkgs.bashInteractive}/bin/bash" + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pkgs.stdenv.cc.cc.lib}/lib" export NIX_BUILD_SHELL=$SHELL export NIX_SHELL="camu-mingw64" export PS1="(\$NIX_SHELL)"$PS1 @@ -287,25 +308,29 @@ }; mingw32 = with pkgs; let - gcc = pkgsCross.mingw32.buildPackages.wrapCC - (pkgsCross.mingw32.buildPackages.gcc-unwrapped.override ({ + gcc = pkgsCross.mingw32.buildPackages.wrapCCWith { + cc = (pkgsCross.mingw32.buildPackages.gcc-unwrapped.override (old: { threadsCross = { model = "win32"; package = null; }; })); + }; gccWin32Stdenv = overrideCC pkgsCross.mingw32.stdenv gcc; in mkShell.override { stdenv = gccWin32Stdenv; } { NIX_HARDENING_ENABLE = ""; nativeBuildInputs = mingw64.nativeBuildInputs; buildInputs = with pkgsCross.mingw32; [ - (zlib.override { static = true; shared = false; }) - (soxr.overrideAttrs (oldAttrs: { - cmakeFlags = [ "-DBUILD_STATIC_LIBS=ON" "-DBUILD_SHARED_LIBS=OFF" ]; + ((buildWithFlags zlib "-Os").override { static = true; shared = false; }) + ((buildWithFlags bzip2 "-Os").override { enableStatic = true; enableShared = false; }) + ((buildWithFlags soxr "-Os").overrideAttrs (oldAttrs: { + cmakeFlags = oldAttrs.cmakeFlags ++ [ "-DBUILD_STATIC_LIBS=ON" "-DBUILD_SHARED_LIBS=OFF" ]; })) - (openssl.override { static = true; }) - xxHash - (libiconv.override { enableStatic = true; enableShared = false; }) + ((buildWithFlags openssl "-Os").override { static = true; }) + (buildWithFlags xxHash "-Os") + ((buildWithFlags libiconv "-Os").override { enableStatic = true; enableShared = false; }) + vulkan-headers ]; shellHook = '' export SHELL="${pkgs.bashInteractive}/bin/bash" + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pkgs.stdenv.cc.cc.lib}/lib" export NIX_BUILD_SHELL=$SHELL export NIX_SHELL="camu-mingw32" export PS1="(\$NIX_SHELL)"$PS1 diff --git a/meson.build b/meson.build index 947fd9a..0c136ee 100644 --- a/meson.build +++ b/meson.build @@ -1,8 +1,13 @@ -project('camu', 'c', version: '0.01', +project('camu', ['c', 'cpp'], # Marking cpp here is required for subproject cross-builds. + version: '0.01', meson_version: '>=0.63.0', default_options: ['warning_level=2', 'c_std=c99'], license: 'GPL-3.0-only') +# Fail early if 'Compiler for build machine not found'. +add_languages('c', native: true) +add_languages('cpp', native: true) + compiler = meson.get_compiler('c') cmake = import('cmake') @@ -10,10 +15,11 @@ is_debug = get_option('debug') is_minsize = get_option('optimization') == 's' is_linux = host_machine.system() == 'linux' is_windows = host_machine.system() == 'windows' +is_msvc = compiler.get_id() == 'msvc' or compiler.get_id() == 'clang-cl' is_android = host_machine.system() == 'android' -alabaster = subproject('libalabaster', default_options: ['tests=false']) -naunet_opts = ['tests=false'] +alabaster = subproject('libalabaster') +naunet_opts = [] if get_option('portal').enabled() naunet_opts += ['json=enabled', 'curl=enabled'] endif @@ -30,7 +36,7 @@ no_video = meson.is_subproject() stela_opts += get_option('renderer-api') == 'vulkan' ? 'window=glfw' : 'window=wayland' elif is_android stela_opts += 'window=glfm' - elif is_windows and get_option('renderer-api') == 'dx11' + elif is_windows stela_opts += 'window=win32' else stela_opts += 'window=glfw' @@ -40,7 +46,7 @@ no_video = meson.is_subproject() elif get_option('renderer-api') == 'dx11' stela_opts += 'api=dx11' else - stela_opts += get_option('renderer') == 'tiger' ? 'api=gles' : 'api=gl' + stela_opts += 'api=gl' endif if get_option('renderer-api') == 'gl-rpi' stela_opts += 'egl-brcm=true' @@ -81,6 +87,6 @@ if not meson.is_subproject() subdir('src/fruits') endif -if get_option('tests') +if get_option('tests').auto() and not meson.is_subproject() subdir('tests') endif diff --git a/meson_options.txt b/meson_options.txt index a9053ce..47ea575 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,6 +1,6 @@ option('codecs', type: 'array', choices: ['ffmpeg', 'stb_image', 'spng', 'wuffs'], value: ['ffmpeg']) option('codec-hwaccel', type: 'feature', value: 'disabled') -option('renderer', type: 'combo', choices: ['libplacebo', 'tiger'], value: 'libplacebo') +option('renderer', type: 'combo', choices: ['libplacebo', 'momo'], value: 'libplacebo') option('renderer-api', type: 'combo', choices: ['vulkan', 'dx11', 'gl', 'gl-rpi'], value: 'gl') option('subtitles', type: 'feature', value: 'enabled') @@ -10,4 +10,5 @@ option('sink', type: 'feature', value: 'enabled') option('sink-only', type: 'boolean', value: false) option('client', type: 'feature', value: 'disabled') -option('tests', type: 'boolean', value: false) +option('win32-compat', type: 'boolean', value: false, yield: true) +option('tests', type: 'feature', value: 'auto', yield: true) diff --git a/src/codec/codec.h b/src/codec/codec.h index 14727d3..16e408c 100644 --- a/src/codec/codec.h +++ b/src/codec/codec.h @@ -35,8 +35,8 @@ enum { enum { CAMU_STREAM_UNKNOWN = AVMEDIA_TYPE_UNKNOWN, - CAMU_STREAM_AUDIO = AVMEDIA_TYPE_AUDIO, // 1 CAMU_STREAM_VIDEO = AVMEDIA_TYPE_VIDEO, // 0 + CAMU_STREAM_AUDIO = AVMEDIA_TYPE_AUDIO, // 1 CAMU_STREAM_SUBTITLE = AVMEDIA_TYPE_SUBTITLE, CAMU_STREAM_ATTACHMENT = AVMEDIA_TYPE_ATTACHMENT }; @@ -77,12 +77,13 @@ enum { CAMU_SEEK_SIZE = 0x10000 }; +// Using values from FFmpeg for potentially less confusing errors. enum { CAMU_STREAM_UNKNOWN = -1, - CAMU_STREAM_AUDIO, - CAMU_STREAM_VIDEO, - CAMU_STREAM_SUBTITLE, - CAMU_STREAM_ATTACHMENT + CAMU_STREAM_VIDEO = 0, + CAMU_STREAM_AUDIO = 1, + CAMU_STREAM_SUBTITLE = 3, + CAMU_STREAM_ATTACHMENT = 4 }; enum { @@ -126,7 +127,11 @@ struct camu_audio_format { s32 format; s32 sample_rate; #ifdef CAMU_HAVE_FFMPEG +#ifndef CAMU_OLD_FFMPEG AVChannelLayout channel_layout; +#else + u64 channel_layout; +#endif #endif s32 channel_count; }; @@ -239,17 +244,49 @@ static inline bool camu_resampler_format_matches(struct camu_resampler_format *f return fmt->in.format == fmt->req.format && fmt->in.sample_rate == fmt->req.sample_rate #ifdef CAMU_HAVE_FFMPEG +#ifndef CAMU_OLD_FFMPEG && av_channel_layout_compare(&fmt->in.channel_layout, &fmt->req.channel_layout) == 0 +#else + && fmt->in.channel_layout == fmt->req.channel_layout +#endif #endif && fmt->in.channel_count == fmt->req.channel_count; } +#ifndef CAMU_OLD_FFMPEG +#define AV_CODECPAR_CHANNEL_LAYOUT(codecpar) ((codecpar)->ch_layout) +#define AV_CODECPAR_CHANNELS(codecpar) ((codecpar)->ch_layout.nb_channels) +static inline void camu_default_channel_layout(AVChannelLayout *ch_layout, s32 channels) +{ + av_channel_layout_default(ch_layout, channels); +} +static inline void camu_copy_channel_layout(AVChannelLayout *dest, AVChannelLayout *src) +{ + av_channel_layout_copy(dest, src); +} +#else +#define AV_CODECPAR_CHANNEL_LAYOUT(codecpar) ((codecpar)->channel_layout) +#define AV_CODECPAR_CHANNELS(codecpar) ((codecpar)->channels) +static inline void camu_default_channel_layout(u64 *channel_layout, s32 channels) +{ + *channel_layout = av_get_default_channel_layout(channels); +} +static inline void camu_copy_channel_layout(u64 *dest, u64 *src) +{ + *dest = *src; +} +#endif + static inline void camu_audio_format_copy(struct camu_audio_format *dest, struct camu_audio_format *src) { dest->format = src->format; dest->sample_rate = src->sample_rate; #ifdef CAMU_HAVE_FFMPEG +#ifndef CAMU_OLD_FFMPEG av_channel_layout_copy(&dest->channel_layout, &src->channel_layout); +#else + dest->channel_layout = src->channel_layout; +#endif #endif dest->channel_count = src->channel_count; } diff --git a/src/codec/ffmpeg/avio.c b/src/codec/ffmpeg/avio.c index 154152e..86130d8 100644 --- a/src/codec/ffmpeg/avio.c +++ b/src/codec/ffmpeg/avio.c @@ -2,20 +2,20 @@ #include "../../cache/handle.h" -s32 camu_avio_read(void *data, u8 *buf, s32 count) +s32 camu_avio_read(void *opaque, u8 *buf, s32 count) { - struct cch_handle *handle = (struct cch_handle *)data; + struct cch_handle *handle = (struct cch_handle *)opaque; return cch_handle_read(handle, buf, count); } -s32 camu_avio_write(void *data, const u8 *buf, s32 count) +s32 camu_avio_write(void *opaque, u8 *buf, s32 count) { - struct cch_handle *handle = (struct cch_handle *)data; + struct cch_handle *handle = (struct cch_handle *)opaque; return cch_handle_write(handle, buf, count); } -s64 camu_avio_seek(void *data, s64 offset, s32 whence) +s64 camu_avio_seek(void *opaque, s64 offset, s32 whence) { - struct cch_handle *handle = (struct cch_handle *)data; + struct cch_handle *handle = (struct cch_handle *)opaque; return (s64)cch_handle_seek(handle, offset, whence); } diff --git a/src/codec/ffmpeg/avio.h b/src/codec/ffmpeg/avio.h index 04aeeb4..bb67c58 100644 --- a/src/codec/ffmpeg/avio.h +++ b/src/codec/ffmpeg/avio.h @@ -2,5 +2,6 @@ #include <al/types.h> -s32 camu_avio_read(void *data, u8 *buf, s32 buf_size); -s64 camu_avio_seek(void *data, s64 offset, s32 whence); +s32 camu_avio_read(void *opaque, u8 *buf, s32 buf_size); +s32 camu_avio_write(void *opaque, u8 *buf, s32 count); +s64 camu_avio_seek(void *opaque, s64 offset, s32 whence); diff --git a/src/codec/ffmpeg/common.c b/src/codec/ffmpeg/common.c index 259ba90..5226df6 100644 --- a/src/codec/ffmpeg/common.c +++ b/src/codec/ffmpeg/common.c @@ -2,6 +2,7 @@ #include <al/log.h> #include <al/lib.h> #include <libavutil/log.h> +#include <libavformat/avformat.h> #include "common.h" @@ -55,5 +56,8 @@ void camu_ff_set_log_callback(void (*callback)(void *, s32, const char *, va_lis void camu_ff_common_init(void) { log_info("Using FFmpeg version "FFMPEG_VERSION"."); +#ifdef CAMU_OLD_FFMPEG + av_register_all(); +#endif camu_ff_set_log_callback(av_log_callback); } diff --git a/src/codec/ffmpeg/decoder.c b/src/codec/ffmpeg/decoder.c index c22d1c1..e097e0c 100644 --- a/src/codec/ffmpeg/decoder.c +++ b/src/codec/ffmpeg/decoder.c @@ -10,11 +10,11 @@ #endif #ifdef CAMU_FF_DECODER_HWACCEL -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN static const char *hwdevces[] = { "vulkan" }; #elif defined NAUNET_ON_WINDOWS static const char *hwdevces[] = { "d3d11va" }; -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL static const char *hwdevces[] = { "vaapi" }; #endif diff --git a/src/codec/ffmpeg/decoder.h b/src/codec/ffmpeg/decoder.h index ab60ef3..4797060 100644 --- a/src/codec/ffmpeg/decoder.h +++ b/src/codec/ffmpeg/decoder.h @@ -4,8 +4,8 @@ #include "../codec.h" -#ifndef CAMU_SINK_NO_VIDEO -//#define CAMU_FF_DECODER_HWACCEL +#ifdef CAMU_USE_HWACCEL +#define CAMU_FF_DECODER_HWACCEL #endif struct camu_ff_decoder { diff --git a/src/codec/ffmpeg/demuxer.c b/src/codec/ffmpeg/demuxer.c index bf2039f..a5821a2 100644 --- a/src/codec/ffmpeg/demuxer.c +++ b/src/codec/ffmpeg/demuxer.c @@ -88,6 +88,13 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl for (u32 i = 0; i < av->format_context->nb_streams; i++) { AVStream *stream = av->format_context->streams[i]; enum AVMediaType type = stream->codecpar->codec_type; +#ifdef CAMU_OLD_FFMPEG + // This is probably not correct. + if (stream->codecpar->channel_layout == 0) { + stream->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; + stream->codecpar->channels = 2; + } +#endif u64 duration = 0; if (type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_SUBTITLE) { // Try to detect attached images. diff --git a/src/codec/ffmpeg/encoder.c b/src/codec/ffmpeg/encoder.c index 50e80e4..5d90785 100644 --- a/src/codec/ffmpeg/encoder.c +++ b/src/codec/ffmpeg/encoder.c @@ -32,7 +32,7 @@ bool camu_ff_encoder_init(struct camu_ff_encoder *enc, char *encoder_name, char } enc->codec_context->sample_rate = 48000; - av_channel_layout_default(&enc->codec_context->ch_layout, CHANNELS); + camu_default_channel_layout(&AV_CODECPAR_CHANNEL_LAYOUT(enc->codec_context), CHANNELS); enc->codec_context->sample_fmt = AV_SAMPLE_FMT_FLT; enc->codec_context->bit_rate = bitrate; enc->codec_context->frame_size = SAMPLES_PER_FRAME; @@ -62,19 +62,20 @@ bool camu_ff_encoder_init(struct camu_ff_encoder *enc, char *encoder_name, char av_dict_free(&opts); AVCodecContext *out_codec = enc->codec_context; + AVFrame *frame = av_frame_alloc(); + frame->format = out_codec->sample_fmt; + frame->sample_rate = out_codec->sample_rate; + camu_copy_channel_layout(&AV_CODECPAR_CHANNEL_LAYOUT(frame), &AV_CODECPAR_CHANNEL_LAYOUT(out_codec)); + av_samples_alloc(frame->data, NULL, AV_CODECPAR_CHANNELS(out_codec), SAMPLES_PER_FRAME, frame->format, 1); + frame->nb_samples = SAMPLES_PER_FRAME; + frame->pts = 0; - enc->fmt.req.format = out_codec->sample_fmt; - enc->fmt.req.sample_rate = out_codec->sample_rate; - av_channel_layout_copy(&enc->fmt.req.channel_layout, &out_codec->ch_layout); - enc->fmt.req.channel_count = out_codec->ch_layout.nb_channels; + enc->fmt.format = frame->format; + enc->fmt.sample_rate = frame->sample_rate; + camu_copy_channel_layout(&enc->fmt.channel_layout, &AV_CODECPAR_CHANNEL_LAYOUT(frame)); + enc->fmt.channel_count = AV_CODECPAR_CHANNELS(frame); - enc->frame = av_frame_alloc(); - enc->frame->format = enc->fmt.req.format; - enc->frame->sample_rate = enc->fmt.req.sample_rate; - av_channel_layout_copy(&enc->frame->ch_layout, &enc->fmt.req.channel_layout); - av_samples_alloc(enc->frame->data, NULL, enc->frame->ch_layout.nb_channels, SAMPLES_PER_FRAME, enc->frame->format, 1); - enc->frame->nb_samples = SAMPLES_PER_FRAME; - enc->frame->pts = 0; + enc->frame = frame; return true; err: diff --git a/src/codec/ffmpeg/encoder.h b/src/codec/ffmpeg/encoder.h index 5f7d06f..3ace4d8 100644 --- a/src/codec/ffmpeg/encoder.h +++ b/src/codec/ffmpeg/encoder.h @@ -9,7 +9,7 @@ struct camu_ff_encoder { AVCodecContext *codec_context; const AVOutputFormat *output_format; - struct camu_resampler_format fmt; + struct camu_audio_format fmt; AVFrame *frame; void (*callback)(void *, AVPacket *); diff --git a/src/codec/ffmpeg/meson.build b/src/codec/ffmpeg/meson.build index eb68fad..56a75b2 100644 --- a/src/codec/ffmpeg/meson.build +++ b/src/codec/ffmpeg/meson.build @@ -3,6 +3,9 @@ ffmpeg_src = [ 'packet_ext.c', ] ffmpeg_args = ['-DCAMU_HAVE_FFMPEG'] +if get_option('codec-hwaccel').enabled() + ffmpeg_args += ['-DCAMU_USE_HWACCEL'] +endif ffmpeg_deps = [] ffmpeg_server_src = [ @@ -16,8 +19,7 @@ ffmpeg_client_src = [ ffmpeg_src, 'decoder.c', 'resampler.c', - 'scaler.c', - 'encoder.c' + 'scaler.c' ] ffmpeg_client_deps = [] @@ -38,7 +40,12 @@ libavcodec = dependency('libavcodec', required: false) libswresample = dependency('libswresample', required: false) libswscale = dependency('libswscale', required: false) if not (libavutil.found() and libavformat.found() and libavcodec.found() and libswresample.found() and libswscale.found()) - ffmpeg_proj = subproject('ffmpeg', required: false) + if get_option('win32-compat') + ffmpeg_proj = subproject('ffmpeg-compat', required: false) + ffmpeg_args += ['-DCAMU_OLD_FFMPEG'] + else + ffmpeg_proj = subproject('ffmpeg', required: false) + endif if ffmpeg_proj.found() libavutil = ffmpeg_proj.get_variable('avutil') libavformat = ffmpeg_proj.get_variable('avformat') @@ -48,9 +55,12 @@ if not (libavutil.found() and libavformat.found() and libavcodec.found() and lib libswscale = ffmpeg_proj.get_variable('swscale') # Only used to set include dirs for FFmpeg. ffmpeg_deps += [ffmpeg_proj.get_variable('ffmpeg_include')] - # We explicitly enable zlib in the FFmpeg build. + # We explicitly enable zlib and maybe bzlib in the FFmpeg build. ffmpeg_deps += [dependency('zlib')] - if is_windows + if not get_option('sink-only') + ffmpeg_deps += [dependency('bzip2')] + endif + if is_windows and not get_option('win32-compat') # Extra static dependencies for Windows. ffmpeg_client_deps += [compiler.find_library('bcrypt')] elif is_android diff --git a/src/codec/ffmpeg/packet_ext.c b/src/codec/ffmpeg/packet_ext.c index acf5bbd..a1a6a5e 100644 --- a/src/codec/ffmpeg/packet_ext.c +++ b/src/codec/ffmpeg/packet_ext.c @@ -16,7 +16,7 @@ void nn_packet_write_av_codec_parameters(struct nn_packet *packet, AVCodecParame NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->width); NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->height); NNWT_PACKET_WRITE_TYPE(packet, AVRational, codecpar->sample_aspect_ratio); -#if LIBAVCODEC_VERSION_INT >= 60 +#if !defined CAMU_OLD_FFMPEG && LIBAVCODEC_VERSION_INT >= 60 NNWT_PACKET_WRITE_TYPE(packet, AVRational, codecpar->framerate); #endif NNWT_PACKET_WRITE_TYPE(packet, enum AVFieldOrder, codecpar->field_order); @@ -26,6 +26,7 @@ void nn_packet_write_av_codec_parameters(struct nn_packet *packet, AVCodecParame NNWT_PACKET_WRITE_TYPE(packet, enum AVColorSpace, codecpar->color_space); NNWT_PACKET_WRITE_TYPE(packet, enum AVChromaLocation, codecpar->chroma_location); NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->video_delay); +#ifndef CAMU_OLD_FFMPEG // Incomplete. NNWT_PACKET_WRITE_TYPE(packet, enum AVChannelOrder, codecpar->ch_layout.order); if (codecpar->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) { @@ -33,6 +34,10 @@ void nn_packet_write_av_codec_parameters(struct nn_packet *packet, AVCodecParame } else { NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->ch_layout.nb_channels); } +#else + NNWT_PACKET_WRITE_TYPE(packet, u64, codecpar->channel_layout); + NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->channels); +#endif NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->sample_rate); NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->block_align); NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->frame_size); @@ -98,7 +103,9 @@ void nn_packet_write_av_packet(struct nn_packet *packet, AVPacket *pkt) } NNWT_PACKET_WRITE_TYPE(packet, s64, pkt->duration); NNWT_PACKET_WRITE_TYPE(packet, s64, pkt->pos); +#ifndef CAMU_OLD_FFMPEG NNWT_PACKET_WRITE_TYPE(packet, AVRational, pkt->time_base); +#endif } void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParameters *codecpar) @@ -120,7 +127,7 @@ void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParamet NNWT_PACKET_READ_TYPE(packet, s32, codecpar->width); NNWT_PACKET_READ_TYPE(packet, s32, codecpar->height); NNWT_PACKET_READ_TYPE(packet, AVRational, codecpar->sample_aspect_ratio); -#if LIBAVCODEC_VERSION_INT >= 60 +#if !defined CAMU_OLD_FFMPEG && LIBAVCODEC_VERSION_INT >= 60 NNWT_PACKET_READ_TYPE(packet, AVRational, codecpar->framerate); #endif NNWT_PACKET_READ_TYPE(packet, enum AVFieldOrder, codecpar->field_order); @@ -130,6 +137,7 @@ void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParamet NNWT_PACKET_READ_TYPE(packet, enum AVColorSpace, codecpar->color_space); NNWT_PACKET_READ_TYPE(packet, enum AVChromaLocation, codecpar->chroma_location); NNWT_PACKET_READ_TYPE(packet, s32, codecpar->video_delay); +#ifndef CAMU_OLD_FFMPEG enum AVChannelOrder order; NNWT_PACKET_READ_TYPE(packet, enum AVChannelOrder, order); if (order == AV_CHANNEL_ORDER_NATIVE) { @@ -141,6 +149,10 @@ void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParamet NNWT_PACKET_READ_TYPE(packet, s32, nb_channels); av_channel_layout_default(&codecpar->ch_layout, nb_channels); } +#else + NNWT_PACKET_READ_TYPE(packet, u64, codecpar->channel_layout); + NNWT_PACKET_READ_TYPE(packet, s32, codecpar->channels); +#endif NNWT_PACKET_READ_TYPE(packet, s32, codecpar->sample_rate); NNWT_PACKET_READ_TYPE(packet, s32, codecpar->block_align); NNWT_PACKET_READ_TYPE(packet, s32, codecpar->frame_size); @@ -214,5 +226,7 @@ void nn_packet_read_av_packet(struct nn_packet *packet, AVPacket *pkt) } NNWT_PACKET_READ_TYPE(packet, s64, pkt->duration); NNWT_PACKET_READ_TYPE(packet, s64, pkt->pos); +#ifndef CAMU_OLD_FFMPEG NNWT_PACKET_READ_TYPE(packet, AVRational, pkt->time_base); +#endif } diff --git a/src/codec/ffmpeg/packet_ext.h b/src/codec/ffmpeg/packet_ext.h index fab9b36..540cdcb 100644 --- a/src/codec/ffmpeg/packet_ext.h +++ b/src/codec/ffmpeg/packet_ext.h @@ -1,8 +1,7 @@ #pragma once #include <nnwt/packet.h> -#include <libavcodec/packet.h> -#include <libavcodec/codec_par.h> +#include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/dict.h> diff --git a/src/codec/ffmpeg/resampler.c b/src/codec/ffmpeg/resampler.c index eacc75b..48cca8e 100644 --- a/src/codec/ffmpeg/resampler.c +++ b/src/codec/ffmpeg/resampler.c @@ -12,26 +12,35 @@ static bool ff_resampler_init(struct camu_resampler *resamp, struct camu_resampl camu_audio_format_copy(&av->fmt, &fmt->req); - s32 ret = swr_alloc_set_opts2(&av->resample_context, - &fmt->req.channel_layout, fmt->req.format, fmt->req.sample_rate, - &fmt->in.channel_layout, fmt->in.format, fmt->in.sample_rate, 0, NULL); - if (ret != 0) { - log_error("Failed to configure resampler context."); - return false; - } + SwrContext *swr = swr_alloc(); + +#ifndef CAMU_OLD_FFMPEG + av_opt_set_chlayout(swr, "in_chlayout", &fmt->in.channel_layout, 0); + av_opt_set_chlayout(swr, "out_chlayout", &fmt->req.channel_layout, 0); +#else + av_opt_set_channel_layout(swr, "in_channel_layout", fmt->in.channel_layout, 0); + av_opt_set_channel_layout(swr, "out_channel_layout", fmt->req.channel_layout, 0); +#endif + av_opt_set_int(swr, "in_sample_rate", fmt->in.sample_rate, 0); + av_opt_set_int(swr, "out_sample_rate", fmt->req.sample_rate, 0); + av_opt_set_sample_fmt(swr, "in_sample_fmt", fmt->in.format, 0); + av_opt_set_sample_fmt(swr, "out_sample_fmt", fmt->req.format, 0); #ifdef CAMU_HAVE_SOXR // Slower but more accurate resampler. - av_opt_set_int(av->resample_context, "resampler", SWR_ENGINE_SOXR, 0); + av_opt_set_int(swr, "resampler", SWR_ENGINE_SOXR, 0); log_info("Using SoX resampler."); #endif - if (swr_init(av->resample_context) != 0) { - swr_free(&av->resample_context); - log_error("Failed to init resampler context."); + s32 ret = swr_init(swr); + if (ret != 0) { + swr_free(&swr); + log_error("Failed to init resampler context (%s).", av_err2str(ret)); return false; } + av->resample_context = swr; + return true; } @@ -44,7 +53,7 @@ static inline void alloc_sample_data(struct camu_ff_resampler *av, s32 sample_co { if (av->sample_count >= sample_count) return; free_sample_data(av); - s32 nb_channels = av->fmt.channel_layout.nb_channels; + s32 nb_channels = av->fmt.channel_count; av_samples_alloc(av->data, NULL, nb_channels, sample_count, av->fmt.format, 32); av->sample_count = sample_count; } diff --git a/src/fruits/cmc/meson.build b/src/fruits/cmc/meson.build index 864af8a..de6d335 100644 --- a/src/fruits/cmc/meson.build +++ b/src/fruits/cmc/meson.build @@ -19,7 +19,7 @@ if use_tui cmc_deps += [notcurses, notcurses_core, codecs_client] endif -if is_windows and meson.is_cross_build() +if is_windows and not is_msvc cmc_args += ['-static', '-static-libgcc', '-static-libstdc++', '-municode', '-mwindows'] endif diff --git a/src/fruits/cmc/ui/util/waveform.c b/src/fruits/cmc/ui/util/waveform.c index 535f219..b114a5e 100644 --- a/src/fruits/cmc/ui/util/waveform.c +++ b/src/fruits/cmc/ui/util/waveform.c @@ -5,7 +5,7 @@ #define WITHIN_RMS(low, high, rms) \ ((low >= 0 && low <= rms) || (high < 0 && high >= -rms) || (low < 0 && high > 0 && rms > 0)) -#define OUTPUT_WAVEFORM_PNG +//#define OUTPUT_WAVEFORM_PNG //#define WAVEFORM_REFERENCE_MODE #ifdef OUTPUT_WAVEFORM_PNG #include <nnwt/file.h> diff --git a/src/fruits/cmsrv/meson.build b/src/fruits/cmsrv/meson.build index dce3d94..b12d00d 100644 --- a/src/fruits/cmsrv/meson.build +++ b/src/fruits/cmsrv/meson.build @@ -8,7 +8,7 @@ if use_tui cmsrv_deps += [notcurses_core] endif -if is_windows and meson.is_cross_build() +if is_windows and not is_msvc cmsrv_args += ['-static', '-static-libgcc', '-static-libstdc++', '-municode', '-mwindows'] endif diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c index 70a0b28..28dcbb5 100644 --- a/src/fruits/cmv/cmv.c +++ b/src/fruits/cmv/cmv.c @@ -3,14 +3,16 @@ #include <nnwt/event_loop.h> #include <nnwt/thread.h> -#include "../../util/color_palette.h" -#include "../../codec/ffmpeg/common.h" #include "../../libsink/desktop.h" #include "../../server/common.h" #ifndef CAMU_SINK_ONLY #include "../../server/server.h" #endif #include "../../server/common.h" +#include "../../util/color_palette.h" +#ifdef CAMU_HAVE_FFMPEG +#include "../../codec/ffmpeg/common.h" +#endif #include "../common.h" @@ -95,7 +97,11 @@ static bool parse_exe_name_params(str *exe_name, str *addr, struct lia_prefs *pr return true; def: +#ifdef CAMU_HAVE_SUBTITLES prefs->enabled_mask = CAMU_MASK_AUDIO | CAMU_MASK_VIDEO | CAMU_MASK_SUBTITLE; +#else + prefs->enabled_mask = CAMU_MASK_AUDIO | CAMU_MASK_VIDEO; +#endif prefs->audio_lang = CAMU_LANG_JAPANESE; prefs->subtitle_lang = CAMU_LANG_ENGLISH; @@ -175,8 +181,10 @@ s32 window_system_main(u32 argc, str *argv, void *extra) c.desktop.exit_callback = exit_callback; c.desktop.userdata = &c; } -#endif str *name = local ? &al_str_c("local") : &al_str_c("desktop"); +#else + str *name = &al_str_c("desktop"); +#endif if (!camu_desktop_connect(&c.desktop, name, &c.loop, type, &addr, CAMU_PORT)) { return EXIT_FAILURE; } diff --git a/src/fruits/cmv/meson.build b/src/fruits/cmv/meson.build index 870345e..bfd2182 100644 --- a/src/fruits/cmv/meson.build +++ b/src/fruits/cmv/meson.build @@ -14,7 +14,7 @@ if use_tui endif cmv_link_args = [] -if is_windows and meson.is_cross_build() +if is_windows and not is_msvc cmv_link_args += ['-static', '-static-libgcc', '-static-libstdc++', '-municode', '-mwindows'] endif diff --git a/src/fruits/droid/ctv/gradle/libs.versions.toml b/src/fruits/droid/ctv/gradle/libs.versions.toml index 4a8d0bc..95dfb43 100644 --- a/src/fruits/droid/ctv/gradle/libs.versions.toml +++ b/src/fruits/droid/ctv/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.9.1" +agp = "8.10.0" [libraries] diff --git a/src/liana/client.c b/src/liana/client.c index 164a4d1..626a752 100644 --- a/src/liana/client.c +++ b/src/liana/client.c @@ -27,7 +27,12 @@ static void data_packet_callback(void *userdata, struct nn_packet_stream *stream static s32 stream_compare(const void *a, const void *b) { - return (s32)((struct camu_codec_stream *)a)->type - (s32)((struct camu_codec_stream *)b)->type; + struct camu_codec_stream *aa = (struct camu_codec_stream *)a; + struct camu_codec_stream *bb = (struct camu_codec_stream *)b; + if (aa->type == bb->type) { + return aa->index - bb->index; + } + return aa->type - bb->type; } static void collect_streams(struct lia_client *client, struct nn_packet *packet) @@ -49,7 +54,7 @@ static void collect_streams(struct lia_client *client, struct nn_packet *packet) fmt->sample_rate = nn_packet_read_s32(packet); fmt->channel_count = nn_packet_read_s32(packet); #ifdef CAMU_HAVE_FFMPEG - av_channel_layout_default(&fmt->channel_layout, fmt->channel_count); + camu_default_channel_layout(&fmt->channel_layout, fmt->channel_count); #endif } else if (type == CAMU_STREAM_VIDEO) { struct camu_video_format *fmt = &stream.video.fmt; @@ -80,8 +85,8 @@ static void collect_streams(struct lia_client *client, struct nn_packet *packet) struct camu_audio_format *fmt = &stream.audio.fmt; fmt->format = codecpar->format; fmt->sample_rate = codecpar->sample_rate; - av_channel_layout_copy(&fmt->channel_layout, &codecpar->ch_layout); - fmt->channel_count = codecpar->ch_layout.nb_channels; + camu_copy_channel_layout(&fmt->channel_layout, &AV_CODECPAR_CHANNEL_LAYOUT(codecpar)); + fmt->channel_count = AV_CODECPAR_CHANNELS(codecpar); break; } case CAMU_STREAM_VIDEO: { diff --git a/src/liana/handlers/codec_client.c b/src/liana/handlers/codec_client.c index fd2569b..38b5d3b 100644 --- a/src/liana/handlers/codec_client.c +++ b/src/liana/handlers/codec_client.c @@ -132,9 +132,9 @@ static bool codec_client_handle_packet(struct lia_client_handler *handler, struc #endif break; } +#endif default: al_assert_and_return(false); -#endif } // Restore packet rindex in case we resue it. diff --git a/src/liana/handlers/codec_server.c b/src/liana/handlers/codec_server.c index de2c927..3b7d31e 100644 --- a/src/liana/handlers/codec_server.c +++ b/src/liana/handlers/codec_server.c @@ -149,7 +149,7 @@ static void codec_server_write_packet(struct lia_server_handler *handler, struct nn_packet_write_u8(packet, LIANA_PACKET_EOF); #ifdef LIANA_SERVER_LOOP codec->pts_offset += codec->demux->get_duration(codec->demux); - codec->demux->seek(codec->demux, 0); + codec->demux->seek(codec->demux, 0, false); #endif } else { nn_packet_write_u8(packet, LIANA_PACKET_ERROR); diff --git a/src/liana/process.c b/src/liana/process.c index 0a6d6b6..a8b57d0 100644 --- a/src/liana/process.c +++ b/src/liana/process.c @@ -65,10 +65,10 @@ bool lia_prepare_visual_data(struct cch_handle *handle, struct lia_visual_data * fmt.req.format = CAMU_SAMPLE_FORMAT_S16; fmt.in.sample_rate = codecpar->sample_rate; fmt.req.sample_rate = codecpar->sample_rate; - av_channel_layout_copy(&fmt.in.channel_layout, &codecpar->ch_layout); - av_channel_layout_copy(&fmt.req.channel_layout, &codecpar->ch_layout); - fmt.in.channel_count = codecpar->ch_layout.nb_channels; - fmt.req.channel_count = codecpar->ch_layout.nb_channels; + camu_copy_channel_layout(&fmt.in.channel_layout, &AV_CODECPAR_CHANNEL_LAYOUT(codecpar)); + camu_copy_channel_layout(&fmt.req.channel_layout, &AV_CODECPAR_CHANNEL_LAYOUT(codecpar)); + fmt.in.channel_count = AV_CODECPAR_CHANNELS(codecpar); + fmt.req.channel_count = AV_CODECPAR_CHANNELS(codecpar); struct raw_samples_data raw; raw.resampler = resampler; diff --git a/src/liana/vcr.c b/src/liana/vcr.c index 4500681..78c2b9c 100644 --- a/src/liana/vcr.c +++ b/src/liana/vcr.c @@ -126,9 +126,11 @@ static nn_thread_result NNWT_THREADCALL vcr_track_thread(void *userdata) continue; } - index++; // Count of packets consumed. + index++; // Count of packets consumed, also increment for WHOLE_FILE mode. +#ifndef VCR_BUFFER_WHOLE_FILE nn_packet_stream_return_packets(vcr->data, al_array_offset(track->cache.cache, 0), index); al_array_remove_range(track->cache.cache, 0, index); +#endif nn_packet_cache_unlock(&track->cache); @@ -153,7 +155,9 @@ static nn_thread_result NNWT_THREADCALL vcr_track_thread(void *userdata) if (corked) { // The cache is already unlocked here. +#ifndef VCR_BUFFER_WHOLE_FILE index = 0; +#endif } else { #ifndef VCR_BUFFER_WHOLE_FILE al_assert(index == packets); diff --git a/src/libsink/desktop.c b/src/libsink/desktop.c index 2bbe906..a2d02c9 100644 --- a/src/libsink/desktop.c +++ b/src/libsink/desktop.c @@ -8,8 +8,8 @@ #else #include "../mixer/audio_miniaudio.h" #endif -#if defined CAMU_RENDERER_TIGER -#include "../render/renderer_tiger.h" +#if defined CAMU_RENDERER_MOMO +#include "../render/renderer_momo.h" #elif defined CAMU_RENDERER_LIBPLACEBO #include "../render/renderer_libplacebo.h" #endif @@ -111,8 +111,9 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque) } static char status[64]; -static void log_playback_pos(struct camu_sink *sink) +static void log_sink_status(struct camu_desktop *c) { + struct camu_sink *sink = &c->sink; struct camu_sink_entry *current = camu_sink_get_current(sink); if (!current) { camu_sink_return_current(sink); @@ -140,10 +141,10 @@ static void log_playback_pos(struct camu_sink *sink) offset += al_snprintf(status + offset, sizeof(status) - offset, "]"); status[offset] = '\0'; - log_info("%s", status); + log_info("%s, window size: %ux%u", status, c->scr.width, c->scr.height); return; notplaying: - log_info("Not playing."); + log_info("Not playing, window size: %ux%u", c->scr.width, c->scr.height); } static void screen_callback(void *userdata, u8 op, void *opaque) @@ -175,7 +176,7 @@ static void screen_callback(void *userdata, u8 op, void *opaque) camu_sink_shuffle(&c->sink); break; case CAMU_SCREEN_STATUS: - log_playback_pos(&c->sink); + log_sink_status(c); break; #ifdef CAMU_SCREEN_DEBUG_KEY case CAMU_SCREEN_DEBUG: @@ -199,8 +200,8 @@ bool camu_desktop_open(struct camu_desktop *c, const char *window_name) if (!camu_screen_init(&c->scr) || !camu_screen_create_window(&c->scr, window_name)) { return false; } -#if defined CAMU_RENDERER_TIGER - c->renderer = camu_renderer_tiger_create(); +#if defined CAMU_RENDERER_MOMO + c->renderer = camu_renderer_momo_create(); #elif defined CAMU_RENDERER_LIBPLACEBO c->renderer = camu_renderer_lp_create(); #endif diff --git a/src/libsink/sink.c b/src/libsink/sink.c index 07bb604..56be556 100644 --- a/src/libsink/sink.c +++ b/src/libsink/sink.c @@ -468,18 +468,17 @@ static void mixer_callback(void *userdata, u8 op) struct camu_sink *sink = (struct camu_sink *)userdata; if (op == CAMU_MIXER_EMPTY) { log_info("Mixer empty."); -#ifndef LIANA_LIST_SCUFFED_LOOP // We need to sync with do_add_entry() because the order of // the START/STOP's in the queue matters. nn_mutex_lock(&sink->lock); - queue_cmd(sink, (struct camu_sink_cmd){ - .op = STOP, - .value.i = CAMU_SINK_AUDIO - }); + // This feels a bit too loose. + if (!(sink->current && AUDIO_STATE(sink->current) == BUFFER_ADDED)) { + queue_cmd(sink, (struct camu_sink_cmd){ + .op = STOP, + .value.i = CAMU_SINK_AUDIO + }); + } nn_mutex_unlock(&sink->lock); -#else - (void)sink; -#endif } } @@ -1526,11 +1525,15 @@ static struct nn_rpc_command commands[] = { { .op = CAMU_SINK_SEEK, .callback = seek_command_callback, .userdata = NULL } }; +// @TODO: Send sink id from list. static void identify_callback(void *userdata, struct nn_rpc_connection *conn, struct nn_packet *packet) { struct camu_sink *sink = (struct camu_sink *)userdata; - (void)sink; - // @TODO: Send sink id from list. + if (sink->type == NNWT_SOCKET_UNIX) { + log_info("Sink connected to %.*s.", al_str_x(&sink->addr)); + } else { + log_info("Sink connected to %.*s:%hu.", al_str_x(&sink->addr), sink->port); + } nn_packet_stream_return_packet(conn->stream, packet); } diff --git a/src/mixer/audio_miniaudio.c b/src/mixer/audio_miniaudio.c index 7e31abf..a0db3f3 100644 --- a/src/mixer/audio_miniaudio.c +++ b/src/mixer/audio_miniaudio.c @@ -27,6 +27,9 @@ static ma_backend backends[] = { #ifdef MA_ENABLE_WASAPI ma_backend_wasapi, #endif +#ifdef MA_ENABLE_DSOUND + ma_backend_dsound, +#endif #ifdef MA_ENABLE_AAUDIO ma_backend_aaudio, #endif @@ -142,7 +145,7 @@ static void audio_miniaudio_pick_format(struct camu_audio *audio, struct camu_re fmt->req.sample_rate = ma->device.playback.internalSampleRate; u32 channels = ma->device.playback.channels; #ifdef CAMU_HAVE_FFMPEG - av_channel_layout_default(&fmt->req.channel_layout, channels); + camu_default_channel_layout(&fmt->req.channel_layout, channels); #endif fmt->req.channel_count = channels; } @@ -162,7 +165,7 @@ static void data_callback(ma_device *device, void *output, const void *input, u3 #define DEFAULT_PERIOD_SIZE_IN_MILLISECONDS 8 #else #define DEFAULT_PERIODS 3 -#define DEFAULT_PERIOD_SIZE_IN_MILLISECONDS 48 +#define DEFAULT_PERIOD_SIZE_IN_MILLISECONDS 64 #endif static bool audio_miniaudio_configure_stream(struct camu_audio *audio, void *opaque) diff --git a/src/mixer/audio_null.c b/src/mixer/audio_null.c index a6eeea3..2fa5ddb 100644 --- a/src/mixer/audio_null.c +++ b/src/mixer/audio_null.c @@ -15,7 +15,7 @@ static void audio_null_pick_format(struct camu_audio *audio, struct camu_resampl fmt->req.format = fmt->in.format; fmt->req.channel_count = fmt->in.channel_count; #ifdef CAMU_HAVE_FFMPEG - av_channel_layout_default(&fmt->req.channel_layout, fmt->in.channel_count); + camu_default_channel_layout(&fmt->req.channel_layout, fmt->in.channel_count); #endif fmt->req.sample_rate = fmt->in.sample_rate; } diff --git a/src/mixer/meson.build b/src/mixer/meson.build index c09f779..e4840c1 100644 --- a/src/mixer/meson.build +++ b/src/mixer/meson.build @@ -22,7 +22,11 @@ if use_miniaudio mixer_deps += [libpulse, alsa] mixer_args += ['-DMA_ENABLE_ALSA', '-DMA_ENABLE_PULSEAUDIO', '-DMA_NO_RUNTIME_LINKING'] elif is_windows - mixer_args += ['-DMA_ENABLE_WASAPI'] + if get_option('win32-compat') + mixer_args += ['-DMA_ENABLE_DSOUND'] + else + mixer_args += ['-DMA_ENABLE_WASAPI'] + endif elif is_android mixer_args += ['-DMA_ENABLE_AAUDIO'] endif diff --git a/src/render/meson.build b/src/render/meson.build index 98b86ec..7e3e394 100644 --- a/src/render/meson.build +++ b/src/render/meson.build @@ -2,23 +2,20 @@ render_src = [] render_deps = [] render_args = [] -if get_option('renderer') == 'tiger' - render_src += ['renderer_tiger.c', 'queue_tiger.c'] - linmath_h = subproject('linmath.h').get_variable('linmath_h') - render_deps += [linmath_h] - libm = compiler.find_library('m', required: false) - if libm.found() - render_deps += [libm] - endif - render_args += ['-DCAMU_RENDERER_TIGER'] +if get_option('renderer') == 'momo' + render_src += ['renderer_momo.c', 'queue_momo.c'] + subdir('momo') + render_deps += [momo] + render_args += ['-DCAMU_RENDERER_MOMO'] elif get_option('renderer') == 'libplacebo' libplacebo_opts = ['warning_level=2', 'demos=false', 'tests=false', 'bench=false', 'fuzz=false', 'glslang=disabled', 'gl-proc-addr=disabled', 'vk-proc-addr=disabled', - 'lcms=disabled', - 'dovi=disabled', - 'libdovi=disabled' + 'lcms=auto', + 'dovi=auto', + 'libdovi=auto', + 'xxhash=auto' ] if get_option('renderer-api') == 'vulkan' or get_option('renderer-api') == 'dx11' @@ -27,12 +24,19 @@ elif get_option('renderer') == 'libplacebo' render_deps += [shaderc] else shaderc_opts = cmake.subproject_options() + shaderc_opts.set_override_option('warning_level', '0') # Doesn't work. reltype = is_minsize ? 'MinSizeRel' : 'Release' shaderc_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : reltype }) shaderc_opts.add_cmake_defines({ 'SHADERC_SKIP_INSTALL': true }) shaderc_opts.add_cmake_defines({ 'SHADERC_SKIP_TESTS': true }) shaderc_opts.add_cmake_defines({ 'SHADERC_SKIP_EXAMPLES': true }) shaderc_opts.add_cmake_defines({ 'SHADERC_SKIP_COPYRIGHT_CHECK': true }) + shaderc_opts.add_cmake_defines({ 'ENABLE_GLSLANG_BINARIES': false }) + shaderc_opts.add_cmake_defines({ 'ENABLE_SPVREMAPPER': false }) + shaderc_opts.add_cmake_defines({ 'ENABLE_HLSL': false }) + spirv_optimizer = true + shaderc_opts.add_cmake_defines({ 'ENABLE_OPT': spirv_optimizer }) + shaderc_opts.add_cmake_defines({ 'ENABLE_EXCEPTIONS_ON_MSVC': false }) shaderc_proj = cmake.subproject('shaderc', options: shaderc_opts) shaderc = shaderc_proj.dependency('shaderc') meson.override_dependency('shaderc', shaderc) @@ -43,20 +47,31 @@ elif get_option('renderer') == 'libplacebo' shaderc_proj.dependency('OSDependent'), shaderc_proj.dependency('GenericCodeGen'), shaderc_proj.dependency('SPIRV'), - shaderc_proj.dependency('SPIRV-Tools-opt'), shaderc_proj.dependency('SPIRV-Tools-static') ] + if spirv_optimizer + render_deps += [ + shaderc_proj.dependency('SPIRV-Tools-opt'), + ] + endif endif #glslang = dependency('glslang', required: false, allow_fallback: false) #if glslang.found() # render_deps += [glslang] #else + # #spirv_tools_opts = cmake.subproject_options() + # #spirv_tools_opts.set_override_option('warning_level', '0') + # #reltype = is_minsize ? 'MinSizeRel' : 'Release' + # #spirv_tools_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : reltype }) + # #spirv_tools_proj = cmake.subproject('SPIRV-Tools', options: spirv_tools_opts) # glslang_opts = cmake.subproject_options() + # glslang_opts.set_override_option('warning_level', '0') # reltype = is_minsize ? 'MinSizeRel' : 'Release' # glslang_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : reltype }) + # #glslang_opts.add_cmake_defines({ 'ALLOW_EXTERNAL_SPIRV_TOOLS': true }) # glslang_opts.add_cmake_defines({ 'ENABLE_OPT': '0' }) # glslang_proj = cmake.subproject('glslang', options: glslang_opts) - # message('CMake targets:\n - ' + '\n - '.join(glslang_proj.target_list())) + # #message('CMake targets:\n - ' + '\n - '.join(glslang_proj.target_list())) # glslang = glslang_proj.dependency('glslang') # spirv = glslang_proj.dependency('SPIRV') # glslang_default_resource_limits = glslang_proj.dependency('glslang-default-resource-limits') @@ -118,22 +133,27 @@ if get_option('subtitles').enabled() default_options: [ 'doc=disabled', 'nls=disabled', - 'tests=disabled', 'tools=disabled', 'cache-build=disabled' ]) + else + libass_opts += ['directwrite=enabled'] endif # libass(e46aede):meson.build:84 # fontconfig(72b9a48):meson.build:28 freetype = dependency('freetype2', version: '>=9.17.3', default_options: [ - 'harfbuzz=disabled' + 'warning_level=0', + 'harfbuzz=disabled', + 'png=disabled' ]) # libass(e46aede):meson.build:90 fribidi = dependency('fribidi', version: '>=0.19.1', default_options: [ + 'warning_level=0', + 'c_args=-Wno-stringop-overflow', # This doesn't work. 'docs=false', 'tests=false', 'bin=false' @@ -143,7 +163,6 @@ if get_option('subtitles').enabled() version: '>=2.0.0', default_options: [ 'freetype=disabled', - 'tests=disabled', 'introspection=disabled', 'docs=disabled', 'utilities=disabled', diff --git a/src/render/momo/meson.build b/src/render/momo/meson.build new file mode 100644 index 0000000..092293a --- /dev/null +++ b/src/render/momo/meson.build @@ -0,0 +1,12 @@ +momo_src = ['momo.c'] +momo_deps = [] +momo_args = [] + +libm = compiler.find_library('m', required: false) +if libm.found() + momo_deps += [libm] +endif +linmath_h = subproject('linmath.h').get_variable('linmath_h') +momo_deps += [linmath_h] + +momo = declare_dependency(sources: momo_src, dependencies: momo_deps, compile_args: momo_args) diff --git a/src/render/momo/momo.c b/src/render/momo/momo.c new file mode 100644 index 0000000..5239efd --- /dev/null +++ b/src/render/momo/momo.c @@ -0,0 +1,35 @@ +#define AL_LOG_SECTION "momo" +#include <al/log.h> + +#include "momo.h" + +bool MOMO_Init(MOMO_Renderer *mmr, +#ifdef STELA_API_OPENGL + bool (*MakeCurrent)(void *), + void (*ReleaseCurrent)(void *), + void (*SwapBuffers)(void *), +#endif + void *Private) +{ + mmr->Private = Private; +#ifdef STELA_API_OPENGL + mmr->GL.MakeCurrent = MakeCurrent; + mmr->GL.ReleaseCurrent = ReleaseCurrent; + mmr->GL.SwapBuffers = SwapBuffers; + mmr->GL.MakeCurrent(mmr->Private); + const char *gl_version = (const char *)glGetString(GL_VERSION); + if (gl_version) { + log_info("GL context version: %s.", gl_version); + } else { + log_warn("Somehow failed to retrive GL_VERSION."); + } +#endif + return true; +} + +void MOMO_Render(MOMO_Renderer *mmr) +{ +#ifdef STELA_API_OPENGL + mmr->GL.SwapBuffers(mmr->Private); +#endif +} diff --git a/src/render/momo/momo.h b/src/render/momo/momo.h new file mode 100644 index 0000000..76686ba --- /dev/null +++ b/src/render/momo/momo.h @@ -0,0 +1,25 @@ +#pragma once + +#include <al/types.h> + +#ifdef STELA_API_OPENGL +#include <stl/gl.h> +#endif + +typedef struct { + struct { + bool (*MakeCurrent)(void *); + void (*ReleaseCurrent)(void *); + void (*SwapBuffers)(void *); + } GL; + void *Private; +} MOMO_Renderer; + +bool MOMO_Init(MOMO_Renderer *mmr, +#ifdef STELA_API_OPENGL + bool (*MakeCurrent)(void *), + void (*ReleaseCurrent)(void *), + void (*SwapBuffers)(void *), +#endif + void *Private); +void MOMO_Render(MOMO_Renderer *mmr); diff --git a/src/render/queue_libplacebo.c b/src/render/queue_libplacebo.c index 7fe9258..5932944 100644 --- a/src/render/queue_libplacebo.c +++ b/src/render/queue_libplacebo.c @@ -30,6 +30,7 @@ static bool queue_lp_configure_subtitles(struct camu_frame_queue *queue, u32 wid ass_set_frame_size(lq->ass_renderer, width, height); ass_set_storage_size(lq->ass_renderer, width, height); ass_set_fonts(lq->ass_renderer, NULL, NULL, ASS_FONTPROVIDER_AUTODETECT, NULL, 0); + ass_set_hinting(lq->ass_renderer, ASS_HINTING_NONE); AVCodecParameters *codecpar = stream->av.stream->codecpar; ass_process_codec_private(lq->ass_track, (const char *)codecpar->extradata, codecpar->extradata_size); diff --git a/src/render/queue_momo.c b/src/render/queue_momo.c new file mode 100644 index 0000000..8e8d7e3 --- /dev/null +++ b/src/render/queue_momo.c @@ -0,0 +1,68 @@ +#include "queue_momo.h" + +static void queue_momo_push(struct camu_frame_queue *queue, struct camu_codec_frame *frame, f64 pts) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)queue; + (void)mq; + (void)pts; + camu_codec_frame_discard(frame); +} + +#ifdef CAMU_HAVE_FFMPEG +static void queue_momo_push_av_frame(struct camu_frame_queue *queue, AVFrame *frame, f64 pts) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)queue; + (void)mq; + (void)pts; + av_frame_free(&frame); +} +#endif + +static void queue_momo_flush(struct camu_frame_queue *queue) +{ + (void)queue; +} + +static s32 queue_momo_count(struct camu_frame_queue *queue) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)queue; + (void)mq; + return 1; +} + +static u8 queue_momo_read(struct camu_frame_queue *queue, f64 pts, void *out) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)queue; + (void)mq; + (void)pts; + (void)out; + return CAMU_QUEUE_OK; +} + +static void queue_momo_reset(struct camu_frame_queue *queue) +{ + struct camu_frame_queue_momo *tq = (struct camu_frame_queue_momo *)queue; + (void)tq; +} + +static void queue_momo_free(struct camu_frame_queue **queue) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)*queue; + al_free(mq); + *queue = NULL; +} + +struct camu_frame_queue *camu_frame_queue_momo_create(void) +{ + struct camu_frame_queue_momo *mq = al_alloc_object(struct camu_frame_queue_momo); + mq->q.push = queue_momo_push; +#ifdef CAMU_HAVE_FFMPEG + mq->q.push_av_frame = queue_momo_push_av_frame; +#endif + mq->q.flush = queue_momo_flush; + mq->q.count = queue_momo_count; + mq->q.read = queue_momo_read; + mq->q.reset = queue_momo_reset; + mq->q.free = queue_momo_free; + return (struct camu_frame_queue *)mq; +} diff --git a/src/render/queue_momo.h b/src/render/queue_momo.h new file mode 100644 index 0000000..c4bf5d1 --- /dev/null +++ b/src/render/queue_momo.h @@ -0,0 +1,9 @@ +#pragma once + +#include "../buffer/frame_queue.h" + +struct camu_frame_queue_momo { + struct camu_frame_queue q; +}; + +struct camu_frame_queue *camu_frame_queue_momo_create(void); diff --git a/src/render/queue_tiger.c b/src/render/queue_tiger.c deleted file mode 100644 index df072d2..0000000 --- a/src/render/queue_tiger.c +++ /dev/null @@ -1,130 +0,0 @@ -#include <al/lib.h> -#include <stl/gl.h> - -#include "queue_tiger.h" - -#define GL_UNPACK_ROW_LENGTH 0x0CF2 - -static void upload_texture(struct camu_frame_queue_tiger *tq, u8 *data, u32 width, u32 height, s32 format, s32 linesize) -{ - glGenTextures(1, &tq->texture_id); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tq->texture_id); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - //if (frame->flags & CAMU_FRAME_DEVICE_ALLOCATED) { - // glBindBuffer(GL_PIXEL_UNPACK_BUFFER, tq->tr->texture_buffer); - //} - glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize); - glPixelStorei(GL_UNPACK_ALIGNMENT, 0); - switch (format) { - case CAMU_PIXEL_FORMAT_RGBA: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - break; - case CAMU_PIXEL_FORMAT_RGB: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, - 0, GL_RGB, GL_UNSIGNED_BYTE, data); - break; - default: - al_assert(false); - } - //glGenerateMipmap(GL_TEXTURE_2D); -} - -static void queue_tiger_push(struct camu_frame_queue *queue, struct camu_codec_frame *frame, f64 pts) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)pts; - tq->queued_frame = frame; -} - -#ifdef CAMU_HAVE_FFMPEG -static void queue_tiger_push_av_frame(struct camu_frame_queue *queue, AVFrame *frame, f64 pts) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)pts; - tq->queued_av_frame = frame; -} -#endif - -static void queue_tiger_flush(struct camu_frame_queue *queue) -{ - (void)queue; -} - -static s32 queue_tiger_count(struct camu_frame_queue *queue) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)tq; - return 1; -} - -static u8 queue_tiger_read(struct camu_frame_queue *queue, f64 pts, void *out) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)pts; - if (tq->queued_frame) { - struct camu_codec_frame *frame = tq->queued_frame; - s32 linesize = frame->video.width; - upload_texture(tq, frame->data, frame->video.width, frame->video.height, frame->format, linesize); - camu_codec_frame_discard(frame); - tq->queued_frame = NULL; - tq->uploaded = true; - } -#ifdef CAMU_HAVE_FFMPEG - if (tq->queued_av_frame) { - AVFrame *frame = tq->queued_av_frame; - s32 linesize = frame->linesize[0]; - switch (frame->format) { - case CAMU_PIXEL_FORMAT_RGBA: - linesize /= 4; - break; - case CAMU_PIXEL_FORMAT_RGB: - linesize /= 3; - break; - } - upload_texture(tq, frame->data[0], frame->width, frame->height, frame->format, linesize); - av_frame_free(&frame); - tq->queued_av_frame = NULL; - tq->uploaded = true; - } -#endif - if (!tq->uploaded) return CAMU_QUEUE_MORE; - *((GLuint *)out) = tq->texture_id; - return CAMU_QUEUE_OK; -} - -static void queue_tiger_reset(struct camu_frame_queue *queue) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)tq; -} - -static void queue_tiger_free(struct camu_frame_queue **queue) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)*queue; - glDeleteTextures(1, &tq->texture_id); - al_free(tq); - *queue = NULL; -} - -struct camu_frame_queue *camu_frame_queue_tiger_create(void) -{ - struct camu_frame_queue_tiger *tq = al_alloc_object(struct camu_frame_queue_tiger); - tq->queued_frame = NULL; - tq->queued_av_frame = NULL; - tq->uploaded = false; - tq->q.push = queue_tiger_push; -#ifdef CAMU_HAVE_FFMPEG - tq->q.push_av_frame = queue_tiger_push_av_frame; -#endif - tq->q.flush = queue_tiger_flush; - tq->q.count = queue_tiger_count; - tq->q.read = queue_tiger_read; - tq->q.reset = queue_tiger_reset; - tq->q.free = queue_tiger_free; - return (struct camu_frame_queue *)tq; -} diff --git a/src/render/queue_tiger.h b/src/render/queue_tiger.h deleted file mode 100644 index af0e229..0000000 --- a/src/render/queue_tiger.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include <stl/gl.h> - -#include "../buffer/frame_queue.h" - -struct camu_frame_queue_tiger { - struct camu_frame_queue q; - GLuint texture_id; - struct camu_renderer_tiger *tr; - struct camu_codec_frame *queued_frame; -#ifdef CAMU_HAVE_FFMPEG - struct AVFrame *queued_av_frame; -#endif - bool uploaded; -}; - -struct camu_frame_queue *camu_frame_queue_tiger_create(void); diff --git a/src/render/renderer.h b/src/render/renderer.h index 1e6ffc0..d2590b1 100644 --- a/src/render/renderer.h +++ b/src/render/renderer.h @@ -7,14 +7,9 @@ #endif #if defined STELA_API_OPENGL -#define CAMU_RENDERER_OPENGL #ifdef STELA_USE_EGL #include <stl/egl.h> #endif -#elif defined STELA_API_VULKAN -#define CAMU_RENDERER_VULKAN -#elif defined STELA_API_DX11 -#define CAMU_RENDERER_DX11 #endif #include "../codec/codec.h" @@ -24,28 +19,32 @@ enum { CAMU_SCALING_NEAREST }; +enum { + CAMU_BACKGROUND_DEFAULT = 0, + CAMU_BACKGROUND_TRANSPARENT +}; + struct camu_frame_queue; struct camu_screen; struct camu_renderer { bool (*create_renderer)( struct camu_renderer *, u32 *, u32 *, -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL (*get_vk_proc_address)(VkInstance, const char *), VkResult (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *), const char *const *(*vk_get_extensions)(u32 *), -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 HWND win32_window, -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL #ifdef STELA_USE_EGL EGLDisplay display, EGLContext context, #endif - void (*get_gl_proc_address(char const *procname))(void), + void (*get_gl_proc_address(char const *))(void), bool (*gl_load_loader)(void *), bool (*gl_make_current)(void *), void (*gl_release_current)(void *), void (*gl_swap_buffers)(void *), -#elif defined CAMU_RENDERER_DX11 #endif void *priv); struct camu_frame_queue *(*create_queue)(struct camu_renderer *); @@ -54,6 +53,7 @@ struct camu_renderer { void (*resize)(struct camu_renderer *, u32 *, u32 *); void (*set_fullscreen)(struct camu_renderer *, bool); void (*set_scaling)(struct camu_renderer *, u8); + void (*set_background)(struct camu_renderer *, u8); void (*render)(struct camu_renderer *, struct camu_screen *, bool); #ifdef CAMU_HAVE_FFMPEG s32 (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, s32 flags); diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c index a2105d6..bfe8c47 100644 --- a/src/render/renderer_libplacebo.c +++ b/src/render/renderer_libplacebo.c @@ -9,7 +9,7 @@ #include "../screen/screen.h" #include "../util/color_palette.h" -#ifdef CAMU_RENDERER_DX11 +#ifdef STELA_API_DX11 #include <nnwt/windows.h> #define COBJMACROS #include <libplacebo/d3d11.h> @@ -42,7 +42,7 @@ static void renderer_lp_resize(struct camu_renderer *renderer, u32 *width, u32 * } } -#ifdef CAMU_RENDERER_DX11 +#ifdef STELA_API_DX11 static void renderer_lp_set_fullscreen(struct camu_renderer *renderer, bool fullscreen) { struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer; @@ -69,6 +69,21 @@ static void renderer_lp_set_scaling(struct camu_renderer *renderer, u8 mode) } } +static void renderer_lp_set_background(struct camu_renderer *renderer, u8 mode) +{ + struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer; + switch (mode) { + case CAMU_BACKGROUND_DEFAULT: + clear_color[3] = 1.f; + lr->params.background = PL_CLEAR_TILES; + break; + case CAMU_BACKGROUND_TRANSPARENT: + clear_color[3] = 0.f; + lr->params.background = PL_CLEAR_SKIP; + break; + } +} + static void log_callback(void *userdata, enum pl_log_level level, const char *message) { (void)userdata; @@ -79,19 +94,34 @@ static void log_callback(void *userdata, enum pl_log_level level, const char *me } } +#ifdef CAMU_HAVE_SUBTITLES +// level = 0(FATAL)-7(VERBOSE). +static void ass_log_callback(s32 level, const char *fmt, va_list args, void *userdata) +{ + (void)userdata; + if (level <= 1) { + al_logv(AL_LOG_ERROR, "ass", fmt, args); + } else { +#ifdef AL_DEBUG + al_logv(AL_LOG_DEBUG, "ass", fmt, args); +#endif + } +} +#endif + static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *width, u32 *height, -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL (*get_vk_proc_address)(VkInstance, const char *), VkResult (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *), const char *const *(*vk_get_extensions)(u32 *), -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 HWND win32_window, -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL #ifdef STELA_USE_EGL EGLDisplay display, EGLContext context, #endif - void (*get_gl_proc_address(char const *procname))(void), + void (*get_gl_proc_address(char const *))(void), bool (*gl_load_loader)(void *), bool (*gl_make_current)(void *), void (*gl_release_current)(void *), @@ -111,13 +141,18 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid clear_color[2] = 255.f; */ +//#define LIBPLACEBO_LOG_TRACE lr->logger = pl_log_create(PL_API_VER, pl_log_params( .log_cb = log_callback, .log_priv = NULL, +#ifdef LIBPLACEBO_LOG_TRACE + .log_level = PL_LOG_TRACE +#else .log_level = PL_LOG_INFO +#endif )); -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN VkResult err; u32 num; @@ -153,6 +188,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid lr->swapchain = pl_vulkan_create_swapchain(lr->vk, pl_vulkan_swapchain_params( .surface = lr->surface, .present_mode = VK_PRESENT_MODE_FIFO_KHR + //.present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR )); if (!lr->swapchain) { log_error("Failed to create vulkan swapchain."); @@ -162,7 +198,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid lr->gpu = lr->vk->gpu; log_info("Using Vulkan."); -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 (void)priv; lr->d3d11 = pl_d3d11_create(lr->logger, pl_d3d11_params( .debug = false @@ -183,7 +219,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid lr->gpu = lr->d3d11->gpu; log_info("Using DirectX 11."); -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL (void)gl_load_loader; lr->gl = pl_opengl_create(lr->logger, pl_opengl_params( .debug = false, @@ -230,8 +266,17 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid // Clear manually so we can draw multiple images per frame. lr->params.border = PL_CLEAR_SKIP; + lr->params.background = PL_CLEAR_TILES; + /* + lr->params.background_color[0] = clear_color[0]; + lr->params.background_color[1] = clear_color[1]; + lr->params.background_color[2] = clear_color[2]; + lr->params.background_transparency = clear_color[3]; + */ + // Prioritize a more consistent image. lr->params.correct_subpixel_offsets = true; + //lr->params.distort_params = pl_distort_params(.unscaled = false); #if 0 struct nn_file file; @@ -254,6 +299,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid #ifdef CAMU_HAVE_SUBTITLES lr->ass = ass_library_init(); + ass_set_message_cb(lr->ass, ass_log_callback, lr); #endif lr->last_render_tick = nn_get_tick(); @@ -339,7 +385,7 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree if (mix.frames) { // weighted is only set when read() returns QUEUE_OK. do_gpu_finish |= weighted; - // Terrible hack. Let's us distinguish single frames with the same dimensions. + // Terrible hack. Lets us distinguish single frames with the same dimensions. // Tied to a libplacebo patch to consider info_priv in the hash. // Also, add in reset_pts to account for buffer resets. This is a completely // broken "hash" of the f64 pts value but hopefully it works for now. @@ -413,8 +459,8 @@ void renderer_lp_free(struct camu_renderer **renderer) struct camu_renderer_lp *lr = (struct camu_renderer_lp *)*renderer; if (lr->renderer) pl_renderer_destroy(&lr->renderer); if (lr->swapchain) pl_swapchain_destroy(&lr->swapchain); -#if defined CAMU_RENDERER_VULKAN -#elif defined CAMU_RENDERER_OPENGL +#if defined STELA_API_VULKAN +#elif defined STELA_API_OPENGL if (lr->gl) pl_opengl_destroy(&lr->gl); #endif if (lr->logger) pl_log_destroy(&lr->logger); @@ -433,12 +479,13 @@ struct camu_renderer *camu_renderer_lp_create(void) lr->r.add_font = renderer_lp_add_font; lr->r.get_latency = renderer_lp_get_latency; lr->r.resize = renderer_lp_resize; -#ifdef CAMU_RENDERER_DX11 +#ifdef STELA_API_DX11 lr->r.set_fullscreen = renderer_lp_set_fullscreen; #else lr->r.set_fullscreen = NULL; #endif lr->r.set_scaling = renderer_lp_set_scaling; + lr->r.set_background = renderer_lp_set_background; lr->r.render = renderer_lp_render; lr->r.free = renderer_lp_free; return (struct camu_renderer *)lr; diff --git a/src/render/renderer_libplacebo.h b/src/render/renderer_libplacebo.h index 7b1cfa2..a0125ba 100644 --- a/src/render/renderer_libplacebo.h +++ b/src/render/renderer_libplacebo.h @@ -10,23 +10,23 @@ #include "renderer.h" -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN #include <libplacebo/vulkan.h> -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 #include <libplacebo/d3d11.h> -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL #include <libplacebo/opengl.h> #endif struct camu_renderer_lp { struct camu_renderer r; -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN VkSurfaceKHR surface; pl_vulkan vk; pl_vk_inst vk_inst; -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 pl_d3d11 d3d11; -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL pl_opengl gl; #endif pl_gpu gpu; diff --git a/src/render/renderer_momo.c b/src/render/renderer_momo.c new file mode 100644 index 0000000..9f217bf --- /dev/null +++ b/src/render/renderer_momo.c @@ -0,0 +1,97 @@ +#define AL_LOG_SECTION "renderer_momo" +#include <al/log.h> + +#include "renderer_momo.h" +#include "queue_momo.h" + +static void renderer_momo_resize(struct camu_renderer *renderer, u32 *width, u32 *height) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)renderer; + (void)mr; + (void)width; + (void)height; +} + +static bool renderer_momo_create_renderer(struct camu_renderer *renderer, u32 *width, u32 *height, +#if defined STELA_API_OPENGL +#ifdef STELA_USE_EGL + EGLDisplay display, + EGLContext context, +#endif + void (*get_gl_proc_address(char const *))(void), + bool (*gl_load_loader)(void *), + bool (*gl_make_current)(void *), + void (*gl_release_current)(void *), + void (*gl_swap_buffers)(void *), +#endif + void *priv) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)renderer; + (void)width; + (void)height; +#if defined STELA_API_OPENGL +#ifdef STELA_USE_EGL + (void)display; + (void)context; +#endif + (void)get_gl_proc_address; + (void)gl_load_loader; + MOMO_Init(&mr->mmr, gl_make_current, gl_release_current, gl_swap_buffers, priv); +#endif +#ifdef CAMU_HAVE_SUBTITLES + mr->ass = ass_library_init(); + // Just to keep these linked in the exe for platform testing. + ASS_Renderer *ar = ass_renderer_init(mr->ass); + ASS_Track *at = ass_new_track(mr->ass); + (void)at; + u32 w = *width, h = *height; + ass_set_frame_size(ar, w, h); + ass_set_storage_size(ar, w, h); + ass_set_fonts(ar, NULL, NULL, ASS_FONTPROVIDER_AUTODETECT, NULL, 0); + ass_set_hinting(ar, ASS_HINTING_NONE); +#endif + return true; +} + +static struct camu_frame_queue *renderer_momo_create_queue(struct camu_renderer *renderer) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)renderer; + struct camu_frame_queue *q = camu_frame_queue_momo_create(); + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)q; + (void)mr; + (void)mq; + return q; +} + +static u32 renderer_momo_get_latency(struct camu_renderer *renderer) +{ + (void)renderer; + return 0; +} + +static void renderer_momo_render(struct camu_renderer *renderer, struct camu_screen *scr, bool force) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)renderer; + (void)scr; + (void)force; + MOMO_Render(&mr->mmr); +} + +static void renderer_momo_free(struct camu_renderer **renderer) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)*renderer; + al_free(mr); + *renderer = NULL; +} + +struct camu_renderer *camu_renderer_momo_create(void) +{ + struct camu_renderer_momo *mr = al_alloc_object(struct camu_renderer_momo); + mr->r.create_renderer = renderer_momo_create_renderer; + mr->r.create_queue = renderer_momo_create_queue; + mr->r.get_latency = renderer_momo_get_latency; + mr->r.resize = renderer_momo_resize; + mr->r.render = renderer_momo_render; + mr->r.free = renderer_momo_free; + return (struct camu_renderer *)mr; +} diff --git a/src/render/renderer_momo.h b/src/render/renderer_momo.h new file mode 100644 index 0000000..3b9084b --- /dev/null +++ b/src/render/renderer_momo.h @@ -0,0 +1,19 @@ +#pragma once + +#ifdef CAMU_HAVE_SUBTITLES +#include <ass/ass.h> +#endif + +#include "momo/momo.h" + +#include "renderer.h" + +struct camu_renderer_momo { + struct camu_renderer r; + MOMO_Renderer mmr; +#ifdef CAMU_HAVE_SUBTITLES + ASS_Library *ass; +#endif +}; + +struct camu_renderer *camu_renderer_momo_create(void); diff --git a/src/render/renderer_tiger.c b/src/render/renderer_tiger.c deleted file mode 100644 index eb99e0c..0000000 --- a/src/render/renderer_tiger.c +++ /dev/null @@ -1,320 +0,0 @@ -#define AL_LOG_SECTION "renderer_tiger" -#include <al/log.h> -#include <al/lib.h> -#include <linmath.h> - -#include "../screen/view.h" -#include "../screen/screen.h" -#include "../util/color_palette.h" - -#include "renderer_tiger.h" -#include "queue_tiger.h" - -#ifdef CAMU_RENDERER_OPENGL -static const GLfloat default_vertices[] = { - 0.f, 0.f, 0.f, 0.f, 0.f, - 0.f, 1.f, 0.f, 0.f, 1.f, - 1.f, 0.f, 0.f, 1.f, 0.f, - 1.f, 0.f, 0.f, 1.f, 0.f, - 0.f, 1.f, 0.f, 0.f, 1.f, - 1.f, 1.f, 0.f, 1.f, 1.f -}; - -static GLfloat clear_color[4] = { 0.f, 0.f, 0.f, 1.f }; - -static const GLchar *default_vs = \ - "#version 100\n" \ - "attribute vec3 a_Position;\n" \ - "attribute vec2 a_TexCoord;\n" \ - "varying vec2 v_TexCoord;\n" \ - "uniform mat4 g_ModelViewProjectionMatrix;\n" \ - "void main() {\n" \ - " gl_Position = g_ModelViewProjectionMatrix * vec4(a_Position, 1.0);\n" \ - " v_TexCoord = a_TexCoord;\n" \ - "}"; - -static const GLchar *default_fs = \ - "#version 100\n" \ - "precision mediump float;\n" \ - "varying vec2 v_TexCoord;\n" \ - "uniform sampler2D g_Texture0;\n" \ - "void main() {\n" \ - " gl_FragColor = texture2D(g_Texture0, v_TexCoord);\n" \ - "}"; - -static bool compile(GLuint shader, const GLchar *source, GLchar *error) -{ - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); - - GLint status; - - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - - if (status == GL_FALSE) { - glGetShaderInfoLog(shader, 256, NULL, error); - return false; - } - - return true; -} - -static bool compile_shaders(struct camu_renderer_tiger *tr) -{ - tr->program = glCreateProgram(); - - GLchar error[256]; - - GLuint vs_shader = glCreateShader(GL_VERTEX_SHADER); - if (!compile(vs_shader, default_vs, error)) { - log_error("Failed to compile vertex shader (%.*s)", sizeof(error), error); - return false; - } - - GLuint fs_shader = glCreateShader(GL_FRAGMENT_SHADER); - if (!compile(fs_shader, default_fs, error)) { - log_error("Failed to compile fragment shader (%.*s)", sizeof(error), error); - return false; - } - - glAttachShader(tr->program, vs_shader); - glAttachShader(tr->program, fs_shader); - glLinkProgram(tr->program); - - return true; -} -#endif - -static void renderer_tiger_resize(struct camu_renderer *renderer, u32 *width, u32 *height) -{ - struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - (void)tr; - (void)width; - (void)height; -} - -static bool renderer_tiger_create_renderer(struct camu_renderer *renderer, u32 *width, u32 *height, -#if defined CAMU_RENDERER_VULKAN - VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL (*get_vk_proc_address)(VkInstance, const char *), - void (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *), - const char *const *(*vk_get_extensions)(u32 *), -#elif defined CAMU_RENDERER_OPENGL -#ifdef STELA_USE_EGL - EGLDisplay display, - EGLContext context, -#endif - void (*get_gl_proc_address(char const *procname))(void), - bool (*gl_load_loader)(void *), - bool (*gl_make_current)(void *), - void (*gl_release_current)(void *), - void (*gl_swap_buffers)(void *), -#endif - void *priv) -{ - struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - (void)width; - (void)height; -#ifdef CAMU_RENDERER_OPENGL - (void)display; - (void)context; - (void)get_gl_proc_address; - - tr->load_loader = gl_load_loader; - tr->make_current = gl_make_current; - tr->release_current = gl_release_current; - tr->swap_buffers = gl_swap_buffers; - tr->priv = priv; - - tr->make_current(tr->priv); - - if (!tr->load_loader(tr->priv)) { - return false; - } - - clear_color[0] = ((global_color_palette.colors[0] >> 16) & 0xff) / 255.f; - clear_color[1] = ((global_color_palette.colors[0] >> 8) & 0xff) / 255.f; - clear_color[2] = ((global_color_palette.colors[0]) & 0xff) / 255.f; - - glClearColor(clear_color[0], clear_color[1], clear_color[2], 1.f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glGenBuffers(1, &tr->vbo); - glBindBuffer(GL_ARRAY_BUFFER, tr->vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(default_vertices), default_vertices, GL_STATIC_DRAW); - - if (!compile_shaders(tr)) return false; - - glUseProgram(tr->program); - - GLint pos = glGetAttribLocation(tr->program, "a_Position"); - glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)0); - if (stl_gl_check_error()) { - log_error("glVertexAttribPointer returned error, use GLES context."); - al_assert_and_return(false); - } - glEnableVertexAttribArray(pos); - GLint texcoord = glGetAttribLocation(tr->program, "a_TexCoord"); - glVertexAttribPointer(texcoord, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)12); - glEnableVertexAttribArray(texcoord); - - //glGenBuffers(1, &tr->texture_buffer); -#endif - -#ifdef CAMU_HAVE_FFMPEG - tr->r.get_buffer2 = NULL; - tr->r.opaque = NULL; -#endif - - return true; -} - -static struct camu_frame_queue *renderer_tiger_create_queue(struct camu_renderer *renderer) -{ -#ifdef CAMU_RENDERER_OPENGL - struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - struct camu_frame_queue *q = camu_frame_queue_tiger_create(); - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)q; - tq->tr = tr; - return q; -#endif -} - -static u32 renderer_tiger_get_latency(struct camu_renderer *renderer) -{ - (void)renderer; - return 0; -} - -static void set_uniform(struct camu_renderer_tiger *tr, const GLchar *name, - u8 type, void *value) -{ -#ifdef CAMU_RENDERER_OPENGL - GLint loc = glGetUniformLocation(tr->program, name); - if (loc == -1) return; - - switch (type) - { - case TYPE_FLOAT: - glUniform1f(loc, *((GLfloat *)value)); - break; - case TYPE_SAMPLER2D: - glUniform1i(loc, (GLuint)(*((GLfloat *)value))); - break; - case TYPE_VEC2: - glUniform2fv(loc, 1, (GLfloat *)value); - break; - case TYPE_VEC3: - glUniform3fv(loc, 1, (GLfloat *)value); - break; - case TYPE_VEC4: - glUniform4fv(loc, 1, (GLfloat *)value); - break; - case TYPE_MAT4: - glUniformMatrix4fv(loc, 1, GL_FALSE, (GLfloat *)value); - break; - case TYPE_MAT3: - glUniformMatrix3fv(loc, 1, GL_FALSE, (GLfloat *)value); - break; - case TYPE_INVALID: - break; - } -#endif -} - -static void renderer_tiger_render(struct camu_renderer *renderer, struct camu_screen *scr, bool force) -{ -#ifdef CAMU_RENDERER_OPENGL - struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - (void)force; - - tr->make_current(tr->priv); - - glClear(GL_COLOR_BUFFER_BIT); - - glUseProgram(tr->program); - glBindBuffer(GL_ARRAY_BUFFER, tr->vbo); - glActiveTexture(GL_TEXTURE0); - -#ifdef CAMU_SCREEN_THREADED - if (al_atomic_load(u8)(&scr->queued, AL_ATOMIC_RELAXED)) { - camu_screen_run_queue(scr); - } -#endif - - if (scr->videos.count > 0) { - struct camu_screen_video *video = &al_array_last(scr->videos); - - GLuint texture_id; - bool weighted; - if (camu_video_buffer_read(video->buf, &texture_id, &weighted)) { - glBindTexture(GL_TEXTURE_2D, texture_id); - - mat4x4 model; - mat4x4_identity(model); - mat4x4_ortho(model, 0.f, (f32)scr->width, (f32)scr->height, 0.f, -1.f, 1.f); - mat4x4_translate_in_place(model, (f32)video->view.x_offset, (f32)video->view.y_offset, 0.f); - mat4x4_scale_aniso(model, model, (f32)video->view.zoom, (f32)video->view.zoom, 1.f); - mat4x4_scale_aniso(model, model, (f32)video->view.width, (f32)video->view.height, 1.f); - set_uniform(tr, "g_ModelViewProjectionMatrix", TYPE_MAT4, model); - - GLuint texture0 = 0; - set_uniform(tr, "g_Texture0", TYPE_SAMPLER2D, &texture0); - - glViewport(0, 0, scr->width, scr->height); - glDrawArrays(GL_TRIANGLES, 0, 6); - } - } - - tr->swap_buffers(tr->priv); -#endif - - tr->release_current(tr->priv); -} - -/* -static void *renderer_tiger_get_device_ptr(struct camu_renderer *renderer, size_t length) -{ - (void)renderer; - (void)length; - return NULL; -#ifdef CAMU_RENDERER_OPENGL - //struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - //glBindBuffer(GL_PIXEL_UNPACK_BUFFER, tr->texture_buffer); - //glBufferData(GL_PIXEL_UNPACK_BUFFER, length, NULL, GL_STREAM_DRAW); - //return glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, length, GL_MAP_WRITE_BIT); -#endif -} - -static void renderer_tiger_commit_device_ptr(struct camu_renderer *renderer) -{ - (void)renderer; -#ifdef CAMU_RENDERER_OPENGL - //struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - //glBindBuffer(GL_PIXEL_UNPACK_BUFFER, tr->texture_buffer); - //glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); -#endif -} -*/ - -static void renderer_tiger_free(struct camu_renderer **renderer) -{ - struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)*renderer; - glDeleteProgram(tr->program); - glDeleteBuffers(1, &tr->vbo); - al_free(tr); - *renderer = NULL; -} - -struct camu_renderer *camu_renderer_tiger_create(void) -{ - struct camu_renderer_tiger *tr = al_alloc_object(struct camu_renderer_tiger); - tr->r.create_renderer = renderer_tiger_create_renderer; - tr->r.create_queue = renderer_tiger_create_queue; - tr->r.get_latency = renderer_tiger_get_latency; - tr->r.resize = renderer_tiger_resize; - tr->r.render = renderer_tiger_render; - tr->r.free = renderer_tiger_free; - return (struct camu_renderer *)tr; -} diff --git a/src/render/renderer_tiger.h b/src/render/renderer_tiger.h deleted file mode 100644 index 5891c20..0000000 --- a/src/render/renderer_tiger.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include <stl/gl.h> - -#include "renderer.h" - -enum { - TYPE_INVALID = 0, - TYPE_FLOAT, - TYPE_VEC4, - TYPE_VEC3, - TYPE_VEC2, - TYPE_MAT4, - TYPE_MAT3, - TYPE_SAMPLER2D -}; - -struct camu_renderer_tiger { - struct camu_renderer r; - GLuint vao; - GLuint vbo; - GLuint program; - GLuint texture_buffer; - bool (*load_loader)(void *); - bool (*make_current)(void *); - void (*release_current)(void *); - void (*swap_buffers)(void *); - void *priv; -}; - -struct camu_renderer *camu_renderer_tiger_create(void); diff --git a/src/screen/screen.c b/src/screen/screen.c index 23afa7e..0ff5eec 100644 --- a/src/screen/screen.c +++ b/src/screen/screen.c @@ -51,7 +51,7 @@ static void do_resize(struct camu_screen *scr, u32 width, u32 height) camu_view_calculate(&video->view, scr->width, scr->height); } // No buffers resize. - al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); + al_atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); } static void resize_callback(void *userdata, u32 width, u32 height) @@ -309,6 +309,18 @@ static bool key_callback(void *userdata, u8 state, u16 button) log_info("Scaling filters enabled."); } return true; + case STELA_KEY_C: + scr->transparent_background = !scr->transparent_background; + if (scr->transparent_background) { + scr->renderer->set_background(scr->renderer, CAMU_BACKGROUND_TRANSPARENT); + log_info("Background transparent."); + } else { + scr->renderer->set_background(scr->renderer, CAMU_BACKGROUND_DEFAULT); + log_info("Background solid."); + } + // Force refresh for if there's no video buffer. + al_atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); + return true; default: break; } @@ -402,6 +414,7 @@ bool camu_screen_create_window(struct camu_screen *scr, const char *name) scr->height = scr->window->height; scr->fullscreen = false; scr->scaling_disabled = false; + scr->transparent_background = false; #ifdef STELA_EVENT_BUFFER nn_thread_create(&scr->thread, event_thread, scr); #endif @@ -412,13 +425,13 @@ bool camu_screen_create_renderer(struct camu_screen *scr, struct camu_renderer * { scr->renderer = renderer; return renderer->create_renderer(renderer, &scr->width, &scr->height, -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN scr->window->get_vk_proc_address, scr->window->vk_create_surface, scr->window->vk_get_extensions, -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 scr->window->win32_window, -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL #ifdef STELA_USE_EGL scr->window->egl_display, scr->window->egl_context, @@ -587,14 +600,14 @@ void camu_screen_set_state(struct camu_screen *scr, s32 state) if (al_atomic_load(s32)(&scr->state, AL_ATOMIC_ACQUIRE) != CAMU_SCREEN_STOPPED) { al_atomic_store(s32)(&scr->state, state, AL_ATOMIC_RELEASE); if (state == CAMU_SCREEN_PAUSED) { - al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); + al_atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); } } } void camu_screen_force_refresh(struct camu_screen *scr) { - al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); + al_atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); camu_screen_wake(scr); } @@ -622,13 +635,15 @@ bool camu_screen_tick(struct camu_screen *scr, bool *force) { s32 state = al_atomic_load(s32)(&scr->state, AL_ATOMIC_RELAXED); al_assert(state != CAMU_SCREEN_STOPPED); - bool paused = state == CAMU_SCREEN_PAUSED; - bool do_render = camu_screen_poll(scr, paused) || !paused; u32 force_refresh = al_atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE); + bool paused = state == CAMU_SCREEN_PAUSED && force_refresh == 0; + bool do_render = camu_screen_poll(scr, paused) || !paused; + // Should be AL_ATOMIC_ACQ_REL. + force_refresh = al_atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE); do_render |= force_refresh > 0; *force = force_refresh > 0; if (force_refresh > 0) { - al_atomic_store(u32)(&scr->force_refresh, 0, AL_ATOMIC_RELEASE); + al_atomic_sub(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELEASE); } return do_render; } diff --git a/src/screen/screen.h b/src/screen/screen.h index 4ba07c2..afd2dee 100644 --- a/src/screen/screen.h +++ b/src/screen/screen.h @@ -64,6 +64,7 @@ struct camu_screen { u32 height; bool fullscreen; bool scaling_disabled; + bool transparent_background; u64 last_click_ts; f64 last_mouse_y; f64 last_mouse_x; diff --git a/src/server/server.c b/src/server/server.c index 6f8da78..ec99921 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -616,6 +616,7 @@ static u8 parse_resource_type(str *line) return CAMU_RESOURCE_HTTP; #else if (0) { + (void)line; #endif #if CACHE_HAVE_CDIO } else if (al_str_cmp(line, &al_str_c("cdda://"), 0, 7) == 0) { @@ -812,7 +813,7 @@ static void connection_closed_callback(void *userdata, struct nn_rpc_connection struct camu_server_sink *sink; al_array_foreach(server->sinks, i, sink) { if (sink->conn == conn) { - log_info("Sink removed."); + log_info("Sink \"%.*s\" removed.", al_str_x(&sink->name)); struct lia_list *list; al_array_foreach(server->lists, j, list) { lia_list_remove_sink(list, sink); diff --git a/subprojects/SPIRV-Cross.wrap b/subprojects/SPIRV-Cross.wrap index 672cb44..a74d4be 100644 --- a/subprojects/SPIRV-Cross.wrap +++ b/subprojects/SPIRV-Cross.wrap @@ -4,3 +4,5 @@ url = https://github.com/KhronosGroup/SPIRV-Cross.git revision = ccff428086b625241de9f225dab0a53269b4d12c depth = 1 method = cmake +patch_directory = SPIRV-Cross +diff_files = SPIRV-Cross/msvc_static_build.diff diff --git a/subprojects/SPIRV-Tools.wrap b/subprojects/SPIRV-Tools.wrap new file mode 100644 index 0000000..dc6fe56 --- /dev/null +++ b/subprojects/SPIRV-Tools.wrap @@ -0,0 +1,6 @@ +[wrap-git] +directory = SPIRV-Tools-v2025.1 +url = https://github.com/KhronosGroup/SPIRV-Tools.git +revision = v2025.1 +depth = 1 +method = cmake diff --git a/subprojects/ffmpeg-compat.wrap b/subprojects/ffmpeg-compat.wrap new file mode 100644 index 0000000..dc3402b --- /dev/null +++ b/subprojects/ffmpeg-compat.wrap @@ -0,0 +1,7 @@ +[wrap-file] +directory = ffmpeg-3.4.14 +source_url = https://ffmpeg.org/releases/ffmpeg-3.4.14.tar.gz +source_filename = ffmpeg-3.4.14.tar.gz +source_hash = 61e255e824341e62fbc83365d84eb754fa558f53985d28ad610d13aeee895d5a +patch_directory = ffmpeg-compat +diff_files = ffmpeg/msvc_build_conform.diff, ffmpeg-compat/ffmpeg.git-effadce6c756247ea8bae32dc13bb3e6f464f0eb.patch diff --git a/subprojects/ffmpeg.wrap b/subprojects/ffmpeg.wrap index fdd551c..21eaac9 100644 --- a/subprojects/ffmpeg.wrap +++ b/subprojects/ffmpeg.wrap @@ -40,3 +40,4 @@ source_hash = 9a6e57a446b671012612aaeb9df5126794d5ac8f2015ca220934f99a6a4e0601 #source_hash = 77e0eedd8ebeafde5807011e700fdea82b306b9f76fe469b4abc5dfefd9579bd patch_directory = ffmpeg +diff_files = ffmpeg/msvc_build_conform.diff diff --git a/subprojects/fontconfig.wrap b/subprojects/fontconfig.wrap index a71b13e..16ea256 100644 --- a/subprojects/fontconfig.wrap +++ b/subprojects/fontconfig.wrap @@ -1,7 +1,7 @@ [wrap-git] -directory = fontconfig-2.15.0 +directory = fontconfig-2.16.2 url = https://gitlab.freedesktop.org/fontconfig/fontconfig.git -revision = 2.15.0 +revision = 2.16.2 depth = 1 [provide] diff --git a/subprojects/glslang.wrap b/subprojects/glslang.wrap index 275f439..7f4eae4 100644 --- a/subprojects/glslang.wrap +++ b/subprojects/glslang.wrap @@ -1,6 +1,6 @@ [wrap-git] -directory = glslang-ef5207f +directory = glslang-15.3.0 url = https://github.com/KhronosGroup/glslang.git -revision = ef5207f9f8cce5097568efb15d3297d8b5d13014 +revision = 15.3.0 depth = 1 method = cmake diff --git a/subprojects/harfbuzz.wrap b/subprojects/harfbuzz.wrap index 97107b5..59a132d 100644 --- a/subprojects/harfbuzz.wrap +++ b/subprojects/harfbuzz.wrap @@ -1,5 +1,5 @@ [wrap-git] -directory = harfbuzz-10.1.0 +directory = harfbuzz-11.2.1 url = https://github.com/harfbuzz/harfbuzz.git -revision = 10.1.0 +revision = 11.2.1 depth = 1 diff --git a/subprojects/libalabaster.wrap b/subprojects/libalabaster.wrap index 6ab8612..2a0e3f4 100644 --- a/subprojects/libalabaster.wrap +++ b/subprojects/libalabaster.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://git.akon.city/libalabaster -revision = 34a5e136b6c79092eee73857bbad25892fe8047a +revision = 92d5840e1440fe45a150079fab5a39877589c20f depth = 1 diff --git a/subprojects/libnaunet.wrap b/subprojects/libnaunet.wrap index c6bd17a..f068c57 100644 --- a/subprojects/libnaunet.wrap +++ b/subprojects/libnaunet.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://git.akon.city/libnaunet -revision = ef86574ec5d859727695da65f683f0774a3b4460 +revision = 9fb3646511998310fc8c967c239803f38b2bdc5b depth = 1 diff --git a/subprojects/miniaudio.wrap b/subprojects/miniaudio.wrap index bf46443..4d577fa 100644 --- a/subprojects/miniaudio.wrap +++ b/subprojects/miniaudio.wrap @@ -1,7 +1,7 @@ [wrap-git] -directory = miniaudio-29c17fc +directory = miniaudio-47020e4 url = https://github.com/mackron/miniaudio.git -revision = 29c17fcb22933c17f4cd375fdf49ecd8f5a4f924 +revision = 47020e4092ddf7cc9dd464fa7c1f7bd462e39a40 depth = 1 patch_directory = miniaudio -diff_files = miniaudio/miniaudio_pulse_flush.diff +diff_files = miniaudio/miniaudio_pulse_flush.diff, miniaudio/miniaudio_wasapi_drain_tweak.diff diff --git a/subprojects/msvc-wine.wrap b/subprojects/msvc-wine.wrap new file mode 100644 index 0000000..b80ca16 --- /dev/null +++ b/subprojects/msvc-wine.wrap @@ -0,0 +1,7 @@ +[wrap-git] +directory = msvc-wine +url = https://github.com/mstorsjo/msvc-wine.git +revision = 44dc13b5e62ecc2373fbe7e4727a525001f403f4 +depth = 1 +patch_directory = msvc-wine +diff_files = msvc-wine/msvc-wine-shebang-nixos.diff diff --git a/subprojects/packagefiles/SPIRV-Cross/msvc_static_build.diff b/subprojects/packagefiles/SPIRV-Cross/msvc_static_build.diff new file mode 100644 index 0000000..5047537 --- /dev/null +++ b/subprojects/packagefiles/SPIRV-Cross/msvc_static_build.diff @@ -0,0 +1,17 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b2ab5ed..49d7d5a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -31,6 +31,12 @@ endif() + # Avoid error on Android NDK 27+'s CMake files + cmake_policy(SET CMP0057 NEW) + ++# https://github.com/KhronosGroup/SPIRV-Cross/issues/2341 ++if (POLICY CMP0091) ++ cmake_policy(SET CMP0091 NEW) ++endif() ++set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") ++ + project(SPIRV-Cross LANGUAGES CXX C) + enable_testing() + diff --git a/subprojects/packagefiles/ffmpeg-compat/ffmpeg.git-effadce6c756247ea8bae32dc13bb3e6f464f0eb.patch b/subprojects/packagefiles/ffmpeg-compat/ffmpeg.git-effadce6c756247ea8bae32dc13bb3e6f464f0eb.patch new file mode 100644 index 0000000..b4fec43 --- /dev/null +++ b/subprojects/packagefiles/ffmpeg-compat/ffmpeg.git-effadce6c756247ea8bae32dc13bb3e6f464f0eb.patch @@ -0,0 +1,73 @@ +From: Rémi Denis-Courmont <remi@remlab.net> +Date: Sun, 16 Jul 2023 15:18:02 +0000 (+0300) +Subject: avcodec/x86/mathops: clip constants used with shift instructions within inline assembly +X-Git-Tag: n6.1~1007 +X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff_plain/effadce6c756247ea8bae32dc13bb3e6f464f0eb + +avcodec/x86/mathops: clip constants used with shift instructions within inline assembly + +Fixes assembling with binutil as >= 2.41 + +Signed-off-by: James Almer <jamrial@gmail.com> +--- + +diff --git a/libavcodec/x86/mathops.h b/libavcodec/x86/mathops.h +index 6298f5ed19..ca7e2dffc1 100644 +--- a/libavcodec/x86/mathops.h ++++ b/libavcodec/x86/mathops.h +@@ -35,12 +35,20 @@ + static av_always_inline av_const int MULL(int a, int b, unsigned shift) + { + int rt, dummy; ++ if (__builtin_constant_p(shift)) + __asm__ ( + "imull %3 \n\t" + "shrdl %4, %%edx, %%eax \n\t" + :"=a"(rt), "=d"(dummy) +- :"a"(a), "rm"(b), "ci"((uint8_t)shift) ++ :"a"(a), "rm"(b), "i"(shift & 0x1F) + ); ++ else ++ __asm__ ( ++ "imull %3 \n\t" ++ "shrdl %4, %%edx, %%eax \n\t" ++ :"=a"(rt), "=d"(dummy) ++ :"a"(a), "rm"(b), "c"((uint8_t)shift) ++ ); + return rt; + } + +@@ -113,19 +121,31 @@ __asm__ volatile(\ + // avoid +32 for shift optimization (gcc should do that ...) + #define NEG_SSR32 NEG_SSR32 + static inline int32_t NEG_SSR32( int32_t a, int8_t s){ ++ if (__builtin_constant_p(s)) + __asm__ ("sarl %1, %0\n\t" + : "+r" (a) +- : "ic" ((uint8_t)(-s)) ++ : "i" (-s & 0x1F) + ); ++ else ++ __asm__ ("sarl %1, %0\n\t" ++ : "+r" (a) ++ : "c" ((uint8_t)(-s)) ++ ); + return a; + } + + #define NEG_USR32 NEG_USR32 + static inline uint32_t NEG_USR32(uint32_t a, int8_t s){ ++ if (__builtin_constant_p(s)) + __asm__ ("shrl %1, %0\n\t" + : "+r" (a) +- : "ic" ((uint8_t)(-s)) ++ : "i" (-s & 0x1F) + ); ++ else ++ __asm__ ("shrl %1, %0\n\t" ++ : "+r" (a) ++ : "c" ((uint8_t)(-s)) ++ ); + return a; + } + diff --git a/subprojects/packagefiles/ffmpeg-compat/meson.build b/subprojects/packagefiles/ffmpeg-compat/meson.build new file mode 100644 index 0000000..7aeeb71 --- /dev/null +++ b/subprojects/packagefiles/ffmpeg-compat/meson.build @@ -0,0 +1,197 @@ +project('ffmpeg', 'c', version: '3.4.14', meson_version: '>=0.57.0') + +ffmpeg_version_string = meson.project_version() + +compiler = meson.get_compiler('c') + +cpu = target_machine.cpu_family() +is_64bit = (cpu == 'x86_64' or cpu == 'aarch64') +is_debug = get_option('debug') +is_minsize = get_option('optimization') == 's' +is_linux = host_machine.system() == 'linux' +is_windows = host_machine.system() == 'windows' +is_msvc = compiler.get_id() == 'msvc' or compiler.get_id() == 'clang-cl' +is_mingw = is_windows and not is_msvc +is_android = host_machine.system() == 'android' + +extra_options = [] + +if not is_debug + extra_options += ['--disable-debug'] +endif + +if is_minsize + extra_options += ['--enable-small'] +endif + +extra_options += ['--arch=' + cpu] +extra_options += ['--cc=' + compiler.cmd_array()[0]] +if meson.is_cross_build() + if is_msvc + extra_options += ['--ld=' + compiler.get_linker_id()] + endif + extra_options += ['--ar=' + meson.get_external_property('ar', 'ar')] + extra_options += ['--nm=' + meson.get_external_property('nm', 'nm')] +endif + +if cpu == 'x86_64' or cpu == 'x86' + extra_options += ['--enable-x86asm'] +endif + +if is_windows + extra_options += ['--extra-cflags=-D_WIN32_WINNT=0x0502'] # Windows Server 2003 with SP1, Windows XP with SP2. + if is_64bit + extra_options += ['--target-os=win64'] + else + extra_options += ['--target-os=win32'] + endif + if is_msvc + extra_options += ['--toolchain=msvc'] + endif + extra_options += ['--enable-w32threads'] +elif is_android + extra_options += ['--target-os=android'] +endif + +#'--extra-ldflags=-Lbuild/subprojects/libalabaster -l:libalabaster.a', +#'--malloc-prefix=al_', + +decoders = 'flac,mp3,mp3float,aac,opus,vorbis,h264,hevc,av1,vp9' +decoders += ',pcm_s32be,pcm_s32le,pcm_s24be,pcm_s24le,pcm_s16be,pcm_s16le' +#decoders += ',pcm_f32be,pcm_f32le,pcm_s32le_planar,pcm_s16be_planar,pcm_s16le_planar' +decoders += ',dca,eac3' +decoders += ',pcm_dvd,mpegvideo,mpeg2video' +#decoders += ',ass,srt' + +demuxers = '' +parsers = '' +if not get_option('sink-only') + demuxers += 'flac,mp3,aac,wav,matroska,mov,avi' + demuxers += ',pcm_s32be,pcm_s32le,pcm_s24be,pcm_s24le,pcm_s16be,pcm_s16le' + #demuxers += ',pcm_f32be,pcm_f32le,pcm_s32le_planar,pcm_s16be_planar,pcm_s16le_planar' + demuxers += ',eac3' + demuxers += ',mpegts,mpegtsraw,mpegps,mpegvideo' + #demuxers += ',ass,srt' + parsers += 'aac,opus,h264,hevc,av1,vp9' + parsers += ',dca' + parsers += ',mpegaudio,mpegvideo,dvd_nav' + extra_options += ['--enable-bzlib'] # matroska +endif + +extra_options += ['--enable-zlib'] +decoders += ',png,apng,mjpeg,jpeg2000,gif,' +if not get_option('sink-only') + demuxers += ',image_png_pipe,image2,mjpeg,image2pipe,image_jpeg_pipe,gif' + parsers += ',png,mjpeg,jpeg2000,gif' +endif + +bsfs = '' +if not get_option('sink-only') + bsfs += 'extract_extradata,mp3_header_decompress' +endif + +hwaccels = '' +if get_option('codec-hwaccel').enabled() + if get_option('renderer-api') == 'vulkan' + extra_options += ['--enable-vulkan'] + hwaccels += 'h264_vulkan,hevc_vulkan,av1_vulkan,vp9_vulkan' + elif is_windows + extra_options += ['--enable-d3d11va'] + hwaccels += 'h264_d3d11va,hevc_d3d11va,av1_d3d11va,vp9_d3d11va' + hwaccels += ',h264_d3d11va2,hevc_d3d11va2,av1_d3d11va2,vp9_d3d11va2' + #extra_options += ['--enable-dxva2'] + #hwaccels += ',h264_dxva2,hevc_dxva2,av1_dxva2,vp9_dxva2' + elif is_android + extra_options += ['--enable-jni', '--enable-mediacodec'] + decoders += ',h264_mediacodec,hevc_mediacodec,av1_mediacodec,vp9_mediacodec' + elif is_linux + extra_options += ['--enable-vaapi'] + endif +else + extra_options += ['--disable-hwaccels'] +endif + +protocols = '' +if not get_option('sink-only') + protocols += 'cache' +endif + +if decoders != '' + extra_options += ['--enable-decoder=' + decoders] +endif + +if demuxers != '' + extra_options += ['--enable-demuxer=' + demuxers] +endif + +if parsers != '' + extra_options += ['--enable-parser=' + parsers] +endif + +if bsfs != '' + extra_options += ['--enable-bsf=' + bsfs] +endif + +if protocols != '' + extra_options += ['--enable-protocol=' + protocols] +endif + +if hwaccels != '' + extra_options += ['--enable-hwaccel=' + hwaccels] +endif + +if is_linux or is_mingw + extra_options += ['--enable-libsoxr'] +endif + +ext_proj = import('unstable-external_project') + +proj = ext_proj.add_project('configure', + configure_options: [ + '--prefix=@PREFIX@', + '--libdir=@PREFIX@/@LIBDIR@', + '--incdir=@PREFIX@/@INCLUDEDIR@', + '--enable-pic', + '--enable-static', + '--disable-shared', + '--disable-logging', + '--disable-all', + '--disable-autodetect', + '--disable-everything', + '--disable-programs', + '--disable-doc', + '--disable-htmlpages', + '--disable-manpages', + '--disable-podpages', + '--disable-txtpages', + '--disable-safe-bitstream-reader', + '--disable-schannel', + '--disable-network', + '--disable-securetransport', + #'--disable-iconv', + '--enable-gpl', + '--enable-version3', + '--disable-nonfree', + '--enable-runtime-cpudetect', + '--enable-asm', + '--enable-inline-asm', + '--enable-avutil', + '--enable-avformat', + '--enable-avcodec', + #'--enable-avdevice', + '--enable-swresample', + '--enable-swscale', + '--disable-indevs', + '--disable-outdevs', + extra_options + ], + cross_configure_options: ['--enable-cross-compile'], + verbose: true) + +avutil = proj.dependency('avutil') +avformat = proj.dependency('avformat') +avcodec = proj.dependency('avcodec') +#avdevice = proj.dependency('avdevice') +swresample = proj.dependency('swresample') +swscale = proj.dependency('swscale') +ffmpeg_include = declare_dependency(include_directories: include_directories('.', 'build/')) diff --git a/subprojects/packagefiles/ffmpeg/meson.build b/subprojects/packagefiles/ffmpeg/meson.build index 0ecae9e..8bcce34 100644 --- a/subprojects/packagefiles/ffmpeg/meson.build +++ b/subprojects/packagefiles/ffmpeg/meson.build @@ -24,11 +24,14 @@ if is_minsize extra_options += ['--enable-small'] endif -extra_options += ['--cc=' + compiler.cmd_array()[0]] extra_options += ['--arch=' + cpu] +extra_options += ['--cc=' + compiler.cmd_array()[0]] if meson.is_cross_build() - extra_options += ['--nm=' + meson.get_external_property('nm', 'nm')] + if is_msvc + extra_options += ['--ld=' + compiler.get_linker_id()] + endif extra_options += ['--ar=' + meson.get_external_property('ar', 'ar')] + extra_options += ['--nm=' + meson.get_external_property('nm', 'nm')] endif if cpu == 'x86_64' or cpu == 'x86' @@ -52,32 +55,45 @@ endif #'--extra-ldflags=-Lbuild/subprojects/libalabaster -l:libalabaster.a', #'--malloc-prefix=al_', -decoders = 'flac,mp3,mp3float,aac,opus,vorbis,alac,mjpeg,jpeg2000,gif,h264,hevc,av1,vp9,vp8' -decoders += ',pcm_f32be,pcm_s32be,pcm_s32le,pcm_s32le_planar,pcm_f32le,pcm_s24be,pcm_s24le,pcm_s16be,pcm_s16be_planar,pcm_s16le,pcm_s16le_planar' -decoders += ',dca' -#decoders += ',pcm_dvd,mpegvideo,mpeg2video' +decoders = 'flac,mp3,mp3float,aac,opus,vorbis,h264,hevc,av1,vp9' +decoders += ',pcm_s32be,pcm_s32le,pcm_s24be,pcm_s24le,pcm_s16be,pcm_s16le' +#decoders += ',pcm_f32be,pcm_f32le,pcm_s32le_planar,pcm_s16be_planar,pcm_s16le_planar' +decoders += ',dca,eac3' +decoders += ',pcm_dvd,mpegvideo,mpeg2video' #decoders += ',ass,srt' -demuxers = 'flac,mp3,aac,wav,image2,mjpeg,image2pipe,image_jpeg_pipe,gif,matroska,mov,avi' -#demuxers += ',mpegts,mpegtsraw,mpegps,mpegvideo' -#demuxers += ',ass,srt' - -parsers = 'aac,opus,mjpeg,jpeg2000,gif,h264,hevc,av1,vp9,vp8' -parsers += ',dca' -#parsers += ',mpegaudio,mpegvideo,dvd_nav' +demuxers = '' +parsers = '' +if not get_option('sink-only') + demuxers += 'flac,mp3,aac,wav,matroska,mov,avi' + demuxers += ',pcm_s32be,pcm_s32le,pcm_s24be,pcm_s24le,pcm_s16be,pcm_s16le' + #demuxers += ',pcm_f32be,pcm_f32le,pcm_s32le_planar,pcm_s16be_planar,pcm_s16le_planar' + demuxers += ',eac3' + demuxers += ',mpegts,mpegtsraw,mpegps,mpegvideo' + #demuxers += ',ass,srt' + parsers += 'aac,opus,h264,hevc,av1,vp9' + parsers += ',dca' + parsers += ',mpegaudio,mpegvideo,dvd_nav' + extra_options += ['--enable-bzlib'] # matroska +endif extra_options += ['--enable-zlib'] -decoders += ',png,apng' -demuxers += ',image_png_pipe' -parsers += ',png' +decoders += ',png,apng,mjpeg,jpeg2000,gif,' +if not get_option('sink-only') + demuxers += ',image_png_pipe,image2,mjpeg,image2pipe,image_jpeg_pipe,gif' + parsers += ',png,mjpeg,jpeg2000,gif' +endif -bsfs = 'extract_extradata,mp3_header_decompress' +bsfs = '' +if not get_option('sink-only') + bsfs += 'extract_extradata,mp3_header_decompress' +endif hwaccels = '' if get_option('codec-hwaccel').enabled() if get_option('renderer-api') == 'vulkan' extra_options += ['--enable-vulkan'] - hwaccels += 'h264_vulkan,hevc_vulkan,av1_vulkan' + hwaccels += 'h264_vulkan,hevc_vulkan,av1_vulkan,vp9_vulkan' elif is_windows extra_options += ['--enable-d3d11va'] hwaccels += 'h264_d3d11va,hevc_d3d11va,av1_d3d11va,vp9_d3d11va' @@ -90,14 +106,39 @@ if get_option('codec-hwaccel').enabled() elif is_linux extra_options += ['--enable-vaapi'] endif +else + extra_options += ['--disable-hwaccels'] +endif + +protocols = '' +if not get_option('sink-only') + protocols += 'cache' +endif + +if decoders != '' + extra_options += ['--enable-decoder=' + decoders] +endif + +if demuxers != '' + extra_options += ['--enable-demuxer=' + demuxers] +endif + +if parsers != '' + extra_options += ['--enable-parser=' + parsers] +endif + +if bsfs != '' + extra_options += ['--enable-bsf=' + bsfs] +endif + +if protocols != '' + extra_options += ['--enable-protocol=' + protocols] endif if hwaccels != '' extra_options += ['--enable-hwaccel=' + hwaccels] endif -protocols = 'cache' - if is_linux or is_mingw extra_options += ['--enable-libsoxr'] endif @@ -122,17 +163,11 @@ proj = ext_proj.add_project('configure', '--disable-manpages', '--disable-podpages', '--disable-txtpages', - '--disable-bzlib', - '--disable-error-resilience', - '--disable-iconv', + '--disable-safe-bitstream-reader', '--disable-schannel', '--disable-network', '--disable-securetransport', - '--disable-sdl2', - '--disable-symver', - '--disable-faan', - '--disable-alsa', - '--disable-xlib', + #'--disable-iconv', '--enable-gpl', '--enable-version3', '--disable-nonfree', @@ -142,16 +177,11 @@ proj = ext_proj.add_project('configure', '--enable-avutil', '--enable-avformat', '--enable-avcodec', - '--enable-avdevice', + #'--enable-avdevice', '--enable-swresample', '--enable-swscale', '--disable-indevs', '--disable-outdevs', - '--enable-demuxer=' + demuxers, - '--enable-decoder=' + decoders, - '--enable-parser=' + parsers, - '--enable-bsf=' + bsfs, - '--enable-protocol=' + protocols, extra_options ], cross_configure_options: ['--enable-cross-compile'], @@ -160,7 +190,7 @@ proj = ext_proj.add_project('configure', avutil = proj.dependency('avutil') avformat = proj.dependency('avformat') avcodec = proj.dependency('avcodec') -avdevice = proj.dependency('avdevice') +#avdevice = proj.dependency('avdevice') swresample = proj.dependency('swresample') swscale = proj.dependency('swscale') ffmpeg_include = declare_dependency(include_directories: include_directories('.', 'build/')) diff --git a/subprojects/packagefiles/ffmpeg/msvc_build_conform.diff b/subprojects/packagefiles/ffmpeg/msvc_build_conform.diff new file mode 100644 index 0000000..3aff7e9 --- /dev/null +++ b/subprojects/packagefiles/ffmpeg/msvc_build_conform.diff @@ -0,0 +1,20 @@ +--- a/configure 2025-03-02 19:22:08.000000000 -0500 ++++ b/configure 2025-05-17 18:43:08.854727216 -0400 +@@ -5184,7 +5184,7 @@ + DEPCCFLAGS=$_flags + fi + +-if $ar 2>&1 | grep -q Microsoft; then ++if $ar 2>&1 | grep -q Microsoft || [ "$ar" == "llvm-lib" ]; then + arflags="-nologo" + ar_o='-out:$@' + elif $ar 2>&1 | grep -q "\[D\] "; then +@@ -5878,6 +5878,8 @@ + enabled x86_32 && check_ldflags -LARGEADDRESSAWARE + add_cppflags -DWIN32_LEAN_AND_MEAN + shlibdir_default="$bindir_default" ++ LIBPREF="" ++ LIBSUF=".lib" + SLIBPREF="" + SLIBSUF=".dll" + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' diff --git a/subprojects/packagefiles/libplacebo/max_align_msvc.diff b/subprojects/packagefiles/libplacebo/max_align_msvc.diff new file mode 100644 index 0000000..13df154 --- /dev/null +++ b/subprojects/packagefiles/libplacebo/max_align_msvc.diff @@ -0,0 +1,14 @@ +diff --git a/src/pl_alloc.h b/src/pl_alloc.h +index 78df08a..29718eb 100644 +--- a/src/pl_alloc.h ++++ b/src/pl_alloc.h +@@ -83,6 +83,9 @@ char *pl_strndup0(void *parent, const char *str, size_t size); + // `priv` at the address of `pub` + sizeof(pub), rounded up to the maximum + // alignment requirements. + ++#if defined(_MSC_VER) ++typedef double max_align_t; ++#endif + #define PL_ALIGN_MEM(size) PL_ALIGN2(size, alignof(max_align_t)) + + #define PL_PRIV(pub) \ diff --git a/subprojects/packagefiles/miniaudio/meson.build b/subprojects/packagefiles/miniaudio/meson.build index c980787..3c9e4c2 100644 --- a/subprojects/packagefiles/miniaudio/meson.build +++ b/subprojects/packagefiles/miniaudio/meson.build @@ -1,2 +1,2 @@ -project('miniaudio', 'c', version: 'git-29c17fc') +project('miniaudio', 'c', version: 'git-47020e4') miniaudio = declare_dependency(include_directories: include_directories('.')) diff --git a/subprojects/packagefiles/miniaudio/miniaudio_wasapi_drain_tweak.diff b/subprojects/packagefiles/miniaudio/miniaudio_wasapi_drain_tweak.diff new file mode 100644 index 0000000..56da73b --- /dev/null +++ b/subprojects/packagefiles/miniaudio/miniaudio_wasapi_drain_tweak.diff @@ -0,0 +1,13 @@ +diff --git a/miniaudio.h b/miniaudio.h +index c12ba87..4d9bbb0 100644 +--- a/miniaudio.h ++++ b/miniaudio.h +@@ -24501,7 +24501,7 @@ static ma_result ma_device_stop__wasapi_nolock(ma_device* pDevice) + */ + if (ma_atomic_bool32_get(&pDevice->wasapi.isStartedPlayback)) { + /* We need to make sure we put a timeout here or else we'll risk getting stuck in a deadlock in some cases. */ +- DWORD waitTime = (pDevice->wasapi.actualBufferSizeInFramesPlayback * 1000) / pDevice->playback.internalSampleRate; ++ DWORD waitTime = ma_calculate_buffer_size_in_milliseconds_from_frames(pDevice->wasapi.actualBufferSizeInFramesPlayback, pDevice->playback.internalSampleRate); + + if (pDevice->playback.shareMode == ma_share_mode_exclusive) { + WaitForSingleObject((HANDLE)pDevice->wasapi.hEventPlayback, waitTime); diff --git a/subprojects/packagefiles/msvc-wine/msvc-wine-shebang-nixos.diff b/subprojects/packagefiles/msvc-wine/msvc-wine-shebang-nixos.diff new file mode 100644 index 0000000..37295a9 --- /dev/null +++ b/subprojects/packagefiles/msvc-wine/msvc-wine-shebang-nixos.diff @@ -0,0 +1,405 @@ +https://github.com/mstorsjo/msvc-wine/pull/187 + +diff --git a/fixinclude b/fixinclude +index 4a8c733..bd5280c 100755 +--- a/fixinclude ++++ b/fixinclude +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + # + # Copyright (c) 2019 Martin Storsjo + # +diff --git a/install.sh b/install.sh +index ac00d9f..039922f 100755 +--- a/install.sh ++++ b/install.sh +@@ -1,4 +1,4 @@ +-#!/bin/sh ++#!/usr/bin/env sh + # + # Copyright (c) 2019 Martin Storsjo + # +diff --git a/lowercase b/lowercase +index ee10cc7..32902f7 100755 +--- a/lowercase ++++ b/lowercase +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + # + # Copyright (c) 2019 Martin Storsjo + # +diff --git a/msvcenv-native.sh b/msvcenv-native.sh +index e83c687..f3a99f1 100755 +--- a/msvcenv-native.sh ++++ b/msvcenv-native.sh +@@ -1,4 +1,4 @@ +-#!/bin/sh ++#!/usr/bin/env sh + # + # Copyright (c) 2019 Martin Storsjo + # +@@ -33,9 +33,9 @@ else + if [ ! -f "$ENV" ]; then + echo $ENV doesn\'t exist + else +- export INCLUDE="$(bash -c ". $ENV && /bin/echo \"\$INCLUDE\"" | sed s/z://g | sed 's/\\/\//g')" +- export LIB="$(bash -c ". $ENV && /bin/echo \"\$LIB\"" | sed s/z://g | sed 's/\\/\//g')" +- MSVCARCH="$(bash -c ". $ENV && /bin/echo \"\$ARCH\"")" ++ export INCLUDE="$(bash -c ". $ENV && /usr/bin/env echo \"\$INCLUDE\"" | sed s/z://g | sed 's/\\/\//g')" ++ export LIB="$(bash -c ". $ENV && /usr/bin/env echo \"\$LIB\"" | sed s/z://g | sed 's/\\/\//g')" ++ MSVCARCH="$(bash -c ". $ENV && /usr/bin/env echo \"\$ARCH\"")" + case $MSVCARCH in + x86) TARGET_ARCH=i686 ;; + x64) TARGET_ARCH=x86_64 ;; +diff --git a/test/test-asm.sh b/test/test-asm.sh +index 5774c02..ba9511b 100755 +--- a/test/test-asm.sh ++++ b/test/test-asm.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Martin Storsjo + # +diff --git a/test/test-cl.sh b/test/test-cl.sh +index 250f092..41fe51b 100755 +--- a/test/test-cl.sh ++++ b/test/test-cl.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Huang Qinjin + # +diff --git a/test/test-clang-cl-cmds.sh b/test/test-clang-cl-cmds.sh +index 885835b..9409d2b 100755 +--- a/test/test-clang-cl-cmds.sh ++++ b/test/test-clang-cl-cmds.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Martin Storsjo + # +diff --git a/test/test-clang-cl.sh b/test/test-clang-cl.sh +index ba7f82d..f99b745 100755 +--- a/test/test-clang-cl.sh ++++ b/test/test-clang-cl.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Martin Storsjo + # +diff --git a/test/test-cmake-clang-cl.sh b/test/test-cmake-clang-cl.sh +index 78485ab..4a6ce3f 100755 +--- a/test/test-cmake-clang-cl.sh ++++ b/test/test-cmake-clang-cl.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Martin Storsjo + # +diff --git a/test/test-cmake.sh b/test/test-cmake.sh +index 6beface..994d07d 100755 +--- a/test/test-cmake.sh ++++ b/test/test-cmake.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Huang Qinjin + # +diff --git a/test/test-dumpbin.sh b/test/test-dumpbin.sh +index 68608d4..dd3841d 100755 +--- a/test/test-dumpbin.sh ++++ b/test/test-dumpbin.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Huang Qinjin + # +diff --git a/test/test-mc.sh b/test/test-mc.sh +index 836a210..2e7d8ab 100755 +--- a/test/test-mc.sh ++++ b/test/test-mc.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2024 Mark Harmstone + # +diff --git a/test/test-meson.sh b/test/test-meson.sh +index 68ac271..bfd6d6d 100755 +--- a/test/test-meson.sh ++++ b/test/test-meson.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Martin Storsjo + # +diff --git a/test/test-midl.sh b/test/test-midl.sh +index 45d9f92..8f9319e 100755 +--- a/test/test-midl.sh ++++ b/test/test-midl.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Martin Storsjo + # +diff --git a/test/test-msbuild.sh b/test/test-msbuild.sh +index 00f03c6..faf284a 100755 +--- a/test/test-msbuild.sh ++++ b/test/test-msbuild.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2024 Sergey Kvachonok + # +diff --git a/test/test-mt.sh b/test/test-mt.sh +index 5f1881b..eda11ab 100755 +--- a/test/test-mt.sh ++++ b/test/test-mt.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Huang Qinjin + # +diff --git a/test/test-vcpkg.sh b/test/test-vcpkg.sh +index dc3d3ce..79ebe51 100755 +--- a/test/test-vcpkg.sh ++++ b/test/test-vcpkg.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2024 Huang Qinjin + # +diff --git a/test/test-wdk-msbuild.sh b/test/test-wdk-msbuild.sh +index b37b3de..90f4189 100755 +--- a/test/test-wdk-msbuild.sh ++++ b/test/test-wdk-msbuild.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2024 Sergey Kvachonok + # +diff --git a/test/test.sh b/test/test.sh +index 1825216..ad9f9c1 100755 +--- a/test/test.sh ++++ b/test/test.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2023 Huang Qinjin + # +diff --git a/vsdownload.py b/vsdownload.py +index d9b4dcf..7598eec 100755 +--- a/vsdownload.py ++++ b/vsdownload.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python3 ++#!/usr/bin/env python3 + # + # Copyright (c) 2019 Martin Storsjo + # +diff --git a/wdk-download.sh b/wdk-download.sh +index e0ea631..7fa8bf0 100755 +--- a/wdk-download.sh ++++ b/wdk-download.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2024 Sergey Kvachonok + # +diff --git a/wrappers/armasm b/wrappers/armasm +index 3797431..bf8ea5a 100755 +--- a/wrappers/armasm ++++ b/wrappers/armasm +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/armasm64 b/wrappers/armasm64 +index fdfdb38..eb1553f 100755 +--- a/wrappers/armasm64 ++++ b/wrappers/armasm64 +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/cl b/wrappers/cl +index 35c1b23..6ca6a56 100755 +--- a/wrappers/cl ++++ b/wrappers/cl +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/cmd b/wrappers/cmd +index 88a39f0..a7ab236 100755 +--- a/wrappers/cmd ++++ b/wrappers/cmd +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/dumpbin b/wrappers/dumpbin +index c6f7f9e..18c5591 100755 +--- a/wrappers/dumpbin ++++ b/wrappers/dumpbin +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/findstr b/wrappers/findstr +index 1146022..136ac0e 100755 +--- a/wrappers/findstr ++++ b/wrappers/findstr +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2024 Huang Qinjin + # +diff --git a/wrappers/lib b/wrappers/lib +index 143da0c..3967675 100755 +--- a/wrappers/lib ++++ b/wrappers/lib +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/link b/wrappers/link +index dba1774..53920d4 100755 +--- a/wrappers/link ++++ b/wrappers/link +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/mc b/wrappers/mc +index c1c5d80..bf71882 100755 +--- a/wrappers/mc ++++ b/wrappers/mc +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/midl b/wrappers/midl +index dd34988..adddcfa 100755 +--- a/wrappers/midl ++++ b/wrappers/midl +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/ml b/wrappers/ml +index db671c7..a5d537b 100755 +--- a/wrappers/ml ++++ b/wrappers/ml +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/ml64 b/wrappers/ml64 +index 0708ebe..df65803 100755 +--- a/wrappers/ml64 ++++ b/wrappers/ml64 +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/msbuild b/wrappers/msbuild +index 65bbf8f..53fdd8f 100755 +--- a/wrappers/msbuild ++++ b/wrappers/msbuild +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2024 Sergey Kvachonok + # +diff --git a/wrappers/msvcenv.sh b/wrappers/msvcenv.sh +index 101e9bb..2d2a918 100755 +--- a/wrappers/msvcenv.sh ++++ b/wrappers/msvcenv.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/mt b/wrappers/mt +index edebd75..ed92f96 100755 +--- a/wrappers/mt ++++ b/wrappers/mt +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/nmake b/wrappers/nmake +index 88102d1..3eaf0f5 100755 +--- a/wrappers/nmake ++++ b/wrappers/nmake +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/rc b/wrappers/rc +index f7b8d97..7afb1ad 100755 +--- a/wrappers/rc ++++ b/wrappers/rc +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # +diff --git a/wrappers/wine-msvc.sh b/wrappers/wine-msvc.sh +index a267283..bb08891 100755 +--- a/wrappers/wine-msvc.sh ++++ b/wrappers/wine-msvc.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # + # Copyright (c) 2018 Martin Storsjo + # diff --git a/subprojects/packagefiles/shaderc/no_hlsl_compile.diff b/subprojects/packagefiles/shaderc/no_hlsl_compile.diff new file mode 100644 index 0000000..ef96592 --- /dev/null +++ b/subprojects/packagefiles/shaderc/no_hlsl_compile.diff @@ -0,0 +1,13 @@ +diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc +index 9bf9a43..507e669 100644 +--- a/libshaderc_util/src/compiler.cc ++++ b/libshaderc_util/src/compiler.cc +@@ -286,7 +286,7 @@ std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::Compile( + bases[static_cast<int>(UniformKind::StorageBuffer)]); + shader.setShiftUavBinding( + bases[static_cast<int>(UniformKind::UnorderedAccessView)]); +- shader.setHlslIoMapping(hlsl_iomap_); ++ //shader.setHlslIoMapping(hlsl_iomap_); + shader.setResourceSetBinding( + hlsl_explicit_bindings_[static_cast<int>(used_shader_stage)]); + shader.setEnvClient(target_client_info.client, diff --git a/subprojects/shaderc.wrap b/subprojects/shaderc.wrap index 575308b..5be87c2 100644 --- a/subprojects/shaderc.wrap +++ b/subprojects/shaderc.wrap @@ -1,8 +1,8 @@ [wrap-git] -directory = shaderc-0ab6bf5 +directory = shaderc-v2025.2 url = https://github.com/google/shaderc.git -revision = 0ab6bf5cefea23cf985ce6296a293170132984ae +revision = v2025.2 depth = 1 method = cmake patch_directory = shaderc -diff_files = shaderc/third_party_fix_build.diff +diff_files = shaderc/third_party_fix_build.diff, shaderc/no_hlsl_compile.diff diff --git a/subprojects/stela.wrap b/subprojects/stela.wrap index c8a8139..9282a6d 100644 --- a/subprojects/stela.wrap +++ b/subprojects/stela.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://git.akon.city/stela -revision = 7d4434ea4ceb1fa5c75f372a73ac6dfe5cb05b1d +revision = 1f1b60ed59cd3b3d594cf16c51cb835cb912fb12 depth = 1 |