When true, the encoder estimates each MB's 16x16 luma variance
and routes low-variance MBs (faces, skin, smooth background) to
segment 2 with delta aqSmoothQiDelta (default -8, sharper) and
high-variance MBs (heavily textured detail) to segment 3 with
delta aqTexturedQiDelta (default +4, coarser). Mid-variance
MBs and any MB also claimed by roiRect keep their existing
segment (segment 1 for ROI takes precedence over activity). Net
effect on VC content: faces look noticeably better at the same
total bitrate. Default false keeps existing behaviour
byte-identical.
Periodic ALTREF refresh schedule, mirroring goldenRefreshPeriod.
When > 0, ALTREF is refreshed exactly every Nth inter frame since
the last keyframe and the static refreshAltrefOnInter flag is
ignored. Default 0 keeps the legacy static behaviour. ALTREF is
typically refreshed less often than GOLDEN so it stays available
as a much older long-term recovery anchor (e.g. burst-loss
fallback that survives a stale golden). Mutable at runtime via
setAltrefRefreshPeriod.
Variance floor above which a MB is classified as "textured"
(segment 3) when activityAq is true. Must be >=
aqSmoothVarThreshold; MBs in between stay in segment 0.
When true, the in-loop deblocking filter level passed to the
underlying encoder is derived per-frame from the active quantizer
(via deriveLoopFilterLevel) instead of using the static
filterLevel field. Default off so existing bit-exact behaviour
is preserved; turn on for VC where deblocking visibly hides
low-bitrate MB edges.
Cyclic intra refresh percentage (0..100). On every inter frame,
round(cyclicRefreshPercent/100 * mbCount) MBs are forced to be
coded as intra (DC_PRED 16x16) instead of running motion search.
The set rotates in raster order across frames so the entire frame
is refreshed every 100/cyclicRefreshPercent inter frames. This
caps inter-prediction error-propagation depth — critical for video
conferencing over lossy networks. Set 0 to disable (default).
Mutable at runtime via setCyclicRefreshPercent.
Optional temporal denoiser. When non-null, each inter frame's
luma plane is pre-filtered against _prevLast (low-motion MBs are
blended toward the reference) before motion search and residual
encode. Reduces bitrate on noisy webcam content without any
decoder change. Keyframes are never denoised (no reference yet).
When a rateController is attached and its consecutiveDrops
counter reaches this value, the encoder forces the next non-key
frame to be encoded as a keyframe instead. Gives the receiver a
clean restart after a packet-loss burst that caused a long drop
sequence. 0 disables (default).
Number of frames encoded since (and including) the last
keyframe. 0 before the first frame; resets to 1 immediately
after a keyframe is emitted. Includes dropped inter frames.
SAD margin by which a GOLDEN NEWMV candidate must beat the
current best to be preferred. Larger than newMvSadBias because
the GOLDEN choice also spends the ref-frame bit. Only consulted
when tryGoldenNewMv is true.
When > 0, the GOLDEN reference is refreshed once every
goldenRefreshPeriod inter frames (the 1st, N+1th, 2N+1th, ...
inter after a keyframe) and held constant in between, regardless of
refreshGoldenOnInter. Gives the decoder a stable long-term
reference for packet-loss recovery and lets motion search target a
non-drifting frame on slow VC content. 0 (default) preserves the
original behaviour where refreshGoldenOnInter is applied every
inter frame. Mutable at runtime via setGoldenRefreshPeriod.
SAD margin by which GOLDEN ZEROMV must beat the current best to
be preferred. Crude proxy for the rate cost of switching the MB's
reference frame (one extra entropy-coded bit). Only consulted
when tryGoldenZeroMv is true.
True iff requestKeyframe has been called and the request has
not yet been consumed (either by an emitted keyframe or vetoed
by minKeyframeInterval and still pending).
Size in bytes of the bitstream produced by the most recent
non-dropped frame. 0 if no frame has been encoded yet or the
last frame was dropped. Equivalent to
lastFrameStats?.bytesEmitted ?? 0.
Snapshot of EncodedVp8Frame.stats from the most recent
non-dropped encoded frame, or null if no frame has been
encoded yet (or the most recent one was dropped).
log2 of the number of residual token partitions (0..3 → 1/2/4/8).
Splitting tokens across multiple partitions isolates packet loss to
a row-group (the decoder discards the affected partition only) and
enables parallel residual decoding. Header partition (mode/MV bits)
is unaffected — only DCT tokens are split.
Upper bound (inclusive) clamped onto the final per-frame QI.
Useful as a quality ceiling in ABR drivers. Default 127
(no ceiling). Mutable at runtime via setQiClamps.
Minimum number of frames between keyframes. Default 0 disables.
When > 0, "soft" keyframe triggers — requestKeyframe, scene-cut
detection (sceneCutMeanAbsDiff), and drop-recovery escalation
(forceKeyAfterConsecutiveDrops) — are deferred until at least
this many frames have elapsed since the last keyframe. A pending
requestKeyframe is held and fires on the first eligible frame.
The hard upper bound keyframeInterval and forceKey: true on
encodeFrame still take effect regardless of this minimum.
Must satisfy 0 <= minKeyframeInterval <= keyframeInterval.
Must satisfy 0 <= minKeyframeInterval <= keyframeInterval.
Mutable at runtime via setMinKeyframeInterval.
Lower bound (inclusive) clamped onto the final per-frame QI,
regardless of whether it came from qi, qiOverride, or the
rateController. Useful as a quality floor in ABR drivers.
Must satisfy 0 <= minQi <= maxQi <= 127. Default 0 (no floor).
Mutable at runtime via setQiClamps.
Bias added to motion-search candidate cost per pel of MV
magnitude: cost = SAD + mvRateBias * (|dy| + |dx|). Trims the
per-MB MV-delta cost on low-motion VC content by preferring
shorter MVs when SAD is comparable. 0 disables (default), keeping
behaviour bit-identical to the pure-SAD search.
SAD margin by which NEARESTMV must beat the current best to be
preferred. Proxies the rate cost of the NEAREST mode bit vs
ZEROMV (NEAREST is one extra mode bit but no MV bits).
Optional callback fired immediately after the rate controller
drops a frame. Mirrors the bookkeeping behaviour of
Vp8CumulativeStats.droppedFrames. Exceptions raised by the
callback propagate out of encodeFrame. Mutable at runtime via
setOnFrameDropped.
Optional callback fired immediately after each non-dropped frame
is encoded, with the same Vp8FrameStats surfaced on
EncodedVp8Frame.stats. Useful for streaming telemetry sinks
(logger, metrics exporter, ABR driver) that prefer push to
polling lastFrameStats. Not fired for dropped frames -- use
onFrameDropped instead. Exceptions raised by the callback
propagate out of encodeFrame. Mutable at runtime via
setOnFrameEncoded.
When true, the per-MB mode decision considers NEAREST/NEAR
predictor MVs (from above/left/aboveleft neighbours) in addition
to ZERO and NEW. Integer motion search for NEW is also seeded at
the best predictor.
Wire probability for the skip-coeff bit. bc.read(probSkipFalse)
returns 0 (MB has tokens) with probability probSkipFalse/256, so
higher values favour "not skipped". Only used when mbNoCoeffSkip.
Optional frame-level rate controller. When provided, the qi
passed to encodeKeyframe/encodeInterFrame comes from
rateController.pickQi(isKey: ...) instead of the static qi
field, and the resulting frame size is fed back via
rateController.update(...).
When false, inter frames keep the previous GOLDEN slot
(refresh_golden_frame = 0, copy_buffer_to_gf = 0). This lets a
stable long-term reference persist past short-term LAST updates.
Mutable at runtime via setRefreshGoldenOnInter.
Optional region of interest in pixel coordinates. When non-null,
every MB whose top-left lies inside the rect is placed in
segment 1 with a quantizer delta of roiQiDelta; MBs outside use
segment 0 (no delta). Translates into an EncoderSegmentation on
every key + inter frame. Classic VC use case: lock the camera's
face area to a sharper qi without spending more total bits.
Coordinates are snapped to the 16x16 MB grid.
Size of the rolling-stats window in non-dropped frames
(forwarded to Vp8CumulativeStats.rollingWindowFrames). 0
(default) disables the rolling ring buffer; all rolling*
getters then return 0.0. Must be >= 0.
If set, the encoder measures mean absolute luma diff between the
next frame's source Y and the previous reference's Y. When the
mean exceeds this value, the frame is promoted to a keyframe
(cheap scene-cut detector). Typical threshold for VC is ~24..40.
Null disables (default).
Mutable at runtime via setSceneCutMeanAbsDiff; null disables.
When > 0, every inter MB whose LAST-relative ZEROMV SAD is at or
below this threshold short-circuits straight to ZEROMV on LAST,
skipping the predictor (NEAREST/NEAR), the NEWMV motion search,
and any GOLDEN-reference evaluation. Saves substantial encoder
CPU on quiet talking-head content and avoids spending NEWMV or
GOLDEN-ref bits on webcam sensor jitter that quantises to zero
anyway. Default 0 keeps existing behaviour byte-identical.
When true, refine the integer-pel motion search result with a
half-pel then quarter-pel diamond search using the sixtap predictor.
Returned MVs remain quarter-pel aligned (even 1/8-pel) so they
round-trip exactly through writeMv.
When true, every inter MB also runs a NEWMV search against the
ALTREF reconstruction. If the refined MV beats the current best
by altrefNewMvSadBias, the MB switches to NEWMV-from-ALTREF.
Mirrors tryGoldenNewMv.
When true, every inter MB also evaluates ZEROMV against the
ALTREF reconstruction. If the ALTREF-zero SAD plus altrefSadBias
beats the LAST-relative best, the MB's reference is switched to
ALTREF (still ZEROMV, no MV bits spent). Lets a stale ALTREF
rescue MBs whose LAST/GOLDEN content has drifted.
When true, each inter MB additionally runs the NEWMV integer +
sub-pel motion search against the GOLDEN reference, in addition
to the LAST-relative search. Lets MBs use real motion to track
content that re-enters from behind an occlusion or that the
short-term LAST reference no longer matches. Default false keeps
existing behaviour byte-identical.
When true, each inter MB additionally evaluates ZEROMV against
the GOLDEN reference and may pick it over the refLast-based
best candidate. Lets MBs whose LAST-relative SAD has drifted (an
occlusion just ended, a packet-loss artifact still lives in LAST,
etc.) fall back to the cleaner long-term reference. Only the
ZEROMV mode is considered against GOLDEN — no MV bits are spent,
just the extra ref-frame bit. Pairs with goldenRefreshPeriod.
Default false keeps existing behaviour byte-identical.
When true, integer-pel motion search uses a diamond pattern
(large + small diamond) instead of the default full-window SAD
scan. Trades a small compression cost (typically <2% bytes on VC
content with searchRange<=4) for an order-of-magnitude
reduction in SAD evaluations at large search ranges. The seed
MV (when predictorMotionSearch is on) is still evaluated, so
the result is no worse than the trivial predictor pick. Default
false keeps the bitstream byte-identical to the baseline
full-search encoder.
When true, the integer motion search scores each candidate by
SAD + ((sadPerBit16 * mvBitCost(mv, defaultMvContext)) >> 8) --
the libvpx Lagrangian rate-distortion formula, where sadPerBit16
is derived from the current base qi via computeRdConsts and
mvBitCost is the exact theoretical entropy cost of writing the
candidate MV under the default MV probs. When this is true,
mvRateBias is ignored by the search.
When true, the LAST-ref per-MB mode pick replaces the four
hand-tuned *SadBias constants with (sadPerBit16 * R) >> 8
where R = mvRefModeBitCost(modeToken, mvRefProbs) (+ mvBitCost
for NEWMV). mvRefProbs is derived from the findNearMvscnt
when predictorMotionSearch is on, else from the all-zeros default
context row. Default false keeps existing behaviour byte-identical.
When true, the keyframe per-MB intra-mode picker replaces the
hand-tuned _yModeBias/_uvModeBias arrays in
intra_mode_select.dart with per-mode Lagrangian biases
(sadPerBit16 * kfModeBitCost(probs, mode)) >> 8 derived from the
active kfYModeProb/kfUvModeProb tables. Requires useMvRateCost
(otherwise sadPerBit16 is 0 and the picker is a no-op). Default
false keeps existing behaviour byte-identical.
Rescind a pending requestKeyframe. No-op if no request is
pending. Useful when an ABR driver wants to back out a previously
queued keyframe (e.g. the receiver re-synced before the next
encodeFrame call).
Convenience wrapper around encodeFrame for tightly-packed I420
(a.k.a. YUV 4:2:0 planar). The input must contain exactly
width*height + 2*(width/2)*(height/2) == width*height*3/2
bytes laid out as Y plane, then U plane, then V plane. Y stride
is taken as width; UV stride as width/2. Throws
ArgumentError on a wrong-sized buffer.
Convenience wrapper around encodeFrame for NV12 input (Y plane
followed by an interleaved UV plane: U0 V0 U1 V1 ...). yPlane
must be width*height bytes; uvInterleaved must be
2*(width/2)*(height/2) == width*(height/2) bytes. Internally
de-interleaves UV into two planar Uint8Lists before calling
encodeFrame with the canonical strides. Throws ArgumentError
on a wrong-sized buffer.
External feedback hook: force an ALTREF refresh on the next
inter frame, regardless of altrefRefreshPeriod /
refreshAltrefOnInter. The request is consumed on the next
encoded frame (a keyframe also clears it). Use this when the
receiver reports the long-term anchor is unusable.
External feedback hook: force a GOLDEN refresh on the next inter
frame, regardless of goldenRefreshPeriod / refreshGoldenOnInter.
The request is consumed on the next encoded frame (a keyframe
also clears it, since keyframes always re-seed GOLDEN). Typical
use: the receiver reported corruption of its long-term reference
and the sender wants a fresh golden snapshot ASAP without paying
for a full keyframe.
External feedback hook (e.g. RTCP PLI/FIR from a remote receiver):
promote the next encodeFrame call to a keyframe even if the
regular keyframeInterval / scene-cut / drop-recovery triggers
would not have fired. The request is consumed on the next call.
Calling this between frames is idempotent.
Reset all in-flight encoder state: reference frames, framesSinceKey
counter, pending KF/GOLDEN/ALTREF requests, and the cached
lastFrameStats. The next encodeFrame call will produce a
keyframe regardless of keyframeInterval. The configured
rate controller (if any) is NOT touched — reset it separately
if you need a fresh leaky-bucket state. Useful when rebinding to
a new peer or restarting a session without rebuilding the
encoder object.
Clear cumulativeStats without touching reference frames,
pending requests, framesSinceKey, or the rate controller.
Use this to start a fresh telemetry window (e.g. one stats
row per second of streaming) without disturbing the in-flight
encode state.
Replace the static base qi at runtime. Takes effect on the
next encodeFrame call that does not pass a qiOverride and
has no rate controller. v must be in [0, 127]. Note that
the active minQi / maxQi clamps still apply.
Replace cyclicRefreshPercent at runtime. Takes effect on the
next inter frame. v must be in [0, 100]. The internal raster
cursor is preserved, so the refresh pattern continues from where
it was -- raising the percentage just enlarges the per-frame
stripe; lowering it shrinks it; setting 0 stops cyclic refresh
without disturbing the cursor.
Replace keyframeInterval at runtime. Must be >= 1 and must
remain >= minKeyframeInterval. Takes effect on the next
encodeFrame call; the in-flight framesSinceKey counter is
not touched.