denoiseY method

Uint8List denoiseY({
  1. required int width,
  2. required int height,
  3. required Uint8List srcY,
  4. required int srcYStride,
  5. required RefFrame prevRef,
})

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;
}