summaryrefslogtreecommitdiff
path: root/v4l2-apps
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-12-01 15:33:59 -0200
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-01 15:33:59 -0200
commit1de05f2d88e6e1fb2926caa368cf2544c65f86f0 (patch)
tree857cee9ed3ca2360735106c9443492a70cedadb7 /v4l2-apps
parent655f032b6b86ac96cefcefe344e181d83d197c87 (diff)
downloadmediapointer-dvb-s2-1de05f2d88e6e1fb2926caa368cf2544c65f86f0.tar.gz
mediapointer-dvb-s2-1de05f2d88e6e1fb2926caa368cf2544c65f86f0.tar.bz2
Implement mmapped streaming reception
From: Mauro Carvalho Chehab <mchehab@infradead.org> Add capabilities to the library and to the driver to receive video streams. Library will use a callback, called every time a new buffer is reported by dqbuf. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'v4l2-apps')
-rw-r--r--v4l2-apps/lib/v4l2_driver.c69
-rw-r--r--v4l2-apps/lib/v4l2_driver.h3
-rw-r--r--v4l2-apps/test/driver-test.c44
3 files changed, 93 insertions, 23 deletions
diff --git a/v4l2-apps/lib/v4l2_driver.c b/v4l2-apps/lib/v4l2_driver.c
index a73d6a3f5..7d6b549a2 100644
--- a/v4l2-apps/lib/v4l2_driver.c
+++ b/v4l2-apps/lib/v4l2_driver.c
@@ -169,7 +169,7 @@ int v4l2_open (char *device, int debug, struct v4l2_driver *drv)
drv->debug=debug;
- if ((drv->fd = open(device, O_RDWR | O_NONBLOCK )) < 0) {
+ if ((drv->fd = open(device, O_RDWR )) < 0) {
perror("Couldn't open video0");
return(errno);
}
@@ -652,23 +652,57 @@ int v4l2_mmap_bufs(struct v4l2_driver *drv, unsigned int num_buffers)
return 0;
}
-/* Returns -1 if all buffers are being used, 0 if ok and errno if error */
-int v4l2_qbuf(struct v4l2_driver *drv)
+int v4l2_rcvbuf(struct v4l2_driver *drv, v4l2_recebe_buffer *rec_buf)
{
- if (((drv->currq+1) % drv->reqbuf.count) == drv->waitq)
- return -1;
+ int ret;
- if (xioctl(drv->fd,VIDIOC_QBUF,&drv->v4l2_bufs[(drv->currq) % drv->reqbuf.count])<0)
- return errno;
+ struct v4l2_buffer buf;
+ memset (&buf, 0, sizeof(buf));
+
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+
+ if (-1 == xioctl (drv->fd, VIDIOC_DQBUF, &buf)) {
+ switch (errno) {
+ case EAGAIN:
+ return 0;
+
+ case EIO:
+ /* Could ignore EIO, see spec. */
+
+ /* fall through */
+
+ default:
+ perror ("dqbuf");
+ return errno;
+ }
+ }
+ prt_buf_info("DQBUF",&buf);
+
+ assert (buf.index < drv->n_bufs);
+
+ ret = rec_buf (&buf,&drv->bufs[buf.index]);
+
+ if (ret) {
+ v4l2_free_bufs(drv);
+ return ret;
+ }
+ if (-1 == xioctl (drv->fd, VIDIOC_QBUF, &buf)) {
+ perror ("qbuf");
+ return errno;
+ }
return 0;
}
+
int v4l2_start_streaming(struct v4l2_driver *drv)
{
uint32_t i;
struct v4l2_buffer buf;
+ if (drv->debug)
+ printf("Activating %d queues\n", drv->n_bufs);
for (i = 0; i < drv->n_bufs; i++) {
int res;
@@ -678,24 +712,19 @@ int v4l2_start_streaming(struct v4l2_driver *drv)
buf.index = i;
res = xioctl (drv->fd, VIDIOC_QBUF, &buf);
-prt_buf_info("***QBUF",&buf);
-printf("res=%d, errno=%d\n", res,errno);
- }
-#if 0
-printf("Activating %d queues\n", drv->n_bufs);
- /* Put all buffers int queue state */
- for (i = 0; i < drv->n_bufs; i++) {
-prt_buf_info("***QBUF",drv->v4l2_bufs[i]);
- if (xioctl(drv->fd,VIDIOC_QBUF,drv->v4l2_bufs[i])<0) {
- perror ("qbuf");
+ if (!res)
+ prt_buf_info("QBUF",&buf);
+ else {
+ perror("qbuf");
return errno;
}
- if (drv->debug)
- prt_buf_info("QBUF",drv->v4l2_bufs[i]);
}
-#endif
+
/* Activates stream */
+ if (drv->debug)
+ printf("Enabling streaming\n");
+
if (xioctl(drv->fd,VIDIOC_STREAMON,&drv->reqbuf.type)<0)
return errno;
diff --git a/v4l2-apps/lib/v4l2_driver.h b/v4l2-apps/lib/v4l2_driver.h
index 1df9da3ba..ef6a754f4 100644
--- a/v4l2-apps/lib/v4l2_driver.h
+++ b/v4l2-apps/lib/v4l2_driver.h
@@ -26,6 +26,8 @@ struct v4l2_t_buf {
size_t length;
};
+typedef int v4l2_recebe_buffer (struct v4l2_buffer *v4l2_buf, struct v4l2_t_buf *buf);
+
struct v4l2_driver {
int fd; /* Driver descriptor */
@@ -72,3 +74,4 @@ int v4l2_mmap_bufs(struct v4l2_driver *drv, unsigned int num_buffers);
int v4l2_free_bufs(struct v4l2_driver *drv);
int v4l2_start_streaming(struct v4l2_driver *drv);
int v4l2_stop_streaming(struct v4l2_driver *drv);
+int v4l2_rcvbuf(struct v4l2_driver *drv, v4l2_recebe_buffer *v4l2_rec_buf);
diff --git a/v4l2-apps/test/driver-test.c b/v4l2-apps/test/driver-test.c
index 32b676836..61f6b812a 100644
--- a/v4l2-apps/test/driver-test.c
+++ b/v4l2-apps/test/driver-test.c
@@ -18,11 +18,19 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <errno.h>
+
+int recebe_buffer (struct v4l2_buffer *v4l2_buf, struct v4l2_t_buf *buf)
+{
+
+ return 0;
+}
int main(void)
{
struct v4l2_driver drv;
struct drv_list *cur;
+ unsigned int count = 10, i;
if (v4l2_open ("/dev/video0", 1,&drv)<0) {
perror("open");
@@ -76,12 +84,42 @@ int main(void)
v4l2_mmap_bufs(&drv, 2);
-// v4l2_start_streaming(&drv);
+ v4l2_start_streaming(&drv);
+
+ printf("Waiting for frames...\n");
+
+ for (i=0;i<count;i++) {
+ fd_set fds;
+ struct timeval tv;
+ int r;
-//sleep (1);
+ FD_ZERO (&fds);
+ FD_SET (drv.fd, &fds);
-// v4l2_stop_streaming(&drv);
+ /* Timeout. */
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+
+ r = select (drv.fd + 1, &fds, NULL, NULL, &tv);
+ if (-1 == r) {
+ if (EINTR == errno)
+ continue;
+
+ perror ("select");
+ return errno;
+ }
+
+ if (0 == r) {
+ fprintf (stderr, "select timeout\n");
+ return errno;
+ }
+
+ if (v4l2_rcvbuf(&drv, recebe_buffer))
+ break;
+ }
+ printf("stopping streaming\n");
+ v4l2_stop_streaming(&drv);
if (v4l2_close (&drv)<0) {
perror("close");