diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterContext.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterContext.cs
index 91b036ff6..fbc79ae5d 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterContext.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterContext.cs
@@ -3,6 +3,9 @@
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.LoopFilter;
+///
+/// Defines the per-frame state boundary used while applying the AV1 deblocking loop filter.
+///
internal class Av1LoopFilterContext
{
}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterDecoder.cs
index bf0c83c95..1a05902de 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterDecoder.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterDecoder.cs
@@ -6,14 +6,43 @@ using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.LoopFilter;
+///
+/// Provides frame traversal for the AV1 in-loop deblocking stage.
+///
internal class Av1LoopFilterDecoder
{
+ ///
+ /// The sequence-level superblock configuration.
+ ///
private readonly ObuSequenceHeader sequenceHeader;
+
+ ///
+ /// The frame dimensions and loop-filter parameters.
+ ///
private readonly ObuFrameHeader frameHeader;
+
+ ///
+ /// The decoded block-mode information addressed by superblock origin.
+ ///
private readonly Av1FrameInfo frameInfo;
+
+ ///
+ /// The reconstructed plane samples supplied to in-loop filtering.
+ ///
private readonly Av1FrameBuffer frameBuffer;
+
+ ///
+ /// The per-frame filter context retained across superblocks.
+ ///
private readonly Av1LoopFilterContext loopFilterContext;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The sequence header that supplies the superblock size.
+ /// The frame header that supplies dimensions and filter parameters.
+ /// The decoded block-mode information for the frame.
+ /// The reconstructed frame samples to filter.
public Av1LoopFilterDecoder(ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, Av1FrameInfo frameInfo, Av1FrameBuffer frameBuffer)
{
this.sequenceHeader = sequenceHeader;
@@ -23,6 +52,11 @@ internal class Av1LoopFilterDecoder
this.loopFilterContext = new();
}
+ ///
+ /// Traverses each superblock in raster order when loop filtering is enabled for the decode pass.
+ ///
+ /// Whether the frame should run the deblocking stage.
+ /// The superblock filtering operation has not been implemented.
public void DecodeFrame(bool doLoopFilterFlag)
{
Guard.NotNull(this.sequenceHeader);
@@ -38,7 +72,8 @@ internal class Av1LoopFilterDecoder
int frameWidthInSuperblocks = Av1Math.DivideLog2Ceiling(this.frameHeader.FrameSize.FrameWidth, this.sequenceHeader.SuperblockSizeLog2);
int frameHeightInSuperblocks = Av1Math.DivideLog2Ceiling(this.frameHeader.FrameSize.FrameHeight, this.sequenceHeader.SuperblockSizeLog2);
- // Loop over a frame : tregger dec_loop_filter_sb for each SB
+ // Filtering proceeds in raster order because vertical and horizontal edges depend on already reconstructed
+ // neighboring blocks, while the final superblock in each row requires distinct delayed-edge handling.
for (int superblockIndexY = 0; superblockIndexY < frameHeightInSuperblocks; ++superblockIndexY)
{
for (int superblockIndexX = 0; superblockIndexX < frameWidthInSuperblocks; ++superblockIndexX)
@@ -49,9 +84,10 @@ internal class Av1LoopFilterDecoder
Point superblockPoint = new(superblockOriginX, superblockOriginY);
Av1SuperblockInfo superblockInfo = this.frameInfo.GetSuperblock(superblockPoint);
+
+ // Mode-info coordinates are measured in 4x4 units, whereas the frame and superblock origins are pixels.
Point superblockOriginInModeInfo = new(superblockOriginX >> 2, superblockOriginY >> 2);
- // LF function for a SB
this.DecodeForSuperblock(
superblockInfo,
superblockOriginInModeInfo,
@@ -63,6 +99,16 @@ internal class Av1LoopFilterDecoder
}
}
+ ///
+ /// Represents the not-yet-implemented deblocking operation for one superblock and plane range.
+ ///
+ /// The decoded modes and delta values for the superblock.
+ /// The superblock origin in 4x4 mode-info units.
+ /// The first color plane to filter.
+ /// The exclusive color-plane index at which filtering stops.
+ /// Whether the superblock is the final block in its raster row.
+ /// The per-superblock loop-filter strength adjustments.
+ /// Always thrown because superblock deblocking has not been implemented.
private void DecodeForSuperblock(Av1SuperblockInfo superblockInfo, Point modeInfoLocation, Av1Plane startPlane, int endPlane, bool endOfRowFlag, Span superblockDeltaLoopFilter)
=> throw new NotImplementedException();
}