@ -32,7 +32,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
private readonly int [ ] [ ] segmentIds = [ ] ;
private int deltaLoopFilterResolution = - 1 ;
private readonly bool readDeltas ;
private readonly int [ ] [ ] tus Count ;
private readonly int [ ] [ ] transformUnit Count ;
private readonly int [ ] firstTransformOffset = new int [ 2 ] ;
private readonly int [ ] coefficientIndex = [ ] ;
@ -59,10 +59,10 @@ internal class Av1TileDecoder : IAv1TileDecoder
modeInfoWideColumnCount = Av1Math . AlignPowerOf2 ( modeInfoWideColumnCount , sequenceHeader . SuperblockSizeLog2 - 2 ) ;
this . aboveNeighborContext = new Av1ParseAboveNeighbor4x4Context ( planesCount , modeInfoWideColumnCount ) ;
this . leftNeighborContext = new Av1ParseLeftNeighbor4x4Context ( planesCount , sequenceHeader . SuperblockModeInfoSize ) ;
this . tus Count = new int [ Av1Constants . MaxPlanes ] [ ] ;
this . tus Count [ 0 ] = new int [ this . FrameBuffer . ModeInfoCount ] ;
this . tus Count [ 1 ] = new int [ this . FrameBuffer . ModeInfoCount ] ;
this . tus Count [ 2 ] = new int [ this . FrameBuffer . ModeInfoCount ] ;
this . transformUnit Count = new int [ Av1Constants . MaxPlanes ] [ ] ;
this . transformUnit Count [ 0 ] = new int [ this . FrameBuffer . ModeInfoCount ] ;
this . transformUnit Count [ 1 ] = new int [ this . FrameBuffer . ModeInfoCount ] ;
this . transformUnit Count [ 2 ] = new int [ this . FrameBuffer . ModeInfoCount ] ;
this . coefficientIndex = new int [ Av1Constants . MaxPlanes ] ;
}
@ -372,12 +372,12 @@ internal class Av1TileDecoder : IAv1TileDecoder
bool isLossless = this . FrameInfo . LosslessArray [ partitionInfo . ModeInfo . SegmentId ] ;
bool isLosslessBlock = isLossless & & ( blockSize > = Av1BlockSize . Block64x64 ) & & ( blockSize < = Av1BlockSize . Block128x128 ) ;
int subSampling = ( this . SequenceHeader . ColorConfig . SubSamplingX ? 1 : 0 ) + ( this . SequenceHeader . ColorConfig . SubSamplingY ? 1 : 0 ) ;
int chromaTus Count = isLosslessBlock ? ( ( maxBlocksWide * maxBlocksHigh ) > > subSampling ) : partitionInfo . ModeInfo . TransformUnitsCount [ ( int ) Av1PlaneType . Uv ] ;
int chromaTransformUnit Count = 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 ] ;
transformInfoIndices [ 2 ] = transformInfoIndices [ 1 ] + chromaTus Count ;
transformInfoIndices [ 2 ] = transformInfoIndices [ 1 ] + chromaTransformUnit Count ;
int forceSplitCount = 0 ;
for ( int row = 0 ; row < maxBlocksHigh ; row + = modeUnitBlocksHigh )
@ -386,37 +386,41 @@ internal class Av1TileDecoder : IAv1TileDecoder
{
for ( int plane = 0 ; plane < planeCount ; + + plane )
{
int totalTus Count ;
int tus Count ;
int subX = plane > 0 & & this . SequenceHeader . ColorConfig . SubSamplingX ? 1 : 0 ;
int subY = plane > 0 & & this . SequenceHeader . ColorConfig . SubSamplingY ? 1 : 0 ;
int totalTransformUnit Count ;
int transformUnit Count ;
int subX = ( plane > 0 & & this . SequenceHeader . ColorConfig . SubSamplingX ) ? 1 : 0 ;
int subY = ( plane > 0 & & this . SequenceHeader . ColorConfig . SubSamplingY ) ? 1 : 0 ;
if ( plane ! = 0 & & ! partitionInfo . IsChroma )
{
continue ;
}
Span < Av1TransformInfo > transformInfos = plane = = 0 ? superblockInfo . GetTransformInfoY ( ) : superblockInfo . GetTransformInfoUv ( ) ;
if ( isLosslessBlock )
{
// TODO: Implement.
int unitHeight = Av1Math . RoundPowerOf2 ( Math . Min ( modeUnitBlocksHigh + row , maxBlocksHigh ) , 0 ) ;
int unitWidth = Av1Math . RoundPowerOf2 ( Math . Min ( modeUnitBlocksWide + column , maxBlocksWide ) , 0 ) ;
totalTusCount = 0 ;
tus Count = ( ( unitWidth - column ) * ( unitHeight - row ) ) > > ( subX + subY ) ;
DebugGuard . IsTrue ( transformInfos [ transformInfoIndices [ plane ] ] . Size = = Av1TransformSize . Size4x4 , "Lossless frame shall have transform units of size 4x4." ) ;
transformUnit Count = ( ( unitWidth - column ) * ( unitHeight - row ) ) > > ( subX + subY ) ;
}
else
{
totalTusCount = partitionInfo . ModeInfo . TransformUnitsCount [ Math . Min ( 1 , plane ) ] ;
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);
totalTransformUnitCount = partitionInfo . ModeInfo . TransformUnitsCount [ Math . Min ( 1 , plane ) ] ;
transformUnitCount = this . transformUnitCount [ plane ] [ forceSplitCount ] ;
DebugGuard . IsFalse ( totalTransformUnitCount = = 0 , nameof ( totalTransformUnitCount ) , string . Empty ) ;
DebugGuard . IsTrue (
totalTransformUnitCount = =
this . transformUnitCount [ plane ] [ 0 ] + this . transformUnitCount [ plane ] [ 1 ] +
this . transformUnitCount [ plane ] [ 2 ] + this . transformUnitCount [ plane ] [ 3 ] ,
nameof ( totalTransformUnitCount ) ,
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 + + )
DebugGuard . IsFalse ( transformUnitCount = = 0 , nameof ( transformUnitCount ) , string . Empty ) ;
for ( int tu = 0 ; tu < transformUnitCount ; tu + + )
{
Av1TransformInfo transformInfo = transformInfos [ transformInfoIndices [ plane ] ] ;
DebugGuard . MustBeLessThanOrEqualTo ( transformInfo . OffsetX , maxBlocksWide , nameof ( transformInfo ) ) ;
@ -1288,8 +1292,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
int transformInfoUvIndex = partitionInfo . ModeInfo . FirstTransformLocation [ ( int ) Av1PlaneType . Uv ] ;
Span < Av1TransformInfo > lumaTransformInfo = superblockInfo . GetTransformInfoY ( ) ;
Span < Av1TransformInfo > chromaTransformInfo = superblockInfo . GetTransformInfoUv ( ) ;
int totalLumaTus Count = 0 ;
int totalChromaTus Count = 0 ;
int totalLumaTransformUnit Count = 0 ;
int totalChromaTransformUnit Count = 0 ;
int forceSplitCount = 0 ;
bool subX = this . SequenceHeader . ColorConfig . SubSamplingX ;
bool subY = this . SequenceHeader . ColorConfig . SubSamplingY ;
@ -1307,8 +1311,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
{
for ( int idx = 0 ; idx < maxBlockWide ; idx + = width , forceSplitCount + + )
{
int lumaTus Count = 0 ;
int chromaTus Count = 0 ;
int lumaTransformUnit Count = 0 ;
int chromaTransformUnit Count = 0 ;
// Update Luminance Transform Info.
int stepColumn = transformSize . Get4x4WideCount ( ) ;
@ -1323,12 +1327,12 @@ internal class Av1TileDecoder : IAv1TileDecoder
lumaTransformInfo [ transformInfoYIndex ] = new Av1TransformInfo (
transformSize , blockColumn , blockRow ) ;
transformInfoYIndex + + ;
lumaTus Count + + ;
totalLumaTus Count + + ;
lumaTransformUnit Count + + ;
totalLumaTransformUnit Count + + ;
}
}
this . tus Count [ ( int ) Av1Plane . Y ] [ forceSplitCount ] = lumaTus Count ;
this . transformUnit Count [ ( int ) Av1Plane . Y ] [ forceSplitCount ] = lumaTransformUnit Count ;
if ( this . SequenceHeader . ColorConfig . IsMonochrome | | ! partitionInfo . IsChroma )
{
@ -1348,31 +1352,31 @@ internal class Av1TileDecoder : IAv1TileDecoder
chromaTransformInfo [ transformInfoUvIndex ] = new Av1TransformInfo (
transformSizeUv , blockColumn , blockRow ) ;
transformInfoUvIndex + + ;
chromaTus Count + + ;
totalChromaTus Count + + ;
chromaTransformUnit Count + + ;
totalChromaTransformUnit Count + + ;
}
}
this . tus Count [ ( int ) Av1Plane . U ] [ forceSplitCount ] = lumaTus Count ;
this . tus Count [ ( int ) Av1Plane . V ] [ forceSplitCount ] = lumaTus Count ;
this . transformUnit Count [ ( int ) Av1Plane . U ] [ forceSplitCount ] = lumaTransformUnit Count ;
this . transformUnit Count [ ( int ) Av1Plane . V ] [ forceSplitCount ] = lumaTransformUnit Count ;
}
}
// Cr Transform Info Update from Cb.
if ( totalChromaTus Count ! = 0 )
if ( totalChromaTransformUnit Count ! = 0 )
{
int originalIndex = transformInfoUvIndex - totalChromaTus Count ;
for ( int i = 0 ; i < totalChromaTus Count ; i + + )
int originalIndex = transformInfoUvIndex - totalChromaTransformUnit Count ;
for ( int i = 0 ; i < totalChromaTransformUnit Count ; i + + )
{
chromaTransformInfo [ transformInfoUvIndex + i ] = chromaTransformInfo [ originalIndex + i ] ;
}
}
partitionInfo . ModeInfo . TransformUnitsCount [ ( int ) Av1PlaneType . Y ] = totalLumaTus Count ;
partitionInfo . ModeInfo . TransformUnitsCount [ ( int ) Av1PlaneType . Uv ] = totalChromaTus Count ;
partitionInfo . ModeInfo . TransformUnitsCount [ ( int ) Av1PlaneType . Y ] = totalLumaTransformUnit Count ;
partitionInfo . ModeInfo . TransformUnitsCount [ ( int ) Av1PlaneType . Uv ] = totalChromaTransformUnit Count ;
this . firstTransformOffset [ ( int ) Av1PlaneType . Y ] + = totalLumaTus Count ;
this . firstTransformOffset [ ( int ) Av1PlaneType . Uv ] + = totalChromaTus Count < < 1 ;
this . firstTransformOffset [ ( int ) Av1PlaneType . Y ] + = totalLumaTransformUnit Count ;
this . firstTransformOffset [ ( int ) Av1PlaneType . Uv ] + = totalChromaTransformUnit Count < < 1 ;
}
/// <summary>