Browse Source

TransformInfo retrieval changes

pull/2633/head
Ynse Hoornenborg 2 years ago
parent
commit
a6a32d4095
  1. 3
      src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs
  2. 2
      src/ImageSharp/Formats/Heif/Av1/Av1BlockSizeExtensions.cs
  3. 39
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameBuffer.cs
  4. 4
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockInfo.cs
  5. 35
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs

3
src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs

@ -72,7 +72,8 @@ internal enum Av1BlockSize : byte
/// <summary>A block of samples, 64 samples wide and 16 samples high.</summary>
Block64x16 = 21,
Invalid = 22,
SizesAll = 22,
SizeS = Block4x16,
Invalid = 255,
Largest = SizeS - 1,
}

2
src/ImageSharp/Formats/Heif/Av1/Av1BlockSizeExtensions.cs

@ -104,7 +104,7 @@ internal static class Av1BlockSizeExtensions
{
Av1BlockSize planeBlockSize = blockSize.GetSubsampled(subX, subY);
Av1TransformSize uvTransformSize = Av1TransformSize.Invalid;
if (planeBlockSize < Av1BlockSize.SizeS)
if (planeBlockSize < Av1BlockSize.SizesAll)
{
uvTransformSize = planeBlockSize.GetMaximumTransformSize();
}

39
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameBuffer.cs

@ -105,35 +105,20 @@ internal partial class Av1FrameBuffer
return this.modeInfos[index];
}
public ref Av1TransformInfo GetTransformY(int index)
public Span<Av1TransformInfo> GetSuperblockTransformY(Point index)
{
Span<Av1TransformInfo> span = this.transformInfosY;
return ref span[index];
int offset = ((index.Y * this.superblockColumnCount) + index.X) * this.modeInfoCountPerSuperblock;
int length = this.modeInfoCountPerSuperblock;
return span.Slice(offset, length);
}
public void SetTransformY(int index, Av1TransformInfo transformInfo)
{
Span<Av1TransformInfo> span = this.transformInfosY;
span[index] = transformInfo;
}
public ref Av1TransformInfo GetTransformY(Point index)
{
Span<Av1TransformInfo> span = this.transformInfosY;
int i = (index.Y * this.superblockColumnCount) + index.X;
return ref span[i * this.modeInfoCountPerSuperblock];
}
public ref Av1TransformInfo GetTransformUv(int index)
public Span<Av1TransformInfo> GetSuperblockTransformUv(Point index)
{
Span<Av1TransformInfo> span = this.transformInfosUv;
return ref span[index];
}
public void SetTransformUv(int index, Av1TransformInfo transformInfo)
{
Span<Av1TransformInfo> span = this.transformInfosUv;
span[index] = transformInfo;
int offset = (((index.Y * this.superblockColumnCount) + index.X) * this.modeInfoCountPerSuperblock) << 1;
int length = this.modeInfoCountPerSuperblock << 1;
return span.Slice(offset, length);
}
public Span<int> GetCoefficients(int plane) =>
@ -198,14 +183,6 @@ internal partial class Av1FrameBuffer
public void ClearDeltaLoopFilter() => Array.Fill(this.deltaLoopFilter, 0);
public Av1TransformInfo? GetTransform(int plane, int transformInfoIndex) =>
plane switch
{
0 => this.GetTransformY(transformInfoIndex),
1 or 2 => this.GetTransformUv(transformInfoIndex),
_ => null,
};
public void UpdateModeInfo(Av1BlockModeInfo modeInfo, Av1SuperblockInfo superblockInfo)
{
this.modeInfos[this.modeInfoMap.NextIndex] = modeInfo;

4
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockInfo.cs

@ -36,5 +36,9 @@ internal class Av1SuperblockInfo
public int TransformInfoIndexUv { get; internal set; }
public Span<Av1TransformInfo> GetTransformInfoY() => this.frameBuffer.GetSuperblockTransformY(this.Position);
public Span<Av1TransformInfo> GetTransformInfoUv() => this.frameBuffer.GetSuperblockTransformUv(this.Position);
public Av1BlockModeInfo GetModeInfo(Point index) => this.frameBuffer.GetModeInfo(this.Position, index);
}

35
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs

@ -373,6 +373,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
bool isLosslessBlock = isLossless && (blockSize >= Av1BlockSize.Block64x64) && (blockSize <= Av1BlockSize.Block128x128);
int subSampling = (this.SequenceHeader.ColorConfig.SubSamplingX ? 1 : 0) + (this.SequenceHeader.ColorConfig.SubSamplingY ? 1 : 0);
int chromaTusCount = isLosslessBlock ? ((maxBlocksWide * maxBlocksHigh) >> subSampling) : partitionInfo.ModeInfo.TransformUnitsCount[(int)Av1PlaneType.Uv];
int[] transformInfoIndices = new int[3];
transformInfoIndices[0] = superblockInfo.TransformInfoIndexY + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Y];
transformInfoIndices[1] = superblockInfo.TransformInfoIndexUv + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv];
@ -409,16 +410,20 @@ internal class Av1TileDecoder : IAv1TileDecoder
tusCount = this.tusCount[plane][forceSplitCount];
DebugGuard.IsFalse(totalTusCount == 0, nameof(totalTusCount), string.Empty);
DebugGuard.IsTrue(totalTusCount == this.tusCount[plane][0] + this.tusCount[plane][1] + this.tusCount[plane][2] + this.tusCount[plane][3], nameof(totalTusCount), string.Empty);
// DebugGuard.IsTrue(totalTusCount == this.tusCount[plane][0] + this.tusCount[plane][1] + this.tusCount[plane][2] + this.tusCount[plane][3], nameof(totalTusCount), string.Empty);
}
DebugGuard.IsFalse(tusCount == 0, nameof(tusCount), string.Empty);
Span<Av1TransformInfo> transformInfos = plane == 0 ? superblockInfo.GetTransformInfoY() : superblockInfo.GetTransformInfoUv();
for (int tu = 0; tu < tusCount; tu++)
{
Av1TransformInfo transformInfo = transformInfos[transformInfoIndices[plane]];
DebugGuard.MustBeLessThanOrEqualTo(transformInfo.OffsetX, maxBlocksWide, nameof(transformInfo));
DebugGuard.MustBeLessThanOrEqualTo(transformInfo.OffsetY, maxBlocksHigh, nameof(transformInfo));
int coefficientIndex = this.coefficientIndex[plane];
int endOfBlock = 0;
Av1TransformInfo transformInfo = this.FrameBuffer.GetTransform(plane, transformInfoIndices[plane])!;
int blockColumn = transformInfo.OffsetX;
int blockRow = transformInfo.OffsetY;
int startX = (partitionInfo.ColumnIndex >> subX) + blockColumn;
@ -432,12 +437,12 @@ internal class Av1TileDecoder : IAv1TileDecoder
if (!partitionInfo.ModeInfo.Skip)
{
endOfBlock = this.TransformBlock(ref reader, partitionInfo, coefficientIndex, transformInfo, plane, blockColumn, blockRow, startX, startY, transformInfo.Size, subX != 0, subY != 0);
endOfBlock = this.ParseTransformBlock(ref reader, partitionInfo, coefficientIndex, transformInfo, plane, blockColumn, blockRow, startX, startY, transformInfo.Size, subX != 0, subY != 0);
}
if (endOfBlock != 0)
{
this.coefficientIndex[plane] += 2;
this.coefficientIndex[plane] += endOfBlock + 1;
transformInfo.CodeBlockFlag = true;
}
else
@ -487,7 +492,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
/// <remarks>
/// The implementation is taken from SVT-AV1 library, which deviates from the code flow in the specification.
/// </remarks>
private int TransformBlock(
private int ParseTransformBlock(
ref Av1SymbolDecoder reader,
Av1PartitionInfo partitionInfo,
int coefficientIndex,
@ -1279,10 +1284,10 @@ internal class Av1TileDecoder : IAv1TileDecoder
private unsafe void UpdateTransformInfo(Av1PartitionInfo partitionInfo, Av1SuperblockInfo superblockInfo, Av1BlockSize blockSize, Av1TransformSize transformSize)
{
int transformInfoYIndex = superblockInfo.TransformInfoIndexY + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Y];
int transformInfoUvIndex = superblockInfo.TransformInfoIndexUv + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv];
Av1TransformInfo lumaTransformInfo = this.FrameBuffer.GetTransformY(transformInfoYIndex);
Av1TransformInfo chromaTransformInfo = this.FrameBuffer.GetTransformUv(transformInfoUvIndex);
int transformInfoYIndex = partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Y];
int transformInfoUvIndex = partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv];
Span<Av1TransformInfo> lumaTransformInfo = superblockInfo.GetTransformInfoY();
Span<Av1TransformInfo> chromaTransformInfo = superblockInfo.GetTransformInfoUv();
int totalLumaTusCount = 0;
int totalChromaTusCount = 0;
int forceSplitCount = 0;
@ -1315,8 +1320,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
{
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
{
this.FrameBuffer.SetTransformY(transformInfoYIndex, new Av1TransformInfo(
transformSize, blockColumn, blockRow));
lumaTransformInfo[transformInfoYIndex] = new Av1TransformInfo(
transformSize, blockColumn, blockRow);
transformInfoYIndex++;
lumaTusCount++;
totalLumaTusCount++;
@ -1340,8 +1345,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
{
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
{
this.FrameBuffer.SetTransformUv(transformInfoUvIndex, new Av1TransformInfo(
transformSizeUv, blockColumn, blockRow));
chromaTransformInfo[transformInfoUvIndex] = new Av1TransformInfo(
transformSizeUv, blockColumn, blockRow);
transformInfoUvIndex++;
chromaTusCount++;
totalChromaTusCount++;
@ -1359,7 +1364,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
int originalIndex = transformInfoUvIndex - totalChromaTusCount;
for (int i = 0; i < totalChromaTusCount; i++)
{
this.FrameBuffer.SetTransformUv(transformInfoUvIndex + i, this.FrameBuffer.GetTransformUv(originalIndex + i));
chromaTransformInfo[transformInfoUvIndex + i] = chromaTransformInfo[originalIndex + i];
}
}

Loading…
Cancel
Save