aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanimir Varbanov <stanimir.varbanov@linaro.org>2017-06-26 14:30:18 +0300
committerStanimir Varbanov <stanimir.varbanov@linaro.org>2017-06-26 14:30:18 +0300
commit9b784867fa0dd2df261876e1035aad13ce087b3f (patch)
tree4a8130582af04c8b0b2c7b10df2c9da289310bde
parent40566395586e6a6b70d0a941ed0261f7326bdc0a (diff)
downloadv4l2-encode-9b784867fa0dd2df261876e1035aad13ce087b3f.tar.gz
check is video device is encoder
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
-rw-r--r--video.c109
1 files changed, 96 insertions, 13 deletions
diff --git a/video.c b/video.c
index 096c7d1..e5a08c0 100644
--- a/video.c
+++ b/video.c
@@ -21,6 +21,7 @@
*/
#include <linux/videodev2.h>
+#include <linux/v4l2-controls.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
@@ -36,15 +37,13 @@
/* mem2mem encoder/decoder */
#define V4L2_BUF_FLAG_LAST 0x00100000
-#define V4L2_QCOM_BUF_FLAG_EOS 0x1000000
-
static char *dbg_type[2] = {"OUTPUT", "CAPTURE"};
static char *dbg_status[2] = {"ON", "OFF"};
int video_open(struct instance *i, char *name)
{
struct v4l2_capability cap;
- int ret;
+ int ret, found = 0;
i->video.fd = open(name, O_RDWR, 0);
if (i->video.fd < 0) {
@@ -69,6 +68,63 @@ int video_open(struct instance *i, char *name)
return -1;
}
+ /* check is it a encoder video device */
+
+ struct v4l2_fmtdesc fdesc;
+
+ memzero(fdesc);
+ fdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ while (!ioctl(i->video.fd, VIDIOC_ENUM_FMT, &fdesc)) {
+ dbg(" %s", fdesc.description);
+
+ switch (fdesc.pixelformat) {
+ case V4L2_PIX_FMT_MPEG:
+ case V4L2_PIX_FMT_H264:
+ case V4L2_PIX_FMT_H263:
+ case V4L2_PIX_FMT_MPEG1:
+ case V4L2_PIX_FMT_MPEG2:
+ case V4L2_PIX_FMT_MPEG4:
+ case V4L2_PIX_FMT_XVID:
+ case V4L2_PIX_FMT_VC1_ANNEX_G:
+ case V4L2_PIX_FMT_VC1_ANNEX_L:
+ case V4L2_PIX_FMT_VP8:
+ found = 1;
+ break;
+ default:
+ err("not a encoder video device");
+ return -1;
+ }
+
+ if (found)
+ break;
+
+ fdesc.index++;
+ }
+
+ found = 0;
+ memzero(fdesc);
+ fdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+
+ while (!ioctl(i->video.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:
+ err("not a encoder video device");
+ return -1;
+ }
+
+ if (found)
+ break;
+
+ fdesc.index++;
+ }
+
return 0;
}
@@ -85,12 +141,14 @@ int video_set_control(struct instance *i)
parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
parm.parm.output.timeperframe.numerator = 1;
- if (i->framerate <= 30 && i->framerate >= 1)
+ if (i->framerate <= 120 && i->framerate >= 1)
parm.parm.output.timeperframe.denominator = i->framerate;
else
parm.parm.output.timeperframe.denominator = 30;
- info("setting framerate: %u", i->framerate);
+ info("setting framerate: %u (%u/%u)", i->framerate,
+ parm.parm.output.timeperframe.numerator,
+ parm.parm.output.timeperframe.denominator);
ret = ioctl(i->video.fd, VIDIOC_S_PARM, &parm);
if (ret)
@@ -108,6 +166,33 @@ int video_set_control(struct instance *i)
if (ret)
err("set control - bitrate (%s)", strerror(errno));
+ if (i->codec == V4L2_PIX_FMT_H264) {
+ memset(&cntrl, 0, sizeof(cntrl));
+ cntrl.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
+ cntrl.value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
+ info("setting h264 profile: %u", cntrl.value);
+ ret = ioctl(i->video.fd, VIDIOC_S_CTRL, &cntrl);
+ if (ret)
+ err("set control - profile (%s)", strerror(errno));
+
+ memset(&cntrl, 0, sizeof(cntrl));
+ cntrl.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
+ cntrl.value = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
+ info("setting h264 level: %u", cntrl.value);
+ ret = ioctl(i->video.fd, VIDIOC_S_CTRL, &cntrl);
+ if (ret)
+ err("set control - level (%s)", strerror(errno));
+
+ memset(&cntrl, 0, sizeof(cntrl));
+ cntrl.id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
+ cntrl.value = 1;
+ info("setting num b frames: %u", cntrl.value);
+ ret = ioctl(i->video.fd, VIDIOC_S_CTRL, &cntrl);
+ if (ret)
+ err("set control - num b frames (%s)", strerror(errno));
+ }
+
+#if 0
struct v4l2_ext_controls ctrls;
struct v4l2_ext_control ctrl[32];
int c = 0;
@@ -150,7 +235,7 @@ int video_set_control(struct instance *i)
ret = ioctl(i->video.fd, VIDIOC_S_EXT_CTRLS, &ctrls);
if (ret)
err("set ext controls (%s)", strerror(errno));
-
+#endif
return 0;
}
@@ -322,9 +407,7 @@ int video_dequeue_capture(struct instance *i, unsigned int *n,
*finished = 0;
- if (buf.flags & V4L2_QCOM_BUF_FLAG_EOS ||
- buf.flags & V4L2_BUF_FLAG_LAST ||
- buf.m.planes[0].bytesused == 0)
+ if (buf.flags & V4L2_BUF_FLAG_LAST || buf.m.planes[0].bytesused == 0)
*finished = 1;
*bytesused = buf.m.planes[0].bytesused;
@@ -351,8 +434,7 @@ int video_dequeue_capture_dmabuf(struct instance *i, unsigned int *n,
*finished = 0;
- if (buf.flags & V4L2_QCOM_BUF_FLAG_EOS ||
- buf.m.planes[0].bytesused == 0)
+ if (buf.flags & V4L2_BUF_FLAG_LAST || buf.m.planes[0].bytesused == 0)
*finished = 1;
*bytesused = buf.m.planes[0].bytesused;
@@ -420,10 +502,11 @@ int video_setup_capture(struct instance *i, unsigned int count, unsigned int w,
return -1;
}
- info("CAPTURE: Set format %ux%u, sizeimage %u, bpl %u",
+ info("CAPTURE: Set format %ux%u, sizeimage %u, bpl %u, pixelformat:%x",
fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
fmt.fmt.pix_mp.plane_fmt[0].sizeimage,
- fmt.fmt.pix_mp.plane_fmt[0].bytesperline);
+ fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
+ fmt.fmt.pix_mp.pixelformat);
vid->cap_w = fmt.fmt.pix_mp.width;
vid->cap_h = fmt.fmt.pix_mp.height;