commaai/openpilot · error · VideoFileInvalid

data must begin with start code

Error message

data must begin with start code

What it means

Thrown by require_nal_unit_start() in openpilot's HEVC video indexing tool when the bytes at the expected NAL unit position do not equal the 4-byte Annex-B start code (00 00 00 01). The indexer (hevc_index) walks the file assuming each NAL unit begins exactly where the previous one ended, so any mismatch means the byte stream is not a sequence of well-formed Annex-B NAL units. It is raised as VideoFileInvalid, marking the input as corrupt or not raw HEVC.

Source

Thrown at openpilot/tools/lib/vidindex.py:155

      else:
        suffix_val = (suffix_val << 1) | ((dat[i] >> j) & 1)
        suffix_len += 1
      j -= 1

      if prefix_val == 1 and prefix_len - 1 == suffix_len:
        val = int(2**(prefix_len-1) - 1 + suffix_val)
        size = prefix_len + suffix_len
        return val, size
    i += 1

  raise VideoFileInvalid("invalid exponential-golomb code")

def require_nal_unit_start(dat: bytes, nal_unit_start: int) -> None:
  if nal_unit_start < 1:
    raise ValueError("start index must be greater than zero")

  if dat[nal_unit_start:nal_unit_start + NAL_UNIT_START_CODE_SIZE] != NAL_UNIT_START_CODE:
    raise VideoFileInvalid("data must begin with start code")

def get_hevc_nal_unit_length(dat: bytes, nal_unit_start: int) -> int:
  try:
    pos = dat.index(NAL_UNIT_START_CODE, nal_unit_start + NAL_UNIT_START_CODE_SIZE)
  except ValueError:
    pos = -1

  # length of NAL unit is byte count up to next NAL unit start index
  nal_unit_len = (pos if pos != -1 else len(dat)) - nal_unit_start
  if DEBUG:
    print("  nal_unit_len:", nal_unit_len)
  return nal_unit_len

def get_hevc_nal_unit_type(dat: bytes, nal_unit_start: int) -> HevcNalUnitType:
  # 7.3.1.2 NAL unit header syntax
  # nal_unit_header( ) {    // descriptor
  #   forbidden_zero_bit    f(1)
  #   nal_unit_type         u(6)

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Verify the input is raw Annex-B HEVC (.hevc stream extracted from a route), not an MP4 container — remux with ffmpeg -c copy -bsf:v hevc_mp4toannexb if needed.
  2. If the file may be truncated/corrupt, call hevc_index with allow_corrupt=True so partial indexing is attempted instead of failing.
  3. Check file integrity: compare size and sha against the route manifest; re-download the segment from the cloud if it came from a partially uploaded route.
  4. Reproduce with a known-good route file to rule out a parsing bug, then report the file to openpilot devs if only that file fails.

Example fix

// before
index = hevc_index('route/segment/camera.hevc')

// after
index = hevc_index('route/segment/camera.hevc', allow_corrupt=True)  // tolerate truncated tail
Defensive patterns

Strategy: validation

Validate before calling

def is_annexb_hevc(path, min_size=6):
    with open(path, 'rb') as f:
        head = f.read(4)
        f.seek(-4, 2)
    import os
    if os.path.getsize(path) < min_size:
        return False
    return head == b'\x00\x00\x00\x01'

Try / catch

from openpilot.tools.lib.vidindex import hevc_index, VideoFileInvalid
try:
    frames, prefix, prefix_dat = hevc_index(path)
except VideoFileInvalid as e:
    if 'start code' in str(e):
        frames, prefix, prefix_dat = hevc_index(path, allow_corrupt=True)
    else:
        raise

Prevention

When it happens

Trigger: Calling hevc_index() (or require_nal_unit_start() directly) on data where dat[i:i+4] != b'\x00\x00\x00\x01'. Typical when the file is not raw HEVC/Annex-B (e.g. it is MP4, MKV, or fragmented), when a NAL length was miscomputed after a corrupt unit, or when passing a start index of trailing garbage. Also raised if nal_unit_start < 1 (ValueError variant: 'start index must be greater than zero').

Common situations: Indexing a camera route file that was truncated mid-write (loggerd crash), feeding an fMP4/AVCC-encapsulated stream without stripping length prefixes, or processing qcamera/resampled streams with emulation prevention edge cases that desync the scanner.

Related errors


AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15). Data as JSON: /api/errors/f6799fa984a0e659. Report an issue: GitHub.