fn decide_constant_quality(
st: &mut StripeState,
settings: &CaptureSettings,
damage: Damage,
is_animated: bool,
recovery_idr: bool,
encoder: EncoderQuality,
) -> HwFrameDecisionExpand description
decide_hw_fullframe for a constant-quality session: the cleanup moves the session’s own
quality to the paint-over one, as main’s paint-over did, rather than holding a frame at a
quantizer. Each encoder then codes the cleanup the way it codes any frame at that quality:
x264’s and x265’s rate factor give a key frame their intra offset (about three steps finer
than the paint-over index), SVT-AV1 its key-frame qindex, and the encoders whose quality
change re-opens the session (x265, SVT-AV1, kvazaar) open on a key frame at it. A frame held
at the paint-over quantizer itself came out coarser than main’s (SVT-AV1 49.6 against 61.0 dB,
x264 53.7 against 56.5 dB).
The session stays at the paint-over quality while the region stays clean: from its cleanup
until motion (more than a small change), so the frames Turbo sends of a still screen, or a
caret blinking on it, do not take a re-opening encoder back to the session’s quality, a key
frame at it, after QP_HYSTERESIS_LIMIT frames. The refresh and the bursts come when
cleanup_due says, as at a constant rate, and no key-frame cleanup follows: on NVENC at CRF 25
and paint-over 18 it lifted the end 0.8 dB for five times the bytes, one key frame of 415 kB
where the refresh is 100. A requested or scheduled key frame is coded at the session’s own
quality, as on main, and its burst at the paint-over one. An encoder whose quality change
re-opens it (EncoderQuality::reopens: x265, kvazaar, SVT-AV1) codes the refresh that moves it
as a key frame, as main’s paint-over did.