denoiseY method
Build a denoised Y plane the same size / stride as srcY.
srcY must be tightly packed at srcYStride over height rows.
prevRef is the previous frame's bordered reconstruction (the
encoder's _prevLast).
Implementation
Uint8List denoiseY({
required int width,
required int height,
required Uint8List srcY,
required int srcYStride,
required RefFrame prevRef,
}) {
final out = Uint8List(srcY.length);
// Copy the whole source first so any non-MB-aligned border rows /
// columns (the visible region is always MB-aligned here) and any
// tail bytes are preserved exactly.
out.setRange(0, srcY.length, srcY);
final mbCols = width >> 4;
final mbRows = height >> 4;
_totalMbCount = mbCols * mbRows;
var blended = 0;
final refStride = prevRef.yStride;
final refOrigin = prevRef.yOrigin;
final refY = prevRef.y;
for (var mbRow = 0; mbRow < mbRows; mbRow++) {
for (var mbCol = 0; mbCol < mbCols; mbCol++) {
final sad = sad16x16At(
srcY: srcY,
srcYStride: srcYStride,
ref: prevRef,
mbRow: mbRow,
mbCol: mbCol,
);
if (sad > motionThreshold) continue;
// Blend this MB: out = (3*src + prev) >> 2.
final srcOff = mbRow * 16 * srcYStride + mbCol * 16;
final refOff = refOrigin + mbRow * 16 * refStride + mbCol * 16;
for (var r = 0; r < 16; r++) {
final sRow = srcOff + r * srcYStride;
final rRow = refOff + r * refStride;
for (var c = 0; c < 16; c++) {
final s = srcY[sRow + c];
final p = refY[rRow + c];
out[sRow + c] = ((s * 3 + p + 2) >> 2) & 0xff;
}
}
blended += 1;
}
}
_denoisedMbCount = blended;
return out;
}