From 5792d05063faa19109c88c1010fec18f3ecce58e Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Tue, 2 Jul 2024 19:37:22 +0200 Subject: [PATCH] Annotate Av1TileDecoder methods with spec sections --- .../Av1/OpenBitstreamUnit/ObuFrameHeader.cs | 5 ++ .../Heif/Av1/OpenBitstreamUnit/ObuReader.cs | 15 +++++- .../Formats/Heif/Av1/Tiling/Av1TileDecoder.cs | 51 +++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameHeader.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameHeader.cs index b145a7a846..a107562637 100644 --- a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameHeader.cs +++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameHeader.cs @@ -73,6 +73,8 @@ internal class ObuFrameHeader internal uint FrameToShowMapIdx { get; set; } + internal uint DisplayFrameId { get; set; } + internal bool ErrorResilientMode { get; set; } internal bool AllowScreenContentTools { get; set; } @@ -88,4 +90,7 @@ internal class ObuFrameHeader internal uint PrimaryReferenceFrame { get; set; } = Av1Constants.PrimaryReferenceFrameNone; internal uint RefreshFrameFlags { get; set; } + + // 5.9.31. Temporal point info syntax + internal uint FramePresentationTime { get; set; } } diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs index 9c2d791060..4736f92342 100644 --- a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs +++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs @@ -894,7 +894,20 @@ internal class ObuReader frameInfo.FrameToShowMapIdx = reader.ReadLiteral(3); } - // TODO: There is still some parts not implemented here + if (sequenceHeader.DecoderModelInfoPresentFlag && sequenceHeader.TimingInfo?.EqualPictureInterval == false) + { + // 5.9.31. Temporal point info syntax. + frameInfo.FramePresentationTime = reader.ReadLiteral((int)sequenceHeader!.DecoderModelInfo!.FramePresentationTimeLength); + } + + int refreshFrameFlags = 0; + if (sequenceHeader.IsFrameIdNumbersPresent) + { + frameInfo.DisplayFrameId = reader.ReadLiteral(idLength); + } + + // TODO: This is incomplete here, not sure how we can display an already decoded frame here. + throw new NotImplementedException("ShowExistingFrame is not yet implemented"); } if (frameInfo.FrameType == ObuFrameType.KeyFrame && frameInfo.ShowFrame) diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs index 685d1d6b8d..ea0af6ce9b 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs @@ -116,6 +116,9 @@ internal class Av1TileDecoder : IAv1TileDecoder private void ClearLoopFilterDelta() => this.FrameBuffer.ClearDeltaLoopFilter(); + /// + /// 5.11.3. Clear block decoded flags function. + /// private void ClearBlockDecodedFlags(int row, int column, int superBlock4x4Size) { int planesCount = this.SequenceHeader.ColorConfig.ChannelCount; @@ -175,6 +178,9 @@ internal class Av1TileDecoder : IAv1TileDecoder // TODO: Implement } + /// + /// 5.11.4. Decode partition syntax. + /// private void ParsePartition(ref Av1SymbolDecoder reader, Point modeInfoLocation, Av1BlockSize blockSize, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo) { int columnIndex = modeInfoLocation.X; @@ -378,6 +384,9 @@ internal class Av1TileDecoder : IAv1TileDecoder } } + /// + /// 5.11.34. Residual syntax. + /// private void Residual(int rowIndex, int columnIndex, Av1BlockSize blockSize) { bool subsamplingX = this.SequenceHeader.ColorConfig.SubSamplingX; @@ -437,6 +446,9 @@ internal class Av1TileDecoder : IAv1TileDecoder private Av1BlockSize GetPlaneResidualSize(Av1BlockSize sizeChunk, int plane) => throw new NotImplementedException(); + /// + /// 5.11.35. Transform block syntax. + /// private void TransformBlock(int plane, int baseX, int baseY, Av1TransformSize transformSize, int x, int y) { Av1PartitionInfo partitionInfo = new(new(1, Av1BlockSize.Invalid, new Point(0, 0)), new(this.FrameBuffer, default), false, Av1PartitionType.None); @@ -522,10 +534,16 @@ internal class Av1TileDecoder : IAv1TileDecoder private void PredictChromaFromLuma(int plane, int startX, int startY, Av1TransformSize transformSize) => throw new NotImplementedException(); + /// + /// 7.11.2. Intra prediction process. + /// private void PredictIntra(int plane, int startX, int startY, bool leftAvailable, bool upAvailable, bool haveAboveRight, bool haveBelowLeft, Av1PredictionMode mode, int log2Width, int log2Height) => throw new NotImplementedException(); private void PredictPalette(int plane, int startX, int startY, int x, int y, Av1TransformSize transformSize) => throw new NotImplementedException(); + /// + /// Page 65, below 5.11.5. Decode block syntax. + /// private void ResetBlockContext(int rowIndex, int columnIndex, Av1BlockSize blockSize) { int block4x4Width = blockSize.Get4x4WideCount(); @@ -552,6 +570,9 @@ internal class Av1TileDecoder : IAv1TileDecoder } } + /// + /// 5.11.16. Block TX size syntax. + /// private static void ReadBlockTransformSize(ref Av1SymbolDecoder reader, int rowIndex, int columnIndex, Av1BlockSize blockSize) { int block4x4Width = blockSize.Get4x4WideCount(); @@ -568,6 +589,9 @@ internal class Av1TileDecoder : IAv1TileDecoder }*/ } + /// + /// 5.11.49. Palette tokens syntax. + /// private static void ReadPaletteTokens(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo) { reader.ReadLiteral(-1); @@ -584,12 +608,18 @@ internal class Av1TileDecoder : IAv1TileDecoder } } + /// + /// 5.11.6. Mode info syntax. + /// private void ReadModeInfo(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo) { DebugGuard.IsTrue(this.FrameInfo.FrameType is ObuFrameType.KeyFrame or ObuFrameType.IntraOnlyFrame, "Only INTRA frames supported."); this.ReadIntraFrameModeInfo(ref reader, partitionInfo); } + /// + /// 5.11.7. Intra frame mode info syntax. + /// private void ReadIntraFrameModeInfo(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo) { if (this.FrameInfo.SegmentationParameters.SegmentIdPrecedesSkip) @@ -631,6 +661,8 @@ internal class Av1TileDecoder : IAv1TileDecoder { // this.IsInter = false; partitionInfo.ModeInfo.YMode = reader.ReadYMode(partitionInfo.AboveModeInfo, partitionInfo.LeftModeInfo); + + // 5.11.42.Intra angle info luma syntax. partitionInfo.ModeInfo.AngleDelta[(int)Av1PlaneType.Y] = IntraAngleInfo(ref reader, partitionInfo.ModeInfo.YMode, partitionInfo.ModeInfo.BlockSize); if (partitionInfo.IsChroma && !this.SequenceHeader.ColorConfig.IsMonochrome) { @@ -640,6 +672,7 @@ internal class Av1TileDecoder : IAv1TileDecoder this.ReadChromaFromLumaAlphas(ref reader, partitionInfo); } + // 5.11.43.Intra angle info chroma syntax. partitionInfo.ModeInfo.AngleDelta[(int)Av1PlaneType.Uv] = IntraAngleInfo(ref reader, partitionInfo.ModeInfo.UvMode, partitionInfo.ModeInfo.BlockSize); } else @@ -699,16 +732,25 @@ internal class Av1TileDecoder : IAv1TileDecoder } } + /// + /// 5.11.46. Palette mode info syntax. + /// private void PaletteModeInfo(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo) => // TODO: Implement. throw new NotImplementedException(); + /// + /// 5.11.45. Read CFL alphas syntax. + /// private void ReadChromaFromLumaAlphas(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo) => // TODO: Implement. throw new NotImplementedException(); + /// + /// 5.11.42. and 5.11.43. + /// private static int IntraAngleInfo(ref Av1SymbolDecoder reader, Av1PredictionMode mode, Av1BlockSize blockSize) { int angleDelta = 0; @@ -724,6 +766,9 @@ internal class Av1TileDecoder : IAv1TileDecoder private static bool IsDirectionalMode(Av1PredictionMode mode) => mode is >= Av1PredictionMode.Vertical and <= Av1PredictionMode.Directional67Degrees; + /// + /// 5.11.8. Intra segment ID syntax. + /// private void IntraSegmentId(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo) { if (this.FrameInfo.SegmentationParameters.Enabled) @@ -746,6 +791,9 @@ internal class Av1TileDecoder : IAv1TileDecoder } } + /// + /// 5.11.9. Read segment ID syntax. + /// private void ReadSegmentId(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo) { int predictor; @@ -861,6 +909,9 @@ internal class Av1TileDecoder : IAv1TileDecoder } } + /// + /// 5.11.56. Read CDEF syntax. + /// private void ReadCdef(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo) { if (partitionInfo.ModeInfo.Skip || this.FrameInfo.CodedLossless || !this.SequenceHeader.EnableCdef || this.FrameInfo.AllowIntraBlockCopy)