Skip to content

webm: pictures cut into AV1 tiles - a tile nothing changes is coded once a film - #168

Merged
donislawdev merged 4 commits into
mainfrom
perf/webm-tiles
Oct 7, 2026
Merged

donislawdev merged 4 commits into
mainfrom
perf/webm-tiles

Conversation

@donislawdev

@donislawdev donislawdev commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

What

A film's pictures differ only in the clock and the square. From 256x144 up the picture is now cut into AV1 tiles on superblock lines, each tile coded by gav1d as a picture of its own and joined under a frame header this package writes (tile_info with the tiles' sizes, the tile group with their lengths). A tile is looked up by what its pixels depend on - the clock's characters in it and the square's columns in it - so the tiles nothing changes are coded once a film, the square's ten places once each, and a change codes only the clock's tile.

Measured

  • A thirty-minute 1920x1080 film of 2 GB: 67.9 s before, 2.8 s and 3.1 s now. libaom decodes all 54 000 frames, exit 0, empty stderr, 1800 distinct pictures (= change_count).
  • Five films from the CLI (1080p, 640x360, 4K, 1001x563, 160x90): libaom and dav1d decode every frame and agree on every frame's hash.
  • Before any code, a probe showed tiles coded alone decode bit for bit inside a frame of many under libaom, dav1d 1.4.1 and gav1d, at five sizes and two layouts.
  • Films of one tile (160x90 and below, and named sizes under one superblock) keep their bytes: the three golden webm films are unchanged.

Changed on purpose

  • Bytes of every film with more than one tile (webm is unreleased, so this is not a major change).
  • The ladder's ceilings for 640x360, 426x240 and 320x180, re-measured (+1.5 to +2.3%).
  • AllocCeiling for webm 512 to 1024: one gav1d call a tile at 21-22 objects a call. Measured 886-891 objects at 1, 4 and 16 threads, 1177 with one object allocated per frame. The 4 MiB to 64 MiB growth check is untouched and green.
  • change_interval no longer says a change costs a whole picture in time (English catalogue and Polish translation).

Guards

  • New: TestEveryTileOfAFilmIsGav1dsCodingOfItsPixelsAndDecodesAsItDoesAlone - every tile in a film is the tail of gav1d's own coding of those pixels, and the decoded frame equals each tile decoded alone. It reads tile_info with a reader of its own and needs no ffmpeg. Proven by three hand mutations (key without the clock, a wrong tile height, a wrong stride).
  • Four film guards now assert that they asked about a film of tiles. Proven by a layout that always gives one tile.

Test plan

  • Film guards by name, the new guard, allocation guard, golden bytes
  • Cheap whole-tree gates (shape, branching, punctuation, types, catalogue, documents)
  • CI

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • WebM films now encode changed picture regions as AV1 tiles, reusing unchanged tiles and processing changed tiles across multiple cores.
    • Progress reporting now accounts for both encoding work and bytes written.
  • Performance
    • A 30-minute, 1920×1080 film can encode in about 3 seconds on 16 threads, compared with the previous 68-second example.

donislawdev and others added 2 commits October 7, 2026 00:15
…coded once a film

A film's pictures differ only in the clock and the square, so from 256x144
up the picture is cut into AV1 tiles on superblock lines: a row under the
clock's band, rows around the square's, a column for each superblock the
clock's characters reach and one for the rest. Each tile is coded by gav1d as
a picture of its own, read where it lies in the picture's planes, and joined
under a frame header this package writes - tile_info with the tiles' sizes,
the tile group with their lengths. A tile is looked up by what its pixels
depend on (the clock's characters in it, the square's columns in it), so the
tiles nothing changes are coded once a film, the square's ten places once
each, and a change codes only the clock's tile.

A thirty-minute 1920x1080 film of 2 GB: 67.9 s before, 2.8 and 3.1 s now,
every one of its 54 000 frames decoded by libaom. Films of one tile keep
their bytes - the three golden films are unchanged.

- A new guard holds every tile in a film to gav1d's own coding of the
  pixels there, and the decoded frame to its tiles decoded alone, read back
  with a tile_info reader of its own. Four film guards now assert that they
  asked about a film of tiles.
- The ladder's ceilings re-measured for the rungs that have tiles.
- The work a change reports is the pixels of the tiles it codes.
- change_interval no longer says a change costs a whole picture in time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…22 objects each

