Vp8Encoder class

Constructors

Vp8Encoder({required int width, required int height, int qi = 24, int keyframeInterval = 30, int minKeyframeInterval = 0, int searchRange = 4, int filterLevel = 0, int sharpness = 0, int filterType = 1, int zeroMvSadBias = 64, bool mbNoCoeffSkip = false, int probSkipFalse = 240, bool refreshGoldenOnInter = true, bool refreshAltrefOnInter = true, bool subPelRefine = true, bool predictorMotionSearch = true, bool useDiamondMotionSearch = false, int nearestSadBias = 16, int nearSadBias = 24, int newMvSadBias = 64, CbrRateController? rateController, int cyclicRefreshPercent = 0, TemporalDenoiser? denoiser, int log2NumTokenPartitions = 0, bool autoLoopFilter = false, int autoLoopFilterMin = 0, int autoLoopFilterMax = 63, int forceKeyAfterConsecutiveDrops = 0, double? sceneCutMeanAbsDiff, ({int height, int width, int x, int y})? roiRect, int roiQiDelta = -16, int mvRateBias = 0, int goldenRefreshPeriod = 0, bool tryGoldenZeroMv = false, int goldenSadBias = 32, bool tryGoldenNewMv = false, int goldenNewMvSadBias = 96, bool activityAq = false, int aqSmoothVarThreshold = 64, int aqTexturedVarThreshold = 1024, int aqSmoothQiDelta = -8, int aqTexturedQiDelta = 4, int staticMbSadThreshold = 0, int altrefRefreshPeriod = 0, bool tryAltrefZeroMv = false, int altrefSadBias = 48, bool tryAltrefNewMv = false, int altrefNewMvSadBias = 96, void onFrameEncoded(Vp8FrameStats stats)?, void onFrameDropped()?, int rollingWindowFrames = 0, int minQi = 0, int maxQi = 127, bool useMvRateCost = false, bool useRdInterMode = false, bool useRdIntraMode = false})

Properties

activityAq → bool
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.
final
altrefNewMvSadBias → int
Tie-breaker bias added to the ALTREF-relative NEWMV SAD before comparing against the current best.
final
altrefRefreshPeriod → int
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.
no setter
altrefSadBias → int
Tie-breaker bias added to ALTREF-relative ZEROMV SAD before comparing against the best LAST-relative pick. Larger values favour staying on LAST.
final
aqSmoothQiDelta → int
Per-MB qi delta applied to "smooth" MBs when activityAq is true. Negative = higher quality. Must lie in -127, 127.
final
aqSmoothVarThreshold → int
Variance ceiling below which a MB is classified as "smooth" (segment 2) when activityAq is true.
final
aqTexturedQiDelta → int
Per-MB qi delta applied to "textured" MBs when activityAq is true. Positive = coarser quant (bit savings). Must lie in -127, 127.
final
aqTexturedVarThreshold → int
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.
final
autoLoopFilter → bool
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.
final
autoLoopFilterMax → int
Upper clamp applied to deriveLoopFilterLevel when autoLoopFilter is true.
final
autoLoopFilterMin → int
Lower clamp applied to deriveLoopFilterLevel when autoLoopFilter is true.
final
cumulativeStats → Vp8CumulativeStats
Lifetime-cumulative telemetry across every non-dropped frame (plus a droppedFrames count). Cleared by reset.
no setter
cyclicRefreshPercent → int
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.
no setter
denoiser → TemporalDenoiser?
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).
final
filterLevel → int
final
filterType → int
final
forceKeyAfterConsecutiveDrops → int
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).
final
framesSinceKey → int
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.
no setter
goldenNewMvSadBias → int
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.
final
goldenRefreshPeriod → int
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.
no setter
goldenSadBias → int
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.
final
hashCode → int
The hash code for this object.
no setterinherited
hasPendingAltrefRefreshRequest → bool
True iff requestAltrefRefresh has been called and not yet consumed by an emitted frame.
no setter
hasPendingGoldenRefreshRequest → bool
True iff requestGoldenRefresh has been called and not yet consumed by an emitted frame.
no setter
hasPendingKeyframeRequest → bool
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).
no setter
height → int
final
keyframeInterval → int
Number of frames between keyframes (>= 1). Mutable at runtime via setKeyframeInterval.
no setter
lastEncodedFrameBytes → int
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.
no setter
lastFrameStats → Vp8FrameStats?
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).
no setter
log2NumTokenPartitions → int
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.
final
maxQi → int
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.
no setter
mbColumns → int
Number of 16x16 macroblock columns (= width >> 4).
no setter
mbNoCoeffSkip → bool
When true, emits mb_no_coeff_skip = 1 and per-MB skip bits so MBs whose residual quantises to all zero spend no token bits.
final
mbRows → int
Number of 16x16 macroblock rows (= height >> 4).
no setter
mbsPerFrame → int
Total number of macroblocks per frame (= mbColumns * mbRows). Equals Vp8FrameStats.totalMbCount for any frame this encoder emits.
no setter
minKeyframeInterval → int
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.
no setter
minQi → int
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.
no setter
mvRateBias → int
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.
final
nearestSadBias → int
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).
final
nearSadBias → int
Same as nearestSadBias but for NEARMV (one more mode bit than NEAREST, so a slightly larger bias).
final
newMvSadBias → int
SAD margin by which NEWMV must beat ZEROMV to be preferred. NEWMV writes mode bits + a full MV delta, so this is larger than the NEAREST/NEAR biases.
final
onFrameDropped → void Function()?
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.
no setter
onFrameEncoded → void Function(Vp8FrameStats stats)?
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.
no setter
predictorMotionSearch → bool
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.
final
probSkipFalse → int
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.
final
qi → int
Static base quantizer index (0..127) used when no Vp8Encoder.rateController is configured and no qiOverride is supplied to encodeFrame. Mutable at runtime via setBaseQi.
no setter
rateController → CbrRateController?
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(...).
final
refreshAltrefOnInter → bool
Same as refreshGoldenOnInter but for the ALTREF slot. Mutable at runtime via setRefreshAltrefOnInter.
no setter
refreshGoldenOnInter → bool
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.
no setter
roiQiDelta → int
Per-MB qi delta applied to MBs inside roiRect. Negative = higher quality. Ignored when roiRect is null.
final
roiRect → ({int height, int width, int x, int y})?
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.
final
rollingWindowFrames → int
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.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
sceneCutMeanAbsDiff → double?
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.
no setter
searchRange → int
final
sharpness → int
final
staticMbSadThreshold → int
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.
final
subPelRefine → bool
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.
final
tryAltrefNewMv → bool
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.
final
tryAltrefZeroMv → bool
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.
final
tryGoldenNewMv → bool
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.
final
tryGoldenZeroMv → bool
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.
final
useDiamondMotionSearch → bool
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.
final
useMvRateCost → bool
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.
final
useRdInterMode → bool
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 findNearMvs cnt when predictorMotionSearch is on, else from the all-zeros default context row. Default false keeps existing behaviour byte-identical.
final
useRdIntraMode → bool
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.
final
width → int
final
zeroMvSadBias → int
SAD margin by which a non-zero MV must beat zero-MV to be chosen. Crude proxy for the rate cost of encoding an explicit delta.
final

