AlexxIT/go2rtc · error

v4l2: invalid video_size

Error message

v4l2: invalid video_size

What it means

v4l2.Open throws "v4l2: invalid video_size" when the caller requests the yuyv422 input_format but codec.FmtpLine is empty — meaning no usable video size was negotiated for the V4L2 device, so raw 422 capture cannot be configured. The library cannot proceed without a size/fmt line and fails the Open call. Callers hit this in handlePipe, do, handleTCP and apiStream.

Solutions

  1. Add an explicit video_size query parameter supported by the camera (check with v4l2-ctl --list-formats-ext).
  2. Verify input_format=yuyv422 is actually supported by the device; switch to a supported format (e.g. mjpeg) if not.
  3. Point the producer at the correct capture /dev/videoN node (not a metadata node).
  4. Confirm the camera is plugged in and not held by another process (fuser /dev/video0).

Example fix

// before
 producer.Open("/dev/video0?input_format=yuyv422")
// after
 producer.Open("/dev/video0?input_format=yuyv422&video_size=640x480&framerate=30")
Defensive patterns

Strategy: validation

Validate before calling

// before Open: confirm the device supports the format+size
// $ v4l2-ctl -d /dev/video0 --list-formats-ext
// ensure URL includes a supported size:
if !strings.Contains(url, "video_size=") && strings.Contains(url, "input_format=yuyv422") {
    return errors.New("raw yuyv422 requires explicit video_size")
}

Try / catch

p, err := v4l2.Open(url)
if err != nil {
    if strings.Contains(err.Error(), "invalid video_size") {
        return fmt.Errorf("camera %s: unsupported format/size, run v4l2-ctl --list-formats-ext: %w", dev, err)
    }
    return err
}

Prevention

When it happens

Trigger: Opening a v4l2 producer with ?input_format=yuyv422 while the camera's format enumeration left codec.FmtpLine empty (device reported no supported frame size/format, or the video_size query was missing/invalid).

Common situations: URL missing video_size parameter; webcam not supporting YUYV at the requested resolution; camera busy or detached so format probing returned nothing; wrong /dev/video node (metadata node instead of capture).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/b79f69dc0e3af502. Report an issue: GitHub.

Appendix: source

Thrown at pkg/v4l2/producer.go:52

	}

	codec := &core.Codec{
		ClockRate:   90000,
		PayloadType: core.PayloadTypeRAW,
	}

	var width, height, pixFmt uint32

	if wh := strings.Split(query.Get("video_size"), "x"); len(wh) == 2 {
		codec.FmtpLine = "width=" + wh[0] + ";height=" + wh[1]
		width = uint32(core.Atoi(wh[0]))
		height = uint32(core.Atoi(wh[1]))
	}

	switch query.Get("input_format") {
	case "yuyv422":
		if codec.FmtpLine == "" {
			return nil, errors.New("v4l2: invalid video_size")
		}
		codec.Name = core.CodecRAW
		codec.FmtpLine += ";colorspace=422"
		pixFmt = device.V4L2_PIX_FMT_YUYV
	case "nv12":
		if codec.FmtpLine == "" {
			return nil, errors.New("v4l2: invalid video_size")
		}
		codec.Name = core.CodecRAW
		codec.FmtpLine += ";colorspace=420mpeg2" // maybe 420jpeg
		pixFmt = device.V4L2_PIX_FMT_NV12
	case "mjpeg":
		codec.Name = core.CodecJPEG
		pixFmt = device.V4L2_PIX_FMT_MJPEG
	case "h264":
		codec.Name = core.CodecH264
		pixFmt = device.V4L2_PIX_FMT_H264
	case "hevc":

View on GitHub (pinned to c245815e75)