75627c8afe
apple / swift (push) Failing after 10s
release / apple (push) Failing after 7s
apple / screenshots (push) Has been skipped
audit / cargo-audit (push) Failing after 1m19s
windows-host / package (push) Failing after 2m44s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, aarch64-pc-windows-msvc, C:\t-a64) (push) Failing after 39s
windows-msix / package (x64, C:\Users\Public\ffmpeg, x86_64-pc-windows-msvc, C:\t) (push) Failing after 39s
windows / build (aarch64-pc-windows-msvc) (push) Failing after 45s
android / android (push) Successful in 5m17s
windows / build (x86_64-pc-windows-msvc) (push) Failing after 45s
ci / web (push) Successful in 57s
ci / docs-site (push) Successful in 56s
ci / rust (push) Successful in 9m19s
ci / bench (push) Successful in 4m40s
decky / build-publish (push) Successful in 26s
deb / build-publish (push) Successful in 2m57s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 33s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 2m56s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 2m35s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 2m20s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 53s
flatpak / build-publish (push) Successful in 4m22s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m51s
docker / deploy-docs (push) Successful in 21s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m50s
Adds negotiated 5.1/7.1 surround to the punktfunk/1 protocol and every client (previously stereo-only): - core: new shared `audio` layout table (LAYOUT_51/71 + identity multistream mapping, canonical wire order FL FR FC LFE RL RR SL SR); Hello/Welcome `audio_channels` negotiation via the trailing-byte back-compat pattern (old peers fall back to stereo); C-ABI `punktfunk_connect_ex6`, `punktfunk_connection_audio_channels`, and in-core multistream decode `punktfunk_connection_next_audio_pcm` for embedders without a multistream Opus decoder. Real-libopus channel-identity round-trip test. - host: native audio thread captures + Opus-(multi)stream-encodes at the negotiated count (with a cross-session cached-capturer channel-mismatch fix); GameStream surround unified onto the safe `opus::MSEncoder`, dropping `audiopus_sys` (~4 unsafe blocks) and un-gating Windows GameStream surround; WASAPI loopback capture relaxed to 2/6/8 with the correct dwChannelMask. - clients: Linux (PipeWire), Windows (WASAPI), Android (AAudio) decode via `opus::MSDecoder` + render multichannel; Apple decodes in-core to PCM → AVAudioEngine with an explicit wire-order channel layout; each gains a Stereo/5.1/7.1 setting. `punktfunk-probe --audio-channels N` is the headless validator. Verified on Linux: core/host/linux/probe test suites + the Android Rust (cargo-ndk) build, clippy -D warnings, and rustfmt all green. Windows/Apple builds, all on-glass checks, and the live native loopback are pending (CI / a free box). Also lands the concurrent in-tree HEVC 4:4:4 host work (PUNKTFUNK_444): it shares the same touched files (quic.rs, punktfunk1.rs, encode/*, ...) and so cannot be committed separately from the surround changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
107 lines
3.7 KiB
Rust
107 lines
3.7 KiB
Rust
//! Runs the C ABI harness under `cargo test`: compiles `tests/c/harness.c`, links it
|
|
//! against the freshly built `libpunktfunk_core.a`, and asserts it round-trips frames
|
|
//! through the lossy loopback. The cross-platform canonical path (querying rustc for
|
|
//! link flags) is `tests/c/run.sh`; this mirrors it so `cargo test` alone covers the
|
|
//! C boundary.
|
|
|
|
use std::path::{Path, PathBuf};
|
|
use std::process::Command;
|
|
|
|
/// Native libs the Rust staticlib needs, minus the ones `cc` already links by default
|
|
/// (`-lSystem`/`-lc`), to avoid duplicate-library linker warnings. See
|
|
/// `rustc --print native-static-libs`.
|
|
fn native_libs() -> &'static [&'static str] {
|
|
if cfg!(target_os = "macos") {
|
|
// The workspace build unifies features into the staticlib, and `quic` pulls
|
|
// rustls's platform verifier → Security/CoreFoundation, plus libopus (the in-core
|
|
// `next_audio_pcm` decode path) which the `abi.rs` object references.
|
|
&[
|
|
"-lopus",
|
|
"-liconv",
|
|
"-lm",
|
|
"-framework",
|
|
"Security",
|
|
"-framework",
|
|
"CoreFoundation",
|
|
]
|
|
} else if cfg!(target_os = "linux") {
|
|
// `-lopus`: the `quic` feature pulls in-core Opus decode (`next_audio_pcm`), whose
|
|
// symbols the linked `abi.rs` object references. Before `-lm` (opus needs libm).
|
|
&[
|
|
"-lopus",
|
|
"-lgcc_s",
|
|
"-lutil",
|
|
"-lrt",
|
|
"-lpthread",
|
|
"-lm",
|
|
"-ldl",
|
|
]
|
|
} else {
|
|
&[]
|
|
}
|
|
}
|
|
|
|
fn ensure_staticlib(profile_dir: &Path) -> PathBuf {
|
|
let staticlib = profile_dir.join("libpunktfunk_core.a");
|
|
if !staticlib.exists() {
|
|
// `cargo test` doesn't always emit the standalone staticlib; build it. The
|
|
// outer cargo's build lock is released during test execution, so this is safe.
|
|
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
|
|
let _ = Command::new(cargo)
|
|
.args(["build", "-p", "punktfunk-core"])
|
|
.status();
|
|
}
|
|
staticlib
|
|
}
|
|
|
|
#[test]
|
|
fn c_abi_harness_round_trips() {
|
|
let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR")); // crates/punktfunk-core
|
|
let harness = manifest.join("tests/c/harness.c");
|
|
let include = manifest.join("../../include");
|
|
|
|
let exe = std::env::current_exe().expect("current_exe");
|
|
// .../target/<profile>/deps/c_abi-<hash> -> target/<profile>
|
|
let profile_dir = exe
|
|
.parent()
|
|
.and_then(Path::parent)
|
|
.expect("profile dir")
|
|
.to_path_buf();
|
|
|
|
let staticlib = ensure_staticlib(&profile_dir);
|
|
assert!(
|
|
staticlib.exists(),
|
|
"staticlib not found at {} (run `cargo build -p punktfunk-core`)",
|
|
staticlib.display()
|
|
);
|
|
assert!(
|
|
include.join("punktfunk_core.h").exists(),
|
|
"generated header missing; build punktfunk-core to regenerate it"
|
|
);
|
|
|
|
let cc = std::env::var("CC").unwrap_or_else(|_| "cc".into());
|
|
let out = profile_dir.join("punktfunk_c_harness");
|
|
|
|
let mut compile = Command::new(&cc);
|
|
compile
|
|
.args(["-std=c11", "-Wall", "-Wextra", "-O2", "-I"])
|
|
.arg(&include)
|
|
.arg(&harness)
|
|
.arg(&staticlib)
|
|
.args(native_libs())
|
|
.arg("-o")
|
|
.arg(&out);
|
|
|
|
match compile.status() {
|
|
Ok(s) => assert!(s.success(), "C harness failed to compile/link"),
|
|
Err(e) => {
|
|
// No C toolchain (unusual) — don't fail the whole suite; run.sh covers CI.
|
|
eprintln!("skipping C ABI test: cannot invoke `{cc}`: {e}");
|
|
return;
|
|
}
|
|
}
|
|
|
|
let run = Command::new(&out).status().expect("run C harness");
|
|
assert!(run.success(), "C harness reported a round-trip failure");
|
|
}
|