// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Heif.Hevc; namespace SixLabors.ImageSharp.Benchmarks.Codecs.Heif; /// /// Measures complete coded-frame traversal through HEVC inverse quantization. /// [MemoryDiagnoser(displayGenColumns: false)] public class HevcInverseQuantizationBenchmarks { /// /// The coded frame width, which is an exact multiple of the maximum transform-block side. /// private const int Width = 1920; /// /// The coded frame height including the final padded coding-tree row for a 1080-line presentation. /// private const int Height = 1088; /// /// The base-two logarithm of the benchmark transform-block side. /// private const int BlockLog2 = 5; /// /// The transform-block side in samples. /// private const int BlockSize = 1 << BlockLog2; /// /// The deterministic quantized coefficients reused by each benchmark block. /// private readonly int[] quantized = new int[BlockSize * BlockSize]; /// /// The reusable dequantized coefficient block. /// private readonly int[] destination = new int[BlockSize * BlockSize]; /// /// The effective default scaling matrices. /// private readonly HevcScalingList scalingList = new(); /// /// Populates a dense, deterministic twelve-bit transform workload outside the measured frame traversal. /// [GlobalSetup] public void Setup() { for (int i = 0; i < this.quantized.Length; i++) { this.quantized[i] = (((i * 7919) + 257) & 131071) - 65536; } } /// /// Measures frame-wide inverse quantization using one uniform scale. /// /// The final coefficient, keeping the block output observable. [Benchmark(Baseline = true)] public int DequantizeFlatFrame() => this.DequantizeFrame(false); /// /// Measures frame-wide inverse quantization using an expanded thirty-two-by-thirty-two scaling matrix. /// /// The final coefficient, keeping the block output observable. [Benchmark] public int DequantizeScalingListFrame() => this.DequantizeFrame(true); /// /// Dequantizes every maximum-size transform block in the coded benchmark frame. /// /// Whether the default intra-luma scaling matrix applies. /// The final dequantized coefficient. private int DequantizeFrame(bool scalingListEnabled) { for (int y = 0; y < Height; y += BlockSize) { for (int x = 0; x < Width; x += BlockSize) { HevcInverseQuantizer.Dequantize( this.quantized, this.destination, BlockLog2, 12, 18, 75, scalingListEnabled, this.scalingList, HevcPlane.Y, true, false, true); } } return this.destination[^1]; } }