diff options
-rw-r--r-- | .hgignore | 12 | ||||
-rw-r--r-- | v4l2-apps/test/Makefile | 7 | ||||
-rw-r--r-- | v4l2-apps/test/v4l2grab.c | 155 |
3 files changed, 169 insertions, 5 deletions
@@ -28,10 +28,12 @@ v4l/Module.markers$ v4l/config-compat.h$ v4l/.myconfig$ v4l/.snapshot$ -v4l2-apps/libv4l2util/.*\.so$ +v4l2-apps/libv4l2util/.*\.so +v4l2-apps/lib/.*\.so v4l2-apps/include v4l2-apps/test/driver-test$ v4l2-apps/test/v4lgrab$ +v4l2-apps/test/v4l2grab$ v4l2-apps/test/ioctl-test$ v4l2-apps/test/sliced-vbi-detect$ v4l2-apps/test/sliced-vbi-test$ @@ -55,10 +57,10 @@ v4l2-apps/util/v4l2-ctl$ v4l2-apps/util/cx18-ctl$ v4l2-apps/util/ivtv-ctl$ v4l2-apps/util/v4l-board-dbg$ -v4l2-apps/libv4l/libv4l[12]/.*.so.0$ -v4l2-apps/libv4l/libv4lconvert/.*.so.0$ -v4l2-apps/libv4l/libv4l[12]/.*.so$ -v4l2-apps/libv4l/libv4lconvert/.*.so$ +v4l2-apps/libv4l/libv4l[12]/.*.so +v4l2-apps/libv4l/libv4lconvert/.*.so +v4l2-apps/libv4l/libv4lconvert/ov511-decomp +v4l2-apps/libv4l/libv4lconvert/ov518-decomp v4l2-spec/capture$ v4l2-spec/capture.c.sgml$ v4l2-spec/entities.sgml$ diff --git a/v4l2-apps/test/Makefile b/v4l2-apps/test/Makefile index d118b9210..71eaa77cf 100644 --- a/v4l2-apps/test/Makefile +++ b/v4l2-apps/test/Makefile @@ -7,6 +7,7 @@ binaries = ioctl-test \ sliced-vbi-detect \ vbi-test \ v4lgrab \ + v4l2grab \ driver-test \ pixfmt-test \ stress-buffer \ @@ -24,9 +25,15 @@ install: ../libv4l2util/libv4l2util.a: ../libv4l2util/v4l2_driver.c ../libv4l2util/frequencies.c make -C ../libv4l2util libv4l2util.a +../libv4l/libv4l2/libv4l2.so: + make -C ../libv4l/ + driver-test: driver-test.o ../libv4l2util/libv4l2util.a pixfmt-test: pixfmt-test.o $(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ -lX11 +v4l2grab: v4l2grab.o + $(CC) $(LDFLAGS) $^ -o $@ ../libv4l/libv4l2/libv4l2.so + include ../Make.rules diff --git a/v4l2-apps/test/v4l2grab.c b/v4l2-apps/test/v4l2grab.c new file mode 100644 index 000000000..20692117e --- /dev/null +++ b/v4l2-apps/test/v4l2grab.c @@ -0,0 +1,155 @@ +/* V4L2 video picture grabber + Copyright (C) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <linux/videodev2.h> +#include "../libv4l/include/libv4l2.h" + +#define CLEAR(x) memset(&(x), 0, sizeof(x)) + +struct buffer { + void *start; + size_t length; +}; + +static void xioctl(int fh, int request, void *arg) +{ + int r; + + do { + r = v4l2_ioctl(fh, request, arg); + } while (r == -1 && ((errno == EINTR) || (errno == EAGAIN))); + + if (r == -1) { + fprintf(stderr, "error %d, %s\n", errno, strerror(errno)); + exit(EXIT_FAILURE); + } +} + +int main(int argc, char **argv) +{ + struct v4l2_format fmt; + struct v4l2_buffer buf; + struct v4l2_requestbuffers req; + enum v4l2_buf_type type; + fd_set fds; + struct timeval tv; + int r, fd = -1; + unsigned int i, n_buffers; + char *dev_name = "/dev/video0"; + char out_name[256]; + FILE *fout; + struct buffer *buffers; + + fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0); + if (fd < 0) { + perror("Cannot open device"); + exit(EXIT_FAILURE); + } + + CLEAR(fmt); + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.width = 640; + fmt.fmt.pix.height = 480; + fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; + fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; + xioctl(fd, VIDIOC_S_FMT, &fmt); + + CLEAR(req); + req.count = 2; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; + xioctl(fd, VIDIOC_REQBUFS, &req); + + buffers = calloc(req.count, sizeof(*buffers)); + for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { + CLEAR(buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = n_buffers; + + xioctl(fd, VIDIOC_QUERYBUF, &buf); + + buffers[n_buffers].length = buf.length; + buffers[n_buffers].start = v4l2_mmap(NULL, buf.length, + PROT_READ | PROT_WRITE, MAP_SHARED, + fd, buf.m.offset); + + if (MAP_FAILED == buffers[n_buffers].start) { + perror("mmap"); + exit(EXIT_FAILURE); + } + } + + for (i = 0; i < n_buffers; ++i) { + CLEAR(buf); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + xioctl(fd, VIDIOC_QBUF, &buf); + } + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + xioctl(fd, VIDIOC_STREAMON, &type); + for (i = 0; i < 20; i++) { + do { + FD_ZERO(&fds); + FD_SET(fd, &fds); + + /* Timeout. */ + tv.tv_sec = 2; + tv.tv_usec = 0; + + r = select(fd + 1, &fds, NULL, NULL, &tv); + } while ((r == -1 && (errno = EINTR))); + if (r == -1) { + perror("select"); + return errno; + } + + CLEAR(buf); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + xioctl(fd, VIDIOC_DQBUF, &buf); + + sprintf(out_name, "out%03d.ppm", i); + fout = fopen(out_name, "w"); + if (!fout) { + perror("Cannot open image"); + exit(EXIT_FAILURE); + } + fprintf(fout, "P6\n%d %d 255\n", + fmt.fmt.pix.width, fmt.fmt.pix.height); + fwrite(buffers[buf.index].start, buf.bytesused, 1, fout); + fclose(fout); + + xioctl(fd, VIDIOC_QBUF, &buf); + } + + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + xioctl(fd, VIDIOC_STREAMOFF, &type); + for (i = 0; i < n_buffers; ++i) + v4l2_munmap(buffers[i].start, buffers[i].length); + v4l2_close(fd); + + return 0; +} |