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
- Use one of the supported formats: 'rgb24', 'nv12', or 'yuv420p'
- For grayscale, decode as nv12/yuv420p and take the Y plane: frames[:, :h, :w] instead of pix_fmt='gray'
- 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
- Whitelist pix_fmt at your API boundary instead of passing user strings through
- Derive grayscale from nv12's Y plane rather than asking ffmpeg for 'gray'
- Watch case-sensitivity: only lowercase format names match
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
- {fn} is empty
- {fn}
- Failed to index {fn!r}
- convert decoded frame: produced {rows} of {frame.height} row
- ffmpeg failed: {result.stderr.decode()}
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/9cc9094c7e60a9ba.
Report an issue: GitHub.