fix(wzp-video): cfg-gate dav1d + svt-av1 off Android target
shiguredo_dav1d and shiguredo_svt_av1 build scripts panic with 'unsupported target: os=android, arch=aarch64'. The AV1 SW fallback is only needed on macOS / Linux desktop — Android uses MediaCodec for AV1 anyway. - Cargo.toml: AV1 SW deps moved under cfg(not(target_os = "android")) - lib.rs: cfg-gate the dav1d and svt_av1 modules and re-exports - factory.rs: on Android, Av1Main paths return NotInitialized when HW MediaCodec is also unavailable (only path on Android) - factory tests: assert NotInitialized on Android, Ok elsewhere Unblocks T4.3.1.1 (Android target-compile of wzp-video / mediacodec). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,11 +7,15 @@ rust-version.workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bytes = { workspace = true }
|
bytes = { workspace = true }
|
||||||
shiguredo_dav1d = "2026.1.0"
|
|
||||||
shiguredo_svt_av1 = "2026.1.0"
|
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
wzp-proto = { path = "../wzp-proto" }
|
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]
|
||||||
|
shiguredo_dav1d = "2026.1.0"
|
||||||
|
shiguredo_svt_av1 = "2026.1.0"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
shiguredo_video_toolbox = "2026.1"
|
shiguredo_video_toolbox = "2026.1"
|
||||||
|
|
||||||
|
|||||||
@@ -68,11 +68,20 @@ pub fn create_video_encoder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CodecId::Av1Main => {
|
CodecId::Av1Main => {
|
||||||
// SVT-AV1 is the universal SW fallback.
|
// SVT-AV1 is the universal SW fallback for non-Android targets.
|
||||||
// macOS VideoToolbox has no AV1 encode. Android MediaCodec AV1
|
// On Android, MediaCodec AV1 (`video/av01`) is the only available
|
||||||
// encode requires API 29+ and may not be available on all devices.
|
// path — shiguredo_svt_av1 does not build for aarch64-linux-android.
|
||||||
let _ = bitrate_bps; // SvtAv1Encoder currently hard-codes bitrate
|
let _ = bitrate_bps; // SvtAv1Encoder currently hard-codes bitrate
|
||||||
Ok(Box::new(crate::svt_av1::SvtAv1Encoder::new(width, height)?))
|
#[cfg(target_os = "android")]
|
||||||
|
{
|
||||||
|
let _ = (width, height);
|
||||||
|
#[allow(clippy::needless_return)]
|
||||||
|
return Err(VideoError::NotInitialized);
|
||||||
|
}
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
{
|
||||||
|
Ok(Box::new(crate::svt_av1::SvtAv1Encoder::new(width, height)?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => Err(VideoError::InvalidInput("not a video codec".into())),
|
_ => Err(VideoError::InvalidInput("not a video codec".into())),
|
||||||
}
|
}
|
||||||
@@ -131,7 +140,9 @@ pub fn create_video_decoder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CodecId::Av1Main => {
|
CodecId::Av1Main => {
|
||||||
// Try platform HW decoders first, then fall back to dav1d.
|
// Try platform HW decoders first, then fall back to dav1d on
|
||||||
|
// non-Android targets. On Android, MediaCodec is the only path —
|
||||||
|
// shiguredo_dav1d does not build for aarch64-linux-android.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
if let Ok(dec) = crate::videotoolbox::VideoToolboxAv1Decoder::new(width, height) {
|
if let Ok(dec) = crate::videotoolbox::VideoToolboxAv1Decoder::new(width, height) {
|
||||||
@@ -140,11 +151,13 @@ pub fn create_video_decoder(
|
|||||||
}
|
}
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
{
|
{
|
||||||
if let Ok(dec) = crate::mediacodec::MediaCodecAv1Decoder::new(width, height) {
|
return crate::mediacodec::MediaCodecAv1Decoder::new(width, height)
|
||||||
return Ok(Box::new(dec));
|
.map(|d| Box::new(d) as Box<dyn VideoDecoder>);
|
||||||
}
|
}
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
{
|
||||||
|
Ok(Box::new(crate::dav1d::Dav1dDecoder::new()?))
|
||||||
}
|
}
|
||||||
Ok(Box::new(crate::dav1d::Dav1dDecoder::new()?))
|
|
||||||
}
|
}
|
||||||
_ => Err(VideoError::InvalidInput("not a video codec".into())),
|
_ => Err(VideoError::InvalidInput("not a video codec".into())),
|
||||||
}
|
}
|
||||||
@@ -157,18 +170,30 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn av1_encoder_factory_creates_svt_av1() {
|
fn av1_encoder_factory_creates_svt_av1() {
|
||||||
let enc = create_video_encoder(CodecId::Av1Main, 640, 480, 2_000_000);
|
let enc = create_video_encoder(CodecId::Av1Main, 640, 480, 2_000_000);
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
assert!(
|
||||||
|
matches!(enc, Err(VideoError::NotInitialized)),
|
||||||
|
"AV1 SW encoder is unavailable on Android (no shiguredo_svt_av1)"
|
||||||
|
);
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
assert!(
|
assert!(
|
||||||
enc.is_ok(),
|
enc.is_ok(),
|
||||||
"AV1 encoder factory should succeed on all platforms"
|
"AV1 encoder factory should succeed on non-Android platforms"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn av1_decoder_factory_creates_decoder() {
|
fn av1_decoder_factory_creates_decoder() {
|
||||||
let dec = create_video_decoder(CodecId::Av1Main, 640, 480);
|
let dec = create_video_decoder(CodecId::Av1Main, 640, 480);
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
assert!(
|
||||||
|
matches!(dec, Err(VideoError::NotInitialized)),
|
||||||
|
"AV1 decoder requires MediaCodec on Android; non-Android device returns NotInitialized"
|
||||||
|
);
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
assert!(
|
assert!(
|
||||||
dec.is_ok(),
|
dec.is_ok(),
|
||||||
"AV1 decoder factory should succeed on all platforms"
|
"AV1 decoder factory should succeed on non-Android (dav1d SW fallback)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
pub mod av1_obu;
|
pub mod av1_obu;
|
||||||
pub mod controller;
|
pub mod controller;
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
pub mod dav1d;
|
pub mod dav1d;
|
||||||
pub mod decoder;
|
pub mod decoder;
|
||||||
pub mod depacketizer;
|
pub mod depacketizer;
|
||||||
@@ -16,11 +17,13 @@ pub mod framer;
|
|||||||
pub mod mediacodec;
|
pub mod mediacodec;
|
||||||
pub mod nack;
|
pub mod nack;
|
||||||
pub mod simulcast;
|
pub mod simulcast;
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
pub mod svt_av1;
|
pub mod svt_av1;
|
||||||
pub mod videotoolbox;
|
pub mod videotoolbox;
|
||||||
|
|
||||||
pub use av1_obu::{Av1Depacketizer, Av1ObuFramer, is_keyframe_obu};
|
pub use av1_obu::{Av1Depacketizer, Av1ObuFramer, is_keyframe_obu};
|
||||||
pub use controller::{VideoQualityController, VideoTarget};
|
pub use controller::{VideoQualityController, VideoTarget};
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
pub use dav1d::Dav1dDecoder;
|
pub use dav1d::Dav1dDecoder;
|
||||||
pub use decoder::VideoDecoder;
|
pub use decoder::VideoDecoder;
|
||||||
pub use depacketizer::H264Depacketizer;
|
pub use depacketizer::H264Depacketizer;
|
||||||
@@ -34,6 +37,7 @@ pub use mediacodec::{
|
|||||||
};
|
};
|
||||||
pub use nack::{CachedPacket, NackAction, NackReceiver, NackSender};
|
pub use nack::{CachedPacket, NackAction, NackReceiver, NackSender};
|
||||||
pub use simulcast::{LayerPacket, LayerTarget, SimulcastEncoder, SimulcastLayer};
|
pub use simulcast::{LayerPacket, LayerTarget, SimulcastEncoder, SimulcastLayer};
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
pub use svt_av1::SvtAv1Encoder;
|
pub use svt_av1::SvtAv1Encoder;
|
||||||
pub use videotoolbox::{
|
pub use videotoolbox::{
|
||||||
VideoToolboxAv1Decoder, VideoToolboxDecoder, VideoToolboxEncoder, VideoToolboxHevcDecoder,
|
VideoToolboxAv1Decoder, VideoToolboxDecoder, VideoToolboxEncoder, VideoToolboxHevcDecoder,
|
||||||
|
|||||||
Reference in New Issue
Block a user