The default film, 640x360 in six tiles, makes 27 calls to gav1d, about 594
objects before anything of this package. Measured at 886 to 891 objects at
one, four and sixteen threads, and 1177 with one object allocated per frame,
the defect the ceiling is for. The owner's decision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository UI (base), Organization UI (inherited)
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: d23d233b-cdb9-4e0f-be00-e6f6ec722ced

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI (base), Organization UI (inherited)
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 5b7bae5c-d41a-4b4e-83a2-ae85ef27b6d7
📥 Commits

Reviewing files that changed from the base of the PR and between b366f42 and d088e3e.

📒 Files selected for processing (19)
  • CHANGELOG.md
  • internal/format/imagelabel/imagelabel.go
  • internal/format/video/ahead.go
  • internal/format/video/av1.go
  • internal/format/video/bits.go
  • internal/format/video/choose.go
  • internal/format/video/grid.go
  • internal/format/video/picture.go
  • internal/format/video/pictures.go
  • internal/format/video/settings.go
  • internal/format/video/still.go
  • internal/format/video/stream.go
  • internal/format/video/tilekey.go
  • internal/format/webm/webm.go
  • internal/guard/film_test.go
  • internal/guard/filmahead_test.go
  • internal/guard/filmtiles_test.go
  • internal/gui/text/locale/registry/en.json
  • internal/gui/text/locale/registry/pl.json

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (20)
  • GitHub Check: race detector (part 3 of 4)
  • GitHub Check: race detector (part 2 of 4)
  • GitHub Check: race detector (part 1 of 4)
  • GitHub Check: race detector (part 0 of 4)
  • GitHub Check: coverage gate
  • GitHub Check: test on macos-latest
  • GitHub Check: test on windows-latest
  • GitHub Check: test on ubuntu-latest
  • GitHub Check: semgrep
  • GitHub Check: the installer installs and leaves
  • GitHub Check: bill of materials
  • GitHub Check: linters
  • GitHub Check: the Chocolatey packages install and leave
  • GitHub Check: reference tools actually installed
  • GitHub Check: known vulnerabilities
  • GitHub Check: staticcheck
  • GitHub Check: import table of the window binary
  • GitHub Check: Analyze (actions)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (go)
🧰 Additional context used
📚 Code guidelines (1)
CONTRIBUTING.md — configured
📓 Path-based instructions (13)
Applies to text shown to the user (labels, buttons, tooltips, placeholders, dialogs, errors, status messages, empty states, translations).

⚙️ CodeRabbit configuration file

Files:

  • internal/gui/text/locale/registry/en.json
  • internal/gui/text/locale/registry/pl.json
  • internal/format/video/settings.go
  • internal/format/video/bits.go
  • internal/format/imagelabel/imagelabel.go
  • internal/guard/film_test.go
  • internal/format/webm/webm.go
  • internal/guard/filmahead_test.go
  • internal/format/video/tilekey.go
  • internal/format/video/grid.go
  • internal/format/video/av1.go
  • internal/guard/filmtiles_test.go
  • internal/format/video/stream.go
  • internal/format/video/picture.go
  • internal/format/video/ahead.go
  • internal/format/video/still.go
  • internal/format/video/choose.go
  • internal/format/video/pictures.go
Verify tests check real behavior and would fail if the implementation were broken.

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/film_test.go
  • internal/guard/filmahead_test.go
  • internal/guard/filmtiles_test.go
These are end-user desktop applications.

⚙️ CodeRabbit configuration file

Files:

  • internal/format/video/settings.go
  • internal/format/video/bits.go
  • internal/format/imagelabel/imagelabel.go
  • internal/guard/film_test.go
  • internal/format/webm/webm.go
  • internal/guard/filmahead_test.go
  • internal/format/video/tilekey.go
  • internal/format/video/grid.go
  • internal/format/video/av1.go
  • internal/guard/filmtiles_test.go
  • internal/format/video/stream.go
  • internal/format/video/picture.go
  • internal/format/video/ahead.go
  • internal/format/video/still.go
  • internal/format/video/choose.go
  • internal/format/video/pictures.go
Performance is a known weak spot of these projects.

⚙️ CodeRabbit configuration file

Files:

  • internal/format/video/settings.go
  • internal/format/video/bits.go
  • internal/format/imagelabel/imagelabel.go
  • internal/guard/film_test.go
  • internal/format/webm/webm.go
  • internal/guard/filmahead_test.go
  • internal/format/video/tilekey.go
  • internal/format/video/grid.go
  • internal/format/video/av1.go
  • internal/guard/filmtiles_test.go
  • internal/format/video/stream.go
  • internal/format/video/picture.go
  • internal/format/video/ahead.go
  • internal/format/video/still.go
  • internal/format/video/choose.go
  • internal/format/video/pictures.go