Methods

clearPendingAltrefRefreshRequest() → void
Rescind a pending requestAltrefRefresh. No-op if no request is pending.
clearPendingGoldenRefreshRequest() → void
Rescind a pending requestGoldenRefresh. No-op if no request is pending.
clearPendingKeyframeRequest() → void
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).
encodeFrame({required Uint8List srcY, required Uint8List srcU, required Uint8List srcV, required int srcYStride, required int srcUvStride, bool? forceKey, int? qiOverride}) → EncodedVp8Frame
encodeI420Frame(Uint8List i420, {bool? forceKey, int? qiOverride}) → EncodedVp8Frame
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.
encodeNv12Frame(Uint8List yPlane, Uint8List uvInterleaved, {bool? forceKey, int? qiOverride}) → EncodedVp8Frame
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.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
requestAltrefRefresh() → void
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.
requestGoldenRefresh() → void
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.
requestKeyframe() → void
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() → void
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.
resetCumulativeStats() → void
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.
setAltrefRefreshPeriod(int v) → void
Replace altrefRefreshPeriod at runtime. Takes effect on the next inter frame. v must be >= 0 (0 falls back to the static refreshAltrefOnInter flag). Does NOT immediately refresh ALTREF -- use requestAltrefRefresh for that.
setBaseQi(int v) → void
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.
setCyclicRefreshPercent(int v) → void
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.
setGoldenRefreshPeriod(int v) → void
Replace goldenRefreshPeriod at runtime. Takes effect on the next inter frame. v must be >= 0 (0 falls back to the static refreshGoldenOnInter flag). Does NOT immediately refresh GOLDEN -- use requestGoldenRefresh for that.
setKeyframeInterval(int v) → void
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.
setMinKeyframeInterval(int v) → void
Replace minKeyframeInterval at runtime. Must be >= 0 and must remain <= keyframeInterval.
setOnFrameDropped(void cb()?) → void
Replace onFrameDropped at runtime. Pass null to unwire the callback. Takes effect on the next dropped frame.
setOnFrameEncoded(void cb(Vp8FrameStats stats)?) → void
Replace onFrameEncoded at runtime. Pass null to unwire the callback. Takes effect on the next encoded frame.
setQiClamps({required int minQi, required int maxQi}) → void
Replace minQi / maxQi at runtime. Same validation as the ctor (0 <= minQi <= maxQi <= 127). Takes effect on the next encodeFrame call.
setRefreshAltrefOnInter(bool v) → void
Replace refreshAltrefOnInter at runtime. Takes effect on the next inter frame. Only consulted when altrefRefreshPeriod is 0.
setRefreshGoldenOnInter(bool v) → void
Replace refreshGoldenOnInter at runtime. Takes effect on the next inter frame. Only consulted when goldenRefreshPeriod is 0.
setSceneCutMeanAbsDiff(double? v) → void
Replace sceneCutMeanAbsDiff at runtime. Pass null to disable scene-cut detection; pass a positive double to set a new threshold.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited