IMX8 + Linux + 海康威视 实现获取摄像头 源码

时间: 2024-01-04 19:01:58 浏览: 51
获取海康威视摄像头的源码,需要先了解一下摄像头的型号和接口类型。如果是USB接口的摄像头,可以使用V4L2(UVC)驱动来进行操作。如果是CSI接口的摄像头,需要根据具体的型号和规格书来开发对应的驱动程序。以下是一个使用V4L2驱动的示例程序: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <sys/ioctl.h> #include <linux/videodev2.h> #define CAMERA_DEVICE "/dev/video0" #define CAPTURE_FILE "frame.raw" #define IMAGE_WIDTH 640 #define IMAGE_HEIGHT 480 struct buffer { void *start; size_t length; }; static void errno_exit(const char *s) { fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno)); exit(EXIT_FAILURE); } static int xioctl(int fd, int request, void *arg) { int r; do { r = ioctl(fd, request, arg); } while (-1 == r && EINTR == errno); return r; } static void process_image(const void *p, int size) { FILE *fp; fp = fopen(CAPTURE_FILE, "wb"); if (fp) { fwrite(p, size, 1, fp); fclose(fp); } } static int read_frame(int fd, struct buffer *buffers) { struct v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) { switch (errno) { case EAGAIN: return 0; case EIO: default: errno_exit("VIDIOC_DQBUF"); } } process_image(buffers[buf.index].start, buf.bytesused); if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); return 1; } static void mainloop(int fd, struct buffer *buffers) { unsigned int count; count = 100; while (count-- > 0) { for (;;) { fd_set fds; struct timeval tv; int r; FD_ZERO(&fds); FD_SET(fd, &fds); tv.tv_sec = 2; tv.tv_usec = 0; r = select(fd + 1, &fds, NULL, NULL, &tv); if (-1 == r) { if (EINTR == errno) continue; errno_exit("select"); } if (0 == r) { fprintf(stderr, "select timeout\n"); exit(EXIT_FAILURE); } if (read_frame(fd, buffers)) break; } } } static void stop_capturing(int fd) { enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type)) errno_exit("VIDIOC_STREAMOFF"); } static void start_capturing(int fd, struct buffer *buffers) { unsigned int i; enum v4l2_buf_type type; for (i = 0; i < 4; ++i) { struct v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf)) errno_exit("VIDIOC_QUERYBUF"); 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) errno_exit("mmap"); } for (i = 0; i < 4; ++i) { struct v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) errno_exit("VIDIOC_STREAMON"); } static void uninit_device(struct buffer *buffers) { unsigned int i; for (i = 0; i < 4; ++i) if (-1 == munmap(buffers[i].start, buffers[i].length)) errno_exit("munmap"); } static void init_mmap(int fd, struct buffer **buffers, unsigned int *n_buffers) { struct v4l2_requestbuffers req; CLEAR(req); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) { if (EINVAL == errno) { fprintf(stderr, "%s does not support " "memory mapping\n", CAMERA_DEVICE); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_REQBUFS"); } } if (req.count < 2) { fprintf(stderr, "Insufficient buffer memory on %s\n", CAMERA_DEVICE); exit(EXIT_FAILURE); } *buffers = calloc(req.count, sizeof(**buffers)); if (!*buffers) { fprintf(stderr, "Out of memory\n"); exit(EXIT_FAILURE); } for (*n_buffers = 0; *n_buffers < req.count; ++*n_buffers) { struct v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = *n_buffers; if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf)) errno_exit("VIDIOC_QUERYBUF"); (*buffers)[*n_buffers].length = buf.length; (*buffers)[*n_buffers].start = mmap(NULL /* start anywhere */, buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, fd, buf.m.offset); if (MAP_FAILED == (*buffers)[*n_buffers].start) errno_exit("mmap"); } } static void init_device(int fd) { struct v4l2_capability cap; struct v4l2_format fmt; if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) { if (EINVAL == errno) { fprintf(stderr, "%s is no V4L2 device\n", CAMERA_DEVICE); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_QUERYCAP"); } } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { fprintf(stderr, "%s is no video capture device\n", CAMERA_DEVICE); exit(EXIT_FAILURE); } if (!(cap.capabilities & V4L2_CAP_STREAMING)) { fprintf(stderr, "%s does not support streaming i/o\n", CAMERA_DEVICE); exit(EXIT_FAILURE); } CLEAR(fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = IMAGE_WIDTH; fmt.fmt.pix.height = IMAGE_HEIGHT; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) errno_exit("VIDIOC_S_FMT"); if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV) { fprintf(stderr, "Libv4l only supports V4L2_PIX_FMT_YUYV format\n"); exit(EXIT_FAILURE); } } int main(int argc, char *argv[]) { struct buffer *buffers; unsigned int n_buffers; int fd = open(CAMERA_DEVICE, O_RDWR | O_NONBLOCK, 0); if (-1 == fd) { fprintf(stderr, "Cannot open %s\n", CAMERA_DEVICE); exit(EXIT_FAILURE); } init_device(fd); init_mmap(fd, &buffers, &n_buffers); start_capturing(fd, buffers); mainloop(fd, buffers); stop_capturing(fd); uninit_device(buffers); close(fd); return 0; } ``` 这个程序会从摄像头中获取视频流,并将每一帧保存到文件中。您需要根据自己的需求进行修改。需要注意的是,这个程序只适用于使用V4L2驱动的摄像头,如果您使用的是CSI接口的摄像头,需要开发对应的驱动程序。

相关推荐

最新推荐

recommend-type

rpad-imx6 Linux手册.pdf

基于imx6ull的Linux系统移植和开发手册,包括开发板外设验证,uboot/kernel/rootfs的移植,硬件外设的驱动移植和开发,Qt/lvgl/awtk等GUI的移植和应用开发。
recommend-type

iMX8QM_RM_Rev_E-芯片手册.pdf

NXP IMX8qm 芯片手册,官网找很久都找不到。对芯片框架,寄存器等详细用法详细描述。驱动开发必备。
recommend-type

iTOP-iMX6ULL 开发板-FFmpeg 移植实现视频采集

FFmpeg(Fast Forward Mpeg)是一种可以用来记录、转换数字音频、视频,并能将其转化为流的多媒体视频处理工具,拥有视频采集功能、视频格式转换、视频抓图等功能。本文档介绍如何将 ffmpeg 移植到 ARM 平台。
recommend-type

飞思卡尔IMX51+android平台 Audio驱动分析

基于飞思卡尔平台IMX51+Android平台音频驱动加载过程的详细分析,并附有结构图,分析了音频驱动,声卡的注册,probe过程,和各个结构体之间的联系
recommend-type

IMX219 数据手册datastreet

IMX219 数据手册datastreet ...imx219满足了高性能拍照应用所需的 [高灵敏度] 、[高帧率拍摄] 等基本功能需求, 由于芯片的小型化, 使得它即使在时尚的窄边框设计的设备的前置摄像头上也能很方便应用。
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

如何用python编写api接口

在Python中编写API接口可以使用多种框架,其中比较流行的有Flask和Django。这里以Flask框架为例,简单介绍如何编写API接口。 1. 安装Flask框架 使用pip命令安装Flask框架: ``` pip install flask ``` 2. 编写API接口 创建一个Python文件,例如app.py,编写以下代码: ```python from flask import Flask, jsonify app = Flask(__name__) @app.route('/api/hello', methods=['GET']) def hello():
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。