Browse Source

Verify AV1 frame operation ownership

pull/2633/head
James Jackson-South 1 month ago
parent
commit
9139ffe6d8
  1. 1
      HEIF_IMPLEMENTATION_PLAN.md
  2. 47
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1EncoderFrameTests.cs

1
HEIF_IMPLEMENTATION_PLAN.md

@ -846,6 +846,7 @@ Encoder verification contract:
- [x] The expanded checkpoint exposed a pre-existing transform-block test that asserted uninitialized pooled padding was zero. The test now initializes the complete physical luma plane with a sentinel and proves the block operation leaves both adjacent padding samples unchanged. The exact net11 Release rebuild remains at 1,005 baseline warnings and zero errors, the focused allocator-order set passes 30 of 30 cases, and the complete HEIF/AV1 namespace passes 8,859 of 8,859 direct VSTest cases with zero failures or skips.
- [x] Combined-frame OBU output now counts the byte-aligned frame and tile-group headers, non-final tile-size fields, and owned tile payloads before emitting the OBU size. It retains only the small allocator-owned header scratch and writes each entropy-coded tile span directly from its detached owner, removing the second file-sized allocator rent and complete-payload copy. A 64 KiB regression proves exactly one sub-payload-sized byte rent with a balanced return and verifies the exact streamed tile tail; the existing two-tile round trip proves size-prefix and ordering parity. The focused writer and production-frame set passes 32 of 32 direct net11 VSTest cases, current-main `aomdec` accepts all 29 generated native-format payloads, and the complete HEIF/AV1 namespace passes 8,860 of 8,860 cases with zero failures or skips.
- [x] Finalized fixed-block decisions now set the block-level transform-skip flag only when every retained luma and coded chroma transform has zero EOB, matching current libaom's conjunction of per-plane skip state. The previous always-false flag produced legal but redundant non-skip and zero-coefficient syntax. Monochrome and 4:2:0 regressions prove both branches from actual coefficient state; the focused decision and production-frame set passes 32 of 32 direct net11 VSTest cases. Current-main `aomdec` accepts all 29 regenerated payloads, the recorded decoded-frame MD5s are unchanged, and affected 16x16 constant 8-bit and 10-bit payloads are one byte smaller. The complete HEIF/AV1 namespace passes 8,862 of 8,862 cases with zero failures or skips.
- [x] Operation-wide allocation tracking now exercises a real 64x64 12-bit 4:4:4 frame through packed-pixel conversion, both native frame owners, picture and coefficient state, reusable block workspaces, entropy coding, OBU framing, and a non-seekable destination. It proves exactly one 60 KiB tile-output reservation from current libaom's all-intra 2.5x rule and balanced exactly-once returns for every tracked allocation before the operation completes. The focused ownership case passes 1 of 1 and the complete HEIF/AV1 namespace passes 8,863 of 8,863 direct net11 VSTest cases with zero failures or skips.
### 7. Write complete AVIF output

47
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1EncoderFrameTests.cs

@ -288,6 +288,53 @@ public class Av1EncoderFrameTests
Assert.Equal(allocation.AllocationId, returned.AllocationId);
}
[Fact]
public void EncodeReturnsEveryOperationAllocationAndUsesOneLibaomSizedTileReservation()
{
const int Width = 64;
const int Height = 64;
const int ExpectedTileOutputLength = 60 * 1024;
using Image<Rgba32> source = new(Width, Height);
for (int y = 0; y < Height; y++)
{
Span<Rgba32> row = source.Frames.RootFrame.PixelBuffer.DangerousGetRowSpan(y);
for (int x = 0; x < Width; x++)
{
row[x] = new Rgba32(
(byte)((x * 3) + y),
(byte)(x + (y * 5)),
(byte)((x * 7) + (y * 11)));
}
}
TestMemoryAllocator allocator = new();
allocator.EnableNonThreadSafeLogging();
Configuration configuration = Configuration.Default.Clone();
configuration.MemoryAllocator = allocator;
using MemoryStream storage = new();
using NonSeekableStream destination = new(storage);
_ = Av1FrameEncoder.Encode(
configuration,
source.Frames.RootFrame,
destination,
CreateColorConfig(Av1BitDepth.TwelveBit, Av1ColorFormat.Yuv444),
qIndex: 37);
Assert.False(destination.CanSeek);
Assert.NotEqual(0, storage.Length);
TestMemoryAllocator.AllocationRequest tileOutput = Assert.Single(
allocator.AllocationLog,
allocation => allocation.ElementType == typeof(byte) && allocation.Length == ExpectedTileOutputLength);
Assert.Equal(ExpectedTileOutputLength, tileOutput.Length);
Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count);
Assert.Equal(
allocator.AllocationLog.Select(allocation => allocation.AllocationId).Order(),
allocator.ReturnLog.Select(returned => returned.AllocationId).Order());
}
private static ObuColorConfig CreateColorConfig(
Av1BitDepth bitDepth,
Av1ColorFormat colorFormat = Av1ColorFormat.Yuv400)

Loading…
Cancel
Save