Applies only to code that builds or styles a GUI.

⚙️ CodeRabbit configuration file

Files:

  • internal/format/video/settings.go
  • internal/format/video/bits.go
  • internal/format/imagelabel/imagelabel.go
  • internal/guard/film_test.go
  • internal/format/webm/webm.go
  • internal/guard/filmahead_test.go
  • internal/format/video/tilekey.go
  • internal/format/video/grid.go
  • internal/format/video/av1.go
  • internal/guard/filmtiles_test.go
  • internal/format/video/stream.go
  • internal/format/video/picture.go
  • internal/format/video/ahead.go
  • internal/format/video/still.go
  • internal/format/video/choose.go
  • internal/format/video/pictures.go
User-facing changelog.

⚙️ CodeRabbit configuration file

Files:

  • CHANGELOG.md
Domain: test file generator (Go; `tfg` CLI and `tfg-gui` Fyne window over one engine).

⚙️ CodeRabbit configuration file

Files:

  • internal/gui/text/locale/registry/en.json
  • internal/gui/text/locale/registry/pl.json
  • internal/format/video/settings.go
  • internal/format/video/bits.go
  • internal/format/imagelabel/imagelabel.go
  • internal/guard/film_test.go
  • internal/format/webm/webm.go
  • internal/guard/filmahead_test.go
  • internal/format/video/tilekey.go
  • internal/format/video/grid.go
  • internal/format/video/av1.go
  • internal/guard/filmtiles_test.go
  • internal/format/video/stream.go
  • internal/format/video/picture.go
  • internal/format/video/ahead.go
  • internal/format/video/still.go
  • internal/format/video/choose.go
  • internal/format/video/pictures.go
SECURITY, HIGH PRIORITY.

⚙️ CodeRabbit configuration file

Files:

  • internal/format/video/settings.go
  • internal/format/video/bits.go
  • internal/format/imagelabel/imagelabel.go
  • internal/guard/film_test.go
  • internal/format/webm/webm.go
  • internal/guard/filmahead_test.go
  • internal/format/video/tilekey.go
  • internal/format/video/grid.go
  • internal/format/video/av1.go
  • internal/guard/filmtiles_test.go
  • internal/format/video/stream.go
  • internal/format/video/picture.go
  • internal/format/video/ahead.go
  • internal/format/video/still.go
  • internal/format/video/choose.go
  • internal/format/video/pictures.go
These apps are QA/developer tools.

⚙️ CodeRabbit configuration file

Files:

  • internal/format/video/settings.go
  • internal/format/video/bits.go
  • internal/format/imagelabel/imagelabel.go
  • internal/guard/film_test.go
  • internal/format/webm/webm.go
  • internal/guard/filmahead_test.go
  • internal/format/video/tilekey.go
  • internal/format/video/grid.go
  • internal/format/video/av1.go
  • internal/guard/filmtiles_test.go
  • internal/format/video/stream.go
  • internal/format/video/picture.go
  • internal/format/video/ahead.go
  • internal/format/video/still.go
  • internal/format/video/choose.go
  • internal/format/video/pictures.go
Go code.

⚙️ CodeRabbit configuration file

Files:

  • internal/format/video/settings.go
  • internal/format/video/bits.go
  • internal/format/imagelabel/imagelabel.go
  • internal/guard/film_test.go
  • internal/format/webm/webm.go
  • internal/guard/filmahead_test.go
  • internal/format/video/tilekey.go
  • internal/format/video/grid.go
  • internal/format/video/av1.go
  • internal/guard/filmtiles_test.go
  • internal/format/video/stream.go
  • internal/format/video/picture.go
  • internal/format/video/ahead.go
  • internal/format/video/still.go
  • internal/format/video/choose.go
  • internal/format/video/pictures.go
Check that documentation matches the actual code in this PR: commands, flags, config keys, file paths, build steps and examples must exist.

⚙️ CodeRabbit configuration file

Files:

  • CHANGELOG.md
All code in this repository is written by an AI coding agent (Claude Code).

⚙️ CodeRabbit configuration file

