|
|
|
@ -30,35 +30,42 @@ public class Av1EncoderFrameTests |
|
|
|
private const int Yuv444 = (int)Av1ColorFormat.Yuv444; |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[InlineData(EightBit, false, false)] |
|
|
|
[InlineData(EightBit, false, true)] |
|
|
|
[InlineData(EightBit, true, false)] |
|
|
|
[InlineData(EightBit, true, true)] |
|
|
|
[InlineData(TenBit, false, false)] |
|
|
|
[InlineData(TenBit, false, true)] |
|
|
|
[InlineData(TenBit, true, false)] |
|
|
|
[InlineData(TenBit, true, true)] |
|
|
|
[InlineData(TwelveBit, false, false)] |
|
|
|
[InlineData(TwelveBit, false, true)] |
|
|
|
[InlineData(TwelveBit, true, false)] |
|
|
|
[InlineData(TwelveBit, true, true)] |
|
|
|
public void RectangularIntraReferencesExtendTheLastAvailableSample(int bitDepthValue, bool transpose, bool extensionAvailable) |
|
|
|
[InlineData(EightBit, false, false, false)] |
|
|
|
[InlineData(EightBit, false, true, false)] |
|
|
|
[InlineData(EightBit, true, false, false)] |
|
|
|
[InlineData(EightBit, true, true, false)] |
|
|
|
[InlineData(TenBit, false, false, false)] |
|
|
|
[InlineData(TenBit, false, true, false)] |
|
|
|
[InlineData(TenBit, true, false, false)] |
|
|
|
[InlineData(TenBit, true, true, false)] |
|
|
|
[InlineData(TwelveBit, false, false, false)] |
|
|
|
[InlineData(TwelveBit, false, true, false)] |
|
|
|
[InlineData(TwelveBit, true, false, false)] |
|
|
|
[InlineData(TwelveBit, true, true, false)] |
|
|
|
[InlineData(EightBit, false, true, true)] |
|
|
|
[InlineData(EightBit, true, true, true)] |
|
|
|
[InlineData(TenBit, false, true, true)] |
|
|
|
[InlineData(TenBit, true, true, true)] |
|
|
|
[InlineData(TwelveBit, false, true, true)] |
|
|
|
[InlineData(TwelveBit, true, true, true)] |
|
|
|
public void RectangularIntraReferencesExtendTheLastAvailableSample(int bitDepthValue, bool transpose, bool extensionAvailable, bool limitedExtent) |
|
|
|
{ |
|
|
|
Av1BitDepth bitDepth = (Av1BitDepth)bitDepthValue; |
|
|
|
if (bitDepth == Av1BitDepth.EightBit) |
|
|
|
{ |
|
|
|
AssertRectangularIntraReferences<byte, Av1IntraSuperblockEncoder.ByteOperator>(bitDepth, transpose, extensionAvailable); |
|
|
|
AssertRectangularIntraReferences<byte, Av1IntraSuperblockEncoder.ByteOperator>(bitDepth, transpose, extensionAvailable, limitedExtent); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
AssertRectangularIntraReferences<ushort, Av1IntraSuperblockEncoder.UInt16Operator>(bitDepth, transpose, extensionAvailable); |
|
|
|
AssertRectangularIntraReferences<ushort, Av1IntraSuperblockEncoder.UInt16Operator>(bitDepth, transpose, extensionAvailable, limitedExtent); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static void AssertRectangularIntraReferences<TSample, TOperator>( |
|
|
|
Av1BitDepth bitDepth, |
|
|
|
bool transpose, |
|
|
|
bool extensionAvailable) |
|
|
|
bool extensionAvailable, |
|
|
|
bool limitedExtent) |
|
|
|
where TSample : unmanaged |
|
|
|
where TOperator : struct, Av1IntraSuperblockEncoder.IBlockEncodingOperator<TSample> |
|
|
|
{ |
|
|
|
@ -76,14 +83,19 @@ public class Av1EncoderFrameTests |
|
|
|
|
|
|
|
// Native reconintra.c extends a four-sample edge through its four-sample neighbor, then
|
|
|
|
// repeats sample seven to cover the twenty samples required by a 4x16 directional ray.
|
|
|
|
// These explicit offsets also distinguish unavailable neighbors from available extension.
|
|
|
|
int[] shortEdge = extensionAvailable |
|
|
|
? [0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7] |
|
|
|
: [0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]; |
|
|
|
|
|
|
|
int[] longEdge = extensionAvailable |
|
|
|
? [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] |
|
|
|
: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15]; |
|
|
|
// A clipped frame leaves only two adjacent samples; backing-buffer values beyond the region
|
|
|
|
// must not contribute. These explicit offsets distinguish all three extension cases.
|
|
|
|
int[] shortEdge = limitedExtent |
|
|
|
? [0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5] |
|
|
|
: extensionAvailable |
|
|
|
? [0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7] |
|
|
|
: [0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]; |
|
|
|
|
|
|
|
int[] longEdge = limitedExtent |
|
|
|
? [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17] |
|
|
|
: extensionAvailable |
|
|
|
? [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] |
|
|
|
: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15]; |
|
|
|
|
|
|
|
int[] expectedAbove = transpose ? longEdge : shortEdge; |
|
|
|
int[] expectedLeft = transpose ? shortEdge : longEdge; |
|
|
|
@ -96,7 +108,7 @@ public class Av1EncoderFrameTests |
|
|
|
// The exact-sized interior includes the corner and twenty projected samples. Sentinel samples
|
|
|
|
// on either side detect writes outside the reference view, including the former 2*long-edge span.
|
|
|
|
Av1IntraSuperblockEncoder.ModeDecision<TSample, TOperator>.PrepareReferenceSamples( |
|
|
|
plane.GetRegion(), |
|
|
|
plane.GetRegion(0, 0, limitedExtent ? width + 3 : 33, limitedExtent ? height + 3 : 33), |
|
|
|
new Point(1, 1), |
|
|
|
width, |
|
|
|
height, |
|
|
|
|