|
#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; |
|
} |