Skip to main content

videocall_codecs/
lib.rs

1/*
2 * Copyright 2025 Security Union LLC
3 *
4 * Licensed under either of
5 *
6 * * Apache License, Version 2.0
7 *   (http://www.apache.org/licenses/LICENSE-2.0)
8 * * MIT license
9 *   (http://opensource.org/licenses/MIT)
10 *
11 * at your option.
12 *
13 * Unless you explicitly state otherwise, any contribution intentionally
14 * submitted for inclusion in the work by you, as defined in the Apache-2.0
15 * license, shall be dual licensed as above, without any additional terms or
16 * conditions.
17 */
18
19//! A high-fidelity, cross-platform video decoder jitter buffer implementation in Rust.
20
21pub mod decoder;
22pub mod encoder;
23pub mod frame;
24pub mod jitter_buffer;
25pub mod jitter_estimator;
26pub mod messages;
27pub mod vp9;
28
29// UniFFI Swift/Kotlin bindings for the pure-Rust VP9 codec. Native-only (the
30// `uniffi` CLI machinery does not build for wasm32), gated behind the `uniffi`
31// feature so nothing else is affected.
32#[cfg(all(feature = "uniffi", not(target_arch = "wasm32")))]
33uniffi::setup_scaffolding!();
34#[cfg(all(feature = "uniffi", not(target_arch = "wasm32")))]
35mod ffi;
36
37/// Deterministic synthetic sources, PSNR metrics, an IVF writer, and (behind
38/// `libvpx`) a synchronous libvpx decode oracle. Used by the VP9 encoder's
39/// TDD harness. Enabled with the `test-utils` feature.
40#[cfg(feature = "test-utils")]
41pub mod testing;
42
43// Diagnostics helper to publish video metrics via the shared event bus.
44#[cfg(feature = "wasm")]
45pub mod video_diagnostics {
46    use videocall_diagnostics::{global_sender, metric, now_ms, DiagEvent};
47
48    /// Publish video stats to the global diagnostics stream. `stream_id` should be
49    /// in the format "from_peer->to_peer" to align with health reporting expectations.
50    pub fn report_video_stats(stream_id: String, fps: Option<f64>, frames_buffered: Option<u64>) {
51        let mut metrics = Vec::new();
52        if let Some(f) = fps {
53            metrics.push(metric!("fps_received", f));
54        }
55        if let Some(b) = frames_buffered {
56            metrics.push(metric!("frames_buffered", b));
57        }
58
59        if metrics.is_empty() {
60            return;
61        }
62
63        let event = DiagEvent {
64            subsystem: "video",
65            stream_id: Some(stream_id),
66            ts_ms: now_ms(),
67            metrics,
68        };
69        // Best-effort broadcast; ignore backpressure errors
70        let _ = global_sender().try_broadcast(event);
71    }
72}