diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-01 15:33:59 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-01 15:33:59 -0200 |
commit | 1de05f2d88e6e1fb2926caa368cf2544c65f86f0 (patch) | |
tree | 857cee9ed3ca2360735106c9443492a70cedadb7 /v4l2-apps | |
parent | 655f032b6b86ac96cefcefe344e181d83d197c87 (diff) | |
download | mediapointer-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.c | 69 | ||||
-rw-r--r-- | v4l2-apps/lib/v4l2_driver.h | 3 | ||||
-rw-r--r-- | v4l2-apps/test/driver-test.c | 44 |
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"); |