From c722459ff2339e4be3e1aff8c1e1127cb1be2f9b Mon Sep 17 00:00:00 2001 From: Donough Liu Date: Sat, 6 Apr 2024 01:27:33 +0800 Subject: [PATCH] Supports FFmpeg 7.0 (#174) * Use ffmpeg 7.0 by default in utils * Add `ffmpeg7` feature * Bump version to `0.15.0` * Better readme * Enable ffmpeg7 by default * Add appropriate note when somebody chose the wrong feature --- .github/workflows/ci.yml | 29 +++++++++++++++++++---------- Cargo.toml | 10 ++++++++-- README.md | 11 +++++++---- src/avformat/avio.rs | 8 ++++++++ utils/linux_ffmpeg.rs | 2 +- utils/mac_ffmpeg.rs | 2 +- utils/windows_ffmpeg.rs | 2 +- 7 files changed, 45 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07a70f0..cc3f050 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: - run: | export FFMPEG_PKG_CONFIG_PATH=${PWD}/tmp/ffmpeg_build/lib/pkgconfig - cargo clippy -vv -- -D warnings + cargo clippy -- -D warnings rust_clippy_check_windows: runs-on: windows-latest @@ -90,26 +90,35 @@ jobs: VCPKG_ROOT: ${{ github.workspace }}/vcpkg LIBCLANG_PATH: ${{ github.workspace }}/clang/lib LLVM_CONFIG_PATH: ${{ github.workspace }}/clang/bin/llvm-config - run: cargo clippy -- -D warnings + # vcpkg doesn't provide FFmpeg 7 yet (https://github.com/microsoft/vcpkg/issues/37888) + run: cargo clippy --no-default-features --features ffmpeg6 -- -D warnings build_static_and_test_ubuntu: runs-on: ubuntu-latest strategy: matrix: - ffmpeg-version: ["release/6.0", "release/6.1"] + ffmpeg-version: ["release/6.0", "release/6.1", "release/7.0"] rust: ["nightly", "1.70.0"] valgrind: ["valgrind", "no valgrind"] include: - # Only run tests on nightly rust + latest FFmpeg - # This is caused by specific bug of FFmpeg 6.0 + # Stop running tests on stable rust or FFmpeg 6.0 (due to specific bug of FFmpeg 6.0) # https://github.com/FFmpeg/FFmpeg/commit/c4f35ba8084f254afe1fb05202abfdcfff63b854 - rust: "nightly" ffmpeg-version: "release/6.1" should_test: "true" + - rust: "nightly" + ffmpeg-version: "release/7.0" + should_test: "true" + - ffmpeg-version: "release/6.0" + additional-cargo-flags: "--no-default-features --features ffmpeg6" + - ffmpeg-version: "release/6.1" + additional-cargo-flags: "--no-default-features --features ffmpeg6" exclude: # Only run valgrind with latest FFmpeg and nightly rust to reduce resource consumption. - valgrind: "valgrind" ffmpeg-version: "release/6.0" + - valgrind: "valgrind" + ffmpeg-version: "release/6.1" - valgrind: "valgrind" rust: "1.70.0" fail-fast: false @@ -168,12 +177,12 @@ jobs: export FFMPEG_PKG_CONFIG_PATH=${PWD}/tmp/ffmpeg_build/lib/pkgconfig if [ '${{ matrix.should_test }}' == 'true' ]; then if [ '${{ matrix.valgrind }}' == 'valgrind' ]; then - cargo valgrind test -vv + cargo valgrind test ${{ matrix.additional-cargo-flags }} else - cargo test -vv + cargo test ${{ matrix.additional-cargo-flags }} fi else - cargo test --no-run -vv + cargo test ${{ matrix.additional-cargo-flags }} --no-run fi # Cross build on Ubuntu, then send it to Windows machine for CI. @@ -268,7 +277,7 @@ jobs: LLVM_CONFIG_PATH: ${{ github.workspace }}/clang/bin/llvm-config run: | copy ${{ github.workspace }}/ffmpeg_prebuilt_cross/lib/libffmpeg.dll . - cargo test --tests --target i686-pc-windows-msvc -vv -- --skip transcode + cargo test --tests --target i686-pc-windows-msvc -- --skip transcode # Check if correct documentation can be generated by docs.rs docs_rs_check: @@ -293,4 +302,4 @@ jobs: - name: Set env run: echo "DOCS_RS=1" >> $GITHUB_ENV - name: Document Generation - run: cargo doc -vv + run: cargo doc diff --git a/Cargo.toml b/Cargo.toml index 4d16967..4638903 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rsmpeg" -version = "0.14.2+ffmpeg.6.1" +version = "0.15.0+ffmpeg.7.0" authors = ["liudingming "] edition = "2021" license = "MIT" @@ -27,6 +27,12 @@ tempdir = "0.3.7" camino = "1.1.6" [features] +# Use FFmpeg 7 by default +default = ["ffmpeg7"] + +# Note that ffmpeg{x} feature is designed to be addable (If it's not, compilation with all-features won't pass) +ffmpeg6 = ["rusty_ffmpeg/ffmpeg6"] +ffmpeg7 = ["ffmpeg6", "rusty_ffmpeg/ffmpeg7"] + # linking system ffmpeg as fallback. link_system_ffmpeg = ["rusty_ffmpeg/link_system_ffmpeg"] -ffmpeg6 = ["rusty_ffmpeg/ffmpeg6"] diff --git a/README.md b/README.md index 819546b..511d1dc 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,8 @@ bash utils/windows_ffmpeg.rs These scripts build latest stable FFmpeg by default. You can build specific FFmpeg version explicitly: ```bash -# macOS & FFmpeg 5.0 -zsh utils/mac_ffmpeg.rs release/5.0 +# macOS & FFmpeg 7.0 +zsh utils/mac_ffmpeg.rs release/7.0 ``` ### Compiling FFmpeg through cargo-vcpkg @@ -109,9 +109,12 @@ Ensure that you have compiled the FFmpeg. Start by adding `rsmpeg` to your `Cargo.toml` file: -```rust +```toml [dependencies] -rsmpeg = "0.14.1" +# Add this if you are using ffmpeg 6.* +rsmpeg = { version = "0.15.0", default-features = false, features = ["ffmpeg6"] } +# Add this if you are using ffmpeg 7.* (feature `ffmpeg7` is enabled by default) +rsmpeg = "0.15.0" ``` Write your simple media file info dumper: diff --git a/src/avformat/avio.rs b/src/avformat/avio.rs index 2683f07..e881492 100644 --- a/src/avformat/avio.rs +++ b/src/avformat/avio.rs @@ -102,11 +102,18 @@ impl AVIOContextCustom { let opaque = unsafe { (opaque as *mut Opaque).as_mut() }.unwrap(); opaque.read_packet.as_mut().unwrap()(&mut opaque.data, buf) } + #[cfg(not(feature = "ffmpeg7"))] unsafe extern "C" fn write_c(opaque: *mut c_void, data: *mut u8, len: i32) -> i32 { let buf = unsafe { slice::from_raw_parts(data, len as usize) }; let opaque = unsafe { (opaque as *mut Opaque).as_mut() }.unwrap(); opaque.write_packet.as_mut().unwrap()(&mut opaque.data, buf) } + #[cfg(feature = "ffmpeg7")] + unsafe extern "C" fn write_c(opaque: *mut c_void, data: *const u8, len: i32) -> i32 { + let buf = unsafe { slice::from_raw_parts(data, len as usize) }; + let opaque = unsafe { (opaque as *mut Opaque).as_mut() }.unwrap(); + opaque.write_packet.as_mut().unwrap()(&mut opaque.data, buf) + } unsafe extern "C" fn seek_c(opaque: *mut c_void, offset: i64, whence: i32) -> i64 { let opaque = unsafe { (opaque as *mut Opaque).as_mut() }.unwrap(); opaque.seek.as_mut().unwrap()(&mut opaque.data, offset, whence) @@ -114,6 +121,7 @@ impl AVIOContextCustom { ( read_packet.is_some().then_some(read_c as _), + // Note: If compiler errors here, you might have used wrong feature flag(ffmpeg6|ffmpeg7). write_packet.is_some().then_some(write_c as _), seek.is_some().then_some(seek_c as _), ) diff --git a/utils/linux_ffmpeg.rs b/utils/linux_ffmpeg.rs index 3107317..37171bf 100755 --- a/utils/linux_ffmpeg.rs +++ b/utils/linux_ffmpeg.rs @@ -26,7 +26,7 @@ fn main() -> Result<()> { let tmp_path = pwd()?.to_string_lossy().to_string(); let build_path = format!("{}/ffmpeg_build", tmp_path); - let branch = std::env::args().nth(1).unwrap_or_else(|| "release/6.1".to_string()); + let branch = std::env::args().nth(1).unwrap_or_else(|| "release/7.0".to_string()); let num_job = std::thread::available_parallelism().unwrap().get(); if fs::metadata("ffmpeg").is_err() { diff --git a/utils/mac_ffmpeg.rs b/utils/mac_ffmpeg.rs index fac0547..e5014f2 100755 --- a/utils/mac_ffmpeg.rs +++ b/utils/mac_ffmpeg.rs @@ -26,7 +26,7 @@ fn main() -> Result<()> { let tmp_path = pwd()?.to_string_lossy().to_string(); let build_path = format!("{}/ffmpeg_build", tmp_path); - let branch = std::env::args().nth(1).unwrap_or_else(|| "release/6.1".to_string()); + let branch = std::env::args().nth(1).unwrap_or_else(|| "release/7.0".to_string()); let num_job = std::thread::available_parallelism().unwrap().get(); if fs::metadata("ffmpeg").is_err() { diff --git a/utils/windows_ffmpeg.rs b/utils/windows_ffmpeg.rs index 77fcb74..322260d 100755 --- a/utils/windows_ffmpeg.rs +++ b/utils/windows_ffmpeg.rs @@ -26,7 +26,7 @@ fn main() -> Result<()> { let tmp_path = pwd()?.to_string_lossy().to_string(); let build_path = format!("{}/ffmpeg_build", tmp_path); - let branch = std::env::args().nth(1).unwrap_or_else(|| "release/6.1".to_string()); + let branch = std::env::args().nth(1).unwrap_or_else(|| "release/7.0".to_string()); let num_job = std::thread::available_parallelism().unwrap().get(); if fs::metadata("ffmpeg").is_err() {