AV1 Loop Restoration Tile-Level Control

The AV1 video codec uses Loop Restoration as a post-reconstruction filtering tool to remove artifacts and restore edge fidelity. While loop restoration is globally defined at the frame header level, its tile-level control is managed through a combination of tile boundary filtering flags and sub-tile Restoration Units (RUs). This architecture allows encoders to selectively apply, tune, or disable loop restoration across individual tiles or sub-regions within a tile to optimize parallel decoding and computational efficiency.

Frame-Level Foundation vs. Tile Execution

Loop restoration configuration begins in the frame header inside the lr_params() syntax element. The bitstream declares the restoration filter type (lr_type) independently for each color plane (Y, U, and V):

When loop restoration is enabled at the frame level, the frame is subdivided into a grid of Restoration Units (RUs), typically sized at 64x64, 128x128, or 256x256 luma samples.

The Tile-Level Control Mechanism

Tile-level control does not rely on a single isolated "on/off" bit in the tile header. Instead, control over a tile's loop restoration behavior is governed by two primary mechanisms:

1. Restoration Unit Signaling Inside Tile Streams

When lr_type is set to RESTORE_SWITCHABLE (or when unit-level coefficients are signaled), the control syntax is parsed directly within the tile data. Each tile contains the restoration unit parameters that correspond to its spatial boundaries.

If an encoder needs to disable loop restoration for an entire tile:

2. The loop_filter_across_tiles_enabled Flag

Loop restoration relies on neighboring reconstructed pixels to compute filter output. The syntax element loop_filter_across_tiles_enabled serves as a critical structural control for loop processing at tile edges:

Multi-Threading and Encoder Flexibility

By decoupling the grid of Restoration Units into tile-aligned segments and controlling edge crossing through loop_filter_across_tiles_enabled, AV1 decoders can run loop restoration in completely independent worker threads per tile. Encoders gain the flexibility to turn off restoration entirely in visually simple tiles by declaring RESTORE_NONE for their respective RUs, conserving processing overhead while allocating restoration filtering only to detail-heavy tiles.