Files
wl-webrtc/src/avhw/types.rs
T
2026-07-03 10:57:05 +08:00

89 lines
3.4 KiB
Rust

/// Commands sent from the WebRTC thread to the SW encoder when the
/// bandwidth estimate changes significantly.
pub enum BitrateCommand {
UpdateBitrate {
target_bps: u64,
},
UpdateResolution {
width: u32,
height: u32,
},
/// Force the next encoded frame to be an IDR. Sent by the WebRTC thread
/// in response to str0m `Event::KeyframeRequest` or a resolution change.
ForceKeyframe,
}
#[derive(Clone, Copy, Debug)]
pub struct ResolutionChange {
pub width: u32,
pub height: u32,
}
/// Per-frame timing snapshot for the software encoder, consumed by the stats
/// thread. `sws_us` measures NV12->YUV420P conversion, `encode_us` measures
/// `avcodec_send_frame` + drain, and `output_bytes` counts encoded bytes
/// produced by libavcodec (even if downstream delivery later drops them).
#[derive(Default, Clone, Copy, Debug)]
pub struct SwEncodeTiming {
pub sws_us: u64,
pub encode_us: u64,
pub output_bytes: usize,
}
/// Outcome of a single `encode_cpu_frame` call. Used by the encode thread
/// to decide whether to report timing stats (only real encodes tick encoded_fps).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EncodeOutcome {
/// Frame was actually encoded and produced output bytes.
Encoded,
/// Frame was dropped because WebRTC is paused (no client connected).
SkippedPaused,
/// Frame was dropped because the encoder is in disconnected state.
SkippedDisconnected,
/// Frame was dropped because its Y-plane hash matched the previous frame.
SkippedDuplicate,
}
/// Per-stage timing breakdown for one encode cycle on the hardware path.
/// Returned by `EncState::encode_frame` so callers can fold the numbers
/// into `crate::stats::FrameTimings`. `transfer_us` is always 0 on the HW
/// path because the frame stays on the GPU; the SW path's struct (if added
/// later) would carry a real readback measurement.
#[derive(Debug, Default, Clone, Copy)]
pub struct EncodeStages {
pub scale_us: u64,
pub transfer_us: u64,
pub encode_us: u64,
}
/// Encoded H.264 frame with timing metadata for WebRTC output.
///
/// MP4 file output (FrameOutput::Muxer) does NOT use this - it writes via
/// avformat which preserves PTS internally. WebRTC output (FrameOutput::Channel)
/// requires explicit PTS propagation so RTP timestamps reflect real capture time.
/// Without this, WebRTC clients' jitter buffers grow to seconds under
/// damage-driven variable frame rate. See issue #24.
#[derive(Debug)]
pub struct EncodedH264Frame {
/// H.264 NAL byte stream (Annex B or AVCC depending on encoder configuration)
pub data: Vec<u8>,
/// PTS in encoder time_base units (1/fps seconds), normalized so first frame = 0.
/// Derived from real capture time, NOT frame counter.
pub pts_ticks: i64,
/// Wall-clock capture time, propagated from CpuNv12Frame for frame_age stat.
pub capture_time: std::time::Instant,
}
/// Owned CPU NV12 frame data for cross-thread transfer.
/// Produced by main thread (VAAPI import + GPU scale + transfer), consumed by encode thread.
pub struct CpuNv12Frame {
pub y_data: Vec<u8>,
pub uv_data: Vec<u8>,
pub y_stride: usize,
pub uv_stride: usize,
pub pts: i64,
/// Wall-clock time when this frame was captured (PipeWire delivery).
/// Used for frame_age stat: time from capture to WebRTC send.
pub capture_time: std::time::Instant,
}