commaai/openpilot · error · NotImplementedError

Unsupported pixel format: {pix_fmt}

Error message

Unsupported pixel format: {pix_fmt}

What it means

decompress_video_data() only reshapes ffmpeg's raw output for three pixel formats: rgb24, nv12, and yuv420p. Any other pix_fmt string reaches the else-branch and raises NotImplementedError. The restriction exists because the output numpy shape (h,w,3 vs h*w*3//2) is hardcoded per format.

Source

Thrown at openpilot/tools/lib/framereader.py:66

          "-threads", threads,
          "-hwaccel", hwaccel,
          "-c:v", "hevc",
          "-vsync", "0",
          "-f", vid_fmt,
          "-flags2", "showall",
          "-i", "pipe:0",
          "-f", "rawvideo",
          "-pix_fmt", pix_fmt,
          "pipe:1"]
  dat = subprocess.check_output(args, input=rawdat)

  ret: np.ndarray
  if pix_fmt == "rgb24":
    ret = np.frombuffer(dat, dtype=np.uint8).reshape(-1, h, w, 3)
  elif pix_fmt in ["nv12", "yuv420p"]:
    ret = np.frombuffer(dat, dtype=np.uint8).reshape(-1, (h*w*3//2))
  else:
    raise NotImplementedError(f"Unsupported pixel format: {pix_fmt}")
  return ret

def ffprobe(fn, fmt=None):
  fn = resolve_name(fn)
  cmd = ["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams"]
  if fmt:
    cmd += ["-f", fmt]
  cmd += ["-i", "pipe:0"]

  try:
    with FileReader(fn) as f:
      ffprobe_output = subprocess.check_output(cmd, input=f.read(4096))
  except subprocess.CalledProcessError as e:
    raise DataUnreadableError(fn) from e
  return json.loads(ffprobe_output)

def get_index_data(fn: str, index_data: dict|None = None):
  if index_data is None:

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Use one of the supported formats: 'rgb24', 'nv12', or 'yuv420p'
  2. For grayscale, decode as nv12/yuv420p and take the Y plane: frames[:, :h, :w] instead of pix_fmt='gray'
  3. For bgr24, decode rgb24 then do frames[..., ::-1]

Example fix

# before
frames = decompress_video_data(raw, w, h, pix_fmt='gray')

# after
frames = decompress_video_data(raw, w, h, pix_fmt='nv12').reshape(-1, h*3//2, w)
gray = frames[:, :h, :]
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_PIX_FMTS = {'rgb24', 'nv12', 'yuv420p'}
assert pix_fmt in SUPPORTED_PIX_FMTS, f'pass one of {SUPPORTED_PIX_FMTS}'

Type guard

def is_supported_pix_fmt(p: str) -> bool:
    return p in ('rgb24', 'nv12', 'yuv420p')

Prevention

When it happens

Trigger: Calling decompress_video_data(..., pix_fmt='gray') or 'bgr24', 'yuv444p', etc. Also calling FrameReader with an unsupported pix_fmt since it forwards the argument.

Common situations: Wanting grayscale frames for a model and passing 'gray'; copying ffmpeg filter names into pix_fmt; typo like 'NV12' (uppercase) which misses the exact-match list.

Related errors


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