moq_video/decode/mod.rs
1//! Subscribe to an H.264, H.265, or AV1 track and decode it to raw frames.
2//!
3//! The decode counterpart to [`encode`](crate::encode), and the mirror of
4//! `moq_audio::decode::Consumer`. [`Consumer`] subscribes to a moq-mux video
5//! track and hands back decoded [`Frame`](crate::Frame)s; a native backend does the work
6//! (VideoToolbox on macOS, Media Foundation / DXVA on Windows, NVDEC on Linux,
7//! openh264 everywhere as the software fallback for H.264).
8//!
9//! H.264 and H.265 are supported, symmetric with what [`encode`](crate::encode)
10//! produces. AV1 is decode-only on NVDEC. H.265 and AV1 are hardware-only (no
11//! software fallback). Any other codec yields
12//! [`Error::UnsupportedCodec`](crate::Error).
13
14// Crate-visible so the NVENC encode backend's round-trip test can decode its
15// output with the software decoder (an in-crate, ffmpeg-free encode->decode
16// check that catches input-pitch corruption).
17pub(crate) mod backend;
18mod consumer;
19mod decoder;
20
21pub use consumer::Consumer;
22pub use decoder::{Config, Decoder, Kind};
23
24#[cfg(test)]
25mod tests {
26 /// Callers (libmoq, moq-transcode) hold these across `.await`s in spawned
27 /// tasks and share frames via `Arc` (the transcode fanout), so both must
28 /// stay `Send` and `Frame` also `Sync` even when a platform's frame wraps
29 /// a GPU handle. Compile-time check; fails per-platform if a variant
30 /// regresses.
31 #[test]
32 fn frame_and_consumer_are_thread_safe() {
33 fn assert_send<T: Send>() {}
34 fn assert_sync<T: Sync>() {}
35 assert_send::<crate::Frame>();
36 assert_sync::<crate::Frame>();
37 assert_send::<super::Consumer>();
38 }
39}