aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanimir Varbanov <stanimir.varbanov@linaro.org>2017-07-28 17:53:12 +0300
committerStanimir Varbanov <stanimir.varbanov@linaro.org>2017-07-28 17:53:12 +0300
commit50a5972b92e0f743743ae4a4e1aabb6de7448873 (patch)
tree0eae5e99a31d99aab2d40bebfd32cfd1985b51ae
parent4192cc1d60335a45cac7eff67f1c4713106b2bb3 (diff)
downloadv4l2-encode-50a5972b92e0f743743ae4a4e1aabb6de7448873.tar.gz
recognize encoder video device automatically
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
-rw-r--r--args.c17
-rw-r--r--common.h2
-rw-r--r--video.c109
3 files changed, 81 insertions, 47 deletions
diff --git a/args.c b/args.c
index 54fa956..124661a 100644
--- a/args.c
+++ b/args.c
@@ -36,12 +36,12 @@ void print_usage(char *name)
printf("\t%s\n", name);
printf("\t-c <codec> - The codec to be used for encoding\n");
printf("\t\t Available codecs: mpeg4, h264, h265, h263, xvid, mpeg2, mpeg1, vp8, vp9\n");
- printf("\t-d use dmabuf instead of mmap\n");
- printf("\t-m <device> - video encoder device (e.g. /dev/video33)\n");
+ printf("\t-d <device> - video encoder device (e.g. /dev/video0)\n");
printf("\t-w video width\n");
printf("\t-h video height\n");
printf("\t-f save encoded frames on disk\n");
printf("\t-g disable test pattern generator\n");
+ printf("\t-n number of frames to encode (default 100)");
printf("\t-v verbose mode\n");
printf("\t-B bitrate\n");
printf("\t-F framerate\n");
@@ -84,16 +84,16 @@ int parse_args(struct instance *i, int argc, char **argv)
init_to_defaults(i);
- while ((c = getopt(argc, argv, "w:h:c:d:m:f:n:gvB:F:b:")) != -1) {
+ i->video.name = "/dev/video0";
+ i->num_frames_to_save = 100;
+
+ while ((c = getopt(argc, argv, "w:h:c:d:f:n:gvB:F:b:")) != -1) {
switch (c) {
case 'c':
i->codec = get_codec(optarg);
i->codec_name = optarg;
break;
case 'd':
- i->use_dmabuf = 1;
- break;
- case 'm':
i->video.name = optarg;
break;
case 'w':
@@ -133,11 +133,6 @@ int parse_args(struct instance *i, int argc, char **argv)
}
}
- if (!i->video.name) {
- err("The following arguments are required: -m -c");
- return -1;
- }
-
if (!i->codec) {
err("Unknown or not set codec (-c)");
return -1;
diff --git a/common.h b/common.h
index 7516a3b..a09ccce 100644
--- a/common.h
+++ b/common.h
@@ -152,8 +152,6 @@ struct instance {
bool disable_gentest;
bool verbose;
- int use_dmabuf;
-
/* Input file related parameters */
struct input in;
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;
}