5 Star 18 Fork 26

zoro / v4l2-learn

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
v4l2_test.c 4.62 KB
一键复制 编辑 原始数据 按行查看 历史
zoro 提交于 2021-09-26 19:41 . v4l2_test* 关联csdn专题详解
/* csdn: 专题讲解
* https://blog.csdn.net/ldl617/category_11006699.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <sys/mman.h>
#include <errno.h>
struct buffer {
void * start;
size_t length;
};
struct buffer *buffers = NULL;
int main(int argc, char **argv)
{
int fd, i, r;
FILE *file_fd;
fd_set fds;
struct timeval tv;
struct v4l2_capability cap;
struct v4l2_input inp;
struct v4l2_fmtdesc fmtdesc;
struct v4l2_format fmt;
struct v4l2_requestbuffers req;
struct v4l2_buffer buf;
enum v4l2_buf_type type;
if (argc != 4) {
printf("Usage: v4l2_test <device> <frame_num> <save_file>\n");
printf("example: v4l2_test /dev/video0 10 test.yuv\n");
goto err1;
}
fd = open(argv[1], O_RDWR);
if (fd < 0) {
printf("open device: %s fail\n", argv[1]);
goto err1;
}
file_fd = fopen(argv[3], "wb+");
if (!file_fd) {
printf("open save_file: %s fail\n", argv[3]);
goto err1;
}
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
printf("Get video capability error!\n");
goto err;
}
if (!(cap.device_caps & V4L2_CAP_VIDEO_CAPTURE)) {
printf("Video device not support capture!\n");
goto err;
}
printf("Support capture!\n");
inp.index = 0;
while (ioctl (fd, VIDIOC_ENUMINPUT, &inp) == 0) {
printf("%s : std: %08x\n", inp.name, inp.std);
inp.index++;
}
inp.index = 1;
if (ioctl (fd, VIDIOC_S_INPUT, &inp) < 0) {
printf("Set input fail\n");
goto err;
}
fmtdesc.index = 0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
while (!ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)) {
printf("fmt name: [%s]\n", fmtdesc.description);
printf("fmt pixelformat : '%c%c%c%c', description = '%s'\n",fmtdesc.pixelformat & 0xFF,
(fmtdesc.pixelformat >> 8) & 0xFF,(fmtdesc.pixelformat >> 16) & 0xFF,
(fmtdesc.pixelformat >> 24) & 0xFF,fmtdesc.description);
fmtdesc.index++;
}
memset(&fmt, 0, sizeof(struct v4l2_format));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 1920;
fmt.fmt.pix.height = 1080;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_ANY;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) {
printf("Set format fail\n");
goto err;
}
req.count = 5;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) {
printf("Reqbufs fail\n");
goto err;
}
printf("buffer number: %d\n", req.count);
buffers = calloc (req.count, sizeof (*buffers));
for(i = 0; i < req.count; i++) {
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buf)) {
printf("Querybuf fail\n");
goto err;
}
printf("buffer[%d]: length = %d, offset = %d\n", i, buf.length, buf.m.offset);
buffers[i].length = buf.length;
buffers[i].start =
mmap (NULL /* start anywhere */,
buf.length,
PROT_READ | PROT_WRITE /* required */,
MAP_SHARED /* recommended */,
fd, buf.m.offset);
if (MAP_FAILED == buffers[i].start) {
printf ("mmap failed\n");
req.count = i;
goto unmmap;
}
}
for (i = 0; i < req.count; ++i)
{
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if (ioctl (fd, VIDIOC_QBUF, &buf) < 0)
printf ("VIDIOC_QBUF failed\n");
printf("buf[%d].flags = 0x%08x\n", i, buf.flags);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(fd, VIDIOC_STREAMON, &type) < 0)
printf ("VIDIOC_STREAMON failed\n");
int num = 0;
while (1)
{
FD_ZERO (&fds);
FD_SET(fd, &fds);
tv.tv_sec = 5;
tv.tv_usec = 0;
r = select (fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r)
{
if (EINTR == errno)
continue;
printf ("select err\n");
}
if (0 == r)
{
fprintf (stderr, "select timeout\n");
exit (EXIT_FAILURE);
}
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (ioctl (fd, VIDIOC_DQBUF, &buf) < 0)
printf("dqbuf fail\n");
fwrite(buffers[buf.index].start, buf.bytesused, 1, file_fd);
if (ioctl (fd, VIDIOC_QBUF, &buf) < 0)
printf("failture VIDIOC_QBUF\n");
num++;
if(num > atoi(argv[2]))
break;
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0)
printf("VIDIOC_STREAMOFF fail\n");
unmmap:
for (i = 0; i < req.count; ++i)
if (-1 == munmap (buffers[i].start, buffers[i].length))
printf ("munmap error");
close (fd);
fclose (file_fd);
return 0;
err:
close(fd);
fclose (file_fd);
err1:
return -1;
}
1
https://gitee.com/ldl17/v4l2-learn.git
git@gitee.com:ldl17/v4l2-learn.git
ldl17
v4l2-learn
v4l2-learn
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891