{"record":{"id":"5e7e8f225fc7bfc7","repo":"commaai/openpilot","slug":"invalid-exponential-golomb-code","errorCode":null,"errorMessage":"invalid exponential-golomb code","messagePattern":"invalid exponential-golomb code","errorType":"exception","errorClass":"VideoFileInvalid","httpStatus":null,"severity":"error","filePath":"openpilot/tools/lib/vidindex.py","lineNumber":148,"sourceCode":"    j = 7\n    while j >= 0:\n      if skip_bits > 0:\n        skip_bits -= 1\n      elif prefix_val == 0:\n        prefix_val = (dat[i] >> j) & 1\n        prefix_len += 1\n      else:\n        suffix_val = (suffix_val << 1) | ((dat[i] >> j) & 1)\n        suffix_len += 1\n      j -= 1\n\n      if prefix_val == 1 and prefix_len - 1 == suffix_len:\n        val = int(2**(prefix_len-1) - 1 + suffix_val)\n        size = prefix_len + suffix_len\n        return val, size\n    i += 1\n\n  raise VideoFileInvalid(\"invalid exponential-golomb code\")\n\ndef require_nal_unit_start(dat: bytes, nal_unit_start: int) -> None:\n  if nal_unit_start < 1:\n    raise ValueError(\"start index must be greater than zero\")\n\n  if dat[nal_unit_start:nal_unit_start + NAL_UNIT_START_CODE_SIZE] != NAL_UNIT_START_CODE:\n    raise VideoFileInvalid(\"data must begin with start code\")\n\ndef get_hevc_nal_unit_length(dat: bytes, nal_unit_start: int) -> int:\n  try:\n    pos = dat.index(NAL_UNIT_START_CODE, nal_unit_start + NAL_UNIT_START_CODE_SIZE)\n  except ValueError:\n    pos = -1\n\n  # length of NAL unit is byte count up to next NAL unit start index\n  nal_unit_len = (pos if pos != -1 else len(dat)) - nal_unit_start\n  if DEBUG:\n    print(\"  nal_unit_len:\", nal_unit_len)","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/tools/lib/vidindex.py#L130-L166","documentation":"vidindex parses HEVC SPS/PPS NAL units by hand, reading exp-golomb codes bit by bit. If no valid code terminator is found within the data (prefix/suffix never balance), the bitstream is malformed at that point and VideoFileInvalid('invalid exponential-golomb code') is raised. It means the camera stream is corrupt, not a code bug.","triggerScenarios":"hevc_index()/get_video_index() on a truncated or corrupt camera file; video from a device whose encoder crashed mid-segment; data corrupted in transfer; a file that is not actually HEVC.","commonSituations":"Dashcam power loss mid-encode producing torn frames; partial segment uploads; bit flips in cheap storage; processing foreign video claiming to be hevc.","solutions":["Confirm the file decodes with the reference decoder: ffmpeg -v error -i file.hevc -f null - ; if ffmpeg also fails, the data is corrupt","Re-download the segment; if it is corrupt at the source, skip that segment in your analysis","Catch VideoFileInvalid per-segment in batch jobs and continue with other segments"],"exampleFix":"# before\nindex, l, prefix = hevc_index(fn)\n\n# after\nfrom openpilot.tools.lib.vidindex import VideoFileInvalid\ntry:\n    index, l, prefix = hevc_index(fn)\nexcept VideoFileInvalid:\n    print(f'{fn}: corrupt HEVC, skipping segment'); continue","handlingStrategy":"try-catch","validationCode":"import subprocess\n\ndef hevc_decodes(fn: str) -> bool:\n    with FileReader(fn) as f:\n        head = f.read(1 << 20)\n    return subprocess.run(['ffmpeg', '-v', 'error', '-f', 'hevc', '-i', 'pipe:0', '-f', 'null', '-'], input=head, capture_output=True).returncode == 0","typeGuard":null,"tryCatchPattern":"from openpilot.tools.lib.vidindex import VideoFileInvalid\ntry:\n    frame_types, dat_len, prefix = hevc_index(fn)\nexcept VideoFileInvalid:\n    mark_segment_corrupt(fn); continue","preventionTips":["Validate camera files with ffmpeg before indexing in batch pipelines","Handle VideoFileInvalid per segment — corruption is data-level, retrying won't help","Suspect power-loss/truncation when many segments fail golomb parsing"],"tags":["video","hevc","corrupt-data","vidindex"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}