aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--args.c4
-rw-r--r--common.h4
-rw-r--r--main.c3
-rw-r--r--video.c140
-rw-r--r--video.h26
5 files changed, 101 insertions, 76 deletions
diff --git a/args.c b/args.c
index 0dd0b58..40c94cd 100644
--- a/args.c
+++ b/args.c
@@ -63,6 +63,8 @@ int get_codec(char *str)
return V4L2_PIX_FMT_MPEG2;
} else if (strncasecmp("mpeg1", str, 5) == 0) {
return V4L2_PIX_FMT_MPEG1;
+ } else if (strncasecmp("vp8", str, 5) == 0) {
+ return V4L2_PIX_FMT_VP8;
}
return 0;
}
@@ -73,7 +75,7 @@ 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:")) != -1) {
+ while ((c = getopt(argc, argv, "w:h:c:d:m:fn:")) != -1) {
switch (c) {
case 'c':
i->codec = get_codec(optarg);
diff --git a/common.h b/common.h
index 804ac1d..11067af 100644
--- a/common.h
+++ b/common.h
@@ -161,8 +161,8 @@ struct instance {
/* Control */
int error; /* The error flag */
- int finish; /* Flag set when decoding has been completed and all
- threads finish */
+ unsigned int finish; /* Flag set when decoding has been completed
+ and all threads finish */
};
#endif /* INCLUDE_COMMON_H */
diff --git a/main.c b/main.c
index d562338..87bb900 100644
--- a/main.c
+++ b/main.c
@@ -222,7 +222,8 @@ void *main_thread_func(void *args)
struct video *vid = &i->video;
struct pollfd pfd;
short revents;
- int ret, n, finished;
+ unsigned int n, finished;
+ int ret;
pfd.fd = vid->fd;
pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM |
diff --git a/video.c b/video.c
index 309bff2..12e79fa 100644
--- a/video.c
+++ b/video.c
@@ -93,9 +93,9 @@ int video_set_control(struct instance *i)
err("set framerate (%s)", strerror(errno));
cntrl.id = V4L2_CID_MPEG_VIDEO_BITRATE;
- cntrl.value = 64000;
+ cntrl.value = 5 * 1024 * 1024;
- info("setting bitrate");
+ info("setting bitrate: %u", cntrl.value);
ret = ioctl(i->video.fd, VIDIOC_S_CTRL, &cntrl);
if (ret)
err("set control - bitrate (%s)", strerror(errno));
@@ -121,7 +121,7 @@ int video_set_control(struct instance *i)
c++;
ctrl[c].id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
- ctrl[c].value = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
+ ctrl[c].value = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
c++;
ctrl[c].id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
@@ -143,7 +143,7 @@ int video_set_control(struct instance *i)
return 0;
}
-int video_export_buf(struct instance *i, int index)
+int video_export_buf(struct instance *i, unsigned int index)
{
struct video *vid = &i->video;
struct v4l2_exportbuffer expbuf;
@@ -171,8 +171,9 @@ int video_export_buf(struct instance *i, int index)
return 0;
}
-static int video_queue_buf(struct instance *i, int index, int l1, int l2,
- int type, int nplanes)
+static int video_queue_buf(struct instance *i, unsigned int index,
+ unsigned int l1, unsigned int l2,
+ unsigned int type, unsigned int nplanes)
{
struct video *vid = &i->video;
struct v4l2_buffer buf;
@@ -225,7 +226,7 @@ static int video_queue_buf(struct instance *i, int index, int l1, int l2,
return 0;
}
-int video_queue_buf_out(struct instance *i, int n, int length)
+int video_queue_buf_out(struct instance *i, unsigned int n, unsigned int length)
{
struct video *vid = &i->video;
@@ -239,7 +240,7 @@ int video_queue_buf_out(struct instance *i, int n, int length)
OUT_PLANES);
}
-int video_queue_buf_cap(struct instance *i, int index)
+int video_queue_buf_cap(struct instance *i, unsigned int index)
{
struct video *vid = &i->video;
@@ -261,7 +262,7 @@ static int video_dequeue_buf(struct instance *i, struct v4l2_buffer *buf)
ret = ioctl(vid->fd, VIDIOC_DQBUF, buf);
if (ret < 0) {
- err("Failed to dequeue buffer (%d)", -errno);
+ err("Failed to dequeue buffer (%s)", strerror(errno));
return -errno;
}
@@ -272,7 +273,7 @@ static int video_dequeue_buf(struct instance *i, struct v4l2_buffer *buf)
return 0;
}
-int video_dequeue_output(struct instance *i, int *n)
+int video_dequeue_output(struct instance *i, unsigned int *n)
{
struct v4l2_buffer buf;
struct v4l2_plane planes[OUT_PLANES];
@@ -293,8 +294,8 @@ int video_dequeue_output(struct instance *i, int *n)
return 0;
}
-int video_dequeue_capture(struct instance *i, int *n, int *finished,
- unsigned int *bytesused)
+int video_dequeue_capture(struct instance *i, unsigned int *n,
+ unsigned int *finished, unsigned int *bytesused)
{
struct v4l2_buffer buf;
struct v4l2_plane planes[CAP_PLANES];
@@ -321,7 +322,8 @@ int video_dequeue_capture(struct instance *i, int *n, int *finished,
return 0;
}
-int video_dequeue_capture_dmabuf(struct instance *i, int *n, int *finished,
+int video_dequeue_capture_dmabuf(struct instance *i, unsigned int *n,
+ unsigned int *finished,
unsigned int *bytesused)
{
struct v4l2_buffer buf;
@@ -348,7 +350,8 @@ int video_dequeue_capture_dmabuf(struct instance *i, int *n, int *finished,
return 0;
}
-int video_stream(struct instance *i, enum v4l2_buf_type type, int status)
+int video_stream(struct instance *i, enum v4l2_buf_type type,
+ unsigned int status)
{
struct video *vid = &i->video;
int ret;
@@ -384,54 +387,56 @@ int video_stop(struct instance *i)
return 0;
}
-int video_setup_capture(struct instance *i, int count, int w, int h)
+int video_setup_capture(struct instance *i, unsigned int count, unsigned int w,
+ unsigned int h)
{
struct video *vid = &i->video;
struct v4l2_format fmt;
struct v4l2_requestbuffers reqbuf;
struct v4l2_buffer buf;
struct v4l2_plane planes[CAP_PLANES];
+ unsigned int n;
int ret;
- int n;
+ memzero(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
fmt.fmt.pix_mp.height = h;
fmt.fmt.pix_mp.width = w;
fmt.fmt.pix_mp.pixelformat = i->codec;
ret = ioctl(vid->fd, VIDIOC_S_FMT, &fmt);
if (ret) {
- err("Failed to set format (%dx%d) (%s)", w, h, strerror(errno));
+ err("CAPTURE: S_FMT failed (%ux%u) (%s)", w, h, strerror(errno));
return -1;
}
+ info("CAPTURE: Set format %ux%u, sizeimage %u, bpl %u",
+ 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);
+
vid->cap_w = fmt.fmt.pix_mp.width;
vid->cap_h = fmt.fmt.pix_mp.height;
vid->cap_buf_size[0] = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
vid->cap_buf_size[1] = fmt.fmt.pix_mp.plane_fmt[1].sizeimage;
- vid->cap_buf_cnt = count;
vid->cap_buf_cnt_min = 1;
vid->cap_buf_queued = 0;
- info("video CAPTURE buffer parameters: %dx%d plane[0]=%d plane[1]=%d",
- fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
- vid->cap_buf_size[0], vid->cap_buf_size[1]);
-
memzero(reqbuf);
- reqbuf.count = vid->cap_buf_cnt;
+ reqbuf.count = count;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
reqbuf.memory = V4L2_MEMORY_MMAP;
ret = ioctl(vid->fd, VIDIOC_REQBUFS, &reqbuf);
- if (ret != 0) {
- err("REQBUFS failed on CAPTURE queue (%s)", strerror(errno));
+ if (ret) {
+ err("CAPTURE: REQBUFS failed (%s)", strerror(errno));
return -1;
}
vid->cap_buf_cnt = reqbuf.count;
- info("Number of CAPTURE buffers is %d (requested %d)",
+ info("CAPTURE: Number of buffers %u (requested %u)",
vid->cap_buf_cnt, count);
for (n = 0; n < vid->cap_buf_cnt; n++) {
@@ -444,9 +449,8 @@ int video_setup_capture(struct instance *i, int count, int w, int h)
buf.length = CAP_PLANES;
ret = ioctl(vid->fd, VIDIOC_QUERYBUF, &buf);
- if (ret != 0) {
- err("QUERYBUF failed on CAPTURE queue (%s)",
- strerror(errno));
+ if (ret) {
+ err("CAPTURE: QUERYBUF failed (%s)", strerror(errno));
return -1;
}
@@ -459,72 +463,75 @@ int video_setup_capture(struct instance *i, int count, int w, int h)
buf.m.planes[0].m.mem_offset);
if (vid->cap_buf_addr[n][0] == MAP_FAILED) {
- err("Failed to MMAP CAPTURE buffer on plane0");
+ err("CAPTURE: MMAP failed (%s)", strerror(errno));
return -1;
}
vid->cap_buf_size[0] = buf.m.planes[0].length;
}
- dbg("Succesfully mmapped %d CAPTURE buffers", n);
+ info("CAPTURE: Succesfully mmapped %u buffers", n);
return 0;
}
-int video_setup_capture_dmabuf(struct instance *i, int count, int w, int h)
+int video_setup_capture_dmabuf(struct instance *i, unsigned int count,
+ unsigned int w, unsigned int h)
{
struct video *vid = &i->video;
struct v4l2_format fmt;
struct v4l2_requestbuffers reqbuf;
int ret;
+ memzero(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
fmt.fmt.pix_mp.height = h;
fmt.fmt.pix_mp.width = w;
fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
ret = ioctl(vid->fd, VIDIOC_S_FMT, &fmt);
if (ret) {
- err("Failed to set format (%dx%d)", w, h);
+ err("CAPTURE: S_FMT failed (%ux%u) (%s)", w, h, strerror(errno));
return -1;
}
+ info("CAPTURE: Set format %ux%u, sizeimage %u, bpl %u",
+ 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);
+
vid->cap_w = fmt.fmt.pix_mp.width;
vid->cap_h = fmt.fmt.pix_mp.height;
vid->cap_buf_size[0] = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
vid->cap_buf_size[1] = fmt.fmt.pix_mp.plane_fmt[1].sizeimage;
- vid->cap_buf_cnt = count;
vid->cap_buf_cnt_min = 1;
vid->cap_buf_queued = 0;
- dbg("video CAPTURE buffer parameters: %dx%d plane[0]=%d plane[1]=%d",
- fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
- vid->cap_buf_size[0], vid->cap_buf_size[1]);
-
memzero(reqbuf);
- reqbuf.count = vid->cap_buf_cnt;
+ reqbuf.count = count;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
reqbuf.memory = V4L2_MEMORY_DMABUF;
ret = ioctl(vid->fd, VIDIOC_REQBUFS, &reqbuf);
- if (ret != 0) {
- err("REQBUFS failed on CAPTURE queue (%s)", strerror(errno));
+ if (ret) {
+ err("CAPTURE: REQBUFS failed (%s)", strerror(errno));
return -1;
}
- info("Number of CAPTURE buffers is %d (requested %d, extra %d)",
- reqbuf.count, vid->cap_buf_cnt, 0);
-
vid->cap_buf_cnt = reqbuf.count;
- dbg("Succesfully requested %d dmabuf CAPTURE buffers", vid->cap_buf_cnt);
+ info("CAPTURE: Number of buffers %u (requested %u)",
+ vid->cap_buf_cnt, count);
+
+ info("CAPTURE: Succesfully requested %u dmabuf buffers",
+ vid->cap_buf_cnt);
return 0;
}
int video_setup_output(struct instance *i, unsigned long codec,
- unsigned int size, int count)
+ unsigned int size, unsigned int count)
{
struct video *vid = &i->video;
struct v4l2_format fmt, try_fmt, g_fmt;
@@ -542,11 +549,16 @@ int video_setup_output(struct instance *i, unsigned long codec,
ret = ioctl(vid->fd, VIDIOC_TRY_FMT, &try_fmt);
if (ret) {
- err("Failed to try format on OUTPUT (%s)", strerror(errno));
+ err("OUTPUT: TRY_FMT failed (%ux%u) (%s)",
+ try_fmt.fmt.pix_mp.width,
+ try_fmt.fmt.pix_mp.height, strerror(errno));
+ return -1;
}
- dbg("Try OUTPUT format sizeimage=%u",
- try_fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
+ info("OUTPUT: Try format %ux%u, sizeimage %u, bpl %u",
+ try_fmt.fmt.pix_mp.width, try_fmt.fmt.pix_mp.height,
+ try_fmt.fmt.pix_mp.plane_fmt[0].sizeimage,
+ try_fmt.fmt.pix_mp.plane_fmt[0].bytesperline);
memzero(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
@@ -556,11 +568,13 @@ int video_setup_output(struct instance *i, unsigned long codec,
ret = ioctl(vid->fd, VIDIOC_S_FMT, &fmt);
if (ret) {
- err("Failed to set format on OUTPUT (%s)", strerror(errno));
+ err("OUTPUT: S_FMT failed %ux%u (%s)", fmt.fmt.pix_mp.width,
+ fmt.fmt.pix_mp.height, strerror(errno));
return -1;
}
- info("Setup OUTPUT buffer size=%u (requested=%u), bytesperline:%u",
+ info("OUTPUT: Set format %ux%u, sizeimage %u, (requested=%u), bpl %u",
+ fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
fmt.fmt.pix_mp.plane_fmt[0].sizeimage, size,
fmt.fmt.pix_mp.plane_fmt[0].bytesperline);
@@ -572,13 +586,15 @@ int video_setup_output(struct instance *i, unsigned long codec,
ret = ioctl(vid->fd, VIDIOC_G_FMT, &g_fmt);
if (ret) {
- err("Failed to get format on OUTPUT (%s)", strerror(errno));
- } else {
- info("Get format sizeimage:%u, bytesperline:%u",
- g_fmt.fmt.pix_mp.plane_fmt[0].sizeimage,
- g_fmt.fmt.pix_mp.plane_fmt[0].bytesperline);
+ err("OUTPUT: G_FMT failed (%s)", strerror(errno));
+ return -1;
}
+ info("OUTPUT: Get format %ux%u, sizeimage %u, bpl %u",
+ g_fmt.fmt.pix_mp.width, g_fmt.fmt.pix_mp.height,
+ g_fmt.fmt.pix_mp.plane_fmt[0].sizeimage,
+ g_fmt.fmt.pix_mp.plane_fmt[0].bytesperline);
+
memzero(reqbuf);
reqbuf.count = count;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
@@ -586,13 +602,13 @@ int video_setup_output(struct instance *i, unsigned long codec,
ret = ioctl(vid->fd, VIDIOC_REQBUFS, &reqbuf);
if (ret) {
- err("REQBUFS failed on OUTPUT queue");
+ err("OUTPUT: REQBUFS failed (%s)", strerror(errno));
return -1;
}
vid->out_buf_cnt = reqbuf.count;
- info("Number of OUTPUT buffers is %d (requested %d)",
+ info("OUTPUT: Number of buffers %u (requested %u)",
vid->out_buf_cnt, count);
for (n = 0; n < vid->out_buf_cnt; n++) {
@@ -605,8 +621,8 @@ int video_setup_output(struct instance *i, unsigned long codec,
buf.length = OUT_PLANES;
ret = ioctl(vid->fd, VIDIOC_QUERYBUF, &buf);
- if (ret != 0) {
- err("QUERYBUF failed on OUTPUT buffer");
+ if (ret) {
+ err("OUTPUT: QUERYBUF failed (%s)", strerror(errno));
return -1;
}
@@ -619,14 +635,14 @@ int video_setup_output(struct instance *i, unsigned long codec,
buf.m.planes[0].m.mem_offset);
if (vid->out_buf_addr[n] == MAP_FAILED) {
- err("Failed to MMAP OUTPUT buffer");
+ err("OUTPUT: MMAP failed (%s)", strerror(errno));
return -1;
}
vid->out_buf_flag[n] = 0;
}
- info("querybuf: OUTPUT sizeimage %d", vid->out_buf_size);
+ info("OUTPUT: Succesfully mmapped %u buffers", n);
return 0;
}
diff --git a/video.h b/video.h
index 84f38dc..efca81b 100644
--- a/video.h
+++ b/video.h
@@ -35,32 +35,38 @@ void video_close(struct instance *i);
* buffer. This is the maximum size a single compressed frame can have.
* The count is the number of the stream buffers to allocate. */
int video_setup_output(struct instance *i, unsigned long codec,
- unsigned int size, int count);
+ unsigned int size, unsigned int count);
/* Setup the CAPTURE queue. The argument extra_buf means the number of extra
* buffers that should added to the minimum number of buffers required
* by MFC. The final number of buffers allocated is stored in the instance
* structure. */
-int video_setup_capture(struct instance *i, int extra_buf, int w, int h);
-int video_setup_capture_dmabuf(struct instance *i, int count, int w, int h);
+int video_setup_capture(struct instance *i, unsigned int count, unsigned int w,
+ unsigned int h);
+int video_setup_capture_dmabuf(struct instance *i, unsigned int count,
+ unsigned int w, unsigned int h);
/* Queue OUTPUT buffer */
-int video_queue_buf_out(struct instance *i, int n, int length);
+int video_queue_buf_out(struct instance *i, unsigned int n,
+ unsigned int length);
/* Queue CAPTURE buffer */
-int video_queue_buf_cap(struct instance *i, int n);
+int video_queue_buf_cap(struct instance *i, unsigned int n);
/* Control MFC streaming */
-int video_stream(struct instance *i, enum v4l2_buf_type type, int status);
+int video_stream(struct instance *i, enum v4l2_buf_type type,
+ unsigned int status);
-int video_export_buf(struct instance *i, int index);
+int video_export_buf(struct instance *i, unsigned int index);
/* Dequeue a buffer, the structure *buf is used to return the parameters of the
* dequeued buffer. */
-int video_dequeue_output(struct instance *i, int *n);
-int video_dequeue_capture(struct instance *i, int *n, int *finished,
+int video_dequeue_output(struct instance *i, unsigned int *n);
+int video_dequeue_capture(struct instance *i, unsigned int *n,
+ unsigned int *finished,
unsigned int *bytesused);
-int video_dequeue_capture_dmabuf(struct instance *i, int *n, int *finished,
+int video_dequeue_capture_dmabuf(struct instance *i, unsigned int *n,
+ unsigned int *finished,
unsigned int *bytesused);
int video_set_control(struct instance *i);