pub struct StripeState {Show 13 fields
pub no_motion_frame_count: u32,
pub paint_over_sent: bool,
pub h264_encoder: Option<H264EncoderWrapper>,
pub h264_burst_frames_remaining: i32,
pub y_buf: Vec<u8>,
pub u_buf: Vec<u8>,
pub v_buf: Vec<u8>,
pub packet_buf: Vec<u8>,
pub last_hash: u64,
pub consecutive_changes: u32,
pub in_damage_block: bool,
pub damage_block_frames_remaining: i32,
pub hash_at_block_start: u64,
}Expand description
Everything one horizontal stripe must remember between frames: its reused buffers, its own live encoder, and the motion / paint-over / damage bookkeeping that drives its send decision.
The frame is striped so independent screen regions can encode in parallel and an unchanged region can be skipped on its own, and that only works if each stripe carries its own cross-frame history. So one instance lives per stripe for the whole session and nothing per-stripe is rebuilt or recomputed from scratch each frame:
- Reused buffers:
y_buf/u_buf/v_bufhold the stripe’s YUV planes andpacket_bufthe encoded output, grown in place rather than reallocated per frame. - Encoder:
h264_encoderis the stripe’s software H.264 instance — libx264 in agplbuild, OpenH264 otherwise — reused until its geometry (or, for x264, chroma format) changes. - Paint-over / recovery:
no_motion_frame_countcounts consecutive static frames,paint_over_sentguards against re-sending a high-quality repaint of a still region, andh264_burst_frames_remainingtracks a post-repaint or recovery streaming burst. - Content-hash damage (only for sources without external damage, i.e. X11):
last_hashis the previous frame’s content hash,consecutive_changescounts changed frames toward the damage-block threshold, andin_damage_block/damage_block_frames_remaining/hash_at_block_startdrive the sustained-motion damage block managed bycontent_dirty.
Fields§
§no_motion_frame_count: u32§paint_over_sent: bool§h264_encoder: Option<H264EncoderWrapper>§h264_burst_frames_remaining: i32§y_buf: Vec<u8>§u_buf: Vec<u8>§v_buf: Vec<u8>§packet_buf: Vec<u8>§last_hash: u64§consecutive_changes: u32§in_damage_block: bool§damage_block_frames_remaining: i32§hash_at_block_start: u64Implementations§
Source§impl StripeState
impl StripeState
Sourcepub fn content_dirty(
&mut self,
bytes: &[u8],
threshold: u32,
duration: i32,
) -> bool
pub fn content_dirty( &mut self, bytes: &[u8], threshold: u32, duration: i32, ) -> bool
Stand in for the compositor damage that X11 capture does not provide: hash this stripe to decide whether it changed since last frame, and once it is clearly in motion, stop re-hashing it every frame by committing to a sustained-motion “damage block”.
The hash is not free, and a region that changes every frame would otherwise be re-hashed
forever while always reporting dirty anyway. So after threshold consecutive changes the
stripe enters a damage block that just reports dirty for duration frames and re-hashes only
once, at the end, to decide whether to extend the block or let it lapse — trading a little
extra sending for far fewer hashes on exactly the regions that need them least:
- Inside a damage block: the stripe is treated as dirty without re-hashing, and the
block’s remaining-frame counter is decremented. Only when the counter reaches zero is the
stripe re-hashed — if it differs from the hash captured at block start the block is renewed
for another
durationframes, otherwise the block exits and the change counter resets. This keeps a continuously-moving region streaming fordurationframes per re-check rather than hashing every frame. - Outside a block: the stripe is hashed and compared to the previous frame. A change
increments
consecutive_changes, and reachingthresholdconsecutive changes opens a new damage block; an unchanged frame resets the counter to zero.
Returns true whenever the stripe is considered dirty (always true while inside a block).
Trait Implementations§
Source§impl Default for StripeState
impl Default for StripeState
Source§fn default() -> StripeState
fn default() -> StripeState
Auto Trait Implementations§
impl !Sync for StripeState
impl Freeze for StripeState
impl RefUnwindSafe for StripeState
impl Send for StripeState
impl Unpin for StripeState
impl UnsafeUnpin for StripeState
impl UnwindSafe for StripeState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian().