aboutsummaryrefslogtreecommitdiff
path: root/video.c
diff options
context:
space:
mode:
Diffstat (limited to 'video.c')
-rw-r--r--video.c109
1 files changed, 75 insertions, 34 deletions
diff --git a/video.c b/video.c
index ae07eda..e655a38 100644
--- a/video.c
+++ b/video.c
@@ -39,42 +39,59 @@
static char *dbg_type[2] = {"OUTPUT", "CAPTURE"};
static char *dbg_status[2] = {"ON", "OFF"};
-int video_open(struct instance *i, char *name)
+/* check is it a decoder video device */
+static int is_video_encoder(int fd, const char *name)
{
struct v4l2_capability cap;
- int ret, found = 0;
-
- i->video.fd = open(name, O_RDWR, 0);
- if (i->video.fd < 0) {
- err("Failed to open video encoder: %s", name);
- return -1;
- }
+ struct v4l2_fmtdesc fdesc;
+ int found = 0;
memzero(cap);
- ret = ioctl(i->video.fd, VIDIOC_QUERYCAP, &cap);
- if (ret) {
- err("Failed to verify capabilities");
+ if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
+ err("Failed to verify capabilities: %m");
return -1;
}
- info("caps (%s): driver=\"%s\" bus_info=\"%s\" card=\"%s\" fd=0x%x",
- name, cap.driver, cap.bus_info, cap.card, i->video.fd);
+ dbg("caps (%s): driver=\"%s\" bus_info=\"%s\" card=\"%s\" "
+ "version=%u.%u.%u", name, cap.driver, cap.bus_info, cap.card,
+ (cap.version >> 16) & 0xff,
+ (cap.version >> 8) & 0xff,
+ cap.version & 0xff);
- if (!(cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) ||
- !(cap.capabilities & V4L2_CAP_STREAMING)) {
+ if (!(cap.capabilities & V4L2_CAP_STREAMING) ||
+ !(cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE)) {
err("Insufficient capabilities for video device (is %s correct?)",
name);
return -1;
}
- /* check is it a encoder video device */
+ memzero(fdesc);
+ fdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- struct v4l2_fmtdesc fdesc;
+ while (!ioctl(fd, VIDIOC_ENUM_FMT, &fdesc)) {
+ dbg(" %s", fdesc.description);
+
+ switch (fdesc.pixelformat) {
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ found = 1;
+ break;
+ default:
+ dbg("%s is not an encoder video device", name);
+ return -1;
+ }
+ if (found)
+ break;
+
+ fdesc.index++;
+ }
+
+ found = 0;
memzero(fdesc);
fdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- while (!ioctl(i->video.fd, VIDIOC_ENUM_FMT, &fdesc)) {
+ while (!ioctl(fd, VIDIOC_ENUM_FMT, &fdesc)) {
dbg(" %s", fdesc.description);
switch (fdesc.pixelformat) {
@@ -91,7 +108,7 @@ int video_open(struct instance *i, char *name)
found = 1;
break;
default:
- err("not a encoder video device");
+ err("%s is not an encoder video device", name);
return -1;
}
@@ -101,29 +118,53 @@ int video_open(struct instance *i, char *name)
fdesc.index++;
}
- found = 0;
- memzero(fdesc);
- fdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ return 0;
+}
- while (!ioctl(i->video.fd, VIDIOC_ENUM_FMT, &fdesc)) {
- dbg(" %s", fdesc.description);
+int video_open(struct instance *i, const char *name)
+{
+ char video_name[64];
+ unsigned idx = 0, v = 0;
+ int ret, fd = -1;
- switch (fdesc.pixelformat) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- found = 1;
- break;
- default:
- err("not a encoder video device");
- return -1;
+ while (v++ < 32) {
+ ret = sprintf(video_name, "/dev/video%d", idx);
+ if (ret < 0)
+ return ret;
+
+ idx++;
+
+ dbg("open video device: %s", video_name);
+
+ fd = open(video_name, O_RDWR, 0);
+ if (fd < 0) {
+ err("Failed to open video device: %s", video_name);
+ continue;
}
- if (found)
+ ret = is_video_encoder(fd, video_name);
+ if (ret < 0) {
+ close(fd);
+ continue;
+ }
+
+ if (!ret)
break;
+ }
- fdesc.index++;
+ if (!ret)
+ info("found encoder video device %s", video_name);
+
+ if (ret < 0)
+ fd = open(name, O_RDWR, 0);
+
+ if (fd < 0) {
+ err("Failed to open video device: %s", name);
+ return -1;
}
+ i->video.fd = fd;
+
return 0;
}