How to Parse AV1 OBU Size with Bitwise Operations

In the AV1 video codec specification, Open Bitstream Units (OBUs) utilize a variable-length integer encoding called LEB128 (Little Endian Base 128) to indicate their payload size when the header's obu_has_size_field flag is set. Parsing this field requires a sequence of specific bit-level operations—primarily bitwise AND, bitwise left shift, and bitwise OR—to reconstruct the integer from a stream of bytes. This article explains how these bitwise operations function together to extract the final size value from an AV1 bitstream.

LEB128 Byte Structure in AV1

Each byte in an AV1 LEB128 sequence is split into two distinct parts:

According to the AV1 specification, an OBU size indicator can span up to 8 bytes, producing an integer up to 56 bits wide (though practically bounded by standard integer limits).

Key Bit-Level Operations Used in Parsing

Decoding the variable-length size requires four core bitwise operations applied in a loop across the input bytes.

1. Bitwise AND for Continuation Detection (& 0x80)

To check whether more bytes must be read, the parser tests the Most Significant Bit (bit 7) using a bitwise AND with the hexadecimal mask 0x80 (10000000 in binary):

bool has_next_byte = (current_byte & 0x80) != 0;

If the result is zero, the loop terminates after processing the current byte's payload.

2. Bitwise AND for Payload Extraction (& 0x7F)

To isolate the lower 7 bits containing the numerical value, the parser uses a bitwise AND with the mask 0x7F (01111111 in binary):

uint64_t payload = current_byte & 0x7F;

This clears the continuation bit, preventing it from corrupting the accumulated size value.

3. Bitwise Left Shift for Alignment (<<)

Because LEB128 stores data in little-endian order, the first byte represents the least significant 7 bits, the second byte represents bits 7 to 13, and so on. The parser aligns the extracted 7-bit payload to its correct power-of-two position using a left shift by (i * 7) bits, where i is the zero-based index of the current byte:

uint64_t shifted_payload = payload << (i * 7);

4. Bitwise OR for Accumulation (| or |=)

To merge the shifted 7-bit segment into the total accumulated integer, the parser performs a bitwise OR operation against the target variable:

obu_size |= shifted_payload;

Complete Implementation Example

Combining these bit-level operations yields the standard AV1 leb128() parsing routine:

uint64_t obu_size = 0;
for (int i = 0; i < 8; i++) {
    uint8_t byte = read_byte();
    
    // Extract lower 7 bits and shift into place, then accumulate
    obu_size |= ((uint64_t)(byte & 0x7F)) << (i * 7);
    
    // Check continuation bit
    if ((byte & 0x80) == 0) {
        break;
    }
}

Constraints and Validation

During parsing, implementations must enforce two AV1-specific bitstream constraints:

  1. Length Limit: If the continuation bit is still 1 after reading 8 bytes, the bitstream is malformed and must trigger a decode error.
  2. Value Padding: Bitstreams can pad small integers across multiple bytes by leaving unused bits as 0 while setting the continuation bit. However, the resulting shifted value must not exceed (1ULL << 32) - 1 if the decoder enforces 32-bit maximum OBU sizes.