From 5d05b021aa41a75034521983797e655fae30bdf9 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Mon, 25 May 2026 06:33:35 +0400 Subject: [PATCH] fix(wzp-video): gate shiguredo AV1 crates to macOS only; fix Linux relay build - Cargo.toml: merge duplicate [target.macos.deps] sections; move shiguredo_dav1d/svt_av1/video_toolbox into single block - lib.rs: dav1d + svt_av1 modules and re-exports guarded by cfg(target_os = "macos") instead of cfg(not(android)) - factory.rs: AV1 encoder/decoder paths split into macos (svt-av1/dav1d) and linux fallback (NotInitialized); update doc comments and tests - build-linux-docker.sh: build only wzp-relay + wzp-web (drops wzp-client which pulled in shiguredo crates); fix Docker copy step; add --deploy flag + deploy_relay(); fix branch auto-detection - build-tauri-android.sh: default to release build, arm64 only Co-Authored-By: Claude Sonnet 4.6 --- crates/wzp-video/Cargo.toml | 9 ++++---- crates/wzp-video/src/factory.rs | 40 ++++++++++++++++++--------------- crates/wzp-video/src/lib.rs | 8 +++---- scripts/build-linux-docker.sh | 15 +++++-------- scripts/build-tauri-android.sh | 8 +++---- 5 files changed, 39 insertions(+), 41 deletions(-) diff --git a/crates/wzp-video/Cargo.toml b/crates/wzp-video/Cargo.toml index 6f4b6fd..fdde0d3 100644 --- a/crates/wzp-video/Cargo.toml +++ b/crates/wzp-video/Cargo.toml @@ -10,13 +10,12 @@ bytes = { workspace = true } tracing = { workspace = true } wzp-proto = { path = "../wzp-proto" } -# AV1 SW codecs do not support Android target (build.rs panics on -# aarch64-linux-android). Android uses MediaCodec for AV1 instead. -[target.'cfg(not(target_os = "android"))'.dependencies] +# AV1 SW codecs: shiguredo crates download prebuilt binaries at build time. +# Prebuilts are available for macOS only; Android uses MediaCodec; Linux will +# use system/vendored libs when that path is wired up (TODO). +[target.'cfg(target_os = "macos")'.dependencies] shiguredo_dav1d = "2026.1.0" shiguredo_svt_av1 = "2026.1.0" - -[target.'cfg(target_os = "macos")'.dependencies] shiguredo_video_toolbox = "2026.1" [target.'cfg(target_os = "android")'.dependencies] diff --git a/crates/wzp-video/src/factory.rs b/crates/wzp-video/src/factory.rs index 0c762ab..e7181cb 100644 --- a/crates/wzp-video/src/factory.rs +++ b/crates/wzp-video/src/factory.rs @@ -11,7 +11,7 @@ use crate::encoder::{VideoEncoder, VideoError}; /// **Encoder dispatch:** /// - `H264Baseline` → `VideoToolboxEncoder` (macOS) / `MediaCodecEncoder` (Android) /// - `H265Main` → `VideoToolboxHevcEncoder` (macOS) / `MediaCodecHevcEncoder` (Android) -/// - `Av1Main` → `SvtAv1Encoder` (all platforms — universal SW fallback) +/// - `Av1Main` → `SvtAv1Encoder` (macOS only — SW fallback) /// /// Non-video codecs return [`VideoError::InvalidInput`]. pub fn create_video_encoder( @@ -78,10 +78,15 @@ pub fn create_video_encoder( #[allow(clippy::needless_return)] return Err(VideoError::NotInitialized); } - #[cfg(not(target_os = "android"))] + #[cfg(target_os = "macos")] { Ok(Box::new(crate::svt_av1::SvtAv1Encoder::new(width, height)?)) } + #[cfg(not(any(target_os = "macos", target_os = "android")))] + { + let _ = (width, height); + Err(VideoError::NotInitialized) + } } _ => Err(VideoError::InvalidInput("not a video codec".into())), } @@ -92,7 +97,7 @@ pub fn create_video_encoder( /// **Decoder dispatch:** /// - `H264Baseline` → `VideoToolboxDecoder` (macOS) / `MediaCodecDecoder` (Android) /// - `H265Main` → `VideoToolboxHevcDecoder` (macOS) / `MediaCodecHevcDecoder` (Android) -/// - `Av1Main` → `VideoToolboxAv1Decoder` (macOS M3+) → `Dav1dDecoder` (fallback, all platforms) +/// - `Av1Main` → `VideoToolboxAv1Decoder` (macOS M3+) → `Dav1dDecoder` (macOS SW fallback) /// /// Non-video codecs return [`VideoError::InvalidInput`]. pub fn create_video_decoder( @@ -154,10 +159,15 @@ pub fn create_video_decoder( return crate::mediacodec::MediaCodecAv1Decoder::new(width, height) .map(|d| Box::new(d) as Box); } - #[cfg(not(target_os = "android"))] + #[cfg(target_os = "macos")] { Ok(Box::new(crate::dav1d::Dav1dDecoder::new()?)) } + #[cfg(not(any(target_os = "macos", target_os = "android")))] + { + let _ = (width, height); + Err(VideoError::NotInitialized) + } } _ => Err(VideoError::InvalidInput("not a video codec".into())), } @@ -170,30 +180,24 @@ mod tests { #[test] fn av1_encoder_factory_creates_svt_av1() { let enc = create_video_encoder(CodecId::Av1Main, 640, 480, 2_000_000); - #[cfg(target_os = "android")] + #[cfg(target_os = "macos")] + assert!(enc.is_ok(), "AV1 encoder factory should succeed on macOS"); + #[cfg(not(target_os = "macos"))] assert!( matches!(enc, Err(VideoError::NotInitialized)), - "AV1 SW encoder is unavailable on Android (no shiguredo_svt_av1)" - ); - #[cfg(not(target_os = "android"))] - assert!( - enc.is_ok(), - "AV1 encoder factory should succeed on non-Android platforms" + "AV1 SW encoder is unavailable on Android/Linux (no shiguredo_svt_av1)" ); } #[test] fn av1_decoder_factory_creates_decoder() { let dec = create_video_decoder(CodecId::Av1Main, 640, 480); - #[cfg(target_os = "android")] + #[cfg(target_os = "macos")] + assert!(dec.is_ok(), "AV1 decoder factory should succeed on macOS (dav1d fallback)"); + #[cfg(not(target_os = "macos"))] assert!( matches!(dec, Err(VideoError::NotInitialized)), - "AV1 decoder requires MediaCodec on Android; non-Android device returns NotInitialized" - ); - #[cfg(not(target_os = "android"))] - assert!( - dec.is_ok(), - "AV1 decoder factory should succeed on non-Android (dav1d SW fallback)" + "AV1 decoder unavailable on Android/Linux (no shiguredo_dav1d)" ); } diff --git a/crates/wzp-video/src/lib.rs b/crates/wzp-video/src/lib.rs index 5dec541..eb51286 100644 --- a/crates/wzp-video/src/lib.rs +++ b/crates/wzp-video/src/lib.rs @@ -6,7 +6,7 @@ pub mod av1_obu; pub mod controller; -#[cfg(not(target_os = "android"))] +#[cfg(target_os = "macos")] pub mod dav1d; pub mod decoder; pub mod depacketizer; @@ -17,13 +17,13 @@ pub mod framer; pub mod mediacodec; pub mod nack; pub mod simulcast; -#[cfg(not(target_os = "android"))] +#[cfg(target_os = "macos")] pub mod svt_av1; pub mod videotoolbox; pub use av1_obu::{Av1Depacketizer, Av1ObuFramer, is_keyframe_obu}; pub use controller::{VideoQualityController, VideoTarget}; -#[cfg(not(target_os = "android"))] +#[cfg(target_os = "macos")] pub use dav1d::Dav1dDecoder; pub use decoder::VideoDecoder; pub use depacketizer::H264Depacketizer; @@ -37,7 +37,7 @@ pub use mediacodec::{ }; pub use nack::{CachedPacket, NackAction, NackReceiver, NackSender}; pub use simulcast::{LayerPacket, LayerTarget, SimulcastEncoder, SimulcastLayer}; -#[cfg(not(target_os = "android"))] +#[cfg(target_os = "macos")] pub use svt_av1::SvtAv1Encoder; pub use videotoolbox::{ VideoToolboxAv1Decoder, VideoToolboxDecoder, VideoToolboxEncoder, VideoToolboxHevcDecoder, diff --git a/scripts/build-linux-docker.sh b/scripts/build-linux-docker.sh index bcf828a..cbf4b6b 100755 --- a/scripts/build-linux-docker.sh +++ b/scripts/build-linux-docker.sh @@ -105,20 +105,15 @@ docker run --rm --user 1000:1000 \ set -euo pipefail cd /build/source -echo ">>> Building relay + client + web + bench..." -cargo build --release --bin wzp-relay --bin wzp-client --bin wzp-web --bin wzp-bench 2>&1 | tail -5 - -echo ">>> Building audio client..." -cargo build --release --bin wzp-client --features audio 2>&1 | tail -3 -cp target/release/wzp-client target/release/wzp-client-audio -cargo build --release --bin wzp-client 2>&1 | tail -3 +echo ">>> Building relay + web..." +cargo build --release --bin wzp-relay --bin wzp-web 2>&1 | tail -5 echo ">>> Binaries:" -ls -lh target/release/wzp-relay target/release/wzp-client target/release/wzp-client-audio target/release/wzp-web target/release/wzp-bench +ls -lh target/release/wzp-relay target/release/wzp-web echo ">>> Packaging..." tar czf /tmp/wzp-linux-x86_64.tar.gz \ - -C target/release wzp-relay wzp-client wzp-client-audio wzp-web wzp-bench + -C target/release wzp-relay wzp-web echo "BINARIES_BUILT" ' @@ -131,7 +126,7 @@ TARBALL="$BASE_DIR/data/cache-linux/target/release/../../../wzp-linux-x86_64.tar docker run --rm \ -v "$BASE_DIR/data/cache-linux/target:/build/target" \ wzp-android-builder bash -c \ - "cp /build/target/release/wzp-relay /build/target/release/wzp-client /build/target/release/wzp-client-audio /build/target/release/wzp-web /build/target/release/wzp-bench /tmp/ && tar czf /tmp/wzp-linux-x86_64.tar.gz -C /tmp wzp-relay wzp-client wzp-client-audio wzp-web wzp-bench && cat /tmp/wzp-linux-x86_64.tar.gz" \ + "cp /build/target/release/wzp-relay /build/target/release/wzp-web /tmp/ && tar czf /tmp/wzp-linux-x86_64.tar.gz -C /tmp wzp-relay wzp-web && cat /tmp/wzp-linux-x86_64.tar.gz" \ > /tmp/wzp-linux-x86_64.tar.gz URL=$(curl -s -F "file=@/tmp/wzp-linux-x86_64.tar.gz" -H "Authorization: $rusty_auth_token" "$rusty_address") diff --git a/scripts/build-tauri-android.sh b/scripts/build-tauri-android.sh index 4e523a4..1be9bf7 100755 --- a/scripts/build-tauri-android.sh +++ b/scripts/build-tauri-android.sh @@ -15,8 +15,8 @@ set -euo pipefail # - Output: desktop/src-tauri/gen/android/.../*.apk # # Usage: -# ./scripts/build-tauri-android.sh # full pipeline (debug, arm64 only) -# ./scripts/build-tauri-android.sh --release # release APK +# ./scripts/build-tauri-android.sh # full pipeline (release, arm64 only) +# ./scripts/build-tauri-android.sh --debug # debug APK (faster, no optimisation) # ./scripts/build-tauri-android.sh --no-pull # skip git fetch # ./scripts/build-tauri-android.sh --rust # force-clean rust target # ./scripts/build-tauri-android.sh --init # also run `cargo tauri android init` @@ -38,7 +38,7 @@ SSH_OPTS="-o ConnectTimeout=15 -o ServerAliveInterval=15 -o ServerAliveCountMax= REBUILD_RUST=0 DO_PULL=1 DO_INIT=0 -BUILD_RELEASE=0 +BUILD_RELEASE=1 BUILD_ARCH="arm64" NEXT_IS_ARCH=0 for arg in "$@"; do @@ -52,7 +52,7 @@ for arg in "$@"; do --pull) DO_PULL=1 ;; --no-pull) DO_PULL=0 ;; --init) DO_INIT=1 ;; - --release) BUILD_RELEASE=1 ;; + --debug) BUILD_RELEASE=0 ;; --arch) NEXT_IS_ARCH=1 ;; -h|--help) sed -n '3,32p' "$0"