refactor(avhw): split encoder module
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
/// 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,
|
||||
}
|
||||
Reference in New Issue
Block a user