commaai/openpilot · error · RuntimeError
ffmpeg failed: {result.stderr.decode()}
Error message
ffmpeg failed: {result.stderr.decode()} What it means
When decoding a qcamera segment with the ffmpeg subprocess (stdin raw file, stdout rawvideo nv12), a non-zero exit code triggers this RuntimeError carrying ffmpeg's stderr. The qcamera file is an HEVC stream inside a ts container; failures usually mean ffmpeg cannot parse the container, was built without the needed demuxer/decoder, or got truncated input via the pipe.
Source
Thrown at openpilot/tools/clip/run.py:160
current_seg: int = -1
get_frame: Callable[[int], np.ndarray] | None = None
for global_idx in range(start_frame, end_frame):
seg_idx, local_idx = global_idx // frames_per_seg, global_idx % frames_per_seg
if seg_idx != current_seg:
current_seg = seg_idx
path = camera_paths[seg_idx] if seg_idx < len(camera_paths) else None
if not path:
raise RuntimeError(f"No camera file for segment {seg_idx}")
if use_qcam:
w, h = frame_size or get_frame_dimensions(path)
with FileReader(path) as f:
result = subprocess.run(["ffmpeg", "-v", "quiet", "-i", "-", "-f", "rawvideo", "-pix_fmt", "nv12", "-"],
input=f.read(), capture_output=True)
if result.returncode != 0:
raise RuntimeError(f"ffmpeg failed: {result.stderr.decode()}")
seg_frames = np.frombuffer(result.stdout, dtype=np.uint8).reshape(-1, w * h * 3 // 2)
get_frame = seg_frames.__getitem__
else:
get_frame = FrameReader(path, pix_fmt="nv12").get
assert get_frame is not None
yield global_idx, get_frame(local_idx)
class FrameQueue:
def __init__(self, camera_paths, start_time, end_time, fps=20, prefetch_count=60, use_qcam=False):
# Probe first valid camera file for dimensions
first_path = next((p for p in camera_paths if p), None)
if not first_path:
raise RuntimeError("No valid camera paths")
self.frame_w, self.frame_h = get_frame_dimensions(first_path)
self._queue, self._stop, self._error = queue.Queue(maxsize=prefetch_count), threading.Event(), NoneView on GitHub (pinned to 516ec1e682)
Solutions
- Run the same command manually to see the real error: ffmpeg -i <qcamera.ts> -f rawvideo -pix_fmt nv12 out.yuv
- Install a full ffmpeg build with HEVC support (e.g. ffmpeg from ffmpeg.org, not a codec-stripped distro package)
- Re-download the qcamera file if it is truncated/corrupt (verify size against the server listing)
- If stderr is empty due to -v quiet, temporarily raise verbosity to '-v error' to capture the cause
Example fix
# before
result = subprocess.run(["ffmpeg", "-v", "quiet", ...])
# after (surface the real cause)
result = subprocess.run(["ffmpeg", "-v", "error", ...])
if result.returncode != 0:
raise RuntimeError(f"ffmpeg failed: {result.stderr.decode(errors='replace') or 'no stderr (check ffmpeg build has hevc)'}") Defensive patterns
Strategy: try-catch
Validate before calling
import shutil, subprocess
assert shutil.which('ffmpeg'), 'ffmpeg not on PATH'
probe = subprocess.run(['ffmpeg', '-decoders'], capture_output=True, text=True)
assert 'hevc' in probe.stdout.lower(), 'system ffmpeg cannot decode HEVC qcamera streams' Try / catch
try:
result = subprocess.run(cmd, input=f.read(), capture_output=True)
except RuntimeError as e:
msg = str(e)
if 'ffmpeg failed' in msg:
if 'decode' in msg or not msg.strip('ffmpeg failed: '):
raise SystemExit('install a full ffmpeg build with HEVC support')
raise SystemExit(f'qcamera decode failed: {msg}')
raise Prevention
- Use '-v error' instead of '-v quiet' so failures carry actionable stderr
- Pin a known-good, full-featured ffmpeg (e.g. via conda/static builds) in environments that run the clip tool
When it happens
Trigger: use_qcam=True path in iter_segment_frames(): subprocess ffmpeg exits non-zero because the .ts is corrupt/truncated; system ffmpeg lacks hevc decoding (--disable-decoders builds, distro 'ffmpeg-free' packages); piping the whole file via stdin when the container needs seekable input.
Common situations: Partially downloaded qcamera.ts; Fedora-style ffmpeg builds without libde265/hevc; old ffmpeg versions with poor hevc-in-mpegts demuxing; empty stderr because '-v quiet' suppressed diagnostics so the message looks empty.
Related errors
- convert decoded frame: produced {rows} of {frame.height} row
- No camera file for segment {seg_idx}
- No valid camera paths
- error getting route metadata: cannot find any uploaded logs
- bundled firmware is {expected_product!r}, expected version {
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/8abe445152c73ab3.
Report an issue: GitHub.