pub(crate) struct RunState<'a> {Show 19 fields
pub(crate) inner: &'a Inner,
pub(crate) ring: &'a DeliveryRing,
pub(crate) encoder: PcmEncoder,
pub(crate) frame_size_per_channel: usize,
pub(crate) channels: usize,
pub(crate) accum: Vec<i16>,
pub(crate) silence_ref: Vec<i16>,
pub(crate) pcm_fill_bytes: usize,
pub(crate) pool: PoolTaker,
pub(crate) red_history: VecDeque<(Vec<u8>, u64)>,
pub(crate) red_spare: Vec<Vec<u8>>,
pub(crate) red_distance: usize,
pub(crate) total_samples_processed: u64,
pub(crate) first_sound_detected: bool,
pub(crate) current_applied_bitrate: i32,
pub(crate) chunks_read: u64,
pub(crate) chunks_silent: u64,
pub(crate) chunks_encoded: u64,
pub(crate) bytes_encoded: u64,
}Expand description
Per-run encode/deliver state, living on the capture thread’s stack for the lifetime of one capture. Holds the encoder, the frame-reassembly buffers, the outgoing buffer recycler, the RED redundancy history, and the running debug-log counters.
Fields§
§inner: &'a Inner§ring: &'a DeliveryRing§encoder: PcmEncoder§frame_size_per_channel: usize§channels: usize§accum: Vec<i16>Reassembly buffer for exactly one Opus frame (i16 samples, filled byte-wise from
the incoming PulseAudio fragments).
silence_ref: Vec<i16>A zeroed reference of the same length as accum; comparing accum == silence_ref
lowers to a single vectorized memcmp for the silence gate, versus a scalar per-sample
scan.
pcm_fill_bytes: usize§pool: PoolTakerOutgoing-buffer recycler, shared with delivered AudioFrames whose drop refills it.
red_history: VecDeque<(Vec<u8>, u64)>RFC 2198 redundancy history: the last red_distance emitted (opus, pts) frames,
oldest-first. Per-run — reset on start, and the frame size is fixed for a run.
red_spare: Vec<Vec<u8>>Retired red_history buffers, reused for the next entry so the steady state (a
silence gap included) allocates nothing. Bounded by red_distance: every buffer
is either in the history or here.
red_distance: usize§total_samples_processed: u64§first_sound_detected: bool§current_applied_bitrate: i32§chunks_read: u64§chunks_silent: u64§chunks_encoded: u64§bytes_encoded: u64Implementations§
Source§impl<'a> RunState<'a>
impl<'a> RunState<'a>
Sourcepub(crate) fn feed(&mut self, src: &[u8])
pub(crate) fn feed(&mut self, src: &[u8])
Feed one PulseAudio PCM fragment into the reassembly buffer, emitting a frame
each time accum fills to exactly one Opus frame.
Fragments arrive at arbitrary byte boundaries, so this copies from src into accum
at pcm_fill_bytes, calling emit_frame (and resetting the fill cursor) whenever a
full frame_size_per_channel * channels * 2-byte chunk accumulates, and loops until
src is drained. Any partial remainder is carried into the next fragment.
Sourcepub(crate) fn emit_frame(&mut self)
pub(crate) fn emit_frame(&mut self)
Encode one reassembled frame and hand it to the delivery thread. The heart of the capture encode path.
- Dynamic bitrate: re-reads the
opus_bitratemirror and reconfigures the encoder only when it changed, so a live bitrate update costs nothing on unchanged frames. - Timestamp:
ptsis the running 48 kHz-domain sample count (total_samples_processed) before this frame, then advanced byframe_size_per_channel— a monotonic per-frame timestamp used for RED offsets and client-side ordering. - Silence gate: when enabled, a frame equal to the zeroed
silence_refis counted and dropped (nothing is sent), so pure silence costs no bandwidth. The first non-silent frame logs once. - Encode in place:
write_ws_prefix_intowrites the RFC 2198 RED framing prefix (which depends only onpts+ history) into a pooled buffer, and the Opus packet is encoded DIRECTLY after it — no assembly copy, and the buffer recycles through the pool, so the steady state allocates nothing. An encode error or a zero-length packet returns the buffer to the pool and drops the frame. - Retain redundancy: with
red_distance > 0, the just-encoded primary is copied ontored_history(bounded, oldest-first) to serve as a future redundant copy, into the buffer the retiring entry hands back. - Hand off: the truncated buffer is pushed to the
DeliveryRing; the capture thread itself never touches the GIL.