---
name: "video"
section: "4"
platform: "openbsd"
package: "man"
version: "8.0-current-20261101"
release: "OpenBSD 8.0-current (2026-11-01)"
platforms: ["freebsd", "openbsd"]
url: "https://new.carta.tech/video"
---

# video(4)

device-independent video driver layer

## NAME

**video** – device-independent video driver layer

## SYNOPSIS

**video\* at uvideo?**

**#include \<sys/types.h\>**

**#include \<sys/ioctl.h\>**

**#include \<sys/videoio.h\>**

## DESCRIPTION

The **video** driver provides support for various video devices. It provides a uniform programming interface layer above different underlying video hardware drivers. The **video** driver uses the V4L2 (Video for Linux Two) API which is widely used by video applications. Therefore this document mainly describes the V4L2 API parts which are supported by the **video** driver.

For security reasons video recording is blanked by default. To achieve this, the **video** driver blanks image data received from the underlying video hardware driver. The superuser can change this behavior using the *kern.video.record* [sysctl(2)](/sysctl/2.md) variable:

```
kern.video.record=0	# Recording is blanked (default)
kern.video.record=1	# Recording is enabled
```

## IOCTLS

The following [ioctl(2)](/ioctl/2.md) commands are supported:

- VIDIOC\_QUERYCAP *struct v4l2\_capability \**

  Query device capabilities.

  ```
  struct v4l2_capability {
  	u_int8_t	driver[16];
  	u_int8_t	card[32];
  	u_int8_t	bus_info[32];
  	u_int32_t	version;
  	u_int32_t	capabilities;
  	u_int32_t	device_caps;
  	u_int32_t	reserved[3];
  };
  ```

- VIDIOC\_ENUM\_FMT *struct v4l2\_fmtdesc \**

  Enumerate image formats.

  ```
  struct v4l2_fmtdesc {
  	u_int32_t	index;
  	u_int32_t	type;
  	u_int32_t	flags;
  	u_int8_t	description[32];
  	u_int32_t	pixelformat;
  	u_int32_t	mbus_code;
  	u_int32_t	reserved[3];
  };
  ```

- VIDIOC\_S\_FMT *struct v4l2\_format \**

  Set the data format.

  ```
  struct v4l2_format {
  	u_int32_t	type;
  	union {
  		struct v4l2_pix_format		pix;
  		struct v4l2_pix_format_mplane	pix_mp;
  		struct v4l2_window		win;
  		struct v4l2_vbi_format		vbi;
  		struct v4l2_sliced_vbi_format	sliced;
  		struct v4l2_sdr_format		sdr;
  		struct v4l2_meta_format		meta;
  		u_int8_t			raw_data[200];
          } fmt;
  };
  ```

- VIDIOC\_G\_FMT *struct v4l2\_format \**

  Get the data format.

  Same structure as for VIDIOC\_S\_FMT.

- VIDIOC\_ENUMINPUT *struct v4l2\_input \**

  Enumerate video inputs.

  ```
  struct v4l2_input {
  	u_int32_t	index;
  	u_int8_t	name[32];
  	u_int32_t	type;
  	u_int32_t	audioset;
  	u_int32_t	tuner;
  	v4l2_std_id	std;
  	u_int32_t	status;
  	u_int32_t	capabilities;
  	u_int32_t	reserved[3];
  };
  ```

- VIDIOC\_G\_INPUT *int \**

  Get the current video input.

- VIDIOC\_S\_INPUT *int \**

  Select the current video input.

- VIDIOC\_REQBUFS *struct v4l2\_requestbuffers \**

  Initiate memory mapping or user pointer I/O.

  ```
  struct v4l2_requestbuffers {
  	u_int32_t	count;
  	u_int32_t	type;
  	u_int32_t	memory;
  	u_int32_t	capabilities;
  	u_Int32_t	flags;
  	u_int32_t	reserved[3];
  };
  ```

- VIDIOC\_QUERYBUF *struct v4l2\_buffer \**

  Query the status of a buffer.

  ```
  struct v4l2_buffer {
  	u_int32_t		index;
  	u_int32_t		type;
  	u_int32_t		bytesused;
  	u_int32_t		flags;
  	u_int32_t		field;
  	struct timeval		timestamp;
  	struct v4l2_timecode	timecode;
  	u_int32_t		sequence;
  	u_int32_t		memory;
  	union {
  		u_int32_t		offset;
  		unsigned long		userptr;
  		struct v4l2_plane	*planes;
  		int32_t			fd;
  	} m;
  	u_int32_t		length;
  	u_int32_t		reserved2;
  	union {
  		int32_t		request_fd;
  		u_int32_t	reserved;
  	}
  };
  ```

- VIDIOC\_QBUF *struct v4l2\_buffer \**

  Add a buffer to the queue.

  Same structure as for VIDIOC\_QUERYBUF.

- VIDIOC\_DQBUF *struct v4l2\_buffer \**

  Remove a buffer from the queue.

  Same structure as for VIDIOC\_QUERYBUF.

- VIDIOC\_STREAMON *int \**

  Start video stream.

- VIDIOC\_STREAMOFF *int \**

  Stop video stream.

- VIDIOC\_TRY\_FMT *struct v4l2\_format \**

  Try a data format.

  Same structure as for VIDIOC\_S\_FMT.

- VIDIOC\_ENUM\_FRAMEINTERVALS *struct v4l2\_frmivalenum \**

  Enumerate frame intervals.

  ```
  struct v4l2_frmivalenum {
  	u_int32_t		index;
  	u_int32_t		pixel_format;
  	u_int32_t		width;
  	u_int32_t		height;
  	u_int32_t		type;
  	union {
  		struct v4l2_fract		discrete;
  		struct v4l2_frmival_stepwise	stepwise;
  	};
  	u_int32_t		reserved[2];
  };
  struct v4l2_frmival_stepwise {
  	struct v4l2_fract min;
  	struct v4l2_fract max;
  	struct v4l2_fract step;
  };
  ```

- VIDIOC\_S\_PARM *struct v4l2\_streamparm \**

  Set streaming parameters.

  ```
  struct v4l2_streamparm {
  	u_int32_t	type;
  	union {
  		struct v4l2_captureparm	capture;
  		struct v4l2_outputparm	output;
  		u_int8_t		raw_data[200];
  	} parm;
  };
  struct v4l2_captureparm	{
  	u_int32_t	capability;
  	u_int32_t	capturemode;
  	struct v4l2_fract	timeperframe;
  	u_int32_t	extendedmode;
  	u_int32_t	readbuffers;
  	u_int32_t	reserved[4];
  };
  struct v4l2_outputparm	{
  	u_int32_t	capability;
  	u_int32_t	outputmode;
  	struct v4l2_fract	timeperframe;
  	u_int32_t	extendedmode;
  	u_int32_t	writebuffers;
  	u_int32_t	reserved[4];
  };
  ```

- VIDIOC\_G\_PARM *struct v4l2\_streamparm \**

  Get the streaming parameters.

  Same structures as for VIDIOC\_S\_PARM.

- VIDIOC\_QUERYCTRL *struct v4l2\_queryctrl \**

  Enumerate control items.

  ```
  struct v4l2_queryctrl {
  	u_int32_t	id;
  	u_int32_t	type;
  	u_int8_t	name[32];
  	int32_t		minimum;
  	int32_t		maximum;
  	int32_t		step;
  	int32_t		default_value;
  	u_int32_t	flags;
  	u_int32_t	reserved[2];
  };
  ```

Command independent enumerations are:

```
enum v4l2_buf_type {
	V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
	V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
	V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
	V4L2_BUF_TYPE_VBI_CAPTURE = 4,
	V4L2_BUF_TYPE_VBI_OUTPUT = 5,
	V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
	V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
	V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
	V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
	V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
	V4L2_BUF_TYPE_SDR_CAPTURE = 11,
	V4L2_BUF_TYPE_SDR_OUTPUT = 12,
	V4L2_BUF_TYPE_META_CAPTURE = 13,
	V4L2_BUF_TYPE_META_OUTPUT = 14,
	/* Deprecated, do not use */
	V4L2_BUF_TYPE_PRIVATE = 0x80,
};
enum v4l2_memory {
	V4L2_MEMORY_MMAP = 1,
	V4L2_MEMORY_USERPTR = 2,
	V4L2_MEMORY_OVERLAY = 3,
	V4L2_MEMORY_DMABUF = 4,
};
enum v4l2_ctrl_type {
	V4L2_CTRL_TYPE_INTEGER = 1,
	V4L2_CTRL_TYPE_BOOLEAN = 2,
	V4L2_CTRL_TYPE_MENU = 3,
	V4L2_CTRL_TYPE_BUTTON = 4,
	V4L2_CTRL_TYPE_INTEGER64 = 5,
	V4L2_CTRL_TYPE_CTRL_CLASS = 6,
	V4L2_CTRL_TYPE_STRING = 7,
	V4L2_CTRL_TYPE_BITMASK = 8,
	V4L2_CTRL_TYPE_INTEGER_MENU = 9,
	V4L2_CTRL_COMPOUND_TYPES = 0x0100,
	V4L2_CTRL_TYPE_U8 = 0x0100,
	V4L2_CTRL_TYPE_U16 = 0x0101,
	V4L2_CTRL_TYPE_U32 = 0x0102,
	V4L2_CTRL_TYPE_AREA = 0x0106,
	/* Compound types are >= 0x0100 */
	V4L2_CTRL_TYPE_HDR10_CLL_INFO = 0x0110,
	V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY = 0x0111,
	V4L2_CTRL_TYPE_H264_SPS = 0x0200,
	V4L2_CTRL_TYPE_H264_PPS = 0x0201,
	V4L2_CTRL_TYPE_H264_SCALING_MATRIX = 0x0202,
	V4L2_CTRL_TYPE_H264_SLICE_PARAMS = 0x0203,
	V4L2_CTRL_TYPE_H264_DECODE_PARAMS = 0x0204,
	V4L2_CTRL_TYPE_H264_PRED_WEIGHTS = 0x0205,
	V4L2_CTRL_TYPE_FWHT_PARAMS = 0x0220,
	V4L2_CTRL_TYPE_VP8_FRAME = 0x0240,
	V4L2_CTRL_TYPE_MPEG2_QUANTISATION = 0x0250,
	V4L2_CTRL_TYPE_MPEG2_SEQUENCE = 0x0251,
	V4L2_CTRL_TYPE_MPEG2_PICTURE = 0x0252,
	V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR = 0x0260,
	V4L2_CTRL_TYPE_VP9_FRAME = 0x0261,
	V4L2_CTRL_TYPE_HEVC_SPS = 0x0270,
	V4L2_CTRL_TYPE_HEVC_PPS = 0x0271,
	V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS = 0x0272,
	V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX = 0x0273,
	V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS = 0x0274,
	V4L2_CTRL_TYPE_AV1_SEQUENCE = 0x280,
	V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY = 0x281,
	V4L2_CTRL_TYPE_AV1_FRAME = 0x282,
	V4L2_CTRL_TYPE_AV1_FILM_GRAIN = 0x283,
};
enum v4l2_frmivaltypes {
	V4L2_FRMIVAL_TYPE_DISCRETE = 1,
	V4L2_FRMIVAL_TYPE_CONTINUOUS = 2,
	V4L2_FRMIVAL_TYPE_STEPWISE = 3,
};
```

Command independent structures are:

```
struct v4l2_pix_format {
	u_int32_t	width;
	u_int32_t	height;
	u_int32_t	pixelformat;
	u_int32_t	field;
	u_int32_t	bytesperline;
	u_int32_t	sizeimage;
	u_int32_t	colorspace;
	u_int32_t	priv;
	u_int32_t	flags;
	union {
		u_int32_t	ycbcr_enc;
		u_int32_t	hsv_enc;
	};
	u_int32_t	quantization;
	u_int32_t	xfer_func;
};
struct v4l2_window {
	struct v4l2_rect	w;
	u_int32_t		field;
	u_int32_t		chromakey;
	struct v4l2_clip	*clips;
	u_int32_t		clipcount;
	void			__user *bitmap;
	u_int8_t		global_alpha;
};
struct v4l2_vbi_format {
	u_int32_t		sampling_rate;
	u_int32_t		offset;
	u_int32_t		samples_per_line;
	u_int32_t		sample_format;
	int32_t			start[2];
	u_int32_t		count[2];
	u_int32_t		flags;
	u_int32_t		reserved[2];
};
struct v4l2_sliced_vbi_format {
	u_int16_t	service_set;
	u_int16_t	service_lines[2][24];
	u_int32_t	io_size;
	u_int32_t	reserved[2];
};
struct v4l2_fract {
	u_int32_t	numerator;
	u_int32_t	denominator;
};
```

Command independent typedefs are:

```
typedef u_int64_t	v4l2_std_id;
```

## READ

Video data can be accessed via the [read(2)](/read/2.md) system call. The main iteration for userland applications occurs as follow:

1. Open /dev/video\* via the [open(2)](/open/2.md) system call.

2. Read video data from the device via the [read(2)](/read/2.md) system call. The video stream will be started automatically with the first read, which means there is no need to issue a VIDIOC\_STREAMON command. The read will always return a consistent video frame, if no error occurs.

3. Process video data and start over again with step 2.

4. When finished, stop the video stream via the [close(2)](/close/2.md) system call.

The [select(2)](/select/2.md), [poll(2)](/poll/2.md) and [kqueue(2)](/kqueue/2.md) system calls are supported for this access type. They will signal when a frame is ready for reading without blocking.

## MMAP

Video data can be accessed via the [mmap(2)](/mmap/2.md) system call. The main iteration for userland applications occurs as follow:

1. Open /dev/video\* via the [open(2)](/open/2.md) system call.

2. Request desired number of buffers via the VIDIOC\_REQBUFS ioctl command. The maximum number of available buffers is normally limited by the hardware driver.

3. Get the length and offset for the previously requested buffers via the VIDIOC\_QUERYBUF ioctl command and map the buffers via the [mmap(2)](/mmap/2.md) system call.

4. Initially queue the buffers via the VIDIOC\_QBUF ioctl command.

5. Start the video stream via the VIDIOC\_STREAMON ioctl command.

6. Dequeue one buffer via the VIDIOC\_DQBUF ioctl command. If the queue is empty, the ioctl will block until a buffer gets queued or an error occurs (e.g. a timeout).

7. Process video data.

8. Requeue the buffer via the VIDIOC\_QBUF ioctl command and start over again with step 6.

9. When finished, stop the video stream via the VIDIOC\_STREAMOFF ioctl command.

The [select(2)](/select/2.md), [poll(2)](/poll/2.md) and [kqueue(2)](/kqueue/2.md) system calls are supported for this access type. They will signal when at least one frame is ready for dequeuing, allowing to call the VIDIOC\_DQBUF ioctl command without blocking.

## FILES

- */dev/video*

  ## SEE ALSO

video(1), [ioctl(2)](/ioctl/2.md), [uvideo(4)](/uvideo/4.md)

## HISTORY

The **video** driver first appeared in OpenBSD 4.4.