Files:

  • internal/gui/text/locale/registry/en.json
  • internal/gui/text/locale/registry/pl.json
  • CHANGELOG.md
  • internal/format/video/settings.go
  • internal/format/video/bits.go
  • internal/format/imagelabel/imagelabel.go
  • internal/guard/film_test.go
  • internal/format/webm/webm.go
  • internal/guard/filmahead_test.go
  • internal/format/video/tilekey.go
  • internal/format/video/grid.go
  • internal/format/video/av1.go
  • internal/guard/filmtiles_test.go
  • internal/format/video/stream.go
  • internal/format/video/picture.go
  • internal/format/video/ahead.go
  • internal/format/video/still.go
  • internal/format/video/choose.go
  • internal/format/video/pictures.go
Source excerpt: **Words a user reads are English, with a flat hyphen and no semicolons.**

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Files:

  • CHANGELOG.md
🪛 ast-grep (0.45.3)
internal/format/video/bits.go

[warning] 44-44: Narrowing a non-constant integer to a smaller fixed-width type (int8/int16/int32, uint8/uint16/uint32) can silently overflow or wrap, yielding negative or truncated values that are dangerous in size, length, or index logic. Validate the source value is within the target type's range before converting (e.g. bounds-check, or use a checked helper), and avoid narrowing untrusted or len()/parsed values.
Context: uint32(x)
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)


[warning] 47-47: Narrowing a non-constant integer to a smaller fixed-width type (int8/int16/int32, uint8/uint16/uint32) can silently overflow or wrap, yielding negative or truncated values that are dangerous in size, length, or index logic. Validate the source value is within the target type's range before converting (e.g. bounds-check, or use a checked helper), and avoid narrowing untrusted or len()/parsed values.
Context: uint32((x+m)>>1)
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)


[warning] 48-48: Narrowing a non-constant integer to a smaller fixed-width type (int8/int16/int32, uint8/uint16/uint32) can silently overflow or wrap, yielding negative or truncated values that are dangerous in size, length, or index logic. Validate the source value is within the target type's range before converting (e.g. bounds-check, or use a checked helper), and avoid narrowing untrusted or len()/parsed values.
Context: uint32((x + m) & 1)
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)

internal/format/video/grid.go

[warning] 200-200: Narrowing a non-constant integer to a smaller fixed-width type (int8/int16/int32, uint8/uint16/uint32) can silently overflow or wrap, yielding negative or truncated values that are dangerous in size, length, or index logic. Validate the source value is within the target type's range before converting (e.g. bounds-check, or use a checked helper), and avoid narrowing untrusted or len()/parsed values.
Context: uint32(tileSizeBytes-1)
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)

internal/guard/filmtiles_test.go

[error] 389-389: Zip-Slip: joining the extraction directory with an attacker-controlled archive entry name (e.g. zip.File.Name / tar.Header.Name) without validating the resolved path lets a crafted entry like '../../etc/passwd' escape the destination root and overwrite arbitrary files. Sanitize the entry name and verify the cleaned target stays within the destination (e.g. reject names containing '..', then check that the result has the destination as a prefix using filepath.Clean + strings.HasPrefix or filepath.Rel).
Context: filepath.Join(dir, planned[0].Name)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(zip-slip-filepath-join-archive-entry-go)

internal/format/video/picture.go

[warning] 343-343: Narrowing a non-constant integer to a smaller fixed-width type (int8/int16/int32, uint8/uint16/uint32) can silently overflow or wrap, yielding negative or truncated values that are dangerous in size, length, or index logic. Validate the source value is within the target type's range before converting (e.g. bounds-check, or use a checked helper), and avoid narrowing untrusted or len()/parsed values.
Context: uint8(16 + (47red+157g+16*b+128)>>8)
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)

🔇 Additional comments (19)
internal/format/imagelabel/imagelabel.go (1)

95-112: LGTM!

internal/format/video/picture.go (1)

91-133: LGTM!

Also applies to: 140-140, 164-164, 219-226, 237-237, 279-310, 330-348

internal/format/video/grid.go (1)

1-228: LGTM!

internal/format/video/tilekey.go (1)

1-97: LGTM!

internal/format/video/bits.go (1)

33-50: LGTM!

Also applies to: 86-89

internal/format/video/stream.go (1)

3-7: LGTM!

Also applies to: 17-39, 50-81, 97-97, 109-146

internal/format/video/still.go (1)

5-5: LGTM!

Also applies to: 17-57, 59-95, 102-104, 129-162, 164-205

internal/format/video/av1.go (1)

3-8: LGTM!

Also applies to: 125-158, 160-223

internal/format/video/choose.go (1)

25-34: LGTM!

Also applies to: 50-50, 61-65, 81-85, 103-158, 218-225, 246-251

internal/format/video/ahead.go (1)

