// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System.Buffers.Binary; using System.Globalization; using System.Text; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Heif; using SixLabors.ImageSharp.Formats.Heif.Av1; using SixLabors.ImageSharp.Formats.Heif.Av1.Motion; using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit; using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction; using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling; using SixLabors.ImageSharp.Formats.Heif.Av1.Transform; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Metadata.Profiles.Cicp; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.Memory; using SixLabors.ImageSharp.Tests.TestUtilities; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; namespace SixLabors.ImageSharp.Tests.Formats.Heif.Av1; /// /// Validates complete AV1 reconstruction against independently decoded native component planes. /// [Trait("Format", "Avif")] public class Av1ReconstructionConformanceTests { /// /// The width and height of one CDEF unit in 4x4 luma mode-information units. /// private const int CdefUnitModeInfoSize = 16; /// /// The hardware configurations covering normal SIMD dispatch and the scalar fallback. /// private const HwIntrinsics ReconstructionConfigurations = HwIntrinsics.AllowAll | HwIntrinsics.DisableHWIntrinsic; /// /// The hardware configurations covering the 256-bit, 128-bit, and scalar palette-reconstruction paths. /// private const HwIntrinsics PaletteConfigurations = HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX | HwIntrinsics.DisableHWIntrinsic; /// /// The hardware configurations covering normal dispatch, narrower vector fallbacks, and scalar intra-block copy. /// private const HwIntrinsics IntraBlockCopyConfigurations = HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX512F | HwIntrinsics.DisableAVX | HwIntrinsics.DisableHWIntrinsic; /// /// The hardware configurations covering the narrower vector widths and scalar fallback for the profile matrix. /// private const HwIntrinsics ProfileFallbackConfigurations = HwIntrinsics.DisableAVX512F | HwIntrinsics.DisableAVX | HwIntrinsics.DisableHWIntrinsic; /// /// The hardware configurations covering the 128-bit and scalar lossless inverse-transform paths. /// private const HwIntrinsics LosslessConfigurations = HwIntrinsics.AllowAll | HwIntrinsics.DisableHWIntrinsic; /// /// The hardware configurations covering the 256-bit, 128-bit, and scalar loop-restoration paths. /// private const HwIntrinsics LoopRestorationConfigurations = HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX | HwIntrinsics.DisableHWIntrinsic; /// /// The coverage bit representing an active Wiener restoration unit. /// private const int WienerRestorationCoverage = 1 << (int)Av1RestorationFilterType.Wiener; /// /// The coverage bit representing an active self-guided restoration unit. /// private const int SelfGuidedRestorationCoverage = 1 << (int)Av1RestorationFilterType.SgrProjection; /// /// The coverage bit representing luma palette prediction. /// private const int LumaPaletteCoverage = 1 << 0; /// /// The coverage bit representing chroma palette prediction. /// private const int ChromaPaletteCoverage = 1 << 1; /// /// The luma and chroma syntax coverage required from the independent palette fixture. /// private const int RequiredPaletteCoverage = LumaPaletteCoverage | ChromaPaletteCoverage; /// /// The bit mask containing every AV1 partition type defined for a coding block. /// private const int RequiredPartitionCoverage = (1 << ((int)Av1PartitionType.Vertical4 + 1)) - 1; /// /// The displayed width shared by the independent lossless fixtures. /// private const int LosslessFixtureWidth = 100; /// /// The displayed height shared by the independent lossless fixtures. /// private const int LosslessFixtureHeight = 60; /// /// The displayed width shared by the independent AV1 profile fixtures. /// private const int ProfileFixtureWidth = 512; /// /// The displayed height shared by the independent AV1 profile fixtures. /// private const int ProfileFixtureHeight = 256; /// /// The displayed width of the independent two-layer progressive fixture. /// private const int ProgressiveFixtureWidth = 33; /// /// The displayed height of the independent two-layer progressive fixture. /// private const int ProgressiveFixtureHeight = 11; /// /// The byte length of the fixture's base layer as declared by its a1lx property. /// private const int ProgressiveFirstLayerSize = 55; /// /// The displayed width and height of the independent scaled-reference fixture. /// private const int ScaledReferenceFixtureSize = 80; /// /// The retained base-layer width and height of the independent scaled-reference fixture. /// private const int ScaledReferenceBaseLayerSize = 40; /// /// The byte length of the scaled-reference fixture's base layer as declared by its a1lx property. /// private const int ScaledReferenceFirstLayerSize = 701; /// /// The displayed width and height of the independent compound image sequence. /// private const int AverageCompoundFixtureSize = 80; /// /// The number of presented frames in the independent compound image sequence. /// private const int AverageCompoundFixtureFrameCount = 19; /// /// The number of shown frames in the official libaom all-intra sequence. /// private const int OfficialAllIntraFixtureFrameCount = 39; /// /// The number of shown frames in the official libaom CDF-update sequence. /// private const int OfficialCdfUpdateFixtureFrameCount = 2; /// /// The number of shown frames in the official libaom temporal motion-field sequence. /// private const int OfficialMotionFieldFixtureFrameCount = 4; /// /// The displayed width of the official libaom extreme-displacement intra-block-copy sequence. /// private const int OfficialIntraBlockCopyFixtureWidth = 1920; /// /// The displayed height of the official libaom extreme-displacement intra-block-copy sequence. /// private const int OfficialIntraBlockCopyFixtureHeight = 1080; /// /// The number of shown frames in the official libaom extreme-displacement intra-block-copy sequence. /// private const int OfficialIntraBlockCopyFixtureFrameCount = 2; /// /// The displayed width of the official libaom two-spatial-layer sequence. /// private const int OfficialTwoSpatialLayerFixtureWidth = 1280; /// /// The displayed height of the official libaom two-spatial-layer sequence. /// private const int OfficialTwoSpatialLayerFixtureHeight = 720; /// /// The number of default-operating-point frames in the official libaom two-spatial-layer sequence. /// private const int OfficialTwoSpatialLayerFixtureFrameCount = 8; /// /// The displayed width of the official libaom two-temporal-layer sequence. /// private const int OfficialTwoTemporalLayerFixtureWidth = 640; /// /// The displayed height of the official libaom two-temporal-layer sequence. /// private const int OfficialTwoTemporalLayerFixtureHeight = 360; /// /// The number of default-operating-point frames in the official libaom two-temporal-layer sequence. /// private const int OfficialTwoTemporalLayerFixtureFrameCount = 8; /// /// The displayed width of the official libaom spatial-and-temporal-layer sequence. /// private const int OfficialSpatialTemporalLayerFixtureWidth = 1280; /// /// The displayed height of the official libaom spatial-and-temporal-layer sequence. /// private const int OfficialSpatialTemporalLayerFixtureHeight = 720; /// /// The number of default-operating-point frames in the official libaom spatial-and-temporal-layer sequence. /// private const int OfficialSpatialTemporalLayerFixtureFrameCount = 8; /// /// The number of frames in the official libaom active-film-grain sequence. /// private const int OfficialFilmGrainFixtureFrameCount = 10; /// /// The width of the official libaom eight-bit monochrome sequence. /// private const int OfficialMonochromeFixtureWidth = 320; /// /// The height of the official libaom eight-bit monochrome sequence. /// private const int OfficialMonochromeFixtureHeight = 180; /// /// The number of frames in the official libaom eight-bit monochrome sequence. /// private const int OfficialMonochromeFixtureFrameCount = 10; /// /// The width of the official libaom eight-bit quantizer-boundary sequences. /// private const int OfficialEightBitQuantizerFixtureWidth = 352; /// /// The height of the official libaom eight-bit quantizer-boundary sequences. /// private const int OfficialEightBitQuantizerFixtureHeight = 288; /// /// The width of the official libaom ten-bit quantizer-boundary sequences. /// private const int OfficialTenBitQuantizerFixtureWidth = 640; /// /// The height of the official libaom ten-bit quantizer-boundary sequences. /// private const int OfficialTenBitQuantizerFixtureHeight = 360; /// /// The number of frames in each official libaom quantizer-boundary sequence. /// private const int OfficialQuantizerFixtureFrameCount = 2; /// /// The minimum dimension retained from the official libaom frame-size matrix. /// private const int OfficialFrameSizeFixtureMinimumDimension = 196; /// /// The maximum dimension retained from the official libaom frame-size matrix. /// private const int OfficialFrameSizeFixtureMaximumDimension = 226; /// /// The number of frames in each official libaom frame-size sequence. /// private const int OfficialFrameSizeFixtureFrameCount = 2; /// /// The coverage bit representing tile-local adaptive CDF updates. /// private const int TileCdfUpdateCoverage = 1 << 0; /// /// The coverage bit representing publication of the selected frame-end CDF. /// private const int FrameEndCdfUpdateCoverage = 1 << 1; /// /// The coverage bit representing temporal reference-motion-vector projection. /// private const int ReferenceFrameMotionVectorCoverage = 1 << 2; /// /// The coverage bit representing displayed film-grain synthesis. /// private const int FilmGrainCoverage = 1 << 3; /// /// The bit mask containing every intra prediction mode. /// private const int RequiredIntraModeCoverage = (1 << (int)Av1PredictionMode.IntraModes) - 1; /// /// The transform types selected by the official all-intra conformance sequence. /// private const int RequiredAllIntraTransformTypeCoverage = (1 << (int)Av1TransformType.DctDct) | (1 << (int)Av1TransformType.AdstDct) | (1 << (int)Av1TransformType.DctAdst) | (1 << (int)Av1TransformType.AdstAdst) | (1 << (int)Av1TransformType.Identity) | (1 << (int)Av1TransformType.VerticalDct) | (1 << (int)Av1TransformType.HorizontalDct); /// /// The displayed width of the official libaom motion-vector sequence. /// private const int OfficialMotionVectorFixtureWidth = 352; /// /// The displayed height of the official libaom motion-vector sequence. /// private const int OfficialMotionVectorFixtureHeight = 288; /// /// The number of shown frames in the official libaom motion-vector sequence. /// private const int OfficialMotionVectorFixtureFrameCount = 4; /// /// The bit mask containing every single-reference and compound inter prediction mode. /// private const int RequiredInterModeCoverage = (1 << ((int)Av1PredictionMode.InterModeEnd - (int)Av1PredictionMode.InterModeStart)) - 1; /// /// The bit mask containing every simple, OBMC, and locally warped motion mode. /// private const int RequiredMotionModeCoverage = (1 << 3) - 1; /// /// The bit mask containing every regular, smooth, and sharp vertical/horizontal filter pair. /// private const int RequiredSwitchableFilterPairCoverage = (1 << 9) - 1; /// /// The coverage bit representing distance-weighted compound prediction. /// private const int DistanceWeightedCompoundCoverage = 1 << 0; /// /// The coverage bit representing a non-inverted wedge compound mask. /// private const int WedgeCompoundCoverage = 1 << 1; /// /// The coverage bit representing an inverted wedge compound mask. /// private const int InvertedWedgeCompoundCoverage = 1 << 2; /// /// The coverage bit representing the first difference-weighted mask orientation. /// private const int DifferenceWeightedCompoundCoverage = 1 << 3; /// /// The coverage bit representing the inverted difference-weighted mask orientation. /// private const int InvertedDifferenceWeightedCompoundCoverage = 1 << 4; /// /// The coverage bit representing smooth inter-intra prediction. /// private const int SmoothInterIntraCoverage = 1 << 5; /// /// The coverage bit representing wedge inter-intra prediction. /// private const int WedgeInterIntraCoverage = 1 << 6; /// /// The coverage bit representing overlapping motion compensation. /// private const int ObmcCoverage = 1 << 7; /// /// The coverage bit representing local warped-motion prediction. /// private const int LocalWarpCoverage = 1 << 8; /// /// The coverage bit representing non-translational global warped-motion prediction. /// private const int GlobalWarpCoverage = 1 << 9; /// /// The hardware configurations covering the available vector widths and the scalar color-conversion fallback. /// private const HwIntrinsics PresentationConfigurations = HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX512F | HwIntrinsics.DisableAVX | HwIntrinsics.DisableHWIntrinsic; /// /// Verifies deblocking syntax, filter activation, component traversal, and presentation for real eight-, ten-, /// and twelve-bit AV1 and AVIF content. /// [Fact] public void DecodeMatchesPinnedLibaomReference() { ValidateFixture( TestImages.Heif.Av1Deblocking8BitAvif, TestImages.Heif.Av1Deblocking8BitPayload, TestImages.Heif.Av1Deblocking8BitReference, 768, 512, Av1BitDepth.EightBit, Av1ColorFormat.Yuv420, HeifBitDepth.Bit8); ValidateFixture( TestImages.Heif.Av1Deblocking10BitAvif, TestImages.Heif.Av1Deblocking10BitPayload, TestImages.Heif.Av1Deblocking10BitReference, 1024, 428, Av1BitDepth.TenBit, Av1ColorFormat.Yuv444, HeifBitDepth.Bit10); ValidateNativeFixture( TestImages.Heif.Av1Deblocking12BitPayload, TestImages.Heif.Av1Deblocking12BitReference, 1024, 428, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv444, requireActiveCdef: false); ValidatePresentedImage(TestImages.Heif.Av1Deblocking12BitAvif, 64, 64, HeifBitDepth.Bit12); } /// /// Verifies active CDEF syntax, strength selection, unit traversal, subsampling, frame edges, and final native /// samples against scalar libaom for independently encoded eight-, ten-, and twelve-bit still-picture streams /// under normal SIMD dispatch and with hardware intrinsics disabled. /// [Fact] public void DecodeWithActiveCdefMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidateActiveCdefFixtures, ReconstructionConfigurations); /// /// Verifies exact presented pixels and public metadata for independently encoded eight-, ten-, and twelve-bit /// active-CDEF AVIF images across the available vector widths and the scalar fallback. /// /// The AVIF input and matching reference-output naming context. /// The expected presented width. /// The expected presented height. /// The expected public sample precision. [Theory] [WithFile(TestImages.Heif.Av1Cdef8BitAvif, PixelTypes.Rgba32, 768, 512, HeifBitDepth.Bit8)] [WithFile(TestImages.Heif.Av1Cdef10BitAvif, PixelTypes.Rgba32, 1024, 428, HeifBitDepth.Bit10)] [WithFile(TestImages.Heif.Av1Cdef12BitAvif, PixelTypes.Rgba32, 1024, 428, HeifBitDepth.Bit12)] public void DecodeWithActiveCdefMatchesPinnedLibavifPresentation( TestImageProvider provider, int width, int height, HeifBitDepth bitDepth) { AssertPresentedMetadata(provider, width, height, bitDepth); FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidatePresentedFixture, PresentationConfigurations, provider); } /// /// Verifies exact native reconstruction for every valid AV1 profile, bit-depth, and chroma-format combination /// supported by AVIF across every available vector width and the scalar fallback. /// [Fact] public void DecodeProfileMatrixMatchesPinnedLibaomReference() => ValidateProfileNativeFixtures(); /// /// Verifies exact native reconstruction for every valid AV1 profile, bit-depth, and chroma-format combination /// under each narrower vector width and the scalar fallback. /// [Fact] public void DecodeProfileMatrixFallbacksMatchPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidateProfileNativeFixtures, ProfileFallbackConfigurations); /// /// Verifies exact presented pixels, public bit-depth metadata, and CICP signaling for every valid AV1 profile, /// bit-depth, and chroma-format combination supported by AVIF. /// /// The AVIF input and matching reference-output naming context. /// The expected public sample precision. [Theory] [WithFile(TestImages.Heif.Av1Profile8BitMonochromeAvif, PixelTypes.Rgba32, HeifBitDepth.Bit8)] [WithFile(TestImages.Heif.Av1Profile8Bit420Avif, PixelTypes.Rgba32, HeifBitDepth.Bit8)] [WithFile(TestImages.Heif.Av1Profile8Bit422Avif, PixelTypes.Rgba32, HeifBitDepth.Bit8)] [WithFile(TestImages.Heif.Av1Profile8Bit444Avif, PixelTypes.Rgba32, HeifBitDepth.Bit8)] [WithFile(TestImages.Heif.Av1Profile10BitMonochromeAvif, PixelTypes.Rgba32, HeifBitDepth.Bit10)] [WithFile(TestImages.Heif.Av1Profile10Bit420Avif, PixelTypes.Rgba32, HeifBitDepth.Bit10)] [WithFile(TestImages.Heif.Av1Profile10Bit422Avif, PixelTypes.Rgba32, HeifBitDepth.Bit10)] [WithFile(TestImages.Heif.Av1Profile10Bit444Avif, PixelTypes.Rgba32, HeifBitDepth.Bit10)] [WithFile(TestImages.Heif.Av1Profile12BitMonochromeAvif, PixelTypes.Rgba32, HeifBitDepth.Bit12)] [WithFile(TestImages.Heif.Av1Profile12Bit420Avif, PixelTypes.Rgba32, HeifBitDepth.Bit12)] [WithFile(TestImages.Heif.Av1Profile12Bit422Avif, PixelTypes.Rgba32, HeifBitDepth.Bit12)] [WithFile(TestImages.Heif.Av1Profile12Bit444Avif, PixelTypes.Rgba32, HeifBitDepth.Bit12)] public void DecodeProfileMatrixMatchesPinnedLibavifPresentation( TestImageProvider provider, HeifBitDepth bitDepth) { using Image image = provider.GetImage(); HeifMetadata metadata = image.Metadata.GetHeifMetadata(); Assert.Equal(HeifCompressionMethod.Av1, metadata.CompressionMethod); Assert.Equal(bitDepth, metadata.BitDepth); CicpProfile colorProfile = Assert.IsType(image.Metadata.CicpProfile); Assert.Equal(CicpColorPrimaries.ItuRBt709_6, colorProfile.ColorPrimaries); Assert.Equal(CicpTransferCharacteristics.Iec61966_2_1, colorProfile.TransferCharacteristics); Assert.Equal(CicpMatrixCoefficients.ItuRBt601_7_525, colorProfile.MatrixCoefficients); Assert.True(colorProfile.FullRange); FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidatePresentedFixture, PresentationConfigurations, provider); } /// /// Verifies decoded luma and chroma palette syntax and exact native samples against scalar libaom for an /// independently encoded AV1 still-picture stream. /// [Fact] public void DecodeWithPaletteMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidatePaletteNativeFixture, PaletteConfigurations); /// /// Verifies that a real palette frame whose tile entropy payload ends early is rejected instead of being decoded /// from the range decoder's implicit zero padding. /// [Fact] public void DecodeFrameBufferRejectsTruncatedPaletteTileEntropy() { const int TruncatedTileByteCount = 8; byte[] validPayload = TestFile.Create(TestImages.Heif.Av1Palette8BitPayload).Bytes; int obuOffset = 0; int finalObuOffset = 0; int finalSizeFieldOffset = 0; int finalSizeFieldLength = 0; ulong finalPayloadLength = 0; while (obuOffset < validPayload.Length) { byte obuHeader = validPayload[obuOffset]; Assert.NotEqual(0, obuHeader & 0x02); int headerLength = 1 + ((obuHeader >> 2) & 1); int sizeFieldOffset = obuOffset + headerLength; Av1BitStreamReader sizeReader = new(validPayload.AsSpan(sizeFieldOffset)); ulong payloadLength = sizeReader.ReadLittleEndianBytes128(out int sizeFieldLength); int nextObuOffset = checked(sizeFieldOffset + sizeFieldLength + (int)payloadLength); if (nextObuOffset == validPayload.Length) { finalObuOffset = obuOffset; finalSizeFieldOffset = sizeFieldOffset; finalSizeFieldLength = sizeFieldLength; finalPayloadLength = payloadLength; } obuOffset = nextObuOffset; } Assert.Equal(ObuType.Frame, (ObuType)((validPayload[finalObuOffset] >> 3) & 0x0F)); Assert.Equal(1, finalSizeFieldLength); Assert.InRange(finalPayloadLength, (ulong)(TruncatedTileByteCount + 1), 0x7FUL); byte[] truncatedPayload = validPayload[..^TruncatedTileByteCount]; truncatedPayload[finalSizeFieldOffset] = (byte)(finalPayloadLength - TruncatedTileByteCount); using Av1Decoder decoder = new(Configuration.Default); Assert.Throws( () => decoder.DecodeFrameBuffer(truncatedPayload, null, null, out _).Dispose()); Assert.Null(decoder.SequenceHeader); Assert.Null(decoder.FrameHeader); Assert.Null(decoder.FrameInfo); } /// /// Verifies decoded luma and chroma palette syntax and exact presented pixels for an independently encoded AVIF /// image across the available vector widths and the scalar fallback. /// /// The AVIF input and matching reference-output naming context. [Theory] [WithFile(TestImages.Heif.Av1Palette8BitAvif, PixelTypes.Rgba32)] public void DecodeWithPaletteMatchesPinnedLibavifPresentation(TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidatePresentedFixture, PresentationConfigurations, provider); /// /// Verifies that malformed data following a decoded palette tile releases its frame state before the same decoder /// processes another payload. /// [Fact] public void DecodeFrameBufferRecoversAfterMalformedFollowingObu() { byte[] validPayload = TestFile.Create(TestImages.Heif.Av1Palette8BitPayload).Bytes; // The palette fixture ends with one combined-frame OBU containing one tile, so the intact prefix creates and // completes a real Av1TileReader. The appended padding OBU declares one zero byte; AV1 padding requires a // trailing-one bit, making this later bounded-payload failure deterministic without corrupting tile entropy. byte[] malformedPayload = [ .. validPayload, 0x7A, // Padding OBU with an explicit payload-size field. 0x01, // LEB128 payload length of one byte. 0x00, // Invalid padding payload with no trailing-one bit. ]; using Av1Decoder decoder = new(Configuration.Default); Assert.Throws( () => decoder.DecodeFrameBuffer(malformedPayload, null, null, out _).Dispose()); Assert.Null(decoder.SequenceHeader); Assert.Null(decoder.FrameHeader); Assert.Null(decoder.FrameInfo); using Av1FrameBuffer recoveredFrameBuffer = decoder.DecodeFrameBuffer(validPayload, null, null, out _); Assert.Equal(33, recoveredFrameBuffer.Width); Assert.Equal(11, recoveredFrameBuffer.Height); Assert.Equal(RequiredPaletteCoverage, GetPaletteCoverage(decoder)); } /// /// Verifies selected intra-block-copy prediction and exact native samples against scalar libaom for an /// independently encoded AV1 still pictures across every available vector width and the scalar fallback. /// [Fact] public void DecodeWithIntraBlockCopyMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidateIntraBlockCopyNativeFixtures, IntraBlockCopyConfigurations); /// /// Verifies exact presented pixels for independently encoded intra-block-copy AVIF images across the available /// vector widths and the scalar fallback. /// /// The AVIF input and matching reference-output naming context. [Theory] [WithFile(TestImages.Heif.Av1IntraBlockCopy8BitAvif, PixelTypes.Rgba32)] [WithFile(TestImages.Heif.Av1IntraBlockCopy10BitAvif, PixelTypes.Rgba32)] [WithFile(TestImages.Heif.Av1IntraBlockCopy12BitAvif, PixelTypes.Rgba32)] public void DecodeWithIntraBlockCopyMatchesPinnedLibavifPresentation( TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidatePresentedFixture, PresentationConfigurations, provider); /// /// Verifies the production single-reference inter-reconstruction path against exact native and presentation /// references across the available vector widths and scalar fallback. /// /// The AVIF input and matching reference-output naming context. [Theory] [WithFile(TestImages.Heif.Av1Progressive8BitAvif, PixelTypes.Rgba32)] public void DecodeProgressiveSingleReferenceMatchesPinnedReferences( TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateProgressiveSingleReferenceFixtureWithDefaultConfiguration, PresentationConfigurations, provider); /// /// Verifies production single-reference inter reconstruction with a constrained allocator. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeProgressiveSingleReferenceWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 1_024 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateProgressiveSingleReferenceFixture(configuration); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Verifies that an essential lsel property returns the selected base spatial layer rather than the final /// progressive layer, with exact pinned-libaom native planes and pinned-libavif presentation. /// /// The selected-layer AVIF input and matching reference-output naming context. [Theory] [WithFile(TestImages.Heif.Av1ScaledReferenceSelectedLayerAvif, PixelTypes.Rgba32)] public void DecodeSelectedProgressiveSpatialLayerMatchesPinnedReferences( TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateSelectedProgressiveSpatialLayerWithDefaultConfiguration, PresentationConfigurations, provider); /// /// Verifies selected-layer native reconstruction and public presentation with constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeSelectedProgressiveSpatialLayerWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 1_024 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateSelectedProgressiveSpatialLayer(configuration); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Verifies an independently encoded 40x40 retained layer scaled into an 80x80 dependent layer against exact /// pinned-libaom native planes and pinned-libavif presentation. /// /// The AVIF input and matching reference-output naming context. [Theory] [WithFile(TestImages.Heif.Av1ScaledReferenceAvif, PixelTypes.Rgba32)] public void DecodeScaledReferenceMatchesPinnedReferences(TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateScaledReferenceFixtureWithDefaultConfiguration, ReconstructionConfigurations, provider); /// /// Verifies scaled-reference reconstruction with constrained tracked allocation and contiguous frame planes. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeScaledReferenceWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 1_024 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateScaledReferenceFixture(configuration); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "RetainedMotionFieldEntry"); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "TemporalMotionFieldEntry"); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Verifies that the production dependent-frame result owns its motion-field storage until decoder disposal. /// [Fact] public void DecodeProgressiveSingleReferenceTracksMotionFieldResultOwnership() { TestMemoryAllocator allocator = new(); allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; byte[] payload = TestFile.Create(TestImages.Heif.Av1Progressive8BitPayload).Bytes; using Av1Decoder decoder = new(configuration); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer( payload, null, null, out _, new Av1LayeredImageIndex(ProgressiveFirstLayerSize, 0, 0)); TestMemoryAllocator.AllocationRequest retainedMotionField = Assert.Single( allocator.AllocationLog, request => request.ElementType.Name == "RetainedMotionFieldEntry"); TestMemoryAllocator.AllocationRequest temporalMotionField = Assert.Single( allocator.AllocationLog, request => request.ElementType.Name == "TemporalMotionFieldEntry"); // Reference-slot and presentation owners are released while DecodeFrameBuffer transfers the native planes. // The decoder's inspectable FrameInfo result remains the final motion-field owner until decoder disposal. Assert.DoesNotContain( allocator.ReturnLog, returned => returned.AllocationId == retainedMotionField.AllocationId); Assert.DoesNotContain( allocator.ReturnLog, returned => returned.AllocationId == temporalMotionField.AllocationId); frameBuffer.Dispose(); Assert.DoesNotContain( allocator.ReturnLog, returned => returned.AllocationId == retainedMotionField.AllocationId); Assert.DoesNotContain( allocator.ReturnLog, returned => returned.AllocationId == temporalMotionField.AllocationId); decoder.Dispose(); decoder.Dispose(); Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == retainedMotionField.AllocationId); Assert.Single(allocator.ReturnLog, returned => returned.AllocationId == temporalMotionField.AllocationId); } /// /// Verifies exact native reconstruction and presentation for an image sequence that exercises equal-weight /// compound prediction. The native reference has been reverified against current official libaom main. /// [Theory] [WithFile(TestImages.Heif.Av1AverageCompoundSequenceAvif, PixelTypes.Rgba32)] public void DecodeRealLibavifSequenceWithEqualAverageCompoundMatchesVerifiedReferences( TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateAverageCompoundSequenceWithDefaultConfiguration, ReconstructionConfigurations, provider); /// /// Verifies the complete compound sequence through a constrained allocator. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeRealLibavifSequenceWithEqualAverageCompoundUsesContiguousPlanes() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 1_024 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateAverageCompoundSequence(configuration); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "RetainedMotionFieldEntry"); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "TemporalMotionFieldEntry"); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Runs the exact compound-sequence comparisons with the default configuration. /// /// The serialized input provider and reference-output naming context. private static void ValidateAverageCompoundSequenceWithDefaultConfiguration(string providerDump) { ValidateAverageCompoundSequence(Configuration.Default); ValidateFinalSequencePresentation(providerDump); } /// /// Validates the complete compound sequence with the requested allocator. /// /// The decoder configuration. private static void ValidateAverageCompoundSequence(Configuration configuration) { byte[] fileBytes = TestFile.Create(TestImages.Heif.Av1AverageCompoundSequenceAvif).Bytes; byte[] referenceBytes = TestFile.Create(TestImages.Heif.Av1AverageCompoundSequenceNativeReference).Bytes; ReadOnlySpan fileHeader = "YUV4MPEG2 W80 H80 F25:1 Ip A0:0 C444 XYSCSS=444 XCOLORRANGE=LIMITED\n"u8; ReadOnlySpan frameHeader = "FRAME\n"u8; ReadOnlySpan nativeReference = referenceBytes; Assert.True(nativeReference.StartsWith(fileHeader)); nativeReference = nativeReference[fileHeader.Length..]; Assert.True(nativeReference.StartsWith(frameHeader)); nativeReference = nativeReference[frameHeader.Length..]; Assert.Equal(AverageCompoundFixtureSize * AverageCompoundFixtureSize * 3, nativeReference.Length); HeifSequence sequence = ParseImageSequence(fileBytes); HeifSequenceTrack track = sequence.ColorTrack; int compoundBlockCount = 0; int visibleFrameCount = 0; bool nativeCompared = false; using Av1Decoder decoder = new(configuration); for (int sampleIndex = 0; sampleIndex < track.Samples.Length; sampleIndex++) { HeifSequenceSample sample = track.Samples[sampleIndex]; Span sampleData = fileBytes.AsSpan((int)sample.Offset, sample.Length); if (sample.IsHidden) { decoder.DecodeSequenceReference( sampleData, track.CicpProfile, track.Av1CodecConfiguration); continue; } ImageFrame decodedFrame; try { decodedFrame = decoder.DecodeSequenceFrame( sampleData, track.CicpProfile, track.Av1CodecConfiguration); } catch (InvalidImageContentException exception) { throw new InvalidImageContentException($"The verified compound fixture failed at sample {sampleIndex}.", exception); } using ImageFrame frame = decodedFrame; ObuSequenceHeader sequenceHeader = Assert.IsType(decoder.SequenceHeader); _ = Assert.IsType(decoder.FrameHeader); Av1FrameBuffer frameBuffer = Assert.IsType>(decoder.FrameBuffer); Av1FrameInfo frameInfo = Assert.IsType(decoder.FrameInfo); // Inter prediction addresses padding with one base span and a logical row stride. The frame owner must // preserve that contract even when the configured allocator would ordinarily split a large buffer. Assert.Equal(1, frameBuffer.BufferY!.FastMemoryGroup.Count); Assert.Equal(1, frameBuffer.BufferCb!.FastMemoryGroup.Count); Assert.Equal(1, frameBuffer.BufferCr!.FastMemoryGroup.Count); int superblockSizeLog2 = sequenceHeader.SuperblockSizeLog2; int superblockColumnCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, superblockSizeLog2) >> superblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameHeight, superblockSizeLog2) >> superblockSizeLog2; for (int superblockRow = 0; superblockRow < superblockRowCount; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount; superblockColumn++) { Av1SuperblockInfo superblockInfo = frameInfo.GetSuperblock(new Point(superblockColumn, superblockRow)); foreach (Av1BlockModeInfo modeInfo in superblockInfo.GetModeInfos()) { if (modeInfo.ReferenceFrames[1] <= Av1ReferenceFrameType.Intra) { continue; } Assert.Equal(Av1CompoundType.Average, modeInfo.CompoundType); compoundBlockCount++; } } } if (visibleFrameCount == AverageCompoundFixtureFrameCount - 1) { Assert.Equal(AverageCompoundFixtureSize, frameBuffer.Width); Assert.Equal(AverageCompoundFixtureSize, frameBuffer.Height); Assert.Equal(Av1BitDepth.EightBit, frameBuffer.BitDepth); Assert.Equal(Av1ColorFormat.Yuv444, frameBuffer.ColorFormat); AssertNativePlanesEqual(decoder, frameBuffer, nativeReference); nativeCompared = true; } visibleFrameCount++; } Assert.Equal(AverageCompoundFixtureFrameCount, visibleFrameCount); Assert.NotEqual(0, compoundBlockCount); Assert.True(nativeCompared); } /// /// Verifies every selectable compound and inter-intra production branch against pinned native and presentation references. /// [Theory] [WithFile(TestImages.Heif.Av1DistanceWeightedCompoundSequenceAvif, PixelTypes.Rgba32)] [WithFile(TestImages.Heif.Av1WedgeCompoundSequenceAvif, PixelTypes.Rgba32)] [WithFile(TestImages.Heif.Av1DifferenceWeightedCompoundSequenceAvif, PixelTypes.Rgba32)] [WithFile(TestImages.Heif.Av1InterIntraSequenceAvif, PixelTypes.Rgba32)] public void DecodeRealLibavifSequencesWithSelectableCompoundAndInterIntraMatchesPinnedReferences( TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateSelectableCompoundSequenceWithDefaultConfiguration, ReconstructionConfigurations, provider); /// /// Verifies selectable compound and inter-intra reconstruction through a constrained allocator. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeRealLibavifSequencesWithSelectableCompoundAndInterIntraUseContiguousPlanes() { ValidateInterPredictionSequenceWithConstrainedAllocator( TestImages.Heif.Av1DistanceWeightedCompoundSequenceAvif, TestImages.Heif.Av1DistanceWeightedCompoundSequenceNativeReference, DistanceWeightedCompoundCoverage, AverageCompoundFixtureSize, AverageCompoundFixtureFrameCount); ValidateInterPredictionSequenceWithConstrainedAllocator( TestImages.Heif.Av1WedgeCompoundSequenceAvif, TestImages.Heif.Av1WedgeCompoundSequenceNativeReference, WedgeCompoundCoverage | InvertedWedgeCompoundCoverage, AverageCompoundFixtureSize, AverageCompoundFixtureFrameCount); ValidateInterPredictionSequenceWithConstrainedAllocator( TestImages.Heif.Av1DifferenceWeightedCompoundSequenceAvif, TestImages.Heif.Av1DifferenceWeightedCompoundSequenceNativeReference, DifferenceWeightedCompoundCoverage | InvertedDifferenceWeightedCompoundCoverage, AverageCompoundFixtureSize, AverageCompoundFixtureFrameCount); ValidateInterPredictionSequenceWithConstrainedAllocator( TestImages.Heif.Av1InterIntraSequenceAvif, TestImages.Heif.Av1InterIntraSequenceNativeReference, SmoothInterIntraCoverage | WedgeInterIntraCoverage, AverageCompoundFixtureSize, AverageCompoundFixtureFrameCount); } /// /// Verifies production OBMC reconstruction against pinned native and presentation references. /// [Theory] [WithFile(TestImages.Heif.Av1ObmcSequenceAvif, PixelTypes.Rgba32)] public void DecodeRealLibavifObmcSequenceMatchesPinnedReferences(TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateObmcSequenceWithDefaultConfiguration, ReconstructionConfigurations, provider); /// /// Verifies production OBMC reconstruction through a constrained allocator. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeRealLibavifObmcSequenceUsesContiguousPlanes() => ValidateInterPredictionSequenceWithConstrainedAllocator( TestImages.Heif.Av1ObmcSequenceAvif, TestImages.Heif.Av1ObmcSequenceNativeReference, ObmcCoverage, AverageCompoundFixtureSize, AverageCompoundFixtureFrameCount); /// /// Verifies production local warped-motion reconstruction against pinned native and presentation references. /// [Theory] [WithFile(TestImages.Heif.Av1LocalWarpSequenceAvif, PixelTypes.Rgba32)] public void DecodeRealLibavifLocalWarpSequenceMatchesPinnedReferences(TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateLocalWarpSequenceWithDefaultConfiguration, ReconstructionConfigurations, provider); /// /// Verifies production local warped-motion reconstruction through a constrained allocator. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeRealLibavifLocalWarpSequenceUsesContiguousPlanes() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 1_024 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateInterPredictionSequence( configuration, TestImages.Heif.Av1LocalWarpSequenceAvif, TestImages.Heif.Av1LocalWarpSequenceNativeReference, LocalWarpCoverage, 256, 2); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "RetainedMotionFieldEntry"); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "TemporalMotionFieldEntry"); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Verifies production non-translational global-motion reconstruction against pinned native and presentation references. /// [Theory] [WithFile(TestImages.Heif.Av1GlobalWarpSequenceAvif, PixelTypes.Rgba32)] public void DecodeRealLibavifGlobalWarpSequenceMatchesPinnedReferences(TestImageProvider provider) => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateGlobalWarpSequenceWithDefaultConfiguration, ReconstructionConfigurations, provider); /// /// Verifies production non-translational global-motion reconstruction through a constrained allocator. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeRealLibavifGlobalWarpSequenceUsesContiguousPlanes() => ValidateInterPredictionSequenceWithConstrainedAllocator( TestImages.Heif.Av1GlobalWarpSequenceAvif, TestImages.Heif.Av1GlobalWarpSequenceNativeReference, GlobalWarpCoverage, 256, 2); /// /// Verifies every intra prediction mode and the fixture's seven transform types against the official /// pinned-libaom all-intra conformance sequence and its exact native output. /// [Fact] public void DecodeOfficialAllIntraSequenceMatchesPinnedLibaomReference() => ValidateOfficialAllIntraFixture(); /// /// Decodes every all-intra IVF sample in one session, compares each frame exactly, and records the syntax /// selections that make the fixture authoritative for prediction and transform coverage. /// private static void ValidateOfficialAllIntraFixture() { byte[] ivf = TestFile.Create(TestImages.Heif.Av1OfficialAllIntraSequence).Bytes; byte[] nativeReference = TestFile.Create(TestImages.Heif.Av1OfficialAllIntraSequenceNativeReference).Bytes; ReadOnlySpan y4mFileHeader = "YUV4MPEG2 W352 H288 F3:1 Ip C420jpeg\n"u8; ReadOnlySpan y4mFrameHeader = "FRAME\n"u8; Assert.True(ivf.AsSpan(0, 4).SequenceEqual("DKIF"u8)); Assert.Equal(0, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(4, 2))); Assert.Equal(32, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(6, 2))); Assert.True(ivf.AsSpan(8, 4).SequenceEqual("AV01"u8)); Assert.Equal(OfficialMotionVectorFixtureWidth, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(12, 2))); Assert.Equal(OfficialMotionVectorFixtureHeight, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(14, 2))); Assert.Equal( OfficialAllIntraFixtureFrameCount, checked((int)BinaryPrimitives.ReadUInt32LittleEndian(ivf.AsSpan(24, 4)))); Assert.True(nativeReference.AsSpan().StartsWith(y4mFileHeader)); int ivfOffset = 32; int nativeOffset = y4mFileHeader.Length; int nativeFrameLength = (OfficialMotionVectorFixtureWidth * OfficialMotionVectorFixtureHeight) + (2 * (OfficialMotionVectorFixtureWidth >> 1) * (OfficialMotionVectorFixtureHeight >> 1)); int intraModeCoverage = 0; int transformTypeCoverage = 0; using Av1Decoder decoder = new(Configuration.Default); for (int frameIndex = 0; frameIndex < OfficialAllIntraFixtureFrameCount; frameIndex++) { int payloadLength = checked((int)BinaryPrimitives.ReadUInt32LittleEndian(ivf.AsSpan(ivfOffset, 4))); ivfOffset += 12; using ImageFrame frame = decoder.DecodeSequenceFrame( ivf.AsSpan(ivfOffset, payloadLength), null, null); ivfOffset += payloadLength; Assert.Equal(OfficialMotionVectorFixtureWidth, frame.Width); Assert.Equal(OfficialMotionVectorFixtureHeight, frame.Height); Assert.True(nativeReference.AsSpan(nativeOffset).StartsWith(y4mFrameHeader)); nativeOffset += y4mFrameHeader.Length; Av1FrameBuffer frameBuffer = Assert.IsType>(decoder.FrameBuffer); Assert.Equal(OfficialMotionVectorFixtureWidth, frameBuffer.Width); Assert.Equal(OfficialMotionVectorFixtureHeight, frameBuffer.Height); Assert.Equal(Av1BitDepth.EightBit, frameBuffer.BitDepth); Assert.Equal(Av1ColorFormat.Yuv420, frameBuffer.ColorFormat); AssertNativePlanesEqual( decoder, frameBuffer, nativeReference.AsSpan(nativeOffset, nativeFrameLength)); nativeOffset += nativeFrameLength; ObuSequenceHeader sequenceHeader = Assert.IsType(decoder.SequenceHeader); Av1FrameInfo frameInfo = Assert.IsType(decoder.FrameInfo); int superblockColumnCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, sequenceHeader.SuperblockSizeLog2) >> sequenceHeader.SuperblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameHeight, sequenceHeader.SuperblockSizeLog2) >> sequenceHeader.SuperblockSizeLog2; for (int superblockRow = 0; superblockRow < superblockRowCount; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount; superblockColumn++) { Av1SuperblockInfo superblockInfo = frameInfo.GetSuperblock(new Point(superblockColumn, superblockRow)); foreach (Av1BlockModeInfo modeInfo in superblockInfo.GetModeInfos()) { if (modeInfo.YMode is >= Av1PredictionMode.IntraModeStart and < Av1PredictionMode.IntraModeEnd) { intraModeCoverage |= 1 << ((int)modeInfo.YMode - (int)Av1PredictionMode.IntraModeStart); } int firstTransformLocation = modeInfo.GetFirstTransformLocation(Av1Plane.Y); int transformUnitCount = modeInfo.GetTransformUnitCount(Av1Plane.Y); foreach (Av1TransformInfo transformInfo in superblockInfo.GetTransformInfoY().Slice(firstTransformLocation, transformUnitCount)) { transformTypeCoverage |= 1 << (int)transformInfo.Type; } } } } } Assert.Equal(ivf.Length, ivfOffset); Assert.Equal(nativeReference.Length, nativeOffset); Assert.Equal(RequiredIntraModeCoverage, intraModeCoverage); Assert.Equal(RequiredAllIntraTransformTypeCoverage, transformTypeCoverage); } /// /// Verifies adaptive tile and frame-end CDF updates against the official pinned-libaom sequence and exact native /// output under normal and scalar dispatch. /// [Fact] public void DecodeOfficialCdfUpdateSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialCdfUpdateFixture, ReconstructionConfigurations); /// /// Verifies temporal reference-motion-vector projection against the official pinned-libaom sequence and exact /// native output under normal and scalar dispatch. /// [Fact] public void DecodeOfficialMotionFieldSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialMotionFieldFixture, ReconstructionConfigurations); /// /// Verifies extreme intra-block-copy displacement vectors against the official pinned-libaom sequence and exact /// native output under normal and scalar dispatch. /// [Fact] public void DecodeOfficialIntraBlockCopySequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialIntraBlockCopyFixture, ReconstructionConfigurations); /// /// Decodes the official intra-block-copy sequence and proves that the active copied blocks reconstruct exactly. /// private static void ValidateOfficialIntraBlockCopyFixture() { byte[] ivf = TestFile.Create(TestImages.Heif.Av1OfficialIntraBlockCopySequence).Bytes; byte[] nativeReference = TestFile.Create(TestImages.Heif.Av1OfficialIntraBlockCopySequenceNativeReference).Bytes; ReadOnlySpan y4mFileHeader = "YUV4MPEG2 W1920 H1080 F30:1 Ip C420jpeg\n"u8; ReadOnlySpan y4mFrameHeader = "FRAME\n"u8; Assert.True(ivf.AsSpan(0, 4).SequenceEqual("DKIF"u8)); Assert.Equal(0, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(4, 2))); Assert.Equal(32, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(6, 2))); Assert.True(ivf.AsSpan(8, 4).SequenceEqual("AV01"u8)); Assert.Equal(OfficialIntraBlockCopyFixtureWidth, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(12, 2))); Assert.Equal(OfficialIntraBlockCopyFixtureHeight, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(14, 2))); Assert.Equal( OfficialIntraBlockCopyFixtureFrameCount, checked((int)BinaryPrimitives.ReadUInt32LittleEndian(ivf.AsSpan(24, 4)))); Assert.True(nativeReference.AsSpan().StartsWith(y4mFileHeader)); int ivfOffset = 32; int nativeOffset = y4mFileHeader.Length; int nativeFrameLength = (OfficialIntraBlockCopyFixtureWidth * OfficialIntraBlockCopyFixtureHeight) + (2 * (OfficialIntraBlockCopyFixtureWidth >> 1) * (OfficialIntraBlockCopyFixtureHeight >> 1)); int intraBlockCopyBlockCount = 0; bool allowIntraBlockCopy = false; using Av1Decoder decoder = new(Configuration.Default); for (int frameIndex = 0; frameIndex < OfficialIntraBlockCopyFixtureFrameCount; frameIndex++) { int payloadLength = checked((int)BinaryPrimitives.ReadUInt32LittleEndian(ivf.AsSpan(ivfOffset, 4))); ivfOffset += 12; using ImageFrame frame = decoder.DecodeSequenceFrame( ivf.AsSpan(ivfOffset, payloadLength), null, null); ivfOffset += payloadLength; Assert.Equal(OfficialIntraBlockCopyFixtureWidth, frame.Width); Assert.Equal(OfficialIntraBlockCopyFixtureHeight, frame.Height); Assert.True(nativeReference.AsSpan(nativeOffset).StartsWith(y4mFrameHeader)); nativeOffset += y4mFrameHeader.Length; Av1FrameBuffer frameBuffer = Assert.IsType>(decoder.FrameBuffer); Assert.Equal(OfficialIntraBlockCopyFixtureWidth, frameBuffer.Width); Assert.Equal(OfficialIntraBlockCopyFixtureHeight, frameBuffer.Height); Assert.Equal(Av1BitDepth.EightBit, frameBuffer.BitDepth); Assert.Equal(Av1ColorFormat.Yuv420, frameBuffer.ColorFormat); AssertNativePlanesEqual( decoder, frameBuffer, nativeReference.AsSpan(nativeOffset, nativeFrameLength)); nativeOffset += nativeFrameLength; ObuFrameHeader frameHeader = Assert.IsType(decoder.FrameHeader); allowIntraBlockCopy |= frameHeader.AllowIntraBlockCopy; intraBlockCopyBlockCount += GetIntraBlockCopyBlockCount(decoder); } Assert.Equal(ivf.Length, ivfOffset); Assert.Equal(nativeReference.Length, nativeOffset); Assert.True(allowIntraBlockCopy); Assert.NotEqual(0, intraBlockCopyBlockCount); } /// /// Verifies exact temporal motion-field reconstruction and balanced ownership with a constrained allocator. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialMotionFieldSequenceWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 2_048 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; int coverage = ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialMotionFieldSequence, TestImages.Heif.Av1OfficialMotionFieldSequenceNativeReference, OfficialMotionFieldFixtureFrameCount); Assert.NotEqual(0, coverage & ReferenceFrameMotionVectorCoverage); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "RetainedMotionFieldEntry"); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "TemporalMotionFieldEntry"); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Validates that the official CDF-update fixture selects both adaptive update boundaries. /// private static void ValidateOfficialCdfUpdateFixture() { int coverage = ValidateOfficialCompactSequence( Configuration.Default, TestImages.Heif.Av1OfficialCdfUpdateSequence, TestImages.Heif.Av1OfficialCdfUpdateSequenceNativeReference, OfficialCdfUpdateFixtureFrameCount); Assert.Equal(TileCdfUpdateCoverage | FrameEndCdfUpdateCoverage, coverage & 3); } /// /// Validates that the official temporal motion-field fixture enables projected reference motion vectors. /// private static void ValidateOfficialMotionFieldFixture() { int coverage = ValidateOfficialCompactSequence( Configuration.Default, TestImages.Heif.Av1OfficialMotionFieldSequence, TestImages.Heif.Av1OfficialMotionFieldSequenceNativeReference, OfficialMotionFieldFixtureFrameCount); Assert.NotEqual(0, coverage & ReferenceFrameMotionVectorCoverage); } /// /// Verifies the default operating point of an official two-spatial-layer sequence against exact pinned-libaom /// native output under normal and scalar dispatch. /// [Fact] public void DecodeOfficialTwoSpatialLayerSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialTwoSpatialLayerFixture, ReconstructionConfigurations); /// /// Verifies the official two-spatial-layer sequence through constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialTwoSpatialLayerSequenceWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 8_192 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialTwoSpatialLayerSequence, TestImages.Heif.Av1OfficialTwoSpatialLayerSequenceNativeReference, OfficialTwoSpatialLayerFixtureFrameCount, OfficialTwoSpatialLayerFixtureWidth, OfficialTwoSpatialLayerFixtureHeight); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Decodes the default operating point of the official two-spatial-layer sequence. /// private static void ValidateOfficialTwoSpatialLayerFixture() => ValidateOfficialCompactSequence( Configuration.Default, TestImages.Heif.Av1OfficialTwoSpatialLayerSequence, TestImages.Heif.Av1OfficialTwoSpatialLayerSequenceNativeReference, OfficialTwoSpatialLayerFixtureFrameCount, OfficialTwoSpatialLayerFixtureWidth, OfficialTwoSpatialLayerFixtureHeight); /// /// Verifies the default operating point of an official two-temporal-layer sequence against exact pinned-libaom /// native output under normal and scalar dispatch. /// [Fact] public void DecodeOfficialTwoTemporalLayerSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialTwoTemporalLayerFixture, ReconstructionConfigurations); /// /// Verifies the official two-temporal-layer sequence through constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialTwoTemporalLayerSequenceWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 8_192 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialTwoTemporalLayerSequence, TestImages.Heif.Av1OfficialTwoTemporalLayerSequenceNativeReference, OfficialTwoTemporalLayerFixtureFrameCount, OfficialTwoTemporalLayerFixtureWidth, OfficialTwoTemporalLayerFixtureHeight); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Decodes the default operating point of the official two-temporal-layer sequence. /// private static void ValidateOfficialTwoTemporalLayerFixture() => ValidateOfficialCompactSequence( Configuration.Default, TestImages.Heif.Av1OfficialTwoTemporalLayerSequence, TestImages.Heif.Av1OfficialTwoTemporalLayerSequenceNativeReference, OfficialTwoTemporalLayerFixtureFrameCount, OfficialTwoTemporalLayerFixtureWidth, OfficialTwoTemporalLayerFixtureHeight); /// /// Verifies the default operating point of an official spatial-and-temporal-layer sequence against exact /// pinned-libaom native output under normal and scalar dispatch. /// [Fact] public void DecodeOfficialSpatialTemporalLayerSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialSpatialTemporalLayerFixture, ReconstructionConfigurations); /// /// Verifies the official spatial-and-temporal-layer sequence through constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialSpatialTemporalLayerSequenceWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 8_192 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialSpatialTemporalLayerSequence, TestImages.Heif.Av1OfficialSpatialTemporalLayerSequenceNativeReference, OfficialSpatialTemporalLayerFixtureFrameCount, OfficialSpatialTemporalLayerFixtureWidth, OfficialSpatialTemporalLayerFixtureHeight); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Decodes the default operating point of the official spatial-and-temporal-layer sequence. /// private static void ValidateOfficialSpatialTemporalLayerFixture() => ValidateOfficialCompactSequence( Configuration.Default, TestImages.Heif.Av1OfficialSpatialTemporalLayerSequence, TestImages.Heif.Av1OfficialSpatialTemporalLayerSequenceNativeReference, OfficialSpatialTemporalLayerFixtureFrameCount, OfficialSpatialTemporalLayerFixtureWidth, OfficialSpatialTemporalLayerFixtureHeight); /// /// Verifies active film-grain presentation and dependent-frame reconstruction against exact pinned-libaom native /// output under normal and scalar dispatch. /// [Fact] public void DecodeOfficialFilmGrainSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialFilmGrainFixture, ReconstructionConfigurations); /// /// Verifies the official film-grain sequence through constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialFilmGrainSequenceWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 2_048 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; int coverage = ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialFilmGrainSequence, TestImages.Heif.Av1OfficialFilmGrainSequenceNativeReference, OfficialFilmGrainFixtureFrameCount); Assert.NotEqual(0, coverage & FilmGrainCoverage); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Decodes the official film-grain sequence and verifies that synthesis is active. /// private static void ValidateOfficialFilmGrainFixture() { int coverage = ValidateOfficialCompactSequence( Configuration.Default, TestImages.Heif.Av1OfficialFilmGrainSequence, TestImages.Heif.Av1OfficialFilmGrainSequenceNativeReference, OfficialFilmGrainFixtureFrameCount); Assert.NotEqual(0, coverage & FilmGrainCoverage); } /// /// Verifies the official ten-bit film-grain sequence against exact pinned-libaom native output. /// [Fact] public void DecodeOfficialTenBitFilmGrainSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialTenBitFilmGrainFixture, ReconstructionConfigurations); /// /// Decodes the official ten-bit film-grain sequence and verifies that synthesis is active. /// private static void ValidateOfficialTenBitFilmGrainFixture() { int coverage = ValidateOfficialCompactSequence( Configuration.Default, TestImages.Heif.Av1OfficialTenBitFilmGrainSequence, TestImages.Heif.Av1OfficialTenBitFilmGrainSequenceNativeReference, OfficialFilmGrainFixtureFrameCount, OfficialMotionVectorFixtureWidth, OfficialMotionVectorFixtureHeight, Av1ColorFormat.Yuv420, Av1BitDepth.TenBit); Assert.NotEqual(0, coverage & FilmGrainCoverage); } /// /// Verifies the official eight-bit monochrome sequence against exact pinned-libaom native output under normal and /// scalar dispatch. /// [Fact] public void DecodeOfficialMonochromeSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialMonochromeFixture, ReconstructionConfigurations); /// /// Verifies the official eight-bit monochrome sequence through constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialMonochromeSequenceWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 2_048 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialMonochromeSequence, TestImages.Heif.Av1OfficialMonochromeSequenceNativeReference, OfficialMonochromeFixtureFrameCount, OfficialMonochromeFixtureWidth, OfficialMonochromeFixtureHeight, Av1ColorFormat.Yuv400); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Decodes the official eight-bit monochrome sequence. /// private static void ValidateOfficialMonochromeFixture() => ValidateOfficialCompactSequence( Configuration.Default, TestImages.Heif.Av1OfficialMonochromeSequence, TestImages.Heif.Av1OfficialMonochromeSequenceNativeReference, OfficialMonochromeFixtureFrameCount, OfficialMonochromeFixtureWidth, OfficialMonochromeFixtureHeight, Av1ColorFormat.Yuv400); /// /// Verifies the official ten-bit monochrome sequence against exact pinned-libaom native output. /// [Fact] public void DecodeOfficialTenBitMonochromeSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialTenBitMonochromeFixture, ReconstructionConfigurations); /// /// Decodes the official ten-bit monochrome sequence. /// private static void ValidateOfficialTenBitMonochromeFixture() => ValidateOfficialCompactSequence( Configuration.Default, TestImages.Heif.Av1OfficialTenBitMonochromeSequence, TestImages.Heif.Av1OfficialTenBitMonochromeSequenceNativeReference, OfficialMonochromeFixtureFrameCount, OfficialMonochromeFixtureWidth, OfficialMonochromeFixtureHeight, Av1ColorFormat.Yuv400, Av1BitDepth.TenBit); /// /// Verifies both official ten-bit sequences through constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialTenBitSequencesWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 2_048 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; int filmGrainCoverage = ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialTenBitFilmGrainSequence, TestImages.Heif.Av1OfficialTenBitFilmGrainSequenceNativeReference, OfficialFilmGrainFixtureFrameCount, OfficialMotionVectorFixtureWidth, OfficialMotionVectorFixtureHeight, Av1ColorFormat.Yuv420, Av1BitDepth.TenBit); ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialTenBitMonochromeSequence, TestImages.Heif.Av1OfficialTenBitMonochromeSequenceNativeReference, OfficialMonochromeFixtureFrameCount, OfficialMonochromeFixtureWidth, OfficialMonochromeFixtureHeight, Av1ColorFormat.Yuv400, Av1BitDepth.TenBit); Assert.NotEqual(0, filmGrainCoverage & FilmGrainCoverage); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Verifies the official eight-bit quantizer boundaries against exact pinned-libaom native output. /// [Fact] public void DecodeOfficialEightBitQuantizerBoundarySequencesMatchPinnedLibaomReferences() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialEightBitQuantizerBoundaryFixtures, ReconstructionConfigurations); /// /// Decodes the official eight-bit quantizer boundaries. /// private static void ValidateOfficialEightBitQuantizerBoundaryFixtures() => ValidateOfficialEightBitQuantizerBoundaryFixturesWithConfiguration(Configuration.Default); /// /// Verifies the official ten-bit quantizer boundaries against exact pinned-libaom native output. /// [Fact] public void DecodeOfficialTenBitQuantizerBoundarySequencesMatchPinnedLibaomReferences() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialTenBitQuantizerBoundaryFixtures, ReconstructionConfigurations); /// /// Decodes the official ten-bit quantizer boundaries. /// private static void ValidateOfficialTenBitQuantizerBoundaryFixtures() => ValidateOfficialTenBitQuantizerBoundaryFixturesWithConfiguration(Configuration.Default); /// /// Verifies the official quantizer boundaries through constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialQuantizerBoundarySequencesWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 2_560 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateOfficialEightBitQuantizerBoundaryFixturesWithConfiguration(configuration); ValidateOfficialTenBitQuantizerBoundaryFixturesWithConfiguration(configuration); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Decodes both retained official eight-bit quantizer-boundary fixtures. /// private static void ValidateOfficialEightBitQuantizerBoundaryFixturesWithConfiguration(Configuration configuration) { ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialEightBitMinimumQuantizerSequence, TestImages.Heif.Av1OfficialEightBitMinimumQuantizerSequenceNativeReference, OfficialQuantizerFixtureFrameCount, OfficialEightBitQuantizerFixtureWidth, OfficialEightBitQuantizerFixtureHeight); ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialEightBitMaximumQuantizerSequence, TestImages.Heif.Av1OfficialEightBitMaximumQuantizerSequenceNativeReference, OfficialQuantizerFixtureFrameCount, OfficialEightBitQuantizerFixtureWidth, OfficialEightBitQuantizerFixtureHeight); } /// /// Decodes both retained official ten-bit quantizer-boundary fixtures. /// private static void ValidateOfficialTenBitQuantizerBoundaryFixturesWithConfiguration(Configuration configuration) { ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialTenBitMinimumQuantizerSequence, TestImages.Heif.Av1OfficialTenBitMinimumQuantizerSequenceNativeReference, OfficialQuantizerFixtureFrameCount, OfficialTenBitQuantizerFixtureWidth, OfficialTenBitQuantizerFixtureHeight, Av1ColorFormat.Yuv420, Av1BitDepth.TenBit, "60:1"); ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialTenBitMaximumQuantizerSequence, TestImages.Heif.Av1OfficialTenBitMaximumQuantizerSequenceNativeReference, OfficialQuantizerFixtureFrameCount, OfficialTenBitQuantizerFixtureWidth, OfficialTenBitQuantizerFixtureHeight, Av1ColorFormat.Yuv420, Av1BitDepth.TenBit, "60:1"); } /// /// Verifies all four corners of the official frame-size matrix against exact pinned-libaom native output. /// [Fact] public void DecodeOfficialFrameSizeCornerSequencesMatchPinnedLibaomReferences() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialFrameSizeCornerFixtures, ReconstructionConfigurations); /// /// Decodes all four retained frame-size corners. /// private static void ValidateOfficialFrameSizeCornerFixtures() => ValidateOfficialFrameSizeCornerFixturesWithConfiguration(Configuration.Default); /// /// Verifies all four frame-size corners through constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialFrameSizeCornerSequencesWithConstrainedAllocator() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 1_024 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateOfficialFrameSizeCornerFixturesWithConfiguration(configuration); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Decodes every retained official frame-size fixture and compares every native sample. /// private static void ValidateOfficialFrameSizeCornerFixturesWithConfiguration(Configuration configuration) { ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialMinimumFrameSizeSequence, TestImages.Heif.Av1OfficialMinimumFrameSizeSequenceNativeReference, OfficialFrameSizeFixtureFrameCount, OfficialFrameSizeFixtureMinimumDimension, OfficialFrameSizeFixtureMinimumDimension); ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialMinimumWidthMaximumHeightSequence, TestImages.Heif.Av1OfficialMinimumWidthMaximumHeightSequenceNativeReference, OfficialFrameSizeFixtureFrameCount, OfficialFrameSizeFixtureMinimumDimension, OfficialFrameSizeFixtureMaximumDimension); ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialMaximumWidthMinimumHeightSequence, TestImages.Heif.Av1OfficialMaximumWidthMinimumHeightSequenceNativeReference, OfficialFrameSizeFixtureFrameCount, OfficialFrameSizeFixtureMaximumDimension, OfficialFrameSizeFixtureMinimumDimension); ValidateOfficialCompactSequence( configuration, TestImages.Heif.Av1OfficialMaximumFrameSizeSequence, TestImages.Heif.Av1OfficialMaximumFrameSizeSequenceNativeReference, OfficialFrameSizeFixtureFrameCount, OfficialFrameSizeFixtureMaximumDimension, OfficialFrameSizeFixtureMaximumDimension); } /// /// Decodes one compact official IVF sequence, compares every native sample, and returns its active frame-state /// coverage mask. /// private static int ValidateOfficialCompactSequence( Configuration configuration, string fixturePath, string nativeReferencePath, int expectedFrameCount, int expectedWidth = OfficialMotionVectorFixtureWidth, int expectedHeight = OfficialMotionVectorFixtureHeight, Av1ColorFormat expectedColorFormat = Av1ColorFormat.Yuv420, Av1BitDepth expectedBitDepth = Av1BitDepth.EightBit, string expectedFrameRate = "30:1") { byte[] ivf = TestFile.Create(fixturePath).Bytes; byte[] nativeReference = TestFile.Create(nativeReferencePath).Bytes; bool hasY4mHeaders = nativeReference.AsSpan().StartsWith("YUV4MPEG2 "u8); int bitDepth = expectedBitDepth switch { Av1BitDepth.EightBit => 8, Av1BitDepth.TenBit => 10, Av1BitDepth.TwelveBit => 12, _ => throw new InvalidOperationException("The compact official sequence oracle requires a valid AV1 bit depth.") }; string y4mColorSpace = expectedColorFormat switch { Av1ColorFormat.Yuv400 => expectedBitDepth == Av1BitDepth.EightBit ? "Cmono" : $"Cmono{bitDepth}", Av1ColorFormat.Yuv420 => expectedBitDepth == Av1BitDepth.EightBit ? "C420jpeg" : $"C420p{bitDepth} XYSCSS=420P{bitDepth}", _ => throw new InvalidOperationException("The compact official sequence oracle supports YUV400 and YUV420 references.") }; ReadOnlySpan y4mFileHeader = hasY4mHeaders ? Encoding.ASCII.GetBytes( $"YUV4MPEG2 W{expectedWidth} H{expectedHeight} F{expectedFrameRate} Ip {y4mColorSpace}\n") : []; ReadOnlySpan y4mFrameHeader = "FRAME\n"u8; Assert.True(ivf.AsSpan(0, 4).SequenceEqual("DKIF"u8)); Assert.Equal(0, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(4, 2))); Assert.Equal(32, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(6, 2))); Assert.True(ivf.AsSpan(8, 4).SequenceEqual("AV01"u8)); Assert.Equal(expectedWidth, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(12, 2))); Assert.Equal(expectedHeight, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(14, 2))); Assert.Equal( expectedFrameCount, checked((int)BinaryPrimitives.ReadUInt32LittleEndian(ivf.AsSpan(24, 4)))); Assert.True(nativeReference.AsSpan().StartsWith(y4mFileHeader)); int ivfOffset = 32; int nativeOffset = y4mFileHeader.Length; int nativeSampleCount = expectedColorFormat == Av1ColorFormat.Yuv400 ? expectedWidth * expectedHeight : (expectedWidth * expectedHeight) + (2 * GetSubsampledSize(expectedWidth, 1) * GetSubsampledSize(expectedHeight, 1)); int nativeFrameLength = nativeSampleCount * (expectedBitDepth == Av1BitDepth.EightBit ? 1 : sizeof(ushort)); int coverage = 0; using Av1Decoder decoder = new(configuration); for (int frameIndex = 0; frameIndex < expectedFrameCount; frameIndex++) { int payloadLength = checked((int)BinaryPrimitives.ReadUInt32LittleEndian(ivf.AsSpan(ivfOffset, 4))); ivfOffset += 12; using ImageFrame frame = decoder.DecodeSequenceFrame( ivf.AsSpan(ivfOffset, payloadLength), null, null); ivfOffset += payloadLength; Assert.Equal(expectedWidth, frame.Width); Assert.Equal(expectedHeight, frame.Height); if (hasY4mHeaders) { Assert.True(nativeReference.AsSpan(nativeOffset).StartsWith(y4mFrameHeader)); nativeOffset += y4mFrameHeader.Length; } Av1FrameBuffer frameBuffer = Assert.IsType>(decoder.FrameBuffer); Assert.Equal(expectedBitDepth, frameBuffer.BitDepth); Assert.Equal(expectedColorFormat, frameBuffer.ColorFormat); AssertNativePlanesEqual( decoder, frameBuffer, nativeReference.AsSpan(nativeOffset, nativeFrameLength), frameIndex); nativeOffset += nativeFrameLength; ObuFrameHeader frameHeader = Assert.IsType(decoder.FrameHeader); coverage |= frameHeader.DisableCdfUpdate ? 0 : TileCdfUpdateCoverage; coverage |= frameHeader.DisableFrameEndUpdateCdf ? 0 : FrameEndCdfUpdateCoverage; coverage |= frameHeader.UseReferenceFrameMotionVectors ? ReferenceFrameMotionVectorCoverage : 0; coverage |= frameHeader.FilmGrainParameters.ApplyGrain ? FilmGrainCoverage : 0; } Assert.Equal(ivf.Length, ivfOffset); Assert.Equal(nativeReference.Length, nativeOffset); return coverage; } /// /// Verifies every ordinary inter mode, motion mode, and switchable dual-filter pair against the official /// pinned-libaom motion-vector conformance sequence and its exact native output. /// [Fact] public void DecodeOfficialMotionVectorSequenceMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateOfficialMotionVectorFixtureWithDefaultConfiguration, ReconstructionConfigurations); /// /// Verifies the official motion-vector conformance sequence through constrained tracked allocation. /// [Fact] [ValidateDisposedMemoryAllocations] public void DecodeOfficialMotionVectorSequenceUsesContiguousPlanes() { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 2_048 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateOfficialMotionVectorFixture(configuration); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "RetainedMotionFieldEntry"); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "TemporalMotionFieldEntry"); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Runs the official motion-vector fixture with the default decoder configuration. /// private static void ValidateOfficialMotionVectorFixtureWithDefaultConfiguration() => ValidateOfficialMotionVectorFixture(Configuration.Default); /// /// Decodes every IVF sample in one retained session, compares each shown frame exactly, and records the /// syntax selections that make the vector authoritative for ordinary inter-mode and filter coverage. /// private static void ValidateOfficialMotionVectorFixture(Configuration configuration) { byte[] ivf = TestFile.Create(TestImages.Heif.Av1OfficialMotionVectorSequence).Bytes; byte[] nativeReference = TestFile.Create(TestImages.Heif.Av1OfficialMotionVectorSequenceNativeReference).Bytes; ReadOnlySpan y4mFileHeader = "YUV4MPEG2 W352 H288 F30:1 Ip C420jpeg\n"u8; ReadOnlySpan y4mFrameHeader = "FRAME\n"u8; Assert.True(ivf.AsSpan(0, 4).SequenceEqual("DKIF"u8)); Assert.Equal(0, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(4, 2))); Assert.Equal(32, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(6, 2))); Assert.True(ivf.AsSpan(8, 4).SequenceEqual("AV01"u8)); Assert.Equal(OfficialMotionVectorFixtureWidth, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(12, 2))); Assert.Equal(OfficialMotionVectorFixtureHeight, BinaryPrimitives.ReadUInt16LittleEndian(ivf.AsSpan(14, 2))); Assert.Equal( OfficialMotionVectorFixtureFrameCount, checked((int)BinaryPrimitives.ReadUInt32LittleEndian(ivf.AsSpan(24, 4)))); Assert.True(nativeReference.AsSpan().StartsWith(y4mFileHeader)); int ivfOffset = 32; int nativeOffset = y4mFileHeader.Length; int nativeFrameLength = (OfficialMotionVectorFixtureWidth * OfficialMotionVectorFixtureHeight) + (2 * (OfficialMotionVectorFixtureWidth >> 1) * (OfficialMotionVectorFixtureHeight >> 1)); int interModeCoverage = 0; int motionModeCoverage = 0; int switchableFilterPairCoverage = 0; using Av1Decoder decoder = new(configuration); for (int frameIndex = 0; frameIndex < OfficialMotionVectorFixtureFrameCount; frameIndex++) { int payloadLength = checked((int)BinaryPrimitives.ReadUInt32LittleEndian(ivf.AsSpan(ivfOffset, 4))); ivfOffset += 12; ImageFrame decodedFrame = decoder.DecodeSequenceFrame( ivf.AsSpan(ivfOffset, payloadLength), null, null); using ImageFrame frame = decodedFrame; ivfOffset += payloadLength; Assert.Equal(OfficialMotionVectorFixtureWidth, frame.Width); Assert.Equal(OfficialMotionVectorFixtureHeight, frame.Height); Assert.True(nativeReference.AsSpan(nativeOffset).StartsWith(y4mFrameHeader)); nativeOffset += y4mFrameHeader.Length; Av1FrameBuffer frameBuffer = Assert.IsType>(decoder.FrameBuffer); Assert.Equal(OfficialMotionVectorFixtureWidth, frameBuffer.Width); Assert.Equal(OfficialMotionVectorFixtureHeight, frameBuffer.Height); Assert.Equal(Av1BitDepth.EightBit, frameBuffer.BitDepth); Assert.Equal(Av1ColorFormat.Yuv420, frameBuffer.ColorFormat); AssertNativePlanesEqual( decoder, frameBuffer, nativeReference.AsSpan(nativeOffset, nativeFrameLength)); nativeOffset += nativeFrameLength; ObuSequenceHeader sequenceHeader = Assert.IsType(decoder.SequenceHeader); Av1FrameInfo frameInfo = Assert.IsType(decoder.FrameInfo); int superblockColumnCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, sequenceHeader.SuperblockSizeLog2) >> sequenceHeader.SuperblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameHeight, sequenceHeader.SuperblockSizeLog2) >> sequenceHeader.SuperblockSizeLog2; for (int superblockRow = 0; superblockRow < superblockRowCount; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount; superblockColumn++) { Av1SuperblockInfo superblockInfo = frameInfo.GetSuperblock(new Point(superblockColumn, superblockRow)); foreach (Av1BlockModeInfo modeInfo in superblockInfo.GetModeInfos()) { if (modeInfo.YMode is < Av1PredictionMode.InterModeStart or >= Av1PredictionMode.InterModeEnd) { continue; } interModeCoverage |= 1 << ((int)modeInfo.YMode - (int)Av1PredictionMode.InterModeStart); motionModeCoverage |= 1 << (int)modeInfo.MotionMode; int verticalFilter = (int)modeInfo.InterpolationFilters[0]; int horizontalFilter = (int)modeInfo.InterpolationFilters[1]; switchableFilterPairCoverage |= 1 << ((verticalFilter * 3) + horizontalFilter); } } } } Assert.Equal(ivf.Length, ivfOffset); Assert.Equal(nativeReference.Length, nativeOffset); Assert.Equal(RequiredInterModeCoverage, interModeCoverage); Assert.Equal(RequiredMotionModeCoverage, motionModeCoverage); Assert.Equal(RequiredSwitchableFilterPairCoverage, switchableFilterPairCoverage); } /// /// Verifies one complete inter-prediction sequence with a separately tracked constrained allocator. /// private static void ValidateInterPredictionSequenceWithConstrainedAllocator( string imagePath, string nativeReferencePath, int requiredCoverage, int fixtureSize, int visibleFrameCount) { TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 1_024 }; allocator.EnableNonThreadSafeLogging(); Configuration configuration = Configuration.Default.Clone(); configuration.MemoryAllocator = allocator; ValidateInterPredictionSequence( configuration, imagePath, nativeReferencePath, requiredCoverage, fixtureSize, visibleFrameCount); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "RetainedMotionFieldEntry"); Assert.Contains(allocator.AllocationLog, request => request.ElementType.Name == "TemporalMotionFieldEntry"); Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); Assert.All( allocator.AllocationLog, allocation => Assert.Single( allocator.ReturnLog, returned => returned.AllocationId == allocation.AllocationId)); } /// /// Runs one selectable compound fixture with exact native and final presentation comparisons. /// /// The serialized input provider and reference-output naming context. private static void ValidateSelectableCompoundSequenceWithDefaultConfiguration(string providerDump) { TestImageProvider provider = FeatureTestRunner.DeserializeForXunit>(providerDump); (string NativeReferencePath, int RequiredCoverage) expected = provider.SourceFileOrDescription switch { TestImages.Heif.Av1DistanceWeightedCompoundSequenceAvif => (TestImages.Heif.Av1DistanceWeightedCompoundSequenceNativeReference, DistanceWeightedCompoundCoverage), TestImages.Heif.Av1WedgeCompoundSequenceAvif => (TestImages.Heif.Av1WedgeCompoundSequenceNativeReference, WedgeCompoundCoverage | InvertedWedgeCompoundCoverage), TestImages.Heif.Av1DifferenceWeightedCompoundSequenceAvif => (TestImages.Heif.Av1DifferenceWeightedCompoundSequenceNativeReference, DifferenceWeightedCompoundCoverage | InvertedDifferenceWeightedCompoundCoverage), TestImages.Heif.Av1InterIntraSequenceAvif => (TestImages.Heif.Av1InterIntraSequenceNativeReference, SmoothInterIntraCoverage | WedgeInterIntraCoverage), _ => throw new InvalidOperationException($"Unexpected selectable-compound fixture: {provider.SourceFileOrDescription}.") }; ValidateInterPredictionSequence( Configuration.Default, provider.SourceFileOrDescription, expected.NativeReferencePath, expected.RequiredCoverage, AverageCompoundFixtureSize, AverageCompoundFixtureFrameCount); ValidateFinalSequencePresentation(providerDump); } /// /// Runs the OBMC sequence with exact final presentation comparison. /// /// The serialized input provider and reference-output naming context. private static void ValidateObmcSequenceWithDefaultConfiguration(string providerDump) { ValidateInterPredictionSequence( Configuration.Default, TestImages.Heif.Av1ObmcSequenceAvif, TestImages.Heif.Av1ObmcSequenceNativeReference, ObmcCoverage, AverageCompoundFixtureSize, AverageCompoundFixtureFrameCount); ValidateFinalSequencePresentation(providerDump); } /// /// Runs the local warped-motion sequence with exact final presentation comparison. /// /// The serialized input provider and reference-output naming context. private static void ValidateLocalWarpSequenceWithDefaultConfiguration(string providerDump) { ValidateInterPredictionSequence( Configuration.Default, TestImages.Heif.Av1LocalWarpSequenceAvif, TestImages.Heif.Av1LocalWarpSequenceNativeReference, LocalWarpCoverage, 256, 2); ValidateFinalSequencePresentation(providerDump); } /// /// Runs the non-translational global-motion sequence with exact final presentation comparison. /// /// The serialized input provider and reference-output naming context. private static void ValidateGlobalWarpSequenceWithDefaultConfiguration(string providerDump) { ValidateInterPredictionSequence( Configuration.Default, TestImages.Heif.Av1GlobalWarpSequenceAvif, TestImages.Heif.Av1GlobalWarpSequenceNativeReference, GlobalWarpCoverage, 256, 2); ValidateFinalSequencePresentation(providerDump); } /// /// Decodes one complete retained-reference sequence and compares its final native samples exactly. /// private static void ValidateInterPredictionSequence( Configuration configuration, string imagePath, string nativeReferencePath, int requiredCoverage, int fixtureSize, int visibleFrameCount) { byte[] fileBytes = TestFile.Create(imagePath).Bytes; byte[] referenceBytes = TestFile.Create(nativeReferencePath).Bytes; string fileHeaderText = $"YUV4MPEG2 W{fixtureSize} H{fixtureSize} F25:1 Ip A0:0 C444 XYSCSS=444 XCOLORRANGE=LIMITED\n"; ReadOnlySpan fileHeader = Encoding.ASCII.GetBytes(fileHeaderText); ReadOnlySpan frameHeader = "FRAME\n"u8; ReadOnlySpan nativeReference = referenceBytes; Assert.True(nativeReference.StartsWith(fileHeader)); nativeReference = nativeReference[fileHeader.Length..]; Assert.True(nativeReference.StartsWith(frameHeader)); nativeReference = nativeReference[frameHeader.Length..]; Assert.Equal(fixtureSize * fixtureSize * 3, nativeReference.Length); HeifSequence sequence = ParseImageSequence(fileBytes); HeifSequenceTrack track = sequence.ColorTrack; int coverage = 0; int decodedVisibleFrameCount = 0; bool nativeCompared = false; using Av1Decoder decoder = new(configuration); for (int sampleIndex = 0; sampleIndex < track.Samples.Length; sampleIndex++) { HeifSequenceSample sample = track.Samples[sampleIndex]; Span sampleData = fileBytes.AsSpan((int)sample.Offset, sample.Length); if (sample.IsHidden) { decoder.DecodeSequenceReference( sampleData, track.CicpProfile, track.Av1CodecConfiguration); coverage |= GetInterPredictionCoverage(decoder); continue; } using ImageFrame frame = decoder.DecodeSequenceFrame( sampleData, track.CicpProfile, track.Av1CodecConfiguration); Av1FrameBuffer frameBuffer = Assert.IsType>(decoder.FrameBuffer); coverage |= GetInterPredictionCoverage(decoder); // Every inter-prediction branch retains the same row-addressed plane contract under constrained allocators. Assert.Equal(1, frameBuffer.BufferY!.FastMemoryGroup.Count); Assert.Equal(1, frameBuffer.BufferCb!.FastMemoryGroup.Count); Assert.Equal(1, frameBuffer.BufferCr!.FastMemoryGroup.Count); if (decodedVisibleFrameCount == visibleFrameCount - 1) { AssertNativePlanesEqual(decoder, frameBuffer, nativeReference); nativeCompared = true; } decodedVisibleFrameCount++; } Assert.Equal(visibleFrameCount, decodedVisibleFrameCount); Assert.Equal(requiredCoverage, coverage & requiredCoverage); Assert.True(nativeCompared); } /// /// Collects the compound, inter-intra, OBMC, and warped modes retained in one decoded frame. /// private static int GetInterPredictionCoverage(Av1Decoder decoder) { ObuSequenceHeader sequenceHeader = Assert.IsType(decoder.SequenceHeader); ObuFrameHeader frameHeader = Assert.IsType(decoder.FrameHeader); Av1FrameInfo frameInfo = Assert.IsType(decoder.FrameInfo); int superblockSizeLog2 = sequenceHeader.SuperblockSizeLog2; int superblockColumnCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, superblockSizeLog2) >> superblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameHeight, superblockSizeLog2) >> superblockSizeLog2; int coverage = 0; for (int superblockRow = 0; superblockRow < superblockRowCount; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount; superblockColumn++) { Av1SuperblockInfo superblockInfo = frameInfo.GetSuperblock(new Point(superblockColumn, superblockRow)); foreach (Av1BlockModeInfo modeInfo in superblockInfo.GetModeInfos()) { if (modeInfo.MotionMode == Av1MotionMode.Obmc) { coverage |= ObmcCoverage; } if (modeInfo.MotionMode == Av1MotionMode.Warped) { coverage |= LocalWarpCoverage; } if (modeInfo.YMode is Av1PredictionMode.GlobalMotionVector or Av1PredictionMode.GlobalGlobalMotionVector && Math.Min(modeInfo.BlockSize.GetWidth(), modeInfo.BlockSize.GetHeight()) >= 8) { int referenceCount = modeInfo.ReferenceFrames[1] > Av1ReferenceFrameType.Intra ? 2 : 1; for (int referenceIndex = 0; referenceIndex < referenceCount; referenceIndex++) { int canonicalReferenceIndex = (int)modeInfo.ReferenceFrames[referenceIndex] - (int)Av1ReferenceFrameType.Last; Av1GlobalMotionParameters globalMotionParameters = frameHeader.GetGlobalMotionParameters()[canonicalReferenceIndex]; if (globalMotionParameters.Type > Av1GlobalMotionType.Translation && !globalMotionParameters.IsInvalid) { coverage |= GlobalWarpCoverage; } } } if (modeInfo.ReferenceFrames[1] == Av1ReferenceFrameType.Intra) { coverage |= modeInfo.UseInterIntraWedge ? WedgeInterIntraCoverage : SmoothInterIntraCoverage; continue; } if (modeInfo.ReferenceFrames[1] <= Av1ReferenceFrameType.Intra) { continue; } coverage |= modeInfo.CompoundType switch { Av1CompoundType.DistanceWeighted => DistanceWeightedCompoundCoverage, Av1CompoundType.Wedge => modeInfo.CompoundWedgeSign ? InvertedWedgeCompoundCoverage : WedgeCompoundCoverage, Av1CompoundType.DifferenceWeighted => modeInfo.DifferenceWeightedMaskType == Av1DifferenceWeightedMaskType.Type38Inverse ? InvertedDifferenceWeightedCompoundCoverage : DifferenceWeightedCompoundCoverage, _ => 0, }; } } } return coverage; } /// /// Verifies lossless syntax, residual reconstruction, and exact native samples against scalar libaom for /// independently encoded eight-, ten-, and twelve-bit AVIF images. /// [Fact] public void DecodeLosslessMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidateLosslessFixtures, LosslessConfigurations); /// /// Verifies exact presented pixels for independently encoded lossless eight-, ten-, and twelve-bit AVIF images /// across the available vector widths and the scalar fallback. /// /// The AVIF input and matching reference-output naming context. /// The expected public sample precision. [Theory] [WithFile(TestImages.Heif.Av1Lossless8BitAvif, PixelTypes.Rgba32, HeifBitDepth.Bit8)] [WithFile(TestImages.Heif.Av1Lossless10BitAvif, PixelTypes.Rgba32, HeifBitDepth.Bit10)] [WithFile(TestImages.Heif.Av1Lossless12BitAvif, PixelTypes.Rgba32, HeifBitDepth.Bit12)] public void DecodeLosslessMatchesPinnedLibavifPresentation( TestImageProvider provider, HeifBitDepth bitDepth) { AssertPresentedMetadata(provider, LosslessFixtureWidth, LosslessFixtureHeight, bitDepth); FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidatePresentedFixture, PresentationConfigurations, provider); } /// /// Verifies active normative super-resolution, chroma-width rounding, replicated edges, and exact native samples /// against scalar libaom for independently encoded eight-, ten-, and twelve-bit still-picture streams. /// [Fact] public void DecodeWithSuperResolutionMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidateSuperResolutionFixtures, ReconstructionConfigurations); /// /// Verifies exact presented pixels and public metadata for independently packaged eight-, ten-, and twelve-bit /// active-super-resolution AVIF images across the available vector widths and the scalar fallback. /// /// The AVIF input and matching reference-output naming context. /// The expected presented width. /// The expected presented height. /// The expected public sample precision. [Theory] [WithFile(TestImages.Heif.Av1SuperResolution8BitAvif, PixelTypes.Rgba32, 768, 512, HeifBitDepth.Bit8)] [WithFile(TestImages.Heif.Av1SuperResolution10BitAvif, PixelTypes.Rgba32, 1024, 428, HeifBitDepth.Bit10)] [WithFile(TestImages.Heif.Av1SuperResolution12BitAvif, PixelTypes.Rgba32, 1024, 428, HeifBitDepth.Bit12)] public void DecodeWithSuperResolutionMatchesPinnedLibavifPresentation( TestImageProvider provider, int width, int height, HeifBitDepth bitDepth) { AssertPresentedMetadata(provider, width, height, bitDepth); FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidatePresentedFixture, PresentationConfigurations, provider); } /// /// Verifies active normative loop restoration and exact native samples against scalar libaom for independently /// encoded eight-, ten-, and twelve-bit still-picture streams. /// [Fact] public void DecodeWithLoopRestorationMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidateLoopRestorationFixtures, LoopRestorationConfigurations); /// /// Verifies combined super-resolution and loop-restoration geometry for independently encoded 8-bit 4:2:0 content. /// [Fact] public void DecodeWithLoopRestorationAndSuperResolutionMatchesPinnedLibaomReference8Bit420() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateLoopRestorationAndSuperResolution8Bit420, LoopRestorationConfigurations); /// /// Verifies combined super-resolution and loop-restoration geometry for independently encoded 10-bit 4:2:2 content. /// [Fact] public void DecodeWithLoopRestorationAndSuperResolutionMatchesPinnedLibaomReference10Bit422() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateLoopRestorationAndSuperResolution10Bit422, LoopRestorationConfigurations); /// /// Verifies combined super-resolution and loop-restoration geometry for independently encoded 12-bit 4:4:4 content. /// [Fact] public void DecodeWithLoopRestorationAndSuperResolutionMatchesPinnedLibaomReference12Bit444() => FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidateLoopRestorationAndSuperResolution12Bit444, LoopRestorationConfigurations); /// /// Verifies exact presented pixels and public metadata for independently encoded eight-, ten-, and twelve-bit /// active-restoration AVIF images across the available vector widths and the scalar fallback. /// /// The AVIF input and matching reference-output naming context. /// The expected presented width. /// The expected presented height. /// The expected public sample precision. [Theory] [WithFile(TestImages.Heif.Av1Restoration8BitAvif, PixelTypes.Rgba32, 768, 512, HeifBitDepth.Bit8)] [WithFile(TestImages.Heif.Av1Restoration10BitAvif, PixelTypes.Rgba32, 1024, 428, HeifBitDepth.Bit10)] [WithFile(TestImages.Heif.Av1Restoration12BitAvif, PixelTypes.Rgba32, 1024, 428, HeifBitDepth.Bit12)] public void DecodeWithLoopRestorationMatchesPinnedLibavifPresentation( TestImageProvider provider, int width, int height, HeifBitDepth bitDepth) { AssertPresentedMetadata(provider, width, height, bitDepth); FeatureTestRunner.RunWithHwIntrinsicsFeature( ValidatePresentedFixture, PresentationConfigurations, provider); } /// /// Verifies that the independently encoded AVIF presentation fixtures collectively select both restoration algorithms. /// [Fact] public void LoopRestorationPresentationFixturesSelectBothAlgorithms() { int restorationCoverage = GetRestorationCoverageFromAvif(TestFile.Create(TestImages.Heif.Av1Restoration8BitAvif).Bytes); restorationCoverage |= GetRestorationCoverageFromAvif(TestFile.Create(TestImages.Heif.Av1Restoration10BitAvif).Bytes); restorationCoverage |= GetRestorationCoverageFromAvif(TestFile.Create(TestImages.Heif.Av1Restoration12BitAvif).Bytes); int requiredCoverage = WienerRestorationCoverage | SelfGuidedRestorationCoverage; Assert.Equal(requiredCoverage, restorationCoverage & requiredCoverage); } /// /// Verifies film-grain template generation, block selection, overlap, chroma scaling, subsampling, high-bit-depth /// arithmetic, and exact native presentation samples against scalar libaom. /// [Fact] public void DecodeWithFilmGrainMatchesPinnedLibaomReference() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidateFilmGrainFixtures, LoopRestorationConfigurations); /// /// Verifies that independently encoded AV1 streams exercise every normative coding-block partition shape. /// [Fact] public void IndependentFixturesCoverEveryPartitionType() { int coverage = GetPartitionCoverage(TestImages.Heif.Av1Cdef8BitPayload); coverage |= GetPartitionCoverage(TestImages.Heif.Av1Cdef10BitPayload); coverage |= GetPartitionCoverage(TestImages.Heif.Av1Cdef12BitPayload); Assert.Equal(RequiredPartitionCoverage, coverage & RequiredPartitionCoverage); } /// /// Validates every native profile fixture under the hardware configuration selected by /// . /// private static void ValidateProfileNativeFixtures() { ValidateProfileNativeFixture( TestImages.Heif.Av1Profile8BitMonochromeAvif, TestImages.Heif.Av1Profile8BitMonochromeReference, Av1BitDepth.EightBit, Av1ColorFormat.Yuv400, ObuSequenceProfile.Main); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile8Bit420Avif, TestImages.Heif.Av1Profile8Bit420Reference, Av1BitDepth.EightBit, Av1ColorFormat.Yuv420, ObuSequenceProfile.Main); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile8Bit422Avif, TestImages.Heif.Av1Profile8Bit422Reference, Av1BitDepth.EightBit, Av1ColorFormat.Yuv422, ObuSequenceProfile.Professional); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile8Bit444Avif, TestImages.Heif.Av1Profile8Bit444Reference, Av1BitDepth.EightBit, Av1ColorFormat.Yuv444, ObuSequenceProfile.High); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile10BitMonochromeAvif, TestImages.Heif.Av1Profile10BitMonochromeReference, Av1BitDepth.TenBit, Av1ColorFormat.Yuv400, ObuSequenceProfile.Main); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile10Bit420Avif, TestImages.Heif.Av1Profile10Bit420Reference, Av1BitDepth.TenBit, Av1ColorFormat.Yuv420, ObuSequenceProfile.Main); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile10Bit422Avif, TestImages.Heif.Av1Profile10Bit422Reference, Av1BitDepth.TenBit, Av1ColorFormat.Yuv422, ObuSequenceProfile.Professional); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile10Bit444Avif, TestImages.Heif.Av1Profile10Bit444Reference, Av1BitDepth.TenBit, Av1ColorFormat.Yuv444, ObuSequenceProfile.High); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile12BitMonochromeAvif, TestImages.Heif.Av1Profile12BitMonochromeReference, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv400, ObuSequenceProfile.Professional); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile12Bit420Avif, TestImages.Heif.Av1Profile12Bit420Reference, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv420, ObuSequenceProfile.Professional); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile12Bit422Avif, TestImages.Heif.Av1Profile12Bit422Reference, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv422, ObuSequenceProfile.Professional); ValidateProfileNativeFixture( TestImages.Heif.Av1Profile12Bit444Avif, TestImages.Heif.Av1Profile12Bit444Reference, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv444, ObuSequenceProfile.Professional); } /// /// Validates one independently encoded AVIF against its native Y4M reference and signaled sequence profile. /// /// The complete AVIF container. /// The native Y4M output produced by the pinned scalar libaom-backed decoder. /// The expected AV1 sample precision. /// The expected native chroma-sampling layout. /// The AV1 profile required by the bit-depth and chroma-format combination. private static void ValidateProfileNativeFixture( string imagePath, string referencePath, Av1BitDepth bitDepth, Av1ColorFormat colorFormat, ObuSequenceProfile sequenceProfile) { byte[] imageBytes = TestFile.Create(imagePath).Bytes; byte[] referenceBytes = TestFile.Create(referencePath).Bytes; (string chromaTag, string extendedChromaTag) = GetY4mColorSpace(bitDepth, colorFormat); string expectedHeader = $"YUV4MPEG2 W{ProfileFixtureWidth} H{ProfileFixtureHeight} F25:1 Ip A0:0 C{chromaTag} XYSCSS={extendedChromaTag} XCOLORRANGE=FULL\n"; int headerTerminator = referenceBytes.AsSpan().IndexOf((byte)'\n'); Assert.NotEqual(-1, headerTerminator); int fileHeaderLength = headerTerminator + 1; Assert.Equal(expectedHeader, Encoding.ASCII.GetString(referenceBytes, 0, fileHeaderLength)); ReadOnlySpan nativeReference = referenceBytes.AsSpan(fileHeaderLength); ReadOnlySpan frameHeader = "FRAME\n"u8; Assert.True(nativeReference.StartsWith(frameHeader)); nativeReference = nativeReference[frameHeader.Length..]; Span payload = GetSoleAv1ItemPayload(imageBytes); using Av1Decoder decoder = new(Configuration.Default); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _); Assert.Equal(ProfileFixtureWidth, frameBuffer.Width); Assert.Equal(ProfileFixtureHeight, frameBuffer.Height); Assert.Equal(bitDepth, frameBuffer.BitDepth); Assert.Equal(colorFormat, frameBuffer.ColorFormat); ObuSequenceHeader sequenceHeader = Assert.IsType(decoder.SequenceHeader); ObuColorConfig colorConfig = sequenceHeader.ColorConfig; Assert.Equal(sequenceProfile, sequenceHeader.SequenceProfile); Assert.Equal(bitDepth, colorConfig.BitDepth); Assert.Equal(colorFormat, colorConfig.GetColorFormat()); Assert.Equal(colorFormat == Av1ColorFormat.Yuv400, colorConfig.IsMonochrome); Assert.True(colorConfig.IsColorDescriptionPresent); Assert.Equal(ObuColorPrimaries.Bt709, colorConfig.ColorPrimaries); Assert.Equal(ObuTransferCharacteristics.Srgb, colorConfig.TransferCharacteristics); Assert.Equal(ObuMatrixCoefficients.Bt601, colorConfig.MatrixCoefficients); Assert.True(colorConfig.ColorRange); AssertNativePlanesEqual(decoder, frameBuffer, nativeReference); } /// /// Gets the Y4M chroma tags that encode one AV1 bit-depth and sampling-layout combination. /// /// The encoded AV1 sample precision. /// The encoded AV1 chroma-sampling layout. /// The Y4M C tag and extended XYSCSS tag. private static (string ChromaTag, string ExtendedChromaTag) GetY4mColorSpace(Av1BitDepth bitDepth, Av1ColorFormat colorFormat) { // Y4M uses a legacy 420jpeg name at eight bits, lowercase p in high-depth C tags, and uppercase P in the // corresponding XYSCSS tags. Keeping the exact spellings detects a reference generated with different layout. return (bitDepth, colorFormat) switch { (Av1BitDepth.EightBit, Av1ColorFormat.Yuv400) => ("mono", "400"), (Av1BitDepth.EightBit, Av1ColorFormat.Yuv420) => ("420jpeg", "420JPEG"), (Av1BitDepth.EightBit, Av1ColorFormat.Yuv422) => ("422", "422"), (Av1BitDepth.EightBit, Av1ColorFormat.Yuv444) => ("444", "444"), (Av1BitDepth.TenBit, Av1ColorFormat.Yuv400) => ("mono10", "400"), (Av1BitDepth.TenBit, Av1ColorFormat.Yuv420) => ("420p10", "420P10"), (Av1BitDepth.TenBit, Av1ColorFormat.Yuv422) => ("422p10", "422P10"), (Av1BitDepth.TenBit, Av1ColorFormat.Yuv444) => ("444p10", "444P10"), (Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv400) => ("mono12", "400"), (Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv420) => ("420p12", "420P12"), (Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv422) => ("422p12", "422P12"), _ => ("444p12", "444P12") }; } /// /// Validates every active-CDEF fixture under the hardware configuration selected by . /// private static void ValidateActiveCdefFixtures() { ValidateActiveCdefFixture( TestImages.Heif.Av1Cdef8BitPayload, TestImages.Heif.Av1Cdef8BitReference, 768, 512, Av1BitDepth.EightBit, Av1ColorFormat.Yuv420); ValidateActiveCdefFixture( TestImages.Heif.Av1Cdef10BitPayload, TestImages.Heif.Av1Cdef10BitReference, 1024, 428, Av1BitDepth.TenBit, Av1ColorFormat.Yuv444); ValidateActiveCdefFixture( TestImages.Heif.Av1Cdef12BitPayload, TestImages.Heif.Av1Cdef12BitReference, 1024, 428, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv444); } /// /// Validates the active-palette native fixture under the hardware configuration selected by /// . /// private static void ValidatePaletteNativeFixture() => ValidateNativeFixture( TestImages.Heif.Av1Palette8BitPayload, TestImages.Heif.Av1Palette8BitReference, 33, 11, Av1BitDepth.EightBit, Av1ColorFormat.Yuv444, requireActiveCdef: false, requireActiveLoopFilter: false, requirePalette: true); /// /// Validates every active intra-block-copy native fixture under the hardware configuration selected by /// . /// private static void ValidateIntraBlockCopyNativeFixtures() { ValidateIntraBlockCopyNativeFixture( TestImages.Heif.Av1IntraBlockCopy8BitAvif, TestImages.Heif.Av1IntraBlockCopy8BitReference, Av1BitDepth.EightBit); ValidateIntraBlockCopyNativeFixture( TestImages.Heif.Av1IntraBlockCopy10BitAvif, TestImages.Heif.Av1IntraBlockCopy10BitReference, Av1BitDepth.TenBit); ValidateIntraBlockCopyNativeFixture( TestImages.Heif.Av1IntraBlockCopy12BitAvif, TestImages.Heif.Av1IntraBlockCopy12BitReference, Av1BitDepth.TwelveBit); } /// /// Validates one independently encoded intra-block-copy AVIF against its native Y4M reference. /// /// The complete AVIF container. /// The native Y4M output produced by the pinned scalar libaom-backed decoder. /// The expected AV1 sample precision. private static void ValidateIntraBlockCopyNativeFixture(string imagePath, string referencePath, Av1BitDepth bitDepth) { byte[] imageBytes = TestFile.Create(imagePath).Bytes; byte[] referenceBytes = TestFile.Create(referencePath).Bytes; ReadOnlySpan fileHeader = bitDepth switch { Av1BitDepth.EightBit => "YUV4MPEG2 W512 H256 F25:1 Ip A0:0 C444 XYSCSS=444 XCOLORRANGE=FULL\n"u8, Av1BitDepth.TenBit => "YUV4MPEG2 W512 H256 F25:1 Ip A0:0 C444p10 XYSCSS=444P10 XCOLORRANGE=FULL\n"u8, _ => "YUV4MPEG2 W512 H256 F25:1 Ip A0:0 C444p12 XYSCSS=444P12 XCOLORRANGE=FULL\n"u8 }; ReadOnlySpan frameHeader = "FRAME\n"u8; // The retained Y4M header locks the independently decoded reference to the expected dimensions, sampling, // bit depth, and full range. Only the following frame payload contains the planar Y, U, and V samples. ReadOnlySpan nativeReference = referenceBytes; Assert.True(nativeReference.StartsWith(fileHeader)); nativeReference = nativeReference[fileHeader.Length..]; Assert.True(nativeReference.StartsWith(frameHeader)); nativeReference = nativeReference[frameHeader.Length..]; Span payload = GetSoleAv1ItemPayload(imageBytes); using Av1Decoder decoder = new(Configuration.Default); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _); Assert.Equal(512, frameBuffer.Width); Assert.Equal(256, frameBuffer.Height); Assert.Equal(bitDepth, frameBuffer.BitDepth); Assert.Equal(Av1ColorFormat.Yuv444, frameBuffer.ColorFormat); Assert.NotNull(decoder.FrameHeader); Assert.True(decoder.FrameHeader.AllowIntraBlockCopy); Assert.NotEqual(0, GetIntraBlockCopyBlockCount(decoder)); AssertNativePlanesEqual(decoder, frameBuffer, nativeReference); } /// /// Runs the exact final-layer native and presentation comparisons with the default configuration. /// /// The serialized AVIF input provider and reference-output naming context. private static void ValidateProgressiveSingleReferenceFixtureWithDefaultConfiguration(string providerDump) { ValidateProgressiveSingleReferenceFixture(Configuration.Default); ValidatePresentedFixture(providerDump); } /// /// Runs the selected-spatial-layer native and presentation comparisons with the default configuration. /// /// The serialized selected-layer provider and reference-output naming context. private static void ValidateSelectedProgressiveSpatialLayerWithDefaultConfiguration(string providerDump) { ValidateSelectedProgressiveSpatialLayer(Configuration.Default); ValidatePresentedFixture(providerDump); } /// /// Runs the exact scaled-reference native and presentation comparison with the default configuration. /// /// The serialized AVIF input provider and reference-output naming context. private static void ValidateScaledReferenceFixtureWithDefaultConfiguration(string providerDump) { ValidateScaledReferenceFixture(Configuration.Default); ValidatePresentedFixture(providerDump); } /// /// Verifies the genuine size-changing layered fixture with the requested allocator. /// /// The decoder configuration. private static void ValidateScaledReferenceFixture(Configuration configuration) { byte[] payload = TestFile.Create(TestImages.Heif.Av1ScaledReferencePayload).Bytes; byte[] baseReferenceBytes = TestFile.Create(TestImages.Heif.Av1ScaledReferenceBaseNativeReference).Bytes; byte[] referenceBytes = TestFile.Create(TestImages.Heif.Av1ScaledReferenceNativeReference).Bytes; ReadOnlySpan fileHeader = "YUV4MPEG2 W80 H80 F25:1 Ip A0:0 C444 XYSCSS=444 XCOLORRANGE=LIMITED\n"u8; ReadOnlySpan frameHeader = "FRAME\n"u8; ReadOnlySpan nativeReference = referenceBytes; Assert.True(nativeReference.StartsWith(fileHeader)); nativeReference = nativeReference[fileHeader.Length..]; Assert.True(nativeReference.StartsWith(frameHeader)); nativeReference = nativeReference[frameHeader.Length..]; Assert.Equal(ScaledReferenceFixtureSize * ScaledReferenceFixtureSize * 3, nativeReference.Length); // Decode the independently declared base extent alone to prove that the retained reference is 40x40 rather // than relying on the 80x80 item presentation dimensions recorded by the container. using (Av1Decoder baseDecoder = new(configuration)) using (Av1FrameBuffer baseFrameBuffer = baseDecoder.DecodeFrameBuffer( payload.AsSpan(0, ScaledReferenceFirstLayerSize), null, null, out _)) { Assert.Equal(ScaledReferenceBaseLayerSize, baseFrameBuffer.Width); Assert.Equal(ScaledReferenceBaseLayerSize, baseFrameBuffer.Height); Assert.Equal(ScaledReferenceBaseLayerSize * ScaledReferenceBaseLayerSize * 3, baseReferenceBytes.Length); AssertNativePlanesEqual(baseDecoder, baseFrameBuffer, baseReferenceBytes); } // Exercise the same retained owner across two calls so the independently verified base samples are checked // in the exact decoder session that supplies the size-changing reference to the dependent frame. using (Av1Decoder sequenceDecoder = new(configuration)) { sequenceDecoder.DecodeSequenceReference( payload.AsSpan(0, ScaledReferenceFirstLayerSize), null, null); Av1FrameBuffer retainedBaseFrameBuffer = Assert.IsType>(sequenceDecoder.FrameBuffer); AssertNativePlanesEqual(sequenceDecoder, retainedBaseFrameBuffer, baseReferenceBytes); using Av1FrameBuffer sequenceFrameBuffer = sequenceDecoder.DecodeFrameBuffer( payload.AsSpan(ScaledReferenceFirstLayerSize), null, null, out _); AssertNativePlanesEqual(sequenceDecoder, sequenceFrameBuffer, nativeReference); } using Av1Decoder decoder = new(configuration); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer( payload, null, null, out _, new Av1LayeredImageIndex(ScaledReferenceFirstLayerSize, 0, 0)); Assert.Equal(ScaledReferenceFixtureSize, frameBuffer.Width); Assert.Equal(ScaledReferenceFixtureSize, frameBuffer.Height); Assert.Equal(Av1BitDepth.EightBit, frameBuffer.BitDepth); Assert.Equal(Av1ColorFormat.Yuv444, frameBuffer.ColorFormat); Assert.Equal(1, frameBuffer.BufferY!.FastMemoryGroup.Count); Assert.Equal(1, frameBuffer.BufferCb!.FastMemoryGroup.Count); Assert.Equal(1, frameBuffer.BufferCr!.FastMemoryGroup.Count); ObuSequenceHeader sequenceHeader = Assert.IsType(decoder.SequenceHeader); ObuFrameHeader finalFrameHeader = Assert.IsType(decoder.FrameHeader); Av1FrameInfo frameInfo = Assert.IsType(decoder.FrameInfo); Assert.Equal(ScaledReferenceFixtureSize, sequenceHeader.MaxFrameWidth); Assert.Equal(ScaledReferenceFixtureSize, sequenceHeader.MaxFrameHeight); Assert.Equal(ObuFrameType.InterFrame, finalFrameHeader.FrameType); Assert.True(finalFrameHeader.LoopFilterParameters.ReferenceDeltaModeEnabled); Assert.NotEqual(0, finalFrameHeader.LoopFilterParameters.FilterLevelU); Assert.NotEqual(0, finalFrameHeader.LoopFilterParameters.FilterLevelV); int interBlockCount = 0; int intraBlockCount = 0; int skippedInterBlockCount = 0; int superblockSizeLog2 = sequenceHeader.SuperblockSizeLog2; int superblockColumnCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, superblockSizeLog2) >> superblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameHeight, superblockSizeLog2) >> superblockSizeLog2; for (int superblockRow = 0; superblockRow < superblockRowCount; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount; superblockColumn++) { Av1SuperblockInfo superblock = frameInfo.GetSuperblock(new Point(superblockColumn, superblockRow)); foreach (Av1BlockModeInfo modeInfo in superblock.GetModeInfos()) { if (modeInfo.ReferenceFrames[0] >= Av1ReferenceFrameType.Last) { interBlockCount++; if (modeInfo.Skip) { skippedInterBlockCount++; } } else { intraBlockCount++; } } } } Assert.NotEqual(0, interBlockCount); Assert.NotEqual(0, intraBlockCount); Assert.NotEqual(0, skippedInterBlockCount); AssertNativePlanesEqual(decoder, frameBuffer, nativeReference); } /// /// Verifies the selected base spatial layer with the requested allocator. /// /// The decoder configuration. private static void ValidateSelectedProgressiveSpatialLayer(Configuration configuration) { byte[] payload = TestFile.Create(TestImages.Heif.Av1ScaledReferencePayload).Bytes; byte[] nativeReference = TestFile.Create(TestImages.Heif.Av1ScaledReferenceBaseNativeReference).Bytes; Assert.Equal(ScaledReferenceBaseLayerSize * ScaledReferenceBaseLayerSize * 3, nativeReference.Length); Av1LayeredImageIndex layeredImageIndex = new(ScaledReferenceFirstLayerSize, 0, 0); int selectedPayloadLength = layeredImageIndex.GetPayloadLength( payload.Length, new Av1LayerSelector(0)); Assert.Equal(ScaledReferenceFirstLayerSize, selectedPayloadLength); using Av1Decoder decoder = new(configuration); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer( payload.AsSpan(0, selectedPayloadLength), null, null, out _, layeredImageIndex); Assert.Equal(ScaledReferenceBaseLayerSize, frameBuffer.Width); Assert.Equal(ScaledReferenceBaseLayerSize, frameBuffer.Height); Assert.Equal(Av1BitDepth.EightBit, frameBuffer.BitDepth); Assert.Equal(Av1ColorFormat.Yuv444, frameBuffer.ColorFormat); Assert.Equal(ObuFrameType.KeyFrame, Assert.IsType(decoder.FrameHeader).FrameType); AssertNativePlanesEqual(decoder, frameBuffer, nativeReference); } /// /// Verifies the final dependent layer with the requested allocator. /// /// The decoder configuration. private static void ValidateProgressiveSingleReferenceFixture(Configuration configuration) { byte[] payload = TestFile.Create(TestImages.Heif.Av1Progressive8BitPayload).Bytes; byte[] referenceBytes = TestFile.Create(TestImages.Heif.Av1Progressive8BitReference).Bytes; ReadOnlySpan fileHeader = "YUV4MPEG2 W33 H11 F25:1 Ip A0:0 C444alpha XYSCSS=444 XCOLORRANGE=FULL\n"u8; ReadOnlySpan frameHeader = "FRAME\n"u8; int planeSampleCount = ProgressiveFixtureWidth * ProgressiveFixtureHeight; int frameSampleCount = planeSampleCount * 4; // The reference stores both progressive YUV444-alpha outputs in decode order. Select the second frame so this // assertion cannot pass by comparing only the independently decodable base layer. ReadOnlySpan nativeReference = referenceBytes; Assert.True(nativeReference.StartsWith(fileHeader)); nativeReference = nativeReference[fileHeader.Length..]; Assert.True(nativeReference.StartsWith(frameHeader)); int storedFrameSize = frameHeader.Length + frameSampleCount; Assert.Equal(storedFrameSize * 2, nativeReference.Length); ReadOnlySpan finalFrameReference = nativeReference[storedFrameSize..]; Assert.True(finalFrameReference.StartsWith(frameHeader)); finalFrameReference = finalFrameReference[frameHeader.Length..]; Assert.Equal(frameSampleCount, finalFrameReference.Length); // The Y4M stores the color item's Y, U, and V planes before the auxiliary alpha plane. Native AV1 reconstruction // is compared with exactly those first three planes of the final dependent frame. ReadOnlySpan colorReference = finalFrameReference[..(planeSampleCount * 3)]; using Av1Decoder decoder = new(configuration); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer( payload, null, null, out _, new Av1LayeredImageIndex(ProgressiveFirstLayerSize, 0, 0)); Assert.Equal(ProgressiveFixtureWidth, frameBuffer.Width); Assert.Equal(ProgressiveFixtureHeight, frameBuffer.Height); Assert.Equal(Av1BitDepth.EightBit, frameBuffer.BitDepth); Assert.Equal(Av1ColorFormat.Yuv444, frameBuffer.ColorFormat); Assert.Equal(1, frameBuffer.BufferY!.FastMemoryGroup.Count); Assert.Equal(1, frameBuffer.BufferCb!.FastMemoryGroup.Count); Assert.Equal(1, frameBuffer.BufferCr!.FastMemoryGroup.Count); ObuSequenceHeader sequenceHeader = Assert.IsType(decoder.SequenceHeader); ObuFrameHeader finalFrameHeader = Assert.IsType(decoder.FrameHeader); Av1FrameInfo frameInfo = Assert.IsType(decoder.FrameInfo); Assert.Equal(ObuFrameType.InterFrame, finalFrameHeader.FrameType); int superblockSizeLog2 = sequenceHeader.SuperblockSizeLog2; int superblockColumnCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, superblockSizeLog2) >> superblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameHeight, superblockSizeLog2) >> superblockSizeLog2; int interBlockCount = 0; // Traverse the final coding-block records once rather than revisiting every 4x4 map cell covered by each // block. The syntax assertions ensure that this fixture reaches only the completed single-reference path. for (int superblockRow = 0; superblockRow < superblockRowCount; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount; superblockColumn++) { Av1SuperblockInfo superblock = frameInfo.GetSuperblock(new Point(superblockColumn, superblockRow)); foreach (Av1BlockModeInfo modeInfo in superblock.GetModeInfos()) { if (modeInfo.ReferenceFrames[0] < Av1ReferenceFrameType.Last) { continue; } Assert.Equal(Av1ReferenceFrameType.None, modeInfo.ReferenceFrames[1]); Assert.Equal(Av1MotionMode.SimpleTranslation, modeInfo.MotionMode); interBlockCount++; } } } Assert.NotEqual(0, interBlockCount); AssertNativePlanesEqual(decoder, frameBuffer, colorReference); DecoderOptions options = new() { Configuration = configuration, MaxFrames = 1 }; byte[] imageBytes = TestFile.Create(TestImages.Heif.Av1Progressive8BitAvif).Bytes; using Image image = Image.Load(options, imageBytes); Assert.Equal(ProgressiveFixtureWidth, image.Width); Assert.Equal(ProgressiveFixtureHeight, image.Height); Assert.Single(image.Frames); Assert.Equal(HeifBitDepth.Bit8, image.Metadata.GetHeifMetadata().BitDepth); } /// /// Parses the selected image-sequence tracks from a complete HEIF fixture. /// /// The complete HEIF file. /// The bounded image-sequence model. private static HeifSequence ParseImageSequence(byte[] fileBytes) { using MemoryStream stream = new(fileBytes, false); Span scratch = stackalloc byte[32]; while (stream.Position < stream.Length) { long boxLength = HeifBoxReader.ReadHeader( stream, stream.Length, scratch, out Heif4CharCode boxType, topLevel: true); long boxStart = stream.Position; if (boxType == Heif4CharCode.Moov) { HeifSequenceParser parser = new(new DecoderOptions { MaxFrames = 32 }); return parser.Parse(stream, boxLength); } stream.Position = checked(boxStart + boxLength); } throw new InvalidImageContentException("The HEIF fixture contains no image sequence."); } /// /// Validates every lossless native fixture under the hardware configuration selected by /// . /// private static void ValidateLosslessFixtures() { ValidateLosslessFixture( TestImages.Heif.Av1Lossless8BitAvif, TestImages.Heif.Av1Lossless8BitReference, Av1BitDepth.EightBit); ValidateLosslessFixture( TestImages.Heif.Av1Lossless10BitAvif, TestImages.Heif.Av1Lossless10BitReference, Av1BitDepth.TenBit); ValidateLosslessFixture( TestImages.Heif.Av1Lossless12BitAvif, TestImages.Heif.Av1Lossless12BitReference, Av1BitDepth.TwelveBit); } /// /// Validates every active super-resolution fixture under the hardware configuration selected by /// . /// private static void ValidateSuperResolutionFixtures() { ValidateSuperResolutionFixture( TestImages.Heif.Av1SuperResolution8BitPayload, TestImages.Heif.Av1SuperResolution8BitReference, 768, 512, Av1BitDepth.EightBit, Av1ColorFormat.Yuv420); ValidateSuperResolutionFixture( TestImages.Heif.Av1SuperResolution10BitPayload, TestImages.Heif.Av1SuperResolution10BitReference, 1024, 428, Av1BitDepth.TenBit, Av1ColorFormat.Yuv444); ValidateSuperResolutionFixture( TestImages.Heif.Av1SuperResolution12BitPayload, TestImages.Heif.Av1SuperResolution12BitReference, 1024, 428, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv444); } /// /// Validates every active loop-restoration fixture under the hardware configuration selected by /// . /// private static void ValidateLoopRestorationFixtures() { int restorationCoverage = ValidateLoopRestorationFixture( TestImages.Heif.Av1Restoration8BitPayload, TestImages.Heif.Av1Restoration8BitReference, 768, 512, Av1BitDepth.EightBit, Av1ColorFormat.Yuv420); restorationCoverage |= ValidateLoopRestorationFixture( TestImages.Heif.Av1Restoration10BitPayload, TestImages.Heif.Av1Restoration10BitReference, 1024, 428, Av1BitDepth.TenBit, Av1ColorFormat.Yuv444); restorationCoverage |= ValidateLoopRestorationFixture( TestImages.Heif.Av1Restoration12BitPayload, TestImages.Heif.Av1Restoration12BitReference, 1024, 428, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv444); // Exact output only proves both restoration algorithms when the independent fixture set // actually selects at least one unit of each type during every feature-runner invocation. int requiredCoverage = WienerRestorationCoverage | SelfGuidedRestorationCoverage; Assert.Equal(requiredCoverage, restorationCoverage & requiredCoverage); } /// /// Validates active restoration after super-resolution for 8-bit 4:2:0 content. /// private static void ValidateLoopRestorationAndSuperResolution8Bit420() => ValidateLoopRestorationFixture( TestImages.Heif.Av1RestorationSuperResolution8BitPayload, TestImages.Heif.Av1RestorationSuperResolution8BitReference, 768, 512, Av1BitDepth.EightBit, Av1ColorFormat.Yuv420, requireSuperResolution: true); /// /// Validates active restoration after super-resolution for 10-bit 4:2:2 content. /// private static void ValidateLoopRestorationAndSuperResolution10Bit422() => ValidateLoopRestorationFixture( TestImages.Heif.Av1RestorationSuperResolution10BitPayload, TestImages.Heif.Av1RestorationSuperResolution10BitReference, 512, 256, Av1BitDepth.TenBit, Av1ColorFormat.Yuv422, requireSuperResolution: true); /// /// Validates active restoration after super-resolution for 12-bit 4:4:4 content. /// private static void ValidateLoopRestorationAndSuperResolution12Bit444() => ValidateLoopRestorationFixture( TestImages.Heif.Av1RestorationSuperResolution12BitPayload, TestImages.Heif.Av1RestorationSuperResolution12BitReference, 1024, 428, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv444, requireSuperResolution: true); /// /// Validates every active film-grain fixture under the hardware configuration selected by /// . /// private static void ValidateFilmGrainFixtures() { ValidateFilmGrainFixture( TestImages.Heif.Av1FilmGrain8BitPayload, TestImages.Heif.Av1FilmGrain8BitReference, 100, 60, Av1BitDepth.EightBit, Av1ColorFormat.Yuv420); ValidateFilmGrainFixture( TestImages.Heif.Av1FilmGrain10BitPayload, TestImages.Heif.Av1FilmGrain10BitReference, 100, 60, Av1BitDepth.TenBit, Av1ColorFormat.Yuv422); ValidateFilmGrainFixture( TestImages.Heif.Av1FilmGrain12BitPayload, TestImages.Heif.Av1FilmGrain12BitReference, 100, 60, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv444); ValidateFilmGrainFixture( TestImages.Heif.Av1FilmGrain8BitRestrictedPayload, TestImages.Heif.Av1FilmGrain8BitRestrictedReference, 100, 60, Av1BitDepth.EightBit, Av1ColorFormat.Yuv420, requireRestrictedRange: true); ValidateFilmGrainFixture( TestImages.Heif.Av1FilmGrain8BitMonochromePayload, TestImages.Heif.Av1FilmGrain8BitMonochromeReference, 100, 60, Av1BitDepth.EightBit, Av1ColorFormat.Yuv400, requireRestrictedRange: true); ValidateFilmGrainFixture( TestImages.Heif.Av1FilmGrain12BitIdentityPayload, TestImages.Heif.Av1FilmGrain12BitIdentityReference, 100, 60, Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv444, requireRestrictedRange: true, requireIdentityMatrix: true); ValidateFilmGrainFixture( TestImages.Heif.Av1FilmGrainOddDimensionsPayload, TestImages.Heif.Av1FilmGrainOddDimensionsReference, 33, 11, Av1BitDepth.EightBit, Av1ColorFormat.Yuv420); } /// /// Validates one elementary-stream sample and its containing AVIF image. /// /// The complete AVIF container. /// The AV1 elementary-stream sample extracted from the container. /// The native planar output produced by the pinned libaom decoder. /// The expected displayed width. /// The expected displayed height. /// The expected AV1 sample precision. /// The expected native chroma-sampling layout. /// The expected public HEIF sample precision. private static void ValidateFixture( string imagePath, string payloadPath, string referencePath, int width, int height, Av1BitDepth bitDepth, Av1ColorFormat colorFormat, HeifBitDepth metadataBitDepth) { ValidateNativeFixture(payloadPath, referencePath, width, height, bitDepth, colorFormat, false); ValidatePresentedImage(imagePath, width, height, metadataBitDepth); } /// /// Validates complete native-plane reconstruction for one AV1 elementary-stream sample. /// /// The AV1 elementary-stream sample. /// The native planar output produced by the pinned libaom decoder. /// The expected reconstructed width. /// The expected reconstructed height. /// The expected AV1 sample precision. /// The expected native chroma-sampling layout. /// Indicates whether the stream must signal and select nonzero CDEF strengths. /// Indicates whether the stream must use normative horizontal upscaling. /// Indicates whether the stream must select at least one loop-restoration unit. /// Indicates whether the displayed frame must synthesize signaled film grain. /// Indicates whether film grain must clip every plane to its restricted range. /// Indicates whether restricted chroma clipping must use the luma endpoints. /// Indicates whether the stream must signal a nonzero deblocking strength. /// Indicates whether the stream must select palette prediction for luma and chroma. /// A bit mask containing every selected loop-restoration filter type. private static int ValidateNativeFixture( string payloadPath, string referencePath, int width, int height, Av1BitDepth bitDepth, Av1ColorFormat colorFormat, bool requireActiveCdef, bool requireSuperResolution = false, bool requireLoopRestoration = false, bool requireFilmGrain = false, bool requireRestrictedRange = false, bool requireIdentityMatrix = false, bool requireActiveLoopFilter = true, bool requirePalette = false) { int restorationCoverage = 0; byte[] payload = TestFile.Create(payloadPath).Bytes; byte[] reference = TestFile.Create(referencePath).Bytes; using Av1Decoder decoder = new(Configuration.Default); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _); Assert.Equal(width, frameBuffer.Width); Assert.Equal(height, frameBuffer.Height); Assert.Equal(bitDepth, frameBuffer.BitDepth); Assert.Equal(colorFormat, frameBuffer.ColorFormat); Assert.NotNull(decoder.FrameHeader); if (requireSuperResolution) { ObuFrameSize frameSize = decoder.FrameHeader.FrameSize; Assert.True(frameSize.FrameWidth < frameSize.SuperResolutionUpscaledWidth); Assert.Equal(width, frameSize.SuperResolutionUpscaledWidth); if (!requireLoopRestoration) { // The original super-resolution fixtures isolate upscaling by disabling restoration. Assert.False(decoder.FrameHeader.LoopRestorationParameters.UsesLoopRestoration); } } if (requireActiveLoopFilter) { ObuLoopFilterParameters filterParameters = decoder.FrameHeader.LoopFilterParameters; Assert.True( filterParameters.FilterLevel[0] != 0 || filterParameters.FilterLevel[1] != 0 || filterParameters.FilterLevelU != 0 || filterParameters.FilterLevelV != 0); } if (requireActiveCdef) { Assert.NotNull(decoder.SequenceHeader); Assert.True(decoder.SequenceHeader.EnableCdef); Assert.False(decoder.FrameHeader.LoopRestorationParameters.UsesLoopRestoration); Assert.NotNull(decoder.FrameInfo); ObuConstraintDirectionalEnhancementFilterParameters parameters = decoder.FrameHeader.CdefParameters; bool hasActiveStrength = false; int superblockSizeLog2 = decoder.SequenceHeader.SuperblockSizeLog2; int superblockColumnCount = Av1Math.AlignPowerOf2(decoder.SequenceHeader.MaxFrameWidth, superblockSizeLog2) >> superblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(decoder.SequenceHeader.MaxFrameHeight, superblockSizeLog2) >> superblockSizeLog2; for (int superblockRow = 0; superblockRow < superblockRowCount && !hasActiveStrength; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount && !hasActiveStrength; superblockColumn++) { Span selectedStrengths = decoder.FrameInfo.GetCdefStrength(new Point(superblockColumn, superblockRow)); // Unassigned entries belong to completely skipped units. Every assigned index must resolve through // the signaled table before the exact output can establish that CDEF changed reconstructed samples. foreach (int selectedStrength in selectedStrengths) { if (selectedStrength >= 0 && (parameters.YStrength[selectedStrength] != 0 || parameters.UvStrength[selectedStrength] != 0)) { hasActiveStrength = true; break; } } } } // The independent output only proves CDEF when the encoded frame selects at least one nonzero strength. Assert.True(hasActiveStrength); } if (requireLoopRestoration) { Assert.True(decoder.FrameHeader.LoopRestorationParameters.UsesLoopRestoration); Assert.NotNull(decoder.FrameInfo); restorationCoverage = GetRestorationCoverage(decoder); Assert.NotEqual(0, restorationCoverage); } if (requireFilmGrain) { Assert.True(decoder.FrameHeader.FilmGrainParameters.ApplyGrain); } if (requireRestrictedRange) { Assert.True(decoder.FrameHeader.FilmGrainParameters.ClipToRestrictedRange); } if (requireIdentityMatrix) { Assert.NotNull(decoder.SequenceHeader); Assert.Equal(ObuMatrixCoefficients.Identity, decoder.SequenceHeader.ColorConfig.MatrixCoefficients); } if (requirePalette) { Assert.Equal(RequiredPaletteCoverage, GetPaletteCoverage(decoder)); } AssertNativePlanesEqual(decoder, frameBuffer, reference); return restorationCoverage; } /// /// Validates lossless frame syntax and complete native reconstruction for one AVIF image. /// /// The independently encoded AVIF container. /// The raw planar output produced by the pinned scalar libaom decoder. /// The expected AV1 sample precision. private static void ValidateLosslessFixture(string imagePath, string referencePath, Av1BitDepth bitDepth) { byte[] imageBytes = TestFile.Create(imagePath).Bytes; byte[] referenceBytes = TestFile.Create(referencePath).Bytes; Span payload = GetSoleAv1ItemPayload(imageBytes); ReadOnlySpan nativeReference = referenceBytes; using Av1Decoder decoder = new(Configuration.Default); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _); Assert.Equal(LosslessFixtureWidth, frameBuffer.Width); Assert.Equal(LosslessFixtureHeight, frameBuffer.Height); Assert.Equal(bitDepth, frameBuffer.BitDepth); Assert.Equal(Av1ColorFormat.Yuv444, frameBuffer.ColorFormat); Assert.NotNull(decoder.SequenceHeader); Assert.NotNull(decoder.FrameHeader); Assert.NotNull(decoder.FrameInfo); Assert.True(decoder.FrameHeader.CodedLossless); Assert.True(decoder.FrameHeader.AllLossless); Assert.Equal(0, decoder.FrameHeader.QuantizationParameters.BaseQIndex); Assert.Equal(ObuMatrixCoefficients.Identity, decoder.SequenceHeader.ColorConfig.MatrixCoefficients); Assert.False(decoder.FrameHeader.AllowIntraBlockCopy); Assert.Equal(0, GetPaletteCoverage(decoder)); bool hasCodedResidual = false; int superblockSizeLog2 = decoder.SequenceHeader.SuperblockSizeLog2; int superblockColumnCount = Av1Math.AlignPowerOf2(decoder.SequenceHeader.MaxFrameWidth, superblockSizeLog2) >> superblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(decoder.SequenceHeader.MaxFrameHeight, superblockSizeLog2) >> superblockSizeLog2; ReadOnlySpan planes = [Av1Plane.Y, Av1Plane.U, Av1Plane.V]; for (int superblockRow = 0; superblockRow < superblockRowCount && !hasCodedResidual; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount && !hasCodedResidual; superblockColumn++) { Point superblock = new(superblockColumn, superblockRow); foreach (Av1Plane plane in planes) { Span coefficients = plane switch { Av1Plane.Y => decoder.FrameInfo.GetCoefficientsY(superblock), Av1Plane.U => decoder.FrameInfo.GetCoefficientsU(superblock), _ => decoder.FrameInfo.GetCoefficientsV(superblock) }; // Each transform reserves an end index followed by its coefficients. Any nonzero stored value // proves that exact output traversed coefficient decoding, inverse quantization, and lossless WHT. foreach (int coefficient in coefficients) { if (coefficient != 0) { hasCodedResidual = true; break; } } if (hasCodedResidual) { break; } } } } Assert.True(hasCodedResidual); AssertNativePlanesEqual(decoder, frameBuffer, nativeReference); } /// /// Validates one independently encoded stream that activates constrained directional enhancement filtering. /// /// The AV1 elementary-stream sample. /// The native planar output produced by the pinned scalar libaom decoder. /// The expected reconstructed width. /// The expected reconstructed height. /// The expected AV1 sample precision. /// The expected native chroma-sampling layout. private static void ValidateActiveCdefFixture( string payloadPath, string referencePath, int width, int height, Av1BitDepth bitDepth, Av1ColorFormat colorFormat) => ValidateNativeFixture(payloadPath, referencePath, width, height, bitDepth, colorFormat, requireActiveCdef: true); /// /// Validates one independently encoded stream that activates normative super-resolution. /// /// The AV1 elementary-stream sample. /// The native planar output produced by the pinned scalar libaom decoder. /// The expected upscaled width. /// The expected reconstructed height. /// The expected AV1 sample precision. /// The expected native chroma-sampling layout. private static void ValidateSuperResolutionFixture( string payloadPath, string referencePath, int width, int height, Av1BitDepth bitDepth, Av1ColorFormat colorFormat) => ValidateNativeFixture( payloadPath, referencePath, width, height, bitDepth, colorFormat, requireActiveCdef: false, requireSuperResolution: true); /// /// Validates one independently encoded stream that activates normative loop restoration. /// /// The AV1 elementary-stream sample. /// The native planar output produced by the pinned scalar libaom decoder. /// The expected reconstructed width. /// The expected reconstructed height. /// The expected AV1 sample precision. /// The expected native chroma-sampling layout. /// Whether the stream must upscale from a narrower coded frame. /// A bit mask containing every selected loop-restoration filter type. private static int ValidateLoopRestorationFixture( string payloadPath, string referencePath, int width, int height, Av1BitDepth bitDepth, Av1ColorFormat colorFormat, bool requireSuperResolution = false) => ValidateNativeFixture( payloadPath, referencePath, width, height, bitDepth, colorFormat, requireActiveCdef: false, requireSuperResolution: requireSuperResolution, requireLoopRestoration: true); /// /// Validates one independently encoded stream that applies film grain to the displayed samples. /// /// The AV1 elementary-stream sample. /// The native planar output produced by the pinned scalar libaom decoder. /// The expected displayed width. /// The expected displayed height. /// The expected AV1 sample precision. /// The expected native chroma-sampling layout. /// Whether film grain must clip every plane to its restricted range. /// Whether restricted chroma clipping must use the luma endpoints. private static void ValidateFilmGrainFixture( string payloadPath, string referencePath, int width, int height, Av1BitDepth bitDepth, Av1ColorFormat colorFormat, bool requireRestrictedRange = false, bool requireIdentityMatrix = false) => ValidateNativeFixture( payloadPath, referencePath, width, height, bitDepth, colorFormat, requireActiveCdef: false, requireFilmGrain: true, requireRestrictedRange: requireRestrictedRange, requireIdentityMatrix: requireIdentityMatrix, requireActiveLoopFilter: false); /// /// Validates the public presentation and metadata produced from one complete AVIF container. /// /// The complete AVIF container. /// The expected displayed width. /// The expected displayed height. /// The expected public HEIF sample precision. private static void ValidatePresentedImage(string imagePath, int width, int height, HeifBitDepth metadataBitDepth) { DecoderOptions options = new() { MaxFrames = 1 }; byte[] imageBytes = TestFile.Create(imagePath).Bytes; using Image image = Image.Load(options, imageBytes); Assert.Equal(width, image.Width); Assert.Equal(height, image.Height); Assert.Single(image.Frames); HeifMetadata metadata = image.Metadata.GetHeifMetadata(); Assert.Equal(HeifCompressionMethod.Av1, metadata.CompressionMethod); Assert.Equal(metadataBitDepth, metadata.BitDepth); } /// /// Verifies the public dimensions, frame count, compression method, and sample precision of one AVIF input. /// /// The AVIF input provider. /// The expected displayed width. /// The expected displayed height. /// The expected public HEIF sample precision. private static void AssertPresentedMetadata( TestImageProvider provider, int width, int height, HeifBitDepth bitDepth) { using Image image = provider.GetImage(); Assert.Equal(width, image.Width); Assert.Equal(height, image.Height); Assert.Single(image.Frames); HeifMetadata metadata = image.Metadata.GetHeifMetadata(); Assert.Equal(HeifCompressionMethod.Av1, metadata.CompressionMethod); Assert.Equal(bitDepth, metadata.BitDepth); } /// /// Compares one AVIF presentation with its retained output through the repository reference-image contract. /// /// The serialized input provider and reference-output naming context. private static void ValidatePresentedFixture(string providerDump) { TestImageProvider provider = FeatureTestRunner.DeserializeForXunit>(providerDump); using Image image = provider.GetImage(); // CICP records the AVIF source component layout, but PNG permits only the identity matrix. The debug image // is a pixel artifact; the test verifies source metadata independently where that is part of the contract. image.DebugSave(provider, new PngEncoder { SkipMetadata = true }); image.CompareToReferenceOutput(ImageComparer.Exact, provider); } /// /// Compares the final visible frame of one AVIF sequence through the repository reference-image contract. /// /// The serialized input provider and reference-output naming context. private static void ValidateFinalSequencePresentation(string providerDump) { TestImageProvider provider = FeatureTestRunner.DeserializeForXunit>(providerDump); using Image sequence = provider.GetImage(); using Image finalFrame = sequence.Frames.CloneFrame(sequence.Frames.Count - 1); // The retained source CICP matrix cannot be represented in a PNG cICP chunk. Omit metadata only from the // diagnostic output; the exact reference comparison below still consumes the original decoded image. finalFrame.DebugSave(provider, new PngEncoder { SkipMetadata = true }); finalFrame.CompareToReferenceOutput(ImageComparer.Exact, provider); } /// /// Verifies that the sole AV1 image item in an independently packaged AVIF uses normative super-resolution. /// /// The complete AVIF file. private static void AssertUsesSuperResolution(Span imageBytes) { Span payload = GetSoleAv1ItemPayload(imageBytes); using Av1Decoder decoder = new(Configuration.Default); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _); Assert.NotNull(decoder.FrameHeader); ObuFrameSize frameSize = decoder.FrameHeader.FrameSize; Assert.True(frameSize.FrameWidth < frameSize.SuperResolutionUpscaledWidth); Assert.Equal(frameBuffer.Width, frameSize.SuperResolutionUpscaledWidth); } /// /// Verifies that the sole AV1 image item in an independently encoded AVIF selects luma and chroma palettes. /// /// The complete AVIF file. private static void AssertUsesPalette(Span imageBytes) { Span payload = GetSoleAv1ItemPayload(imageBytes); using Av1Decoder decoder = new(Configuration.Default); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _); Assert.Equal(RequiredPaletteCoverage, GetPaletteCoverage(decoder)); } /// /// Verifies that the sole AV1 image item in an independently encoded AVIF selects intra-block-copy prediction. /// /// The complete AVIF file. private static void AssertUsesIntraBlockCopy(Span imageBytes) { Span payload = GetSoleAv1ItemPayload(imageBytes); using Av1Decoder decoder = new(Configuration.Default); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _); Assert.NotNull(decoder.FrameHeader); Assert.True(decoder.FrameHeader.AllowIntraBlockCopy); Assert.NotEqual(0, GetIntraBlockCopyBlockCount(decoder)); } /// /// Decodes the sole image item in an independently generated AVIF fixture and returns its restoration coverage. /// /// The complete AVIF file. /// A bit mask containing every selected loop-restoration filter type. private static int GetRestorationCoverageFromAvif(Span imageBytes) { Span payload = GetSoleAv1ItemPayload(imageBytes); using Av1Decoder decoder = new(Configuration.Default); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _); Assert.NotNull(decoder.FrameHeader); Assert.True(decoder.FrameHeader.LoopRestorationParameters.UsesLoopRestoration); Assert.NotNull(decoder.FrameInfo); int restorationCoverage = GetRestorationCoverage(decoder); Assert.NotEqual(0, restorationCoverage); return restorationCoverage; } /// /// Gets the partition types selected by one independently encoded AV1 elementary stream. /// /// The AV1 elementary-stream sample. /// A bit mask containing every selected partition type. private static int GetPartitionCoverage(string payloadPath) { byte[] payload = TestFile.Create(payloadPath).Bytes; using Av1Decoder decoder = new(Configuration.Default); using Av1FrameBuffer frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _); Assert.NotNull(decoder.SequenceHeader); Assert.NotNull(decoder.FrameInfo); int superblockSizeLog2 = decoder.SequenceHeader.SuperblockSizeLog2; int superblockColumnCount = Av1Math.AlignPowerOf2(decoder.SequenceHeader.MaxFrameWidth, superblockSizeLog2) >> superblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(decoder.SequenceHeader.MaxFrameHeight, superblockSizeLog2) >> superblockSizeLog2; int halfSuperblockSize = 1 << (superblockSizeLog2 - 1); int coverage = 0; // Mode records retain their bitstream traversal order and store each final coding block once, so iterating // the parsed count observes every selected leaf partition without repeatedly visiting its covered 4x4 cells. // Split itself creates no mode record. All other partition types are terminal, so a leaf below half the // superblock size on both axes proves that the parser reached it through at least one recursive split. for (int superblockRow = 0; superblockRow < superblockRowCount; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount; superblockColumn++) { Av1SuperblockInfo superblock = decoder.FrameInfo.GetSuperblock(new Point(superblockColumn, superblockRow)); foreach (Av1BlockModeInfo modeInfo in superblock.GetModeInfos()) { coverage |= 1 << (int)modeInfo.PartitionType; if (modeInfo.BlockSize.GetWidth() < halfSuperblockSize && modeInfo.BlockSize.GetHeight() < halfSuperblockSize) { coverage |= 1 << (int)Av1PartitionType.Split; } } } } return coverage; } /// /// Gets the complete media-data payload from a single-item AVIF conformance fixture. /// /// The complete AVIF file. /// The sole AV1 image-item payload. private static Span GetSoleAv1ItemPayload(Span imageBytes) { int offset = 0; while (offset < imageBytes.Length) { int headerLength = HeifBoxReader.ParseHeader(imageBytes[offset..], out long payloadLength, out Heif4CharCode boxType); Assert.InRange(payloadLength, 0, int.MaxValue); int payloadLength32 = (int)payloadLength; if (boxType == Heif4CharCode.Mdat) { // Every conformance container passed here deliberately stores its sole AV1 item as the complete // mdat payload, so feature assertions inspect the exact bytes used by public presentation decoding. return imageBytes.Slice(offset + headerLength, payloadLength32); } offset = checked(offset + headerLength + payloadLength32); } Assert.Fail("The AVIF fixture does not contain a media-data box."); return []; } /// /// Returns the luma and chroma palette classes selected by a decoded frame. /// /// The decoder after tile parsing and reconstruction. /// A bit mask containing the selected plane classes. private static int GetPaletteCoverage(Av1Decoder decoder) { Assert.NotNull(decoder.FrameHeader); Assert.NotNull(decoder.FrameInfo); int modeInfoWidth = Av1Math.DivideLog2Ceiling(decoder.FrameHeader.FrameSize.FrameWidth, Av1Constants.ModeInfoSizeLog2); int modeInfoHeight = Av1Math.DivideLog2Ceiling(decoder.FrameHeader.FrameSize.FrameHeight, Av1Constants.ModeInfoSizeLog2); int paletteCoverage = 0; for (int y = 0; y < modeInfoHeight; y++) { for (int x = 0; x < modeInfoWidth; x++) { Av1BlockModeInfo modeInfo = decoder.FrameInfo.GetModeInfoAt(new Point(x, y)); if (modeInfo.GetPaletteSize(Av1PlaneType.Y) != 0) { paletteCoverage |= LumaPaletteCoverage; } if (modeInfo.GetPaletteSize(Av1PlaneType.Uv) != 0) { paletteCoverage |= ChromaPaletteCoverage; } } } return paletteCoverage; } /// /// Counts the final coding blocks that select intra-block-copy prediction. /// /// The decoder after tile parsing and reconstruction. /// The number of selected intra-block-copy coding blocks. private static int GetIntraBlockCopyBlockCount(Av1Decoder decoder) { Assert.NotNull(decoder.SequenceHeader); Assert.NotNull(decoder.FrameInfo); int superblockSizeLog2 = decoder.SequenceHeader.SuperblockSizeLog2; int superblockColumnCount = Av1Math.AlignPowerOf2(decoder.SequenceHeader.MaxFrameWidth, superblockSizeLog2) >> superblockSizeLog2; int superblockRowCount = Av1Math.AlignPowerOf2(decoder.SequenceHeader.MaxFrameHeight, superblockSizeLog2) >> superblockSizeLog2; int blockCount = 0; // Mode records retain final coding blocks in bitstream order. Traversing each record once counts selected // intra-block-copy operations without repeatedly visiting the 4x4 cells covered by a larger block. for (int superblockRow = 0; superblockRow < superblockRowCount; superblockRow++) { for (int superblockColumn = 0; superblockColumn < superblockColumnCount; superblockColumn++) { Av1SuperblockInfo superblock = decoder.FrameInfo.GetSuperblock(new Point(superblockColumn, superblockRow)); foreach (Av1BlockModeInfo modeInfo in superblock.GetModeInfos()) { if (modeInfo.UseIntraBlockCopy) { blockCount++; } } } } return blockCount; } /// /// Returns the restoration algorithms selected by the decoded frame's unit grids. /// /// The decoder after tile parsing and reconstruction. /// A bit mask containing every selected loop-restoration filter type. private static int GetRestorationCoverage(Av1Decoder decoder) { int restorationCoverage = 0; for (int plane = 0; plane < decoder.SequenceHeader!.ColorConfig.PlaneCount; plane++) { int rowCount = decoder.FrameInfo!.GetLoopRestorationUnitRowCount(plane); int columnCount = decoder.FrameInfo.GetLoopRestorationUnitColumnCount(plane); for (int row = 0; row < rowCount; row++) { for (int column = 0; column < columnCount; column++) { Av1RestorationFilterType filterType = decoder.FrameInfo.GetLoopRestorationUnit(plane, row, column).FilterType; if (filterType != Av1RestorationFilterType.None) { restorationCoverage |= 1 << (int)filterType; } } } } return restorationCoverage; } /// /// Compares every visible native component sample with the independent planar reference. /// /// The decoder state used to identify the coded block containing a mismatch. /// The reconstructed AV1 component planes. /// The planar Y, U, and V samples produced by the current-main libaom decoder. /// The zero-based sequence-frame index, or -1 for a standalone sample. private static void AssertNativePlanesEqual( Av1Decoder decoder, Av1FrameBuffer frameBuffer, ReadOnlySpan reference, int frameIndex = -1) { (int chromaSubsamplingX, int chromaSubsamplingY) = frameBuffer.ColorFormat switch { Av1ColorFormat.Yuv420 => (1, 1), Av1ColorFormat.Yuv422 => (1, 0), _ => (0, 0) }; int referenceOffset = 0; ReadOnlySpan planes = frameBuffer.ColorFormat == Av1ColorFormat.Yuv400 ? [Av1Plane.Y] : [Av1Plane.Y, Av1Plane.U, Av1Plane.V]; int mismatchCount = 0; Av1Plane largestMismatchPlane = default; int largestMismatchX = 0; int largestMismatchY = 0; ushort largestExpected = 0; ushort largestActual = 0; StringBuilder mismatchDescription = null; foreach (Av1Plane plane in planes) { int subsamplingX = plane == Av1Plane.Y ? 0 : chromaSubsamplingX; int subsamplingY = plane == Av1Plane.Y ? 0 : chromaSubsamplingY; int planeWidth = GetSubsampledSize(frameBuffer.Width, subsamplingX); int planeHeight = GetSubsampledSize(frameBuffer.Height, subsamplingY); if (frameBuffer.BitDepth == Av1BitDepth.EightBit) { Buffer2DRegion actualPlane = frameBuffer.DeriveBlockPointer(plane, subsamplingX, subsamplingY); for (int y = 0; y < planeHeight; y++) { Span actualRow = actualPlane.DangerousGetRowSpan(y)[..planeWidth]; ReadOnlySpan expectedRow = reference.Slice(referenceOffset, planeWidth); for (int x = 0; x < planeWidth; x++) { if (expectedRow[x] != actualRow[x]) { if (mismatchCount < 16) { mismatchDescription ??= new StringBuilder(); mismatchDescription.Append(CultureInfo.InvariantCulture, $" {plane}({x},{y})={expectedRow[x]}/{actualRow[x]}"); } if (mismatchCount == 0 || Math.Abs(expectedRow[x] - actualRow[x]) > Math.Abs(largestExpected - largestActual)) { largestMismatchPlane = plane; largestMismatchX = x; largestMismatchY = y; largestExpected = expectedRow[x]; largestActual = actualRow[x]; } mismatchCount++; } } referenceOffset += planeWidth; } } else { // aomdec writes high-bit-depth YUV as little-endian 16-bit values, independently of host endianness. for (int y = 0; y < planeHeight; y++) { Span actualRow = frameBuffer.GetHighBitDepthRowSpan(plane, y, subsamplingX, subsamplingY); for (int x = 0; x < planeWidth; x++) { ushort expected = BinaryPrimitives.ReadUInt16LittleEndian(reference.Slice(referenceOffset, sizeof(ushort))); if (expected != actualRow[x]) { if (mismatchCount < 16) { mismatchDescription ??= new StringBuilder(); mismatchDescription.Append(CultureInfo.InvariantCulture, $" {plane}({x},{y})={expected}/{actualRow[x]}"); } if (mismatchCount == 0 || Math.Abs(expected - actualRow[x]) > Math.Abs(largestExpected - largestActual)) { largestMismatchPlane = plane; largestMismatchX = x; largestMismatchY = y; largestExpected = expected; largestActual = actualRow[x]; } mismatchCount++; } referenceOffset += sizeof(ushort); } } } } Assert.Equal(reference.Length, referenceOffset); AssertSampleEqual( decoder, largestMismatchPlane, largestMismatchX, largestMismatchY, largestExpected, largestActual, mismatchCount, mismatchDescription?.ToString() ?? string.Empty, frameIndex); } /// /// Calculates a component dimension after chroma subsampling with the AV1 rounding rule. /// /// The luma dimension. /// The component subsampling shift. /// The subsampled component dimension. private static int GetSubsampledSize(int size, int subsampling) => (size + (1 << subsampling) - 1) >> subsampling; /// /// Reports the exact component coordinate when independently decoded samples differ. /// /// The decoder state used to identify the coded block containing the sample. /// The compared component plane. /// The sample X coordinate. /// The sample Y coordinate. /// The reference sample. /// The reconstructed sample. /// The total number of unequal native samples. /// The first unequal samples in plane traversal order. /// The zero-based sequence-frame index, or -1 for a standalone sample. private static void AssertSampleEqual( Av1Decoder decoder, Av1Plane plane, int x, int y, ushort expected, ushort actual, int mismatchCount, string mismatchDescription, int frameIndex) { if (expected != actual) { ObuSequenceHeader sequenceHeader = Assert.IsType(decoder.SequenceHeader); int subsamplingX = plane == Av1Plane.Y || !sequenceHeader.ColorConfig.SubSamplingX ? 0 : 1; int subsamplingY = plane == Av1Plane.Y || !sequenceHeader.ColorConfig.SubSamplingY ? 0 : 1; Av1FrameInfo frameInfo = Assert.IsType(decoder.FrameInfo); int modeInfoColumn = (x << subsamplingX) >> Av1Constants.ModeInfoSizeLog2; int modeInfoRow = (y << subsamplingY) >> Av1Constants.ModeInfoSizeLog2; Av1BlockModeInfo modeInfo = frameInfo.GetModeInfoAt(new Point(modeInfoColumn, modeInfoRow)); int blockColumn = modeInfoColumn; while (blockColumn > 0 && ReferenceEquals(frameInfo.GetModeInfoAt(new Point(blockColumn - 1, modeInfoRow)), modeInfo)) { blockColumn--; } int blockRow = modeInfoRow; while (blockRow > 0 && ReferenceEquals(frameInfo.GetModeInfoAt(new Point(modeInfoColumn, blockRow - 1)), modeInfo)) { blockRow--; } int superblockSize = frameInfo.SuperblockModeInfoSize; Av1SuperblockInfo superblock = frameInfo.GetSuperblock(new Point(blockColumn / superblockSize, blockRow / superblockSize)); Span transforms = superblock.GetTransformInfoY().Slice( modeInfo.GetFirstTransformLocation(Av1Plane.Y), modeInfo.GetTransformUnitCount(Av1Plane.Y)); Av1TransformInfo containingTransform = transforms[0]; int containingTransformIndex = 0; int transformColumn = modeInfoColumn - blockColumn; int transformRow = modeInfoRow - blockRow; for (int transformIndex = 0; transformIndex < transforms.Length; transformIndex++) { Av1TransformInfo transform = transforms[transformIndex]; if (transformColumn >= transform.OffsetX && transformColumn < transform.OffsetX + transform.Size.Get4x4WideCount() && transformRow >= transform.OffsetY && transformRow < transform.OffsetY + transform.Size.Get4x4HighCount()) { containingTransform = transform; containingTransformIndex = transformIndex; break; } } int superblockTransformIndex = modeInfo.GetFirstTransformLocation(Av1Plane.Y) + containingTransformIndex; Span superblockTransforms = superblock.GetTransformInfoY(); Span superblockCoefficients = superblock.CoefficientsY; int coefficientOffset = 0; for (int transformIndex = 0; transformIndex < superblockTransformIndex; transformIndex++) { if (superblockTransforms[transformIndex].CodeBlockFlag) { coefficientOffset += superblockCoefficients[coefficientOffset] + 1; } } StringBuilder coefficientDescription = new(); if (containingTransform.CodeBlockFlag) { int coefficientCount = superblockCoefficients[coefficientOffset]; coefficientDescription.Append(CultureInfo.InvariantCulture, $", quantized-coefficients={coefficientCount}:["); for (int coefficientIndex = 0; coefficientIndex < coefficientCount; coefficientIndex++) { if (coefficientIndex != 0) { coefficientDescription.Append(','); } coefficientDescription.Append(superblockCoefficients[coefficientOffset + coefficientIndex + 1]); } coefficientDescription.Append(']'); } ObuFrameHeader frameHeader = Assert.IsType(decoder.FrameHeader); int cdefUnitColumn = (modeInfoColumn % superblockSize) / CdefUnitModeInfoSize; int cdefUnitRow = (modeInfoRow % superblockSize) / CdefUnitModeInfoSize; int cdefStrengthIndex = frameInfo.GetCdefStrength(superblock.Position)[cdefUnitColumn + (cdefUnitRow << 1)]; int cdefStrength = cdefStrengthIndex < 0 ? -1 : frameHeader.CdefParameters.YStrength[cdefStrengthIndex]; int nextModeInfoRow = Math.Min(modeInfoRow + 1, frameHeader.ModeInfoRowCount - 1); Av1BlockModeInfo nextRowModeInfo = frameInfo.GetModeInfoAt(new Point(modeInfoColumn, nextModeInfoRow)); Av1BlockModeInfo aboveModeInfo = frameInfo.GetModeInfoAt(new Point(modeInfoColumn, Math.Max(blockRow - 1, 0))); Av1BlockModeInfo leftModeInfo = frameInfo.GetModeInfoAt(new Point(Math.Max(blockColumn - 1, 0), modeInfoRow)); string frameDescription = frameIndex < 0 ? string.Empty : $"Frame {frameIndex}, "; StringBuilder filmGrainCoefficientDescription = new(); ReadOnlySpan filmGrainCoefficients = frameHeader.FilmGrainParameters.ArCoeffsYPlus128; int filmGrainCoefficientCount = 2 * (int)frameHeader.FilmGrainParameters.ArCoeffLag * ((int)frameHeader.FilmGrainParameters.ArCoeffLag + 1); for (int coefficientIndex = 0; coefficientIndex < filmGrainCoefficientCount; coefficientIndex++) { if (coefficientIndex != 0) { filmGrainCoefficientDescription.Append(','); } filmGrainCoefficientDescription.Append((int)filmGrainCoefficients[coefficientIndex] - 128); } // Exact conformance failures need the owning syntax state. A coordinate alone does not distinguish // prediction, residual reconstruction, and in-loop filtering failures inside a large coded frame. Assert.Fail( $"{frameDescription}plane {plane} differs at ({x}, {y}): expected {expected}, actual {actual}. " + $"Total unequal samples={mismatchCount}:{mismatchDescription}. " + $"Block={modeInfo.BlockSize}, mode={modeInfo.YMode}, partition={modeInfo.PartitionType}, skip={modeInfo.Skip}, " + $"refs={modeInfo.ReferenceFrames[0]}/{modeInfo.ReferenceFrames[1]}, " + $"mvs={modeInfo.MotionVectors[0].Row},{modeInfo.MotionVectors[0].Column}/" + $"{modeInfo.MotionVectors[1].Row},{modeInfo.MotionVectors[1].Column}, compound={modeInfo.CompoundType}, " + $"filters={modeInfo.InterpolationFilters[0]}/{modeInfo.InterpolationFilters[1]}, motion={modeInfo.MotionMode}, " + $"filter-intra={modeInfo.UseFilterIntra}/{modeInfo.FilterIntraMode}, angle-delta={modeInfo.GetAngleDelta(plane)}, " + $"palette-size={modeInfo.GetPaletteSize(plane)}, transforms={modeInfo.GetTransformUnitCount(plane)}, " + $"transform={containingTransform.Size}/{containingTransform.Type}/coded={containingTransform.CodeBlockFlag} " + $"at ({containingTransform.OffsetX}, {containingTransform.OffsetY}), block-origin=({blockColumn}, {blockRow}). " + $"Loop-filter={frameHeader.LoopFilterParameters.FilterLevel[0]}/{frameHeader.LoopFilterParameters.FilterLevel[1]}, " + $"sharpness={frameHeader.LoopFilterParameters.SharpnessLevel}, delta-q={frameHeader.DeltaQParameters.IsPresent}, " + $"superblock-q={superblock.SuperblockQuantizerIndex}{coefficientDescription}, " + $"delta-lf={frameHeader.DeltaLoopFilterParameters.IsPresent}/{frameHeader.DeltaLoopFilterParameters.IsMulti}, " + $"CDEF={cdefStrengthIndex}/{cdefStrength}, restoration={frameHeader.LoopRestorationParameters.Items[0].Type}, " + $"film-grain={frameHeader.FilmGrainParameters.ApplyGrain}/" + $"overlap={frameHeader.FilmGrainParameters.OverlapFlag}/" + $"update={frameHeader.FilmGrainParameters.UpdateGrain}/seed={frameHeader.FilmGrainParameters.GrainSeed}, " + $"grain-points={frameHeader.FilmGrainParameters.NumYPoints}/" + $"{frameHeader.FilmGrainParameters.NumCbPoints}/{frameHeader.FilmGrainParameters.NumCrPoints}, " + $"grain-ar={frameHeader.FilmGrainParameters.ArCoeffLag}/" + $"{frameHeader.FilmGrainParameters.ArCoeffShiftMinus6}, " + $"grain-y-coefficients=[{filmGrainCoefficientDescription}], " + $"grain-scale={frameHeader.FilmGrainParameters.GrainScalingMinus8}/" + $"{frameHeader.FilmGrainParameters.GrainScaleShift}, " + $"tiles={frameHeader.TilesInfo.TileColumnCount}x{frameHeader.TilesInfo.TileRowCount}, " + $"first-tile-end=({frameHeader.TilesInfo.TileColumnStartModeInfo[1]}, {frameHeader.TilesInfo.TileRowStartModeInfo[1]}). " + $"Neighbors: above={aboveModeInfo.BlockSize}/{aboveModeInfo.YMode}/skip={aboveModeInfo.Skip}, " + $"left={leftModeInfo.BlockSize}/{leftModeInfo.YMode}/skip={leftModeInfo.Skip}, " + $"next-row={nextRowModeInfo.BlockSize}/{nextRowModeInfo.YMode}/skip={nextRowModeInfo.Skip}/" + $"angle-delta={nextRowModeInfo.GetAngleDelta(plane)}/transforms={nextRowModeInfo.GetTransformUnitCount(plane)}."); } } }