基于V4L2摄像头采集图片程序设计
#ifndef __COMMON_H #define __COMMON_H //该头文件定义的是摄像头在屏幕上显示的宽度和高度 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include <stdint.h> typedef unsigned char U8; typedef unsigned int U32; typedef unsigned short U16; #define WIDTH 800 #define HEIGHT 600 #endif //__COMMON_H
#ifndef __VIDEOCAPTURE_H
#define __VIDEOCAPTURE_H
#include"common.h"
#include<sys/mman.h>
#include<fcntl.h>
#include<linux/videodev2.h>
#define VIDEODEVNAME ("/dev/video0")
#define COUNT 4
//需要调用的摄像头相关的接口,包括初始化,开始,结束,采取一帧的数据并保存
int initCamera();
void unInitCamera();
int startCamera();
int stopCamera();
int getOneFrame(U8* pcYuvBuffer);
#endif //__VIDEOCAPTURE_H
#include"videoCapture.h"
static U8* pcYuv[COUNT]={NULL};
static int vidDevFd = -1;
static int nLength = 0;
static struct v4l2_buffer dequeBuffer;
static struct v4l2_buffer queueBuffer;
//初始化摄像头程序
int initCamera()
{
//open /dev/video*
//open video device
vidDevFd = open(VIDEODEVNAME, O_RDONLY);
if (vidDevFd < 0)
{
fprintf(stderr, "open %s failed %s\n",VIDEODEVNAME, strerror(errno));
return -1;
}
//printf("vidDevFd = %d!\n", vidDevFd);
//设置视频格式
//set video device format
struct v4l2_format vidDevFmt;
vidDevFmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
vidDevFmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
vidDevFmt.fmt.pix.width = WIDTH;
vidDevFmt.fmt.pix.height = HEIGHT;
if (0 != ioctl(vidDevFd, VIDIOC_S_FMT, &vidDevFmt))
{
fprintf(stderr, "VIDIOC_S_FMT failed %s\n", strerror(errno));
unInitCamera();
return -1;
}
//request buffers
//max count need to be considered
struct v4l2_requestbuffers reqBuffer;
reqBuffer.count = COUNT;
reqBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqBuffer.memory = V4L2_MEMORY_MMAP;
if (0 != ioctl(vidDevFd, VIDIOC_REQBUFS, &reqBuffer))
{
fprintf(stderr, "VIDIOC_REQBUFS failed %s\n", strerror(errno));
unInitCamera();
return -1;
}
//query buffers
int i = 0;
struct v4l2_buffer qryBuffer;
qryBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
qryBuffer.memory = V4L2_MEMORY_MMAP;
for (i = 0; i < COUNT; i++)
{
qryBuffer.index = i;
if (0 != ioctl(vidDevFd, VIDIOC_QUERYBUF, &qryBuffer))
{
fprintf(stderr, "VIDIOC_QUERYBUF failed %s\n", strerror(errno));
unInitCamera();
return -1;
}
printf("qryBuffer.m.offset=%d, qryBuffer.lenght=%d\n", qryBuffer.m.offset, qryBuffer.length);
//mmap video device memory allocated by VIDIOC_REQBUFS
pcYuv[i] = mmap(NULL, qryBuffer.length, PROT_READ, MAP_SHARED, vidDevFd, qryBuffer.m.offset);
nLength = qryBuffer.length;
//queue buffers
struct v4l2_buffer queBuffer;
queBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
queBuffer.memory = V4L2_MEMORY_MMAP;
queBuffer.index = qryBuffer.index;
if (0 != ioctl(vidDevFd, VIDIOC_QBUF, &queBuffer))
{
fprintf(stderr, "init VIDIOC_QBUF failed %s\n", strerror(errno));
unInitCamera();
return -1;
}
}
dequeBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
dequeBuffer.memory = V4L2_MEMORY_MMAP;
queueBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
queueBuffer.memory = V4L2_MEMORY_MMAP;
return 0;
}
//取消摄像头
void unInitCamera()
{
int i = 0;
for (i = 0; i < COUNT; i++)
{
if (NULL != pcYuv[i])
{
if (-1 == munmap(pcYuv[i], nLength));
{
//fprintf(stderr,"munmap error:%s!\n",strerror(errno));
}
pcYuv[i] = NULL;
}
}
if (vidDevFd >= 0)
close(vidDevFd);
}
//摄像头开始
int startCamera()
{
//start camera
int nArg = 1;
if (0 != ioctl(vidDevFd, VIDIOC_STREAMON, &nArg))
{
fprintf(stderr, "VIDIOC_STREAMON failed %s\n", strerror(errno));
unInitCamera();
return -1;
}
return 0;
}
//停止摄像头
int stopCamera()
{
//stop camera
int nArg = 1;
if (0 != ioctl(vidDevFd, VIDIOC_STREAMOFF, &nArg))
{
fprintf(stderr, "VIDIOC_STREAMOFF failed %s\n", strerror(errno));
unInitCamera();
return -1;
}
return 0;
}
//获取Frame
int getOneFrame(unsigned char* pcYuyvBuffer)
{
if (0 != ioctl(vidDevFd, VIDIOC_DQBUF, &dequeBuffer))
{
fprintf(stderr, "VIDIOC_DQBUF failed %s\n", strerror(errno));
unInitCamera();
return -1;
}
//get frame
memcpy(pcYuyvBuffer, pcYuv[dequeBuffer.index], dequeBuffer.length);
printf("len=%d\n",dequeBuffer.length);
//queue
queueBuffer.index = dequeBuffer.index;
if (0 != ioctl(vidDevFd, VIDIOC_QBUF, &queueBuffer))
{
fprintf(stderr, "VIDIOC_QBUF failed %s\n", strerror(errno));
unInitCamera();
return -1;
}
return 0;
}
#include"videoCapture.h"
int main(void )
{
int nRet = 0;
//char yuyv[WIDTH*HEIGHT*2];
char* pcYuvBuffer = NULL;
if(-1 == initCamera())
{
printf("initCamera failed!\n");
goto ERR;
}
if (-1 == startCamera())
{
printf("startCamera failed!\n");
goto ERR;
}
pcYuvBuffer = (char*)malloc((WIDTH*HEIGHT*2)*sizeof(char));
if (NULL == pcYuvBuffer)
{
printf("malloc YUYV buffer failed!\n");
goto ERR;
}
int nDstFd = open("mytest.yuv", O_CREAT|O_EXCL|O_RDWR|O_TRUNC, 0777);
if (nDstFd == -1)
{
fprintf(stderr, "open mytest.yuv failed:%s\n", strerror(errno));
}
int nFrameNum = 0;
while(1)
{
if (20 == nFrameNum)
break;
memset(pcYuvBuffer, 0, WIDTH*HEIGHT*2);
//if (-1 == getOneFrame(yuyv))
if (-1 == getOneFrame(pcYuvBuffer))
{
printf("getOneFrame error!\n");
goto ERR;
}
//if (-1 == write(nDstFd, yuyv, WIDTH*HEIGHT*2))
if (-1 == write(nDstFd, pcYuvBuffer, WIDTH*HEIGHT*2))
{
fprintf(stderr, "write error:%s\n", strerror(errno));
goto ERR;
}
nFrameNum++;
}
if (-1 == stopCamera())
{
printf("stopCamera error!\n");
}
ERR:
if (NULL != pcYuvBuffer)
{
free(pcYuvBuffer);
pcYuvBuffer = NULL;
}
unInitCamera();
close(nDstFd);
nDstFd = -1;
return 0;
}
基于V4L2摄像头采集图片程序设计的更多相关文章
- Linux 下V4l2摄像头采集图片,实现yuyv转RGB,RGB转BMP,RGB伸缩,jpeglib 库实现压缩RGB到内存中,JPEG经UDP发送功(转)
./configure CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld --host=arm-linux --prefix=/usr/loca ...
- 基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集【转】
转自:http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html 一直想把USB摄像头接到Zedboard上,搭建 ...
- 14、USB摄像头(V4L2接口)的图片采集
参考网站http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html 一.一些知识 1.V4L和V4L2. V4L是 ...
- 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)
编写带界面的图像处理程序,选择opencv+mfc是一种很好的选择:在读取摄像头数据方面,网上的方法很多,其中shiqiyu的camerads的方法是较好的. 基于现有资料 ...
- 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)持续更新
编写带界面的图像处理程序,选择opencv+mfc是一种很好的选择:在读取摄像头数据方面,网上的方法很多,其中shiqiyu的camerads的方法是较好的. 基于现有资料 ...
- 基于视频压缩的实时监控系统-sprint1基于epoll架构的采集端程序设计
part1:产品功能 part2:epoll机制 select与epoll区别 1.select与epoll没有太大的区别.除了select有文件描述符限制(1024个),select每次调用都需 ...
- V4L2视频采集原理
一.简介 Video for Linuxtwo(Video4Linux2)简称V4L2,是V4L的改进版.V4L2是linux操作系统下用于采集图片.视频和音频数据的API接口,配合适当的视频采集设备 ...
- linux之V4L2摄像头应用流程【转】
本文转载自:http://blog.csdn.net/tommy_wxie/article/details/11486907 对于v4l2,上次是在调试收音机驱动的时候用过,其他也就只是用i2c配置一 ...
- Linux之V4L2视频采集编程详解
V4L2(Video For Linux Two) 是内核提供给应用程序访问音.视频驱动的统一接口. Linux系统中,视频设备被当作一个设备文件来看待,设备文件存放在 /dev目录下,完整路径的设 ...
随机推荐
- ●HDU 2871 Memory Control(Splay)
●赘述题目 四种操作: ○Reset:将整个内存序列清空. ○New a:在尽量靠左的位置新建一个长度为a的内存块,并输出改内存块起始位置.(各个内存块即使相邻也不会合并..) ○Free a:将a点 ...
- MFC 程序入口和执行流程
MFC(微软基础类库)以C++类的形式封装了Windows API,给开发者提供了便利,但是初学者常常会疑惑MFC程序的入口在哪里?下面给大家简单介绍一下MFC 程序入口和执行流程. 一 MFC程序执 ...
- Server-U FTP与AD完美集成方案详解
最近咱有个任务,那就是把公司的文件服务器.FTP服务器.邮件服务器进行迁移并作相应的整合.登陆后台查看了,公司目前正在使用的方案.FTP服务器使用的是Server-u FTP,验证方式选择的windo ...
- easyui combobox setValue数据绑不上
var synj = "<%=arrbj[3]%>"; var xnxq = "<%=xnxq%>"; OnchangeSelect($ ...
- java 反射机制 观点
反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧! 一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本 ...
- pupeteer初体验
官方文档: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagescreenshotoptions puppet ...
- ng-book札记——内置指令
Angular提供了一些内置指令(directive),这些添加在HTML元素(element)上的特性(attribute)可以赋予更多的动态行为. NgIf ngIf指令用于在某个条件下显示或者隐 ...
- Spring Security基于Java配置
Maven依赖 <dependencies> <!-- ... other dependency elements ... --> <dependency> < ...
- 在linux系统中I/O 调度的选择
I/O 调度算法再各个进程竞争磁盘I/O的时候担当了裁判的角色.他要求请求的次序和时机做最优化的处理,以求得尽可能最好的整体I/O性能. 在linux下面列出4种调度算法 CFQ (Compl ...
- 安卓高级Fresco图片框架的时候
Fresco:2015FaceBook推出的 及其强大 支持webp图片格式 和渐进式图片加载 中文文档 使用方法 引入依赖 点击查看具体教程 基本使用步骤 在布局中使用其标签 <com.fac ...