AV1 Parser Synchronization on Corrupted OBUs
This article explores how an AV1 decoder maintains bitstream synchronization when encountering corrupted Open Bitstream Units (OBUs). It details the architectural mechanisms defined in the AV1 specification—such as explicit size signaling, temporal delineation, container boundaries, and heuristic header hunting—that allow a parser to isolate invalid data, discard unreadable elements, and safely recover the decoding pipeline without crashing or losing frame alignment.
Explicit OBU Size Delimitation via LEB128
The primary defense against bitstream corruption propagation in AV1
is explicit length signaling within the OBU header. When the
obu_has_size_field flag is set in the 1- or 2-byte OBU
header, the length of the trailing payload is encoded immediately after
using a variable-length format known as LEB128 (Little-Endian Base
128).
If a corruption event is confined entirely to the OBU payload, the
parser reads the obu_size field to determine precisely how
many bytes the current unit occupies. The parser skips over the corrupt
payload and advances its read pointer directly to the start of the next
OBU header, preventing a local bit error from invalidating the entire
stream.
Framing Formats and Container Boundaries
When the bitstream is encapsulated within container formats (such as ISOBMFF or WebM) or the AV1 Annex B byte stream format, higher-level markers provide additional containment boundaries:
- Annex B Streams: Structure the bitstream into Temporal Units (TUs) and Frame Units (FUs), each prefixed with its own LEB128 length. If an inner OBU header or size field is damaged, the parser falls back to the outer TU or FU size to skip the entire corrupted unit and resume parsing at the next valid temporal boundary.
- Media Containers: Modern demuxers pass discrete chunks (samples or packets) to the AV1 parser. A failure within one container sample is isolated to that specific packet, allowing the parser to reset its bit-reading state at the boundary of the next packet.
Key OBU Resynchronization Anchors
When corruption damages the OBU header or the LEB128 size field itself, jumping via length is no longer possible. In such scenarios, the parser enters a search state to locate valid synchronization anchors:
- Temporal Delimiter OBU
(
OBU_TEMPORAL_DELIMITER): Signals the start of a new timestamp and temporal unit. Locating a Temporal Delimiter allows the parser to clear current frame buffers and establish the temporal index for following packets. - Sequence Header OBU
(
OBU_SEQUENCE_HEADER): Resets critical decoding state parameters (such as profile, level, bit depth, and color config). If parsing context is lost due to widespread corruption, locating a new Sequence Header enables a full decoder re-initialization. - Key Frames (
KEY_FRAME): Within Frame or Tile Group OBUs, locating an intra-coded key frame allows the spatial reconstruction pipeline to recover without relying on previous, potentially missing reference frames.
Pattern Matching and Heuristic Resynchronization
Unlike legacy codecs (such as MPEG-2 or H.264) that utilize explicit
3-byte or 4-byte start codes (e.g., 0x000001), AV1 OBUs do
not mandate universal start code emulation prevention prefixes.
Consequently, if a parser loses alignment in a raw bitstream lacking
length indicators, it must employ heuristic validation across sliding
byte windows:
- Header Validation: The parser examines candidate
bytes for valid
obu_typevalues (currently defined from 1 to 15; reserved values are rejected). - Flag Consistency: It checks the
obu_forbidden_bit(which must strictly be0), verifies theobu_extension_flagto see if a second header byte is present, and inspects reserved bits within the extension header. - Trailing Bit Verification: Spec-compliant OBUs
require byte alignment via trailing bits (
trailing_bits()), consisting of a single1bit followed by zero or more0bits to complete the byte. Parsers check for these trailing patterns at predicted unit ends.
Once a candidate sequence (such as a Temporal Delimiter followed by a Sequence Header or Frame Header) passes these structural rules, the parser locks synchronization and resumes normal decoding operations.