33-47: LGTM!

Also applies to: 66-130, 146-147, 164-164, 195-200, 211-211, 221-275

internal/format/video/pictures.go (1)

1-244: LGTM!

internal/format/webm/webm.go (1)

60-72: LGTM!

Also applies to: 98-98, 192-192, 250-251, 268-268

internal/format/video/settings.go (1)

86-86: LGTM!

Also applies to: 203-210

CHANGELOG.md (1)

27-32: LGTM!

internal/gui/text/locale/registry/en.json (1)

1229-1230: LGTM!

internal/gui/text/locale/registry/pl.json (1)

247-247: LGTM!

internal/guard/film_test.go (1)

507-512: LGTM!

Also applies to: 545-550, 570-575, 594-598, 645-654, 662-664

internal/guard/filmahead_test.go (1)

96-101: LGTM!

Also applies to: 112-117, 144-166

internal/guard/filmtiles_test.go (1)

1-394: LGTM!


📝 Walkthrough

Walkthrough

The WebM video pipeline now encodes AV1 tiles, reuses coded tiles across picture changes, and assembles tiled frame samples. It adds tile-aware planning, work accounting, and parallel encoding, with tests that inspect tile data and decoded output.

Changes

AV1 tile-based WebM encoding

Layer / File(s) Summary
Picture geometry and tile layout
internal/format/imagelabel/imagelabel.go, internal/format/video/picture.go, internal/format/video/grid.go, internal/format/video/tilekey.go
Adds shared picture geometry, AV1 tile layouts, tile rectangles, and keys based on clock characters and square placement.
Tile encoding and frame assembly
internal/format/video/bits.go, internal/format/video/still.go, internal/format/video/av1.go, internal/format/video/stream.go
Encodes tile rectangles and assembles their data into AV1 frame samples. Stream bounds now account for tile information and tile-group bytes.
Tile planning and WebM writing
internal/format/video/choose.go, internal/format/video/ahead.go, internal/format/video/pictures.go, internal/format/webm/webm.go, internal/format/video/settings.go, internal/gui/text/locale/registry/*.json, CHANGELOG.md
Planning retains sampled tiles, picture coding reuses tile jobs, and WebM progress reports tile work. The NewStream call sites pass a label; the exported Coded, Encode, and PictureWork APIs are removed.
Tiled-film validation
internal/guard/film_test.go, internal/guard/filmahead_test.go, internal/guard/filmtiles_test.go
Tests require tiled output in selected cases, check parallel output and progress, and compare encoded tile data and decoded pixels.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Refactor

Sequence Diagram(s)

sequenceDiagram
  participant WebM as WebM writer
  participant Pictures
  participant Crew
  participant Encoder as encodeTile
  participant Sampler as frameShape.sample
  WebM->>Pictures: Request picture change
  Pictures->>Crew: Offer tile jobs
  Crew->>Encoder: Encode selected tile rectangle
  Pictures->>Sampler: Assemble coded tiles into frame sample
  Pictures-->>WebM: Return key and copy samples
Loading

Suggested labels: performance, ui

Merge Risk: ⚪ Minimal · up to d088e

WebM films with multiple tiles now encode AV1 tiles independently and reuse unchanged tiles, which greatly speeds up long films. Films with one tile keep their bytes. No concrete defect was found, and new guards check tile contents and decoded pixels, so the change appears ready to merge.

🚥 Pre-merge checks | ✅ 12 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Safe File Parsing ⚠️ Warning The new test parser can panic on malformed WebM/AV1 data. In internal/guard/filmtiles_test.go, frameOBU indexes p[0] without checking that the OBU payload is non-empty (line 209). `readFilmTiles… Make frameOBU and readFilmTiles reject truncated input with errors. Check the frame payload length before reading p[0], validate before and all header/tile-size ranges before indexing or slicing, and change filmBits.bit/bits to …
Scope, Duplication And Docs ⚠️ Warning The PR adds multi-tile frames, but the WebM size-limit explanation remains inaccurate. gridFor creates multiple tiles for eligible pictures (internal/format/video/grid.go:59-71), and the changelog… Update JointLimits comments and the English and Polish WebM width/height explanations. State that frames can use multiple AV1 tiles, and explain why the existing 4096×2304 area cap still applies—or revise the cap if multi-tile frames shou…
✅ Passed checks (12 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes splitting WebM pictures into AV1 tiles and coding unchanged tiles once per film. It is specific and relevant to the main change.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Tests For Changed Behavior ✅ Passed The PR changes runtime video encoding from whole pictures to independently coded AV1 tiles. Added and updated film guards cover tile layout, tile reuse, assembled-frame decoding, reserve limits, helpe…
No Secrets Or Debug Leftovers ✅ Passed The reviewed diff adds no CLAUDE.md, CLAUDE.local.md, AGENTS.md, .claude/ or .env files. Searches of added lines found no credentials, private URLs, local absolute paths, email addresses, IP addresses…
No Hardcoded Ui Styling ✅ Passed The PR does not change GUI code. The only GUI-path changes are English and Polish locale strings; the changed-file inventory contains no XAML, Slint, Fyne, Tkinter, or WPF code-behind. The styling che…
No Obvious Performance Problems ✅ Passed No clear performance problem matches this check. The changed video path walks changes and tile keys linearly in Stream.Work (internal/format/video/stream.go:117–130), and tile encoding through `ga…
Desktop Robustness ✅ Passed No explicit desktop-robustness failure is introduced. The GUI changes only update locale text. The new WebM tile workers are closed and awaited by defer pics.Close() and crew.stop; encoding checks…
System Changes Are Reversible ✅ Passed The changed-file inventory covers AV1/WebM tile encoding, picture layout, labels, tests, and text. The patch adds no changes to network filters or rules, proxies, firewalls, system time, process hooki…
Clear User-Facing Text ✅ Passed The PR changes the WebM change-interval description and changelog wording. The setting description remains consistent in English and Polish. No changed controls, icon-only buttons, confirmations, or v…
No Resource Leaks ✅ Passed No unbounded resource leak is introduced. webm.Write defers pics.Close() immediately after creating Pictures, including error and cancellation returns; crew.stop() closes the queue and waits f…
Full details: Safe File Parsing

Explanation

The new test parser can panic on malformed WebM/AV1 data. In internal/guard/filmtiles_test.go, frameOBU indexes p[0] without checking that the OBU payload is non-empty (line 209). readFilmTiles also calls filmBits.bit, which explicitly panics on a truncated header (lines 31–34), and indexes the tile-group header and size bytes without first checking their bounds (lines 116–129). The parser reads files generated in a temporary directory, not arbitrary user-selected files, but malformed generated output can still crash the test process instead of returning a parse error. The edited English and Polish JSON entries only change text.

Resolution

Make frameOBU and readFilmTiles reject truncated input with errors. Check the frame payload length before reading p[0], validate before and all header/tile-size ranges before indexing or slicing, and change filmBits.bit/bits to return errors that callers propagate. Keep the parser bounded to the expected generated-file size.

Full details: Scope, Duplication And Docs

Explanation

The PR adds multi-tile frames, but the WebM size-limit explanation remains inaccurate. gridFor creates multiple tiles for eligible pictures (internal/format/video/grid.go:59-71), and the changelog now describes tiled encoding. However, JointLimits still says the encoder codes a picture as one AV1 tile (internal/format/video/settings.go:106-117), and the English and Polish UI registry entries repeat that claim (en.json:1592-1595, pl.json:320). This leaves user-facing configuration guidance inconsistent with the changed behavior.

Resolution

Update JointLimits comments and the English and Polish WebM width/height explanations. State that frames can use multiple AV1 tiles, and explain why the existing 4096×2304 area cap still applies—or revise the cap if multi-tile frames should allow a larger picture area.

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

donislawdev and others added 2 commits October 7, 2026 08:17
…the ejected preset follow

Planning counts a frame's tile_info as this package now writes it, one bit
for one tile at 1x1, rather than the three gav1d could write, so the bound on
the smallest film at the default settings came ten bytes closer to the film:
3294 B to 3284 B. The film itself is the same - 3284 B is written and decodes
in libaom frame for frame, 3283 B is refused with the new minimum.

The ejected empty-and-minimal recipe asks for that size, so its bytes move
again before any release carried the film, under the decision the row
records. The site's format and preset pages and the preset screens' totals
are regenerated from the program.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, not a panic

A panic in a guard ends every guard of the package, not the one that read a
broken film. The bit reader says it ran out instead, and the reader of
tile_info and the tile group refuses a header that ends inside itself, a
frame that ends before its tile group or inside a tile's size, and an empty
frame OBU. filmOne is filmWithSeed without the seed rather than a copy of it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@donislawdev
donislawdev merged commit f678b0b into main Oct 7, 2026
25 checks passed
@donislawdev
donislawdev deleted the perf/webm-tiles branch October 7, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant