Skip to content

Instantly share code, notes, and snippets.

@jkuri
Created March 25, 2018 10:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkuri/ae991f95c3259dfd1400c11eccd5d8af to your computer and use it in GitHub Desktop.
Save jkuri/ae991f95c3259dfd1400c11eccd5d8af to your computer and use it in GitHub Desktop.
Output all video devices, capabilities, frame sizes and related framerates on Linux using V4L2

Output all video devices, capabilities, frame sizes and related framerates on Linux using V4L2

Compile it using

clang -o print_devices print_devices.c

Example output

Driver:'uvcvideo', Card:'USB 2.0 Camera', Device: '/dev/video0', buf_info:'usb-xhci-hcd.2.auto-1.2', version:264486, capabilities:0x84200001}
Pixel format: 'YUYV', Description = 'YUYV 4:2:2'
Size: 640x480
  0.030s (33.000 fps)
  0.067s (15.000 fps)
Size: 1280x720
  0.100s (10.000 fps)
Size: 640x360
  0.030s (33.000 fps)
  0.067s (15.000 fps)
Size: 544x288
  0.030s (33.000 fps)
  0.067s (15.000 fps)
Size: 432x240
  0.030s (33.000 fps)
  0.067s (15.000 fps)
...
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
static int v4l2_is_v4l_device(const char *name)
{
return !strncmp(name, "video", 5) ||
!strncmp(name, "radio", 5) ||
!strncmp(name, "vbi", 3) ||
!strncmp(name, "v4l-subdev", 10);
}
static int v4l2_get_device_list()
{
int fd, ret;
DIR *dir;
struct dirent *entry;
struct v4l2_capability cap;
struct v4l2_fmtdesc fmt;
struct v4l2_frmsizeenum frmsize;
struct v4l2_frmivalenum frmival;
dir = opendir("/dev");
if (!dir) {
fprintf(stderr, "Could not open /dev directory!\n");
return 1;
}
while ((entry = readdir(dir))) {
char device_name[256];
if (!v4l2_is_v4l_device(entry->d_name)) {
continue;
}
snprintf(device_name, sizeof(device_name), "/dev/%s", entry->d_name);
if ((fd = open(device_name, O_RDONLY)) == -1) {
fprintf(stderr, "Cannot open device %s\n", device_name);
return 1;
}
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
fprintf(stderr, "Cannot get capabilities!\n");
return 1;
}
printf("Driver:'%s', Card:'%s', Device: '%s', buf_info:'%s', version:%d, capabilities:0x%x}\n", cap.driver, cap.card, device_name, cap.bus_info, cap.version, cap.capabilities);
fmt.index = 0;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
while ((ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmt)) >= 0) {
fprintf(stderr, "Pixel format: '%c%c%c%c', Description = '%s'\n", fmt.pixelformat & 0xFF, (fmt.pixelformat >> 8) & 0xFF, (fmt.pixelformat >> 16) & 0xFF, (fmt.pixelformat >> 24) & 0xFF, fmt.description);
frmsize.pixel_format = fmt.pixelformat;
frmsize.index = 0;
while ((ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize)) >= 0) {
if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
fprintf(stderr, "Size: %dx%d\n", frmsize.discrete.width, frmsize.discrete.height);
frmival.index = 0;
frmival.pixel_format = fmt.pixelformat;
frmival.width = frmsize.discrete.width;
frmival.height = frmsize.discrete.height;
while ((ret = ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival)) >= 0) {
if (frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
char sec[100], fps[100];
sprintf(sec, "%.3f", (1.0 * frmival.discrete.numerator) / frmival.discrete.denominator);
sprintf(fps, "%.3f", (1.0 * frmival.discrete.denominator) / frmival.discrete.numerator);
fprintf(stderr, " %ss (%s fps)\n", sec, fps);
}
frmival.index++;
}
}
frmsize.index++;
}
printf("\n");
fmt.index++;
}
}
return 0;
}
int main() {
int ret;
if ((ret = v4l2_get_device_list()) != 0) {
fprintf(stderr, "Error\n");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment