diff --git a/.gitattributes b/.gitattributes index 0c8aa3e10..152bf9d72 100644 --- a/.gitattributes +++ b/.gitattributes @@ -23,9 +23,14 @@ *.exp filter=lfs diff=lfs merge=lfs -text *.a filter=lfs diff=lfs merge=lfs -text *.so filter=lfs diff=lfs merge=lfs -text +*.so.* filter=lfs diff=lfs merge=lfs -text *.dylib filter=lfs diff=lfs merge=lfs -text *.pdb filter=lfs diff=lfs merge=lfs -text +# FFmpeg per-platform CLI binaries (no extension) +deps/FFmpeg/ffmpeg.linux-x64 filter=lfs diff=lfs merge=lfs -text +deps/FFmpeg/ffmpeg.osx-arm64 filter=lfs diff=lfs merge=lfs -text + # setup *.msi filter=lfs diff=lfs merge=lfs -text *.cab filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/test-linux-game.yml b/.github/workflows/test-linux-game.yml index 2cf7d0b15..763c6a8c6 100644 --- a/.github/workflows/test-linux-game.yml +++ b/.github/workflows/test-linux-game.yml @@ -57,7 +57,7 @@ jobs: - name: Install runtime dependencies run: | sudo apt-get update - sudo apt-get install -y libopenal-dev libvulkan1 xvfb lld vulkan-validationlayers + sudo apt-get install -y libopenal-dev libvulkan1 xvfb lld vulkan-validationlayers libva2 libva-drm2 libva-x11-2 - name: Start virtual display run: | # Lavapipe's x11 WSI needs a display server to expose VK_KHR_swapchain, diff --git a/deps/FFmpeg/checkout.bat b/deps/FFmpeg/checkout.bat deleted file mode 100644 index e4ea0eca4..000000000 --- a/deps/FFmpeg/checkout.bat +++ /dev/null @@ -1,8 +0,0 @@ -CALL ..\find_git.cmd -IF NOT ERRORLEVEL 0 ( - ECHO "Could not find git.exe" - EXIT /B %ERRORLEVEL% -) -%GIT_CMD% clone https://git.ffmpeg.org/ffmpeg.git ../../externals/ffmpeg -rem checkout n3.3.3 tag -IF NOT ERRORLEVEL 0 PAUSE \ No newline at end of file diff --git a/deps/FFmpeg/dotnet/build.sh b/deps/FFmpeg/dotnet/build.sh deleted file mode 100644 index bf8ad3a12..000000000 --- a/deps/FFmpeg/dotnet/build.sh +++ /dev/null @@ -1,242 +0,0 @@ -#!/bin/sh - -# References/help -# https://trac.ffmpeg.org/wiki/CompilationGuide/MSVC -# https://pracucci.com/compile-ffmpeg-on-windows-with-visual-studio-compiler.html -# https://stackoverflow.com/questions/41358478/is-it-possible-to-build-ffmpeg-x64-on-windows - -# Pre-requisites: -# Install MSYS2 and YASM as indicated in https://pracucci.com/compile-ffmpeg-on-windows-with-visual-studio-compiler.html - -# Prior to running one of the command the following steps must be performed: -# 1. Start a Visual Studio prompt (should be located under C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\) -# a. for X86 start vcvars32.bat -# b. for x64 start vcvars64.bat -# 2. Then run MSYS2 command prompt (C:\workspace\windows\msys64\msys2_shell.cmd) -# 3. Set the current working directory to where ffmpeg sources are installed (e.g. /c/Projects/stride/externals/ffmpeg) - -# cmds -# C:\Windows\system32\cmd.exe -# "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvars64.bat" -# C:\workspace\msys64\msys2_shell.cmd -use-full-path -# cd C:\\Dev\\stride\\externals\\ffmpeg -# C:\\Dev\\stride\\deps\\FFmpeg\\Windows\\build.sh - -clean() { - # We could also do a distclean to also remove previously built binaries - make clean -} - -configure_windows_x64_shared() { - "${BASEDIR}/configure" \ - --toolchain=msvc \ - --arch=amd64 \ - --enable-asm \ - --enable-shared \ - --enable-version3 \ - --enable-w32threads \ - --enable-yasm \ - --disable-debug \ - --disable-doc \ - --disable-programs \ - --disable-static \ - --target-os=win64 \ - --prefix="${BASEDIR}/build/windows/x64" -} - -configure_windows_arm64_shared() { - "${BASEDIR}/configure" \ - --toolchain=msvc \ - --arch=arm64 \ - --enable-asm \ - --enable-shared \ - --enable-version3 \ - --enable-w32threads \ - --enable-yasm \ - --disable-debug \ - --disable-doc \ - --disable-programs \ - --disable-static \ - --disable-x86asm \ - --target-os=win64 \ - --prefix="${BASEDIR}/build/windows/arm64" -} - -configure_windows_x86_shared() { - "${BASEDIR}/configure" \ - --toolchain=msvc \ - --arch=x86 \ - --enable-asm \ - --enable-shared \ - --enable-version3 \ - --enable-w32threads \ - --enable-x86asm \ - --disable-debug \ - --disable-doc \ - --disable-programs \ - --disable-static \ - --target-os=win32 \ - --prefix="${BASEDIR}/build/windows/x86" -} - -configure_windows_x86_exe() { - "${BASEDIR}/configure" \ - --toolchain=msvc \ - --arch=x86 \ - --enable-asm \ - --enable-static \ - --enable-version3 \ - --enable-w32threads \ - --enable-yasm \ - --disable-debug \ - --disable-doc \ - --disable-ffplay \ - --disable-ffprobe \ - --disable-ffserver \ - --disable-shared \ - --target-os=win32 \ - --prefix="${BASEDIR}/build/windows/x86" -} - -configure_windows_x64_exe() { - "${BASEDIR}/configure" \ - --toolchain=msvc \ - --arch=amd64 \ - --enable-asm \ - --enable-static \ - --enable-version3 \ - --enable-w32threads \ - --enable-yasm \ - --disable-debug \ - --disable-doc \ - --disable-ffplay \ - --disable-ffprobe \ - --disable-ffserver \ - --disable-shared \ - --target-os=win64 \ - --prefix="${BASEDIR}/build/windows/x64" -} - -configure_windows_arm64_exe() { - "${BASEDIR}/configure" \ - --toolchain=msvc \ - --arch=arm64 \ - --enable-asm \ - --enable-static \ - --enable-version3 \ - --enable-w32threads \ - --enable-yasm \ - --disable-debug \ - --disable-doc \ - --disable-ffplay \ - --disable-ffprobe \ - --disable-ffserver \ - --disable-shared \ - --disable-x86asm \ - --target-os=win64 \ - --prefix="${BASEDIR}/build/windows/arm64" -} - -install() { - make -j${NUMBER_OF_CORES} && make install -} - -build_windows_x64_shared() { - oot="${BASEDIR}/build/windows/x64/oot/ffmpeg" - mkdir -p "$oot" - pushd "$oot" - - # Configure ffmpeg (can be skipped if already done) - configure_windows_x64_shared - # Make sure any previous build doesn't pollute the current one (can be skipped if configure didn't change since last time) - clean - # Build FFmpeg and copy binaries+include files into the installation folder (defined by --prefix in the configure command) - install - - popd -} - -build_windows_arm64_shared() { - oot="${BASEDIR}/build/windows/arm64/oot/ffmpeg" - mkdir -p "$oot" - pushd "$oot" - - # Configure ffmpeg (can be skipped if already done) - configure_windows_arm64_shared - # Make sure any previous build doesn't pollute the current one (can be skipped if configure didn't change since last time) - clean - # Build FFmpeg and copy binaries+include files into the installation folder (defined by --prefix in the configure command) - install - - popd -} - -build_windows_x86_shared() { - oot="${BASEDIR}/build/windows/x86/oot/ffmpeg" - mkdir -p "$oot" - pushd "$oot" - - # Configure ffmpeg (can be skipped if already done) - configure_windows_x86_shared - # Make sure any previous build doesn't pollute the current one (can be skipped if configure didn't change since last time) - clean - # Build FFmpeg and copy binaries+include files into the installation folder (defined by --prefix in the configure command) - install - - popd -} - -build_windows_x64_exe() { - oot="${BASEDIR}/build/windows/x64/oot/ffmpeg" - mkdir -p "$oot" - pushd "$oot" - - # Configure ffmpeg (can be skipped if already done) - configure_windows_x64_exe - # Make sure any previous build doesn't pollute the current one (can be skipped if configure didn't change since last time) - clean - # Build FFmpeg and copy binaries+include files into the installation folder (defined by --prefix in the configure command) - install - - popd -} - -build_windows_arm64_exe() { - oot="${BASEDIR}/build/windows/arm64/oot/ffmpeg" - mkdir -p "$oot" - pushd "$oot" - - # Configure ffmpeg (can be skipped if already done) - configure_windows_arm64_exe - # Make sure any previous build doesn't pollute the current one (can be skipped if configure didn't change since last time) - clean - # Build FFmpeg and copy binaries+include files into the installation folder (defined by --prefix in the configure command) - install - - popd -} - -build_windows_x86_exe() { - oot="${BASEDIR}/build/windows/x86/oot/ffmpeg" - mkdir -p "$oot" - pushd "$oot" - - # Configure ffmpeg (can be skipped if already done) - configure_windows_x86_exe - # Make sure any previous build doesn't pollute the current one (can be skipped if configure didn't change since last time) - clean - # Build FFmpeg and copy binaries+include files into the installation folder (defined by --prefix in the configure command) - install - - popd -} - -BASEDIR=$(pwd) -NUMBER_OF_CORES=$(nproc) - -# Uncomment a line to run that configuration -#build_windows_x64_shared -build_windows_x86_shared -#build_windows_x64_exe -#build_windows_x86_exe -#build_windows_arm64_exe diff --git a/deps/FFmpeg/dotnet/linux-x64/libavcodec.so.61 b/deps/FFmpeg/dotnet/linux-x64/libavcodec.so.61 new file mode 100755 index 000000000..d7388c478 --- /dev/null +++ b/deps/FFmpeg/dotnet/linux-x64/libavcodec.so.61 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ef9225d5cf5bc9d704846a28c85c17990b5064aaee950571770c5ae501d9f68 +size 4241360 diff --git a/deps/FFmpeg/dotnet/linux-x64/libavdevice.so.61 b/deps/FFmpeg/dotnet/linux-x64/libavdevice.so.61 new file mode 100755 index 000000000..f1748751c --- /dev/null +++ b/deps/FFmpeg/dotnet/linux-x64/libavdevice.so.61 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d693b7c3c0ba18c3ce57ea51d8ab485450a69dea3d5253059bd5f5e5fb1720a0 +size 14592 diff --git a/deps/FFmpeg/dotnet/linux-x64/libavfilter.so.10 b/deps/FFmpeg/dotnet/linux-x64/libavfilter.so.10 new file mode 100755 index 000000000..430f6c903 --- /dev/null +++ b/deps/FFmpeg/dotnet/linux-x64/libavfilter.so.10 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8df7b76ea5ae5cb5a7dc81a9efb7f2f7c5ba8cfc2258180513d9cd97e0e051e8 +size 154968 diff --git a/deps/FFmpeg/dotnet/linux-x64/libavformat.so.61 b/deps/FFmpeg/dotnet/linux-x64/libavformat.so.61 new file mode 100755 index 000000000..05c9e3cf0 --- /dev/null +++ b/deps/FFmpeg/dotnet/linux-x64/libavformat.so.61 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca8f1acd1b303c20bc82bdbb3fa31ec7f341d0b103e3ec7b8a3e8c0d2a4e0769 +size 758600 diff --git a/deps/FFmpeg/dotnet/linux-x64/libavutil.so.59 b/deps/FFmpeg/dotnet/linux-x64/libavutil.so.59 new file mode 100755 index 000000000..29303deff --- /dev/null +++ b/deps/FFmpeg/dotnet/linux-x64/libavutil.so.59 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30d6348a55ade3b06a70b277584dbbbd50cd978e5a93f57a17f1edd2016815dc +size 732232 diff --git a/deps/FFmpeg/dotnet/linux-x64/libswresample.so.5 b/deps/FFmpeg/dotnet/linux-x64/libswresample.so.5 new file mode 100755 index 000000000..e5eecb652 --- /dev/null +++ b/deps/FFmpeg/dotnet/linux-x64/libswresample.so.5 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bfbbe4f997e3ee34ef2536413944ee04fe3196b763a499f87d7417aa73c2b25 +size 108976 diff --git a/deps/FFmpeg/dotnet/linux-x64/libswscale.so.8 b/deps/FFmpeg/dotnet/linux-x64/libswscale.so.8 new file mode 100755 index 000000000..a918e2a2d --- /dev/null +++ b/deps/FFmpeg/dotnet/linux-x64/libswscale.so.8 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d9f12b01668d4af8903147bdfe5b7d4b81030a5bae0fedeae8311458f0a9c2c +size 535008 diff --git a/deps/FFmpeg/dotnet/notes.txt b/deps/FFmpeg/dotnet/notes.txt deleted file mode 100644 index b05860a66..000000000 --- a/deps/FFmpeg/dotnet/notes.txt +++ /dev/null @@ -1,62 +0,0 @@ -== x64 DLL version == - -This is a FFmpeg win64 shared build. - -FFMpeg version: 3.3.3 (9079c70d2095643af6954001d0627445650b85a6) - -This FFmpeg build was configured with: - --toolchain=msvc - --arch=x86_64 - --enable-version3 - --enable-yasm - --enable-asm - --enable-shared - --enable-w32threads - --enable-avresample - --disable-ffserver - --disable-programs - --disable-doc - --disable-static - --target-os=win64 - - -== x86 DLL version == - -This is a FFmpeg x86 generic shared build. - -FFMpeg version: 3.3.3 (9079c70d2095643af6954001d0627445650b85a6) - -This FFmpeg build was configured with: - --toolchain=msvc - --arch=x86 - --enable-version3 - --enable-yasm - --enable-asm - --enable-shared - --enable-w32threads - --enable-avresample - --disable-ffserver - --disable-programs - --disable-doc - --disable-static - - -// Instructions for building FFmpeg: -# ref: https://pracucci.com/compile-ffmpeg-on-windows-with-visual-studio-compiler.html - -1. checkout ffmpeg -2. download MSYS (​http://msys2.github.io) -3. install it C:\workspace\windows\msys64 -4. run MSYS command prompt (C:\workspace\windows\msys64\msys2_shell.cmd) -5. install package with "pacman -Su make gcc diffutils autoconf automake gperf yasm python" -6. go to C:\workspace\windows\msys64 -7. edit msys2_shell.cmd file -8. uncomment the "set MSYS2_PATH_TYPE=inherit" line so that environment variables are available -9. download yasm http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe -10. rename it to yasm.exe and move it to C:\workspace\windows -11. Add C:\workspace\windows to PATH environment variable -12. in C:\ProgramData\Microsoft\AndroidNDK64\android-ndk-r13b\build\tools\make_standalone_toolchain.py - * in get_host_tag_or_die method add support for MSYS - elif (platform.system() == 'MSYS_NT-10.0' or - platform.system() == 'MINGW64_NT-10.0'): - host_tag = 'windows-x86_64' \ No newline at end of file diff --git a/deps/FFmpeg/dotnet/osx-arm64/libavcodec.61.dylib b/deps/FFmpeg/dotnet/osx-arm64/libavcodec.61.dylib new file mode 100755 index 000000000..fc026566d --- /dev/null +++ b/deps/FFmpeg/dotnet/osx-arm64/libavcodec.61.dylib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6766f50729325f4c20e880b56ff8f869b474bd900fe35471a64d8fc8cc08c935 +size 2661400 diff --git a/deps/FFmpeg/dotnet/osx-arm64/libavdevice.61.dylib b/deps/FFmpeg/dotnet/osx-arm64/libavdevice.61.dylib new file mode 100755 index 000000000..3ce9605ba --- /dev/null +++ b/deps/FFmpeg/dotnet/osx-arm64/libavdevice.61.dylib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5280eebd4d37ffa2600d614dd8bfef70422db05194ffd5f97fb5f34d1593d06 +size 35688 diff --git a/deps/FFmpeg/dotnet/osx-arm64/libavfilter.10.dylib b/deps/FFmpeg/dotnet/osx-arm64/libavfilter.10.dylib new file mode 100755 index 000000000..eb5babb8c --- /dev/null +++ b/deps/FFmpeg/dotnet/osx-arm64/libavfilter.10.dylib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:202cc65322b0ccc64df742d647662cae4f5c0e9139d67a2a12a123fa9b31ecfe +size 136232 diff --git a/deps/FFmpeg/dotnet/osx-arm64/libavformat.61.dylib b/deps/FFmpeg/dotnet/osx-arm64/libavformat.61.dylib new file mode 100755 index 000000000..6e1c0afbd --- /dev/null +++ b/deps/FFmpeg/dotnet/osx-arm64/libavformat.61.dylib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b880d7608976a1676fc763ebf4290873874902074ff7cadd30789f14ce1d8b28 +size 709688 diff --git a/deps/FFmpeg/dotnet/osx-arm64/libavutil.59.dylib b/deps/FFmpeg/dotnet/osx-arm64/libavutil.59.dylib new file mode 100755 index 000000000..fa82d47c4 --- /dev/null +++ b/deps/FFmpeg/dotnet/osx-arm64/libavutil.59.dylib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acdcd7a72be171b862587aa1053e5c4ab2fdf1c3b7b12154f5cede912caafa50 +size 542904 diff --git a/deps/FFmpeg/dotnet/osx-arm64/libswresample.5.dylib b/deps/FFmpeg/dotnet/osx-arm64/libswresample.5.dylib new file mode 100755 index 000000000..b984a79fb --- /dev/null +++ b/deps/FFmpeg/dotnet/osx-arm64/libswresample.5.dylib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b26e573f915e211046672419909a6796ebdb69baeae0b05e54732ef9cdd005c +size 87000 diff --git a/deps/FFmpeg/dotnet/osx-arm64/libswscale.8.dylib b/deps/FFmpeg/dotnet/osx-arm64/libswscale.8.dylib new file mode 100755 index 000000000..bcc8787c7 --- /dev/null +++ b/deps/FFmpeg/dotnet/osx-arm64/libswscale.8.dylib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e09921db6251805ae0bb51a39a679cde29e5859ddf0d0335f5921b7e5b9f3ec7 +size 369544 diff --git a/deps/FFmpeg/dotnet/win-arm64/avcodec-57.dll b/deps/FFmpeg/dotnet/win-arm64/avcodec-57.dll deleted file mode 100644 index 9921e50f1..000000000 --- a/deps/FFmpeg/dotnet/win-arm64/avcodec-57.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7f69cd8022a13a8be34f01506e10b9bbf92f0bb04d6eb71a662267b47c54351d -size 9722880 diff --git a/deps/FFmpeg/dotnet/win-arm64/avcodec-61.dll b/deps/FFmpeg/dotnet/win-arm64/avcodec-61.dll new file mode 100644 index 000000000..32747bc01 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-arm64/avcodec-61.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f11af5322848d625649c7d176870b441d70b2468bb9f1e50877636007876ad2 +size 2697216 diff --git a/deps/FFmpeg/dotnet/win-arm64/avdevice-57.dll b/deps/FFmpeg/dotnet/win-arm64/avdevice-57.dll deleted file mode 100644 index 1da95f167..000000000 --- a/deps/FFmpeg/dotnet/win-arm64/avdevice-57.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9e8c57dcd4b5e3cb81b035597424c800fb44f52607af295ac487728888f6c040 -size 204800 diff --git a/deps/FFmpeg/dotnet/win-arm64/avdevice-61.dll b/deps/FFmpeg/dotnet/win-arm64/avdevice-61.dll new file mode 100644 index 000000000..a1f2a43b9 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-arm64/avdevice-61.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:492f103bd1e3665de8c39a8d9317aec7f23f7af553d6a5de814c8419299416be +size 15360 diff --git a/deps/FFmpeg/dotnet/win-arm64/avfilter-10.dll b/deps/FFmpeg/dotnet/win-arm64/avfilter-10.dll new file mode 100644 index 000000000..a5898a5f3 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-arm64/avfilter-10.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:092b69c5fc586c8493428a902556702474ac3e1b909adc129eb5597f830e9df8 +size 142848 diff --git a/deps/FFmpeg/dotnet/win-arm64/avfilter-6.dll b/deps/FFmpeg/dotnet/win-arm64/avfilter-6.dll deleted file mode 100644 index 5bd50d126..000000000 --- a/deps/FFmpeg/dotnet/win-arm64/avfilter-6.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a7f4842a8224747bbaff9a5e0d5b2e191f4c7d2085099cd6d5b56ace545ad7ea -size 1856512 diff --git a/deps/FFmpeg/dotnet/win-arm64/avformat-57.dll b/deps/FFmpeg/dotnet/win-arm64/avformat-57.dll deleted file mode 100644 index 0ffde0bca..000000000 --- a/deps/FFmpeg/dotnet/win-arm64/avformat-57.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3725c5ed89c43e6cf1060a413773644eaf78a5c2efacf7e8f9413f994c62e33d -size 2210816 diff --git a/deps/FFmpeg/dotnet/win-arm64/avformat-61.dll b/deps/FFmpeg/dotnet/win-arm64/avformat-61.dll new file mode 100644 index 000000000..e5c393114 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-arm64/avformat-61.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a9ee4dc5cfa80d225b759e2dcc6bdc84d2e8d4724e6e585a82389989d0cb15e +size 707072 diff --git a/deps/FFmpeg/dotnet/win-arm64/avutil-55.dll b/deps/FFmpeg/dotnet/win-arm64/avutil-55.dll deleted file mode 100644 index 4681da3e8..000000000 --- a/deps/FFmpeg/dotnet/win-arm64/avutil-55.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b434850920c56ed34c9047f0f904d7dc8673ba580de40bc601f7df28b88b1255 -size 623616 diff --git a/deps/FFmpeg/dotnet/win-arm64/avutil-59.dll b/deps/FFmpeg/dotnet/win-arm64/avutil-59.dll new file mode 100644 index 000000000..449d4d6ee --- /dev/null +++ b/deps/FFmpeg/dotnet/win-arm64/avutil-59.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf50fb717053718eb0e17c7251d1a1c9c1b2526fdd2a3bd61741265a103df3c5 +size 530432 diff --git a/deps/FFmpeg/dotnet/win-arm64/swresample-2.dll b/deps/FFmpeg/dotnet/win-arm64/swresample-2.dll deleted file mode 100644 index f7f8269b7..000000000 --- a/deps/FFmpeg/dotnet/win-arm64/swresample-2.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fcf2ea93ba2a06818955cf2cd7880c5771f147f885a10b64aa72410e98b58525 -size 186880 diff --git a/deps/FFmpeg/dotnet/win-arm64/swresample-5.dll b/deps/FFmpeg/dotnet/win-arm64/swresample-5.dll new file mode 100644 index 000000000..b564c6918 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-arm64/swresample-5.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ceb23d7ad38f9d1adf4bb7bb65898fbdf0eb8fd989ccc24bf2f8a3225d77f12 +size 70144 diff --git a/deps/FFmpeg/dotnet/win-arm64/swscale-4.dll b/deps/FFmpeg/dotnet/win-arm64/swscale-4.dll deleted file mode 100644 index 83fbfa08c..000000000 --- a/deps/FFmpeg/dotnet/win-arm64/swscale-4.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:eefb4dc92d198b7bd7013f3a68afc3f1a3b131327db7bbdd2148ca59305a13e1 -size 452608 diff --git a/deps/FFmpeg/dotnet/win-arm64/swscale-8.dll b/deps/FFmpeg/dotnet/win-arm64/swscale-8.dll new file mode 100644 index 000000000..9ff7d6780 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-arm64/swscale-8.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f22ba431a7da148a1f24a5da3e257613b915f105e111541dc79e4b898820e162 +size 338944 diff --git a/deps/FFmpeg/dotnet/win-x64/avcodec-57.dll b/deps/FFmpeg/dotnet/win-x64/avcodec-57.dll deleted file mode 100644 index 5ae25b683..000000000 --- a/deps/FFmpeg/dotnet/win-x64/avcodec-57.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a9665ac0382166204b3fe4a05e5c7a2cd6edcb4d2656aa54adf2d2d0753e33ba -size 10908672 diff --git a/deps/FFmpeg/dotnet/win-x64/avcodec-61.dll b/deps/FFmpeg/dotnet/win-x64/avcodec-61.dll new file mode 100644 index 000000000..6fc5a9cf5 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-x64/avcodec-61.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:222c8d3099acd8eacf47b40338c3d8fd99517e48ffe68f942fb7473559ec9e8f +size 4144128 diff --git a/deps/FFmpeg/dotnet/win-x64/avdevice-57.dll b/deps/FFmpeg/dotnet/win-x64/avdevice-57.dll deleted file mode 100644 index aef65a611..000000000 --- a/deps/FFmpeg/dotnet/win-x64/avdevice-57.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9c74436ef4dce4fe8970fbba514c67e99b0e7ebb8a868e2f375e73c7736ec2f -size 185856 diff --git a/deps/FFmpeg/dotnet/win-x64/avdevice-61.dll b/deps/FFmpeg/dotnet/win-x64/avdevice-61.dll new file mode 100644 index 000000000..db1bf6fa9 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-x64/avdevice-61.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95b25bbea098bae01ac10cb2fc39dc971865ab12d57ae973c4b99fa4221cf500 +size 16896 diff --git a/deps/FFmpeg/dotnet/win-x64/avfilter-10.dll b/deps/FFmpeg/dotnet/win-x64/avfilter-10.dll new file mode 100644 index 000000000..d19701469 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-x64/avfilter-10.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:846579b73ae443969de04bda0f73c970c0928c25c8264065cd0c913a4295ac1c +size 156160 diff --git a/deps/FFmpeg/dotnet/win-x64/avfilter-6.dll b/deps/FFmpeg/dotnet/win-x64/avfilter-6.dll deleted file mode 100644 index e0b931d88..000000000 --- a/deps/FFmpeg/dotnet/win-x64/avfilter-6.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a98f4954516e648c287da18f4a7cffdcd85b5ffc314dbc9af1413386efc78a1b -size 2219008 diff --git a/deps/FFmpeg/dotnet/win-x64/avformat-57.dll b/deps/FFmpeg/dotnet/win-x64/avformat-57.dll deleted file mode 100644 index 840a4dc55..000000000 --- a/deps/FFmpeg/dotnet/win-x64/avformat-57.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e27749d84a2410cf2f42937a9afbe8aefb908dd53fad4ef8a18f4883d53c5226 -size 2144768 diff --git a/deps/FFmpeg/dotnet/win-x64/avformat-61.dll b/deps/FFmpeg/dotnet/win-x64/avformat-61.dll new file mode 100644 index 000000000..ac7f25c0d --- /dev/null +++ b/deps/FFmpeg/dotnet/win-x64/avformat-61.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cf332068580bc6b5f2be437194be51f974264bfc63557ea3231424f8d592bae +size 742912 diff --git a/deps/FFmpeg/dotnet/win-x64/avutil-55.dll b/deps/FFmpeg/dotnet/win-x64/avutil-55.dll deleted file mode 100644 index 46a3ac11d..000000000 --- a/deps/FFmpeg/dotnet/win-x64/avutil-55.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8fee906cce37070992e8a8915933b0a465aa92c1c76dc6da0c21d0fcb4b76a3b -size 620544 diff --git a/deps/FFmpeg/dotnet/win-x64/avutil-59.dll b/deps/FFmpeg/dotnet/win-x64/avutil-59.dll new file mode 100644 index 000000000..87b64fa77 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-x64/avutil-59.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed9b00c0858ef13668842646fb4ead9e881053fea0636a5bda3f537f6fe09520 +size 765440 diff --git a/deps/FFmpeg/dotnet/win-x64/swresample-2.dll b/deps/FFmpeg/dotnet/win-x64/swresample-2.dll deleted file mode 100644 index feeb87762..000000000 --- a/deps/FFmpeg/dotnet/win-x64/swresample-2.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fad3e26b39029ed019798f59b814679aea5e0b1b1e84f9d3b30b7a00f8066029 -size 209408 diff --git a/deps/FFmpeg/dotnet/win-x64/swresample-5.dll b/deps/FFmpeg/dotnet/win-x64/swresample-5.dll new file mode 100644 index 000000000..8983528e4 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-x64/swresample-5.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a6bfe69a3b2ac02db76c53334be439fac971a5b9e9e3be164c255d45e5bcd3c +size 105984 diff --git a/deps/FFmpeg/dotnet/win-x64/swscale-4.dll b/deps/FFmpeg/dotnet/win-x64/swscale-4.dll deleted file mode 100644 index e0fc6ffcf..000000000 --- a/deps/FFmpeg/dotnet/win-x64/swscale-4.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a3c1e512dc830041d156d1694e430a5cae8d2d4a152ccc938b115e36fd96c348 -size 590336 diff --git a/deps/FFmpeg/dotnet/win-x64/swscale-8.dll b/deps/FFmpeg/dotnet/win-x64/swscale-8.dll new file mode 100644 index 000000000..28ec710d0 --- /dev/null +++ b/deps/FFmpeg/dotnet/win-x64/swscale-8.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7ad48d4bb3ace0a7dc8f1a15d3f421013ebc7bfd3e609e2f0a0bccf3b5eb39c +size 559616 diff --git a/deps/FFmpeg/ffmpeg.exe b/deps/FFmpeg/ffmpeg.exe index 38678c292..ae0e440b9 100644 --- a/deps/FFmpeg/ffmpeg.exe +++ b/deps/FFmpeg/ffmpeg.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7def5065a350b40cd20f9c2fd551b250948b886cb5f31cb4b9d9aa39566dd16b -size 48005120 +oid sha256:dafa8e6b99289f3eede788389a273ecde382816635782cfcec0b6cc5d9c9fa30 +size 8864768 diff --git a/deps/FFmpeg/ffmpeg.linux-x64 b/deps/FFmpeg/ffmpeg.linux-x64 new file mode 100755 index 000000000..a620692e5 --- /dev/null +++ b/deps/FFmpeg/ffmpeg.linux-x64 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dae8b48cbcc9777df31d3d553739dca0e0add1098c7144ced4d6ea6bc732e888 +size 9311984 diff --git a/deps/FFmpeg/ffmpeg.osx-arm64 b/deps/FFmpeg/ffmpeg.osx-arm64 new file mode 100755 index 000000000..556e14357 --- /dev/null +++ b/deps/FFmpeg/ffmpeg.osx-arm64 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:164eb5f2121bb6342b67d72fbe6338c14cbf536982aa5781f0297fa7a1a0386c +size 6157320 diff --git a/deps/FFmpeg/ffmpeg.win-arm64.exe b/deps/FFmpeg/ffmpeg.win-arm64.exe new file mode 100644 index 000000000..8c0fc56d2 --- /dev/null +++ b/deps/FFmpeg/ffmpeg.win-arm64.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b06b6bb403051e857c5db40db09be5615530d3387d093d6ef3262fe4249d6b8 +size 6062592 diff --git a/deps/FFmpeg/notes-win-arm64.txt b/deps/FFmpeg/notes-win-arm64.txt deleted file mode 100644 index 9078da649..000000000 --- a/deps/FFmpeg/notes-win-arm64.txt +++ /dev/null @@ -1 +0,0 @@ -For win-arm64: Use https://github.com/azeno/FFmpeg/tree/win-arm64, it's based on release/3.4 \ No newline at end of file diff --git a/deps/FFmpeg/notes.txt b/deps/FFmpeg/notes.txt index 618d5b340..7f3287008 100644 --- a/deps/FFmpeg/notes.txt +++ b/deps/FFmpeg/notes.txt @@ -1 +1,10 @@ -Extracted from ffmpeg-20160530-git-d74cc61-win64-static.zip \ No newline at end of file +FFmpeg 7.1.1 (LGPL libs, GPL CLI with libx264 + platform HW encoders) +Built by .github/workflows/dep-ffmpeg.yml — re-run that workflow and copy +the artifacts to refresh. + +Layout: + ffmpeg.exe Windows x64 CLI (libx264 + MF + NVENC) + ffmpeg.win-arm64.exe Windows arm64 CLI (libx264 + MF) + ffmpeg.linux-x64 Linux x64 CLI (libx264 + VA-API) + ffmpeg.osx-arm64 macOS arm64 CLI (libx264 + VideoToolbox) + dotnet// Shared libav* libraries shipped with games diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index cddb4e8d5..da7709a8e 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -10,7 +10,7 @@ - + diff --git a/sources/engine/Stride.Assets/Media/SoundAssetCompiler.cs b/sources/engine/Stride.Assets/Media/SoundAssetCompiler.cs index 9a1a1ff05..54c67df2f 100644 --- a/sources/engine/Stride.Assets/Media/SoundAssetCompiler.cs +++ b/sources/engine/Stride.Assets/Media/SoundAssetCompiler.cs @@ -34,7 +34,7 @@ namespace Stride.Assets.Media public DecodeSoundFileCommand(string url, SoundAsset parameters, IAssetFinder assetFinder) : base(url, parameters, assetFinder) { - Version = 3; + Version = 4; } /// diff --git a/sources/engine/Stride.Assets/Media/VideoAssetCompiler.cs b/sources/engine/Stride.Assets/Media/VideoAssetCompiler.cs index 3e6c70ad6..5cca57524 100644 --- a/sources/engine/Stride.Assets/Media/VideoAssetCompiler.cs +++ b/sources/engine/Stride.Assets/Media/VideoAssetCompiler.cs @@ -66,7 +66,7 @@ namespace Stride.Assets.Media public EncodeVideoFileCommand(string url, VideoConvertParameters description, IAssetFinder assetFinder, AVCodecID[] listSupportedCodecNames) : base(url, description, assetFinder) { - Version = 4; + Version = 5; ListSupportedCodecNames = listSupportedCodecNames; } diff --git a/sources/engine/Stride.Assets/Stride.Assets.csproj b/sources/engine/Stride.Assets/Stride.Assets.csproj index 16dcb0fb4..fc68ad9cf 100644 --- a/sources/engine/Stride.Assets/Stride.Assets.csproj +++ b/sources/engine/Stride.Assets/Stride.Assets.csproj @@ -69,7 +69,22 @@ runtimes\%(RecursiveDir)native\%(Filename)%(Extension) + + runtimes\win-x64\native\ffmpeg.exe + PreserveNewest + + + runtimes\win-arm64\native\ffmpeg.exe + PreserveNewest + + + runtimes\linux-x64\native\ffmpeg + PreserveNewest + + + runtimes\osx-arm64\native\ffmpeg PreserveNewest diff --git a/sources/engine/Stride.Assets/ToolLocator.cs b/sources/engine/Stride.Assets/ToolLocator.cs index 89b0ad163..21f3c6771 100644 --- a/sources/engine/Stride.Assets/ToolLocator.cs +++ b/sources/engine/Stride.Assets/ToolLocator.cs @@ -1,10 +1,7 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Reflection; -using System.Text; -using System.Threading.Tasks; +using System.Runtime.InteropServices; using Stride.Core.IO; namespace Stride.Assets; @@ -32,6 +29,18 @@ static class ToolLocator } var asmDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + + // RID-keyed bundled binary: runtimes//native/{.exe}. This is where + // Stride.Assets.csproj copies the per-platform ffmpeg CLIs. + var rid = GetCurrentRid(); + if (rid != null) + { + var ridTool = UPath.Combine(asmDir, new UFile($"runtimes/{rid}/native/{toolName}{exeExt}")); + if (File.Exists(ridTool)) + return ridTool; + } + + // Legacy locations kept for backward compatibility with older deps/ layouts. var tool = UPath.Combine(asmDir, new UFile($"{toolName}{exeExt}")); if (File.Exists(tool)) return tool; @@ -42,4 +51,22 @@ static class ToolLocator return null; } + + private static string GetCurrentRid() + { + string os; + if (OperatingSystem.IsWindows()) os = "win"; + else if (OperatingSystem.IsLinux()) os = "linux"; + else if (OperatingSystem.IsMacOS()) os = "osx"; + else return null; + + var arch = RuntimeInformation.OSArchitecture switch + { + Architecture.X64 => "x64", + Architecture.Arm64 => "arm64", + Architecture.X86 => "x86", + _ => null, + }; + return arch == null ? null : $"{os}-{arch}"; + } } diff --git a/sources/engine/Stride.Video/FFmpeg/AudioStream.cs b/sources/engine/Stride.Video/FFmpeg/AudioStream.cs index b8a40263a..e0a86b9da 100644 --- a/sources/engine/Stride.Video/FFmpeg/AudioStream.cs +++ b/sources/engine/Stride.Video/FFmpeg/AudioStream.cs @@ -15,9 +15,10 @@ namespace Stride.Video.FFmpeg public AudioStream([NotNull] AVStream* pStream, [NotNull] FFmpegMedia media) : base(pStream, media) { - var pCodec = pStream->codec; - ChannelCount = pCodec->channels; - SampleRate = pCodec->sample_rate; + var pCodecpar = pStream->codecpar; + // FFmpeg 5.1+: channels/channel_layout replaced by AVChannelLayout ch_layout. + ChannelCount = pCodecpar->ch_layout.nb_channels; + SampleRate = pCodecpar->sample_rate; } /// diff --git a/sources/engine/Stride.Video/FFmpeg/FFmpegCodec.cs b/sources/engine/Stride.Video/FFmpeg/FFmpegCodec.cs index 988962e73..b35e2ad8d 100644 --- a/sources/engine/Stride.Video/FFmpeg/FFmpegCodec.cs +++ b/sources/engine/Stride.Video/FFmpeg/FFmpegCodec.cs @@ -67,9 +67,9 @@ namespace Stride.Video.FFmpeg /// /// Initializes a new instance of the class. /// - public FFmpegCodec(GraphicsDevice graphcsDevice, AVCodecContext* originalContext) + public FFmpegCodec(GraphicsDevice graphcsDevice, AVCodecParameters* originalCodecpar) { - var codecId = originalContext->codec_id; + var codecId = originalCodecpar->codec_id; var pCodec = ffmpeg.avcodec_find_decoder(codecId); if (pCodec == null) // TODO: log? @@ -77,13 +77,17 @@ namespace Stride.Video.FFmpeg int ret; var pCodecContext = ffmpeg.avcodec_alloc_context3(pCodec); - var pCodecParam = ffmpeg.avcodec_parameters_alloc(); - ret = ffmpeg.avcodec_parameters_from_context(pCodecParam, originalContext); - if (ret < 0) - // TODO: log? - throw new ApplicationException($"Could not retrieve codec parameters. Error code={ret.ToString("X8")}"); // Set the context get_format function + ret = ffmpeg.avcodec_parameters_to_context(pCodecContext, originalCodecpar); + if (ret < 0) + // TODO: log? + throw new ApplicationException($"Could not fill codec parameters. Error code={ret.ToString("X8")}"); + +#if STRIDE_GRAPHICS_API_DIRECT3D11 + // HW decode is wired up for D3D11VA only. On other backends, fall through to FFmpeg's + // software path (default get_format + no hw_device_ctx) — codec picks a SW pix_fmt + // and sws_scale converts to the Target texture's RGBA later. getFormat = (context, formats) => { AVPixelFormat* pixelFormat; @@ -98,11 +102,6 @@ namespace Stride.Video.FFmpeg }; pCodecContext->get_format = getFormat; - ret = ffmpeg.avcodec_parameters_to_context(pCodecContext, pCodecParam); - if (ret < 0) - // TODO: log? - throw new ApplicationException($"Could not fill codec parameters. Error code={ret.ToString("X8")}"); - // create the hardware device context. AVBufferRef* pHWDeviceContextLocal; if (ffmpeg.av_hwdevice_ctx_create(&pHWDeviceContextLocal, HardwareDeviceType, null, null, 0) >= 0) @@ -111,13 +110,13 @@ namespace Stride.Video.FFmpeg pHWDeviceContext = pHWDeviceContextLocal; pCodecContext->hw_device_ctx = ffmpeg.av_buffer_ref(pHWDeviceContext); } +#endif // Setup hardware acceleration context //if (IsHardwareAccelerated) // CreateHarwareAccelerationContext(graphcsDevice, pCodecContext, pCodec); - if ((pCodec->capabilities & ffmpeg.AV_CODEC_CAP_TRUNCATED) == ffmpeg.AV_CODEC_CAP_TRUNCATED) - pCodecContext->flags |= ffmpeg.AV_CODEC_FLAG_TRUNCATED; + // AV_CODEC_CAP_TRUNCATED / AV_CODEC_FLAG_TRUNCATED removed in FFmpeg 5.0 — modern parsers handle framing. if (ffmpeg.avcodec_is_open(pCodecContext) == 0) { @@ -126,7 +125,6 @@ namespace Stride.Video.FFmpeg // TODO: log? throw new ApplicationException($"Could not open codec. Error code={ret.ToString("X8")}"); } - ffmpeg.avcodec_parameters_free(&pCodecParam); pAVCodecContext = pCodecContext; } @@ -297,7 +295,7 @@ namespace Stride.Video.FFmpeg ffmpeg.av_buffer_unref(&pHWDeviceContextLocal); var pAVCodecContextLocal = pAVCodecContext; - ffmpeg.avcodec_close(pAVCodecContextLocal); + // avcodec_close removed in FFmpeg 7.0 — avcodec_free_context handles closing. ffmpeg.avcodec_free_context(&pAVCodecContextLocal); } diff --git a/sources/engine/Stride.Video/FFmpeg/FFmpegMedia.cs b/sources/engine/Stride.Video/FFmpeg/FFmpegMedia.cs index a65a6dc6e..107f8705f 100644 --- a/sources/engine/Stride.Video/FFmpeg/FFmpegMedia.cs +++ b/sources/engine/Stride.Video/FFmpeg/FFmpegMedia.cs @@ -172,34 +172,25 @@ namespace Stride.Video.FFmpeg { FFmpegUtils.EnsurePlatformSupport(); - var skip_to_keyframe = stream.AVStream->skip_to_keyframe; - try + if (currentStreams.TryGetValue(stream, out var streamInfo)) { - if (currentStreams.TryGetValue(stream, out var streamInfo)) - { - // flush the codec buffered images - streamInfo.Codec.Flush(pDecodedFrame); - } - - // flush the format buffered images - ffmpeg.avformat_flush(AVFormatContext); - - // perform the actual seek - stream.AVStream->skip_to_keyframe = 1; - var ret = ffmpeg.av_seek_frame(AVFormatContext, stream.Index, timestamp, ffmpeg.AVSEEK_FLAG_BACKWARD); - if (ret < 0) - { - Logger.Error($"Could not seek frame. Error code={ret.ToString("X8")}"); - Logger.Error(GetErrorMessage(ret)); - return false; - } - - return true; + // flush the codec buffered images + streamInfo.Codec.Flush(pDecodedFrame); } - finally + + // flush the format buffered images + ffmpeg.avformat_flush(AVFormatContext); + + // AVSEEK_FLAG_BACKWARD already lands on the nearest preceding keyframe. + var ret = ffmpeg.av_seek_frame(AVFormatContext, stream.Index, timestamp, ffmpeg.AVSEEK_FLAG_BACKWARD); + if (ret < 0) { - stream.AVStream->skip_to_keyframe = skip_to_keyframe; + Logger.Error($"Could not seek frame. Error code={ret.ToString("X8")}"); + Logger.Error(GetErrorMessage(ret)); + return false; } + + return true; } [ItemNotNull, NotNull] @@ -212,29 +203,34 @@ namespace Stride.Video.FFmpeg // TODO: log? throw new InvalidOperationException(@"Media isn't open."); - var codecContext = *stream.AVStream->codec; + var pCodecpar = stream.AVStream->codecpar; var streamInfo = GetStreamInfo(stream); var dstData = new byte_ptrArray4(); var dstLinesize = new int_array4(); - ffmpeg.av_image_fill_arrays(ref dstData, ref dstLinesize, (byte*)streamInfo.Image.Buffer, DestinationPixelFormat, codecContext.width, codecContext.height, 1); + ffmpeg.av_image_fill_arrays(ref dstData, ref dstLinesize, (byte*)streamInfo.Image.Buffer, DestinationPixelFormat, pCodecpar->width, pCodecpar->height, 1); streamInfo.Image.Linesize = dstLinesize[0]; var extractedFrameCount = 0; - var packet = new AVPacket(); - var pPacket = &packet; - ffmpeg.av_init_packet(pPacket); - - for (int i = 0; i < count; i++) + // FFmpeg 6.0+: av_init_packet removed; packets must be heap-allocated via av_packet_alloc. + var pPacket = ffmpeg.av_packet_alloc(); + try { - var extractionStatus = ExtractNextImage(streamInfo, pPacket, stream.AVStream, dstData, dstLinesize); - streamInfo.ReachedEnd = extractionStatus == FrameExtractionStatus.ReachEOF; - if (extractionStatus == FrameExtractionStatus.Succeeded) - ++extractedFrameCount; - } + for (int i = 0; i < count; i++) + { + var extractionStatus = ExtractNextImage(streamInfo, pPacket, stream.AVStream, dstData, dstLinesize); + streamInfo.ReachedEnd = extractionStatus == FrameExtractionStatus.ReachEOF; + if (extractionStatus == FrameExtractionStatus.Succeeded) + ++extractedFrameCount; + } - return extractedFrameCount; + return extractedFrameCount; + } + finally + { + ffmpeg.av_packet_free(&pPacket); + } } /// @@ -252,9 +248,9 @@ namespace Stride.Video.FFmpeg // Unfortunately the side data was not present in the stream // -> we need to decode and look in the first packet and frame. var streamInfo = GetStreamInfo(stream); - var packet = new AVPacket(); - var pPacket = &packet; - ffmpeg.av_init_packet(pPacket); + // FFmpeg 6.0+: av_init_packet removed; av_packet_alloc returns a heap packet + // and av_packet_free in the finally below replaces av_packet_unref + struct dtor. + var pPacket = ffmpeg.av_packet_alloc(); var pCodecContext = streamInfo.Codec.pAVCodecContext; try @@ -313,7 +309,7 @@ namespace Stride.Video.FFmpeg } finally { - ffmpeg.av_packet_unref(pPacket); + ffmpeg.av_packet_free(&pPacket); ffmpeg.av_frame_unref(pDecodedFrame); // return to the beginning of the media file (just in case) @@ -325,16 +321,16 @@ namespace Stride.Video.FFmpeg { if (!currentStreams.TryGetValue(stream, out var streamInfo)) { - var codecContext = *(stream.AVStream->codec); - var width = codecContext.width; - var height = codecContext.height; + var pCodecpar = stream.AVStream->codecpar; + var width = pCodecpar->width; + var height = pCodecpar->height; var convertedFrameBufferSize = ffmpeg.av_image_get_buffer_size(DestinationPixelFormat, width, height, 1); convertedFrameBufferSize = (convertedFrameBufferSize + 3) & ~0x03; // align on a boundary of 4 (32-bits) currentStreams[stream] = streamInfo = new StreamInfo { - Codec = new FFmpegCodec(graphicsDevice, &codecContext), + Codec = new FFmpegCodec(graphicsDevice, pCodecpar), Image = new VideoImage(width, height, convertedFrameBufferSize), }; } @@ -379,8 +375,13 @@ namespace Stride.Video.FFmpeg } ret = ffmpeg.avcodec_receive_frame(pCodecContext, pDecodedFrame); - //if (ret == ffmpeg.AVERROR(ffmpeg.EAGAIN)) // don't want to block the execution thread - // continue; + if (ret == ffmpeg.AVERROR(ffmpeg.EAGAIN)) + { + // Decoder needs more packets before producing a frame — normal flow + // control with the modern send_packet / receive_frame API. Loop back + // and feed it the next packet. + continue; + } if (ret < 0) { diff --git a/sources/engine/Stride.Video/FFmpeg/FFmpegStream.cs b/sources/engine/Stride.Video/FFmpeg/FFmpegStream.cs index 509e18b1c..37b446ce8 100644 --- a/sources/engine/Stride.Video/FFmpeg/FFmpegStream.cs +++ b/sources/engine/Stride.Video/FFmpeg/FFmpegStream.cs @@ -32,7 +32,7 @@ namespace Stride.Video.FFmpeg { if (pStream == null) throw new ArgumentNullException(nameof(pStream)); AVStream = pStream; - Codec = pStream->codec->codec_id; + Codec = pStream->codecpar->codec_id; Media = media; Index = pStream->index; Metadata = FFmpegUtils.ToDictionary(pStream->metadata); @@ -81,8 +81,7 @@ namespace Stride.Video.FFmpeg if (media == null) throw new ArgumentNullException(nameof(media)); FFmpegStream result; - var pCodec = pStream->codec; - switch (pCodec->codec_type) + switch (pStream->codecpar->codec_type) { case AVMediaType.AVMEDIA_TYPE_AUDIO: result = new AudioStream(pStream, media); diff --git a/sources/engine/Stride.Video/FFmpeg/FFmpegUtils.cs b/sources/engine/Stride.Video/FFmpeg/FFmpegUtils.cs index 8b3e60ca1..5315d440d 100644 --- a/sources/engine/Stride.Video/FFmpeg/FFmpegUtils.cs +++ b/sources/engine/Stride.Video/FFmpeg/FFmpegUtils.cs @@ -4,6 +4,8 @@ #if STRIDE_VIDEO_FFMPEG using System; using System.Collections.Generic; +using System.IO; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using FFmpeg.AutoGen; @@ -22,7 +24,10 @@ namespace Stride.Video.FFmpeg [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CheckPlatformSupport() { - return (Platform.Type == PlatformType.Windows || Platform.Type == PlatformType.Android); + return Platform.Type == PlatformType.Windows + || Platform.Type == PlatformType.Linux + || Platform.Type == PlatformType.macOS + || Platform.Type == PlatformType.Android; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -41,8 +46,7 @@ namespace Stride.Video.FFmpeg return; initialized = true; - ffmpeg.av_register_all(); - ffmpeg.avcodec_register_all(); + // av_register_all / avcodec_register_all removed in FFmpeg 4.0 / 5.0 — registration is automatic now. ffmpeg.avformat_network_init(); } @@ -73,20 +77,40 @@ namespace Stride.Video.FFmpeg // |---- avformat // |---- avcodec // |---- avutil + // FFmpeg.AutoGen 7.x resolves libav* through its own LibraryLoader which probes + // ffmpeg.RootPath. Default ("") only searches the OS standard paths and never finds + // SONAME-versioned libavutil.so.59 / libavutil.59.dylib we ship. + // Two layouts to handle: tests flatten libs into the assembly dir, regular asm builds + // keep them in runtimes//native/. Check both. + var asmDir = Path.GetDirectoryName(typeof(FFmpegUtils).Assembly.Location); + if (asmDir != null) + { + var rid = GetCurrentRid(); + var runtimesDir = rid != null ? Path.Combine(asmDir, "runtimes", rid, "native") : null; + // RID builds flatten DLLs to asmDir; portable builds keep them under runtimes//native/. + var probe = Platform.Type switch + { + PlatformType.Windows => "avutil-59.dll", + PlatformType.macOS => "libavutil.59.dylib", + _ => "libavutil.so.59", + }; + ffmpeg.RootPath = runtimesDir != null && File.Exists(Path.Combine(runtimesDir, probe)) ? runtimesDir : asmDir; + } + if (Platform.Type == PlatformType.Windows) { var type = typeof(FFmpegUtils); - NativeLibraryHelper.PreloadLibrary("avutil-55", type); - NativeLibraryHelper.PreloadLibrary("swresample-2", type); - NativeLibraryHelper.PreloadLibrary("avcodec-57", type); - NativeLibraryHelper.PreloadLibrary("avformat-57", type); - NativeLibraryHelper.PreloadLibrary("swscale-4", type); - NativeLibraryHelper.PreloadLibrary("avfilter-6", type); - NativeLibraryHelper.PreloadLibrary("avdevice-57", type); + NativeLibraryHelper.PreloadLibrary("avutil-59", type); + NativeLibraryHelper.PreloadLibrary("swresample-5", type); + NativeLibraryHelper.PreloadLibrary("avcodec-61", type); + NativeLibraryHelper.PreloadLibrary("avformat-61", type); + NativeLibraryHelper.PreloadLibrary("swscale-8", type); + NativeLibraryHelper.PreloadLibrary("avfilter-10", type); + NativeLibraryHelper.PreloadLibrary("avdevice-61", type); } else { - // This is likely there for forcing dll loading (on Android?), it will need some review. + // Force-load via a no-op API call so dlopen happens here (clearer stacks on failure). uint version; version = ffmpeg.avutil_version(); version = ffmpeg.swresample_version(); @@ -98,6 +122,23 @@ namespace Stride.Video.FFmpeg } } + private static string GetCurrentRid() + { + string os; + if (OperatingSystem.IsWindows()) os = "win"; + else if (OperatingSystem.IsLinux()) os = "linux"; + else if (OperatingSystem.IsMacOS()) os = "osx"; + else return null; + + var arch = RuntimeInformation.OSArchitecture switch + { + Architecture.X64 => "x64", + Architecture.Arm64 => "arm64", + _ => null, + }; + return arch == null ? null : $"{os}-{arch}"; + } + /// /// Converts a * to a Dictionary<string,string>. /// diff --git a/sources/engine/Stride.Video/FFmpeg/VideoStream.cs b/sources/engine/Stride.Video/FFmpeg/VideoStream.cs index fae18f95c..d607f62ea 100644 --- a/sources/engine/Stride.Video/FFmpeg/VideoStream.cs +++ b/sources/engine/Stride.Video/FFmpeg/VideoStream.cs @@ -16,8 +16,8 @@ namespace Stride.Video.FFmpeg public VideoStream([NotNull] AVStream* pStream, [NotNull] FFmpegMedia media) : base(pStream, media) { - var pCodec = pStream->codec; - var framerateRatio = pCodec->framerate; + var pCodecpar = pStream->codecpar; + var framerateRatio = pCodecpar->framerate; // HOTFIX (#95) if (framerateRatio.den == 0) @@ -30,9 +30,9 @@ namespace Stride.Video.FFmpeg FPS = Convert.ToDouble(framerateRatio.num) / Convert.ToDouble(framerateRatio.den); FrameDuration = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / Convert.ToInt64(FPS)); } - PixelFormat = pCodec->pix_fmt; - Height = pCodec->height; - Width = pCodec->width; + PixelFormat = (AVPixelFormat)pCodecpar->format; + Height = pCodecpar->height; + Width = pCodecpar->width; } /// diff --git a/sources/engine/Stride.Video/VideoInstance.FFmpeg.cs b/sources/engine/Stride.Video/VideoInstance.FFmpeg.cs index 66facbdeb..3713fa99e 100644 --- a/sources/engine/Stride.Video/VideoInstance.FFmpeg.cs +++ b/sources/engine/Stride.Video/VideoInstance.FFmpeg.cs @@ -132,17 +132,20 @@ namespace Stride.Video if (videoComponent.Target != null) { - videoTexture.SetTargetContentToVideoStream(videoComponent.Target); - - // Now update the video texture with data of the new video frame: + // Upload the decoded RGBA frame directly into the user-supplied Target. + // We bypass VideoTexture's Swap-based machinery: it ping-pongs the user's + // Target with an internal renderTargetTexture and undoes the swap on Stop() + // — so once the video ends, the last decoded frame is stashed in the + // internal texture and the user-facing Target reverts to its uninitialized + // contents. Writing straight to the Target means the decoded data persists. + // Cost: skips mip generation, which the previous path supported via + // VideoTexture.GenerateMipMaps but defaults to single-mip anyway. var graphicsContext = services.GetSafeServiceAs(); - - if (streamInfo.Codec.IsHardwareAccelerated && streamInfo.Image == null) - videoTexture.CopyDecoderOutputToTopLevelMipmap(graphicsContext, streamInfo.Codec.DecoderOutputTexture); - else - videoTexture.UpdateTopLevelMipmapFromData(graphicsContext, streamInfo.Image); - - videoTexture.GenerateMipMaps(graphicsContext); + unsafe + { + var dataPointer = new ReadOnlySpan((void*)streamInfo.Image.Buffer, streamInfo.Image.BufferSize); + videoComponent.Target.SetData(graphicsContext.CommandList, dataPointer, arrayIndex: 0, mipLevel: 0); + } } } @@ -179,8 +182,9 @@ namespace Stride.Video Duration = stream.Duration; AllocateVideoTexture(stream.Width, stream.Height); } - catch + catch (Exception ex) { + Logger.Error($"InitializeMediaImpl failed: {ex}"); ReleaseMedia(); return; }