commaai/openpilot · error · VideoFileInvalid
slice_type must be 0, 1, or 2
Error message
slice_type must be 0, 1, or 2
What it means
Raised in get_hevc_slice_type() when the first ue(v) Exp-Golomb element of a slice segment header decodes to a value greater than 2. Per H.265 Table 7-7 only slice_type 0 (B), 1 (P), 2 (I) exist; all other values (3-9 are H.264-era repeat flags that HEVC removed) indicate the bit reader is misaligned — the stream is parsed at the wrong bit offset, usually due to a corrupt slice, wrong first-slice handling, or a file that is not HEVC.
Source
Thrown at openpilot/tools/lib/vidindex.py:258
# in bitstreams conforming to this version of this Specification. Other values for num_extra_slice_header_bits are reserved
# for future use by ITU-T | ISO/IEC. However, decoders shall allow num_extra_slice_header_bits to have any value.
# TODO: get from PPS_NUT pic_parameter_set_rbsp( ) for corresponding slice_pic_parameter_set_id
num_extra_slice_header_bits = 0
skip_bits += num_extra_slice_header_bits
# 7.4.7.1 General slice segment header semantics
# slice_type specifies the coding type of the slice according to Table 7-7.
# Table 7-7 - Name association to slice_type
# slice_type | Name of slice_type
# 0 | B (B slice)
# 1 | P (P slice)
# 2 | I (I slice)
# unsigned integer 0-th order Exp-Golomb-coded syntax element with the left bit first
slice_type, _ = get_ue(dat, rbsp_start, skip_bits)
if DEBUG:
print(" slice_type:", slice_type, f"(first slice: {is_first_slice})")
if slice_type > 2:
raise VideoFileInvalid("slice_type must be 0, 1, or 2")
return slice_type, is_first_slice
def hevc_index(hevc_file_name: str, allow_corrupt: bool=False) -> tuple[list, int, bytes]:
with FileReader(hevc_file_name) as f:
dat = f.read()
if len(dat) < NAL_UNIT_START_CODE_SIZE + 1:
raise VideoFileInvalid("data is too short")
if dat[0] != 0x00:
raise VideoFileInvalid("first byte must be 0x00")
prefix_dat = b""
frame_types = []
i = 1 # skip past first byte 0x00
try:
while i < len(dat):View on GitHub (pinned to 516ec1e682)
Solutions
- Retry with allow_corrupt=True — hevc_index wraps the parse loop so a bad slice can be skipped.
- Confirm the file is actually HEVC (check the SPS/parameter-set prefix data or run ffprobe) and not H.264 or an MP4 container.
- If one segment of a route fails, re-download it; cloud-stored segments are sometimes incomplete on first fetch.
- Inspect with an independent parser (ffprobe -show_frames) to confirm the file itself is damaged rather than a vidindex bug.
Example fix
# before
frames, prefix, prefix_dat = hevc_index(path)
# after
try:
frames, prefix, prefix_dat = hevc_index(path)
except VideoFileInvalid:
frames, prefix, prefix_dat = hevc_index(path, allow_corrupt=True) Defensive patterns
Strategy: try-catch
Try / catch
try:
frames, prefix, prefix_dat = hevc_index(path)
except VideoFileInvalid as e:
if 'slice_type' in str(e):
# bitstream desync: retry tolerating corruption, or re-fetch the segment
frames, prefix, prefix_dat = hevc_index(path, allow_corrupt=True)
else:
raise Prevention
- Validate with ffprobe that the file is HEVC and decodes before running vidindex.
- Keep container->Annex-B conversions lossless (use -bsf:v hevc_mp4toannexb, never re-encode).
- For cloud routes, verify segment upload completed before indexing.
When it happens
Trigger: hevc_index() reaches a NAL typed as a slice (VCL NAL unit) and get_ue() at rbsp_start + skip_bits returns > 2. Happens with bitstream corruption, when emulation-prevention bytes were removed/added incorrectly upstream, or when an H.264 stream is fed to the HEVC indexer.
Common situations: Corrupt dashboard-camera segments (SD card wear, interrupted writes), processing a renamed H.264 qcamera file through the HEVC path, or indexing partially-uploaded cloud routes. Sometimes a single bad frame in an otherwise good route.
Related errors
- data must begin with start code
- data to short to contain nal unit header
- data is too short
- first byte must be 0x00
- invalid config backup: {backup}
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/2c6798901d416482.
Report an issue: GitHub.