mirror of
https://github.com/stride3d/stride.git
synced 2026-10-12 02:23:23 +00:00
ffmpeg: upgrade to 7.1.1 (binaries + Stride.Video 7.x API migration)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Vendored
-8
@@ -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
|
||||
Vendored
-242
@@ -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
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4ef9225d5cf5bc9d704846a28c85c17990b5064aaee950571770c5ae501d9f68
|
||||
size 4241360
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d693b7c3c0ba18c3ce57ea51d8ab485450a69dea3d5253059bd5f5e5fb1720a0
|
||||
size 14592
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8df7b76ea5ae5cb5a7dc81a9efb7f2f7c5ba8cfc2258180513d9cd97e0e051e8
|
||||
size 154968
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ca8f1acd1b303c20bc82bdbb3fa31ec7f341d0b103e3ec7b8a3e8c0d2a4e0769
|
||||
size 758600
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:30d6348a55ade3b06a70b277584dbbbd50cd978e5a93f57a17f1edd2016815dc
|
||||
size 732232
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1bfbbe4f997e3ee34ef2536413944ee04fe3196b763a499f87d7417aa73c2b25
|
||||
size 108976
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2d9f12b01668d4af8903147bdfe5b7d4b81030a5bae0fedeae8311458f0a9c2c
|
||||
size 535008
|
||||
Vendored
-62
@@ -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'
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6766f50729325f4c20e880b56ff8f869b474bd900fe35471a64d8fc8cc08c935
|
||||
size 2661400
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d5280eebd4d37ffa2600d614dd8bfef70422db05194ffd5f97fb5f34d1593d06
|
||||
size 35688
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:202cc65322b0ccc64df742d647662cae4f5c0e9139d67a2a12a123fa9b31ecfe
|
||||
size 136232
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b880d7608976a1676fc763ebf4290873874902074ff7cadd30789f14ce1d8b28
|
||||
size 709688
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:acdcd7a72be171b862587aa1053e5c4ab2fdf1c3b7b12154f5cede912caafa50
|
||||
size 542904
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1b26e573f915e211046672419909a6796ebdb69baeae0b05e54732ef9cdd005c
|
||||
size 87000
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e09921db6251805ae0bb51a39a679cde29e5859ddf0d0335f5921b7e5b9f3ec7
|
||||
size 369544
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7f69cd8022a13a8be34f01506e10b9bbf92f0bb04d6eb71a662267b47c54351d
|
||||
size 9722880
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3f11af5322848d625649c7d176870b441d70b2468bb9f1e50877636007876ad2
|
||||
size 2697216
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9e8c57dcd4b5e3cb81b035597424c800fb44f52607af295ac487728888f6c040
|
||||
size 204800
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:492f103bd1e3665de8c39a8d9317aec7f23f7af553d6a5de814c8419299416be
|
||||
size 15360
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:092b69c5fc586c8493428a902556702474ac3e1b909adc129eb5597f830e9df8
|
||||
size 142848
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a7f4842a8224747bbaff9a5e0d5b2e191f4c7d2085099cd6d5b56ace545ad7ea
|
||||
size 1856512
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3725c5ed89c43e6cf1060a413773644eaf78a5c2efacf7e8f9413f994c62e33d
|
||||
size 2210816
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3a9ee4dc5cfa80d225b759e2dcc6bdc84d2e8d4724e6e585a82389989d0cb15e
|
||||
size 707072
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b434850920c56ed34c9047f0f904d7dc8673ba580de40bc601f7df28b88b1255
|
||||
size 623616
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bf50fb717053718eb0e17c7251d1a1c9c1b2526fdd2a3bd61741265a103df3c5
|
||||
size 530432
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fcf2ea93ba2a06818955cf2cd7880c5771f147f885a10b64aa72410e98b58525
|
||||
size 186880
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9ceb23d7ad38f9d1adf4bb7bb65898fbdf0eb8fd989ccc24bf2f8a3225d77f12
|
||||
size 70144
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:eefb4dc92d198b7bd7013f3a68afc3f1a3b131327db7bbdd2148ca59305a13e1
|
||||
size 452608
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f22ba431a7da148a1f24a5da3e257613b915f105e111541dc79e4b898820e162
|
||||
size 338944
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a9665ac0382166204b3fe4a05e5c7a2cd6edcb4d2656aa54adf2d2d0753e33ba
|
||||
size 10908672
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:222c8d3099acd8eacf47b40338c3d8fd99517e48ffe68f942fb7473559ec9e8f
|
||||
size 4144128
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e9c74436ef4dce4fe8970fbba514c67e99b0e7ebb8a868e2f375e73c7736ec2f
|
||||
size 185856
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:95b25bbea098bae01ac10cb2fc39dc971865ab12d57ae973c4b99fa4221cf500
|
||||
size 16896
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:846579b73ae443969de04bda0f73c970c0928c25c8264065cd0c913a4295ac1c
|
||||
size 156160
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a98f4954516e648c287da18f4a7cffdcd85b5ffc314dbc9af1413386efc78a1b
|
||||
size 2219008
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e27749d84a2410cf2f42937a9afbe8aefb908dd53fad4ef8a18f4883d53c5226
|
||||
size 2144768
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1cf332068580bc6b5f2be437194be51f974264bfc63557ea3231424f8d592bae
|
||||
size 742912
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8fee906cce37070992e8a8915933b0a465aa92c1c76dc6da0c21d0fcb4b76a3b
|
||||
size 620544
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ed9b00c0858ef13668842646fb4ead9e881053fea0636a5bda3f537f6fe09520
|
||||
size 765440
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fad3e26b39029ed019798f59b814679aea5e0b1b1e84f9d3b30b7a00f8066029
|
||||
size 209408
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3a6bfe69a3b2ac02db76c53334be439fac971a5b9e9e3be164c255d45e5bcd3c
|
||||
size 105984
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a3c1e512dc830041d156d1694e430a5cae8d2d4a152ccc938b115e36fd96c348
|
||||
size 590336
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b7ad48d4bb3ace0a7dc8f1a15d3f421013ebc7bfd3e609e2f0a0bccf3b5eb39c
|
||||
size 559616
|
||||
Vendored
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7def5065a350b40cd20f9c2fd551b250948b886cb5f31cb4b9d9aa39566dd16b
|
||||
size 48005120
|
||||
oid sha256:dafa8e6b99289f3eede788389a273ecde382816635782cfcec0b6cc5d9c9fa30
|
||||
size 8864768
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dae8b48cbcc9777df31d3d553739dca0e0add1098c7144ced4d6ea6bc732e888
|
||||
size 9311984
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:164eb5f2121bb6342b67d72fbe6338c14cbf536982aa5781f0297fa7a1a0386c
|
||||
size 6157320
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3b06b6bb403051e857c5db40db09be5615530d3387d093d6ef3262fe4249d6b8
|
||||
size 6062592
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
For win-arm64: Use https://github.com/azeno/FFmpeg/tree/win-arm64, it's based on release/3.4
|
||||
Vendored
+10
-1
@@ -1 +1,10 @@
|
||||
Extracted from ffmpeg-20160530-git-d74cc61-win64-static.zip
|
||||
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/<rid>/ Shared libav* libraries shipped with games
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<PackageVersion Include="DotRecast.Detour" Version="2025.2.1" />
|
||||
<PackageVersion Include="DotRecast.Recast" Version="2025.2.1" />
|
||||
<PackageVersion Include="DotRecast.Recast.Toolset" Version="2025.2.1" />
|
||||
<PackageVersion Include="FFmpeg.AutoGen" Version="3.4.0.2" />
|
||||
<PackageVersion Include="FFmpeg.AutoGen" Version="7.1.1" />
|
||||
<PackageVersion Include="K4os.Compression.LZ4.Legacy" Version="1.3.6" />
|
||||
<PackageVersion Include="Microsoft.Direct3D.WARP" Version="1.0.18" />
|
||||
<PackageVersion Include="Microsoft.ML.OnnxRuntime" Version="1.20.1" />
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Stride.Assets.Media
|
||||
public DecodeSoundFileCommand(string url, SoundAsset parameters, IAssetFinder assetFinder)
|
||||
: base(url, parameters, assetFinder)
|
||||
{
|
||||
Version = 3;
|
||||
Version = 4;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,22 @@
|
||||
<StrideNativeLib Include="..\..\..\deps\msdfgen\Release\**\*.dll;..\..\..\deps\msdfgen\Release\**\*.so;..\..\..\deps\msdfgen\Release\**\*.dylib">
|
||||
<Link>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</Link>
|
||||
</StrideNativeLib>
|
||||
<!-- Asset compiler ffmpeg CLI — ship every RID under runtimes/<rid>/native/ so the package
|
||||
is portable across hosts. ToolLocator resolves the right one at runtime via the current RID. -->
|
||||
<Content Include="..\..\..\deps\FFmpeg\ffmpeg.exe">
|
||||
<Link>runtimes\win-x64\native\ffmpeg.exe</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\deps\FFmpeg\ffmpeg.win-arm64.exe">
|
||||
<Link>runtimes\win-arm64\native\ffmpeg.exe</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\deps\FFmpeg\ffmpeg.linux-x64">
|
||||
<Link>runtimes\linux-x64\native\ffmpeg</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\deps\FFmpeg\ffmpeg.osx-arm64">
|
||||
<Link>runtimes\osx-arm64\native\ffmpeg</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -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/<rid>/native/<tool>{.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}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -67,9 +67,9 @@ namespace Stride.Video.FFmpeg
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FFmpegCodec"/> class.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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/<rid>/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/<rid>/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}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="AVDictionary"/>* to a Dictionary<string,string>.
|
||||
/// </summary>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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<GraphicsContext>();
|
||||
|
||||
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<byte>((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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user