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