#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "v4l2.h"
#define CLEAR(x) memset (&x, 0, sizeof(x))
#define VIDEO_FORMAT V4L2_PIX_FMT_YUYV
//V4L2_PIX_FMT_MJPEG
//V4L2_PIX_FMT_JPEG
//V4L2_PIX_FMT_YUYV
//V4L2_PIX_FMT_YVU420
//V4L2_PIX_FMT_RGB32
FILE *file_fd;
#define CAPTURE_FILE "test.jpg"
char *mpeg[] = {"./1.jpg", "./2.jpg", "./3.jpg", "./4.jpg", "./5.jpg"};
int init_dev(pass_data *s)
{
//s->fd = open (s->dev_name, O_RDWR | O_NONBLOCK, 0);
s->fd = open (s->dev_name, O_RDWR, 0);
if(s->fd < 0)
{
printf("open %s failed\n",s->dev_name);
exit(1);
}
struct v4l2_capability cap;
if(ioctl (s->fd, VIDIOC_QUERYCAP, &cap) < 0)
{
printf("get vidieo capability error,error code: %d \n", errno);
exit(1);
}
// Print capability infomations
printf("\nCapability Informations:\n");
printf("Driver Name:%s\nCard Name:%s\nBus info:%s\nDriver Version:%u.%u.%u\nCapabilities: X\n",
cap.driver,cap.card,cap.bus_info,
(cap.version>>16)&0XFF, (cap.version>>8)&0XFF,cap.version&0XFF,
cap.capabilities );
//获取设备支持的视频格式
struct v4l2_fmtdesc fmtdesc;
CLEAR (fmtdesc);
fmtdesc.index = 0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf("\nSupport format:\n");
while ((ioctl(s->fd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0)
{
printf("/t%d.\n{\npixelformat = '%c%c%c%c',\ndescription = '%s'\n }\n",
fmtdesc.index+1,
fmtdesc.pixelformat & 0xFF,
(fmtdesc.pixelformat >> 8) & 0xFF,
(fmtdesc.pixelformat >> 16) & 0xFF,
(fmtdesc.pixelformat >> 24) & 0xFF,
fmtdesc.description);
fmtdesc.index++;
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
{
fprintf (stderr, "%s is no video capture device\n", s->dev_name);
exit (EXIT_FAILURE);
}
///////////取景窗口缩放/有的摄像头不支持/////////////////////////////////////////////////////////////////////////
//检查是否支持某种帧格式
struct v4l2_format fmt2;
fmt2.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt2.fmt.pix.pixelformat = VIDEO_FORMAT;
if(ioctl(s->fd,VIDIOC_TRY_FMT,&fmt2)==-1)
if(errno==EINVAL)
printf("not support format %s!\n",VIDEO_FORMAT);
//设置视频捕获格式
///////////////////////////
//////////////////////////
struct v4l2_format fmt;
CLEAR (fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 320;
fmt.fmt.pix.height = 240;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
fmt.fmt.pix.pixelformat = VIDEO_FORMAT;
//设置图像格式
if(ioctl (s->fd, VIDIOC_S_FMT, &fmt) < 0)
{
printf("failture VIDIOC_S_FMT\n");
exit(1);
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// 显示当前帧的相关信息
struct v4l2_format fmt3;
fmt3.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl(s->fd,VIDIOC_G_FMT,&fmt3);
printf("\nCurrent data format information:\n twidth:%d\n theight:%d\n",
fmt3.fmt.pix.width,fmt3.fmt.pix.height);
struct v4l2_fmtdesc fmtdes;
fmtdes.index=0;
fmtdes.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
while(ioctl(s->fd,VIDIOC_ENUM_FMT,&fmtdes)!=-1)
{
if(fmtdes.pixelformat & fmt3.fmt.pix.pixelformat)
{
printf(" tformat:%s\n",fmtdes.description);
break;
}
fmtdes.index++;
}
///////////////////////////////////////////////////////////////////////
//视频分配捕获内存
struct v4l2_requestbuffers req;
CLEAR (req);
req.count = 5;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
//申请缓冲,count是申请的数量
if(ioctl (s->fd, VIDIOC_REQBUFS, &req) < 0)
{
printf("failture VIDIOC_REQBUFS\n");
exit(1);
}
if (req.count < 2)
printf("Insufficient buffer memory\n");
//内存中建立对应空间
//获取缓冲帧的地址、长度
//s->buffers = calloc (req.count, sizeof (*s->buffers));//在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针
s->buffers = (buffer *)calloc (req.count, sizeof (*s->buffers));
if (!s->buffers)
{
fprintf (stderr, "Out of memory/n");
exit (EXIT_FAILURE);
}
for (s->n_buffers = 0; s->n_buffers < req.count; ++s->n_buffers)
{
struct v4l2_buffer buf; //驱动中的一帧
CLEAR (buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = s->n_buffers;// 要获取内核视频缓冲区的信息编号
if (-1 == ioctl (s->fd, VIDIOC_QUERYBUF, &buf)) //映射用户空间
{
printf ("VIDIOC_QUERYBUF error\n");
exit(-1);
}
s->buffers[s->n_buffers].length = buf.length;
fprintf (stderr, "%d---------------/n",s->buffers[s->n_buffers].length);
// 把内核空间缓冲区映射到用户空间缓冲区
s->buffers[s->n_buffers].start = mmap (NULL , //通过mmap建立映射关系
buf.length,
PROT_READ | PROT_WRITE ,
MAP_SHARED ,
s->fd,
buf.m.offset);
if (MAP_FAILED == s->buffers[s->n_buffers].start)
{
printf ("mmap failed\n");
exit(1);
}
}
//投放一个空的视频缓冲区到视频缓冲区输入队列中
//把四个缓冲帧放入队列,并启动数据流
unsigned int i;
// 将缓冲帧放入队列
enum v4l2_buf_type type;
for (i = 0; i < s->n_buffers; ++i)
{
struct v4l2_buffer buf;
CLEAR (buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i; //指定要投放到视频输入队列中的内核空间视频缓冲区的编号;
if (-1 == ioctl (s->fd, VIDIOC_QBUF, &buf))//申请到的缓冲进入列队
printf ("VIDIOC_QBUF failed\n");
}
//开始捕捉图像数据
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == ioctl (s->fd, VIDIOC_STREAMON, &type))
{
printf ("VIDIOC_S
基于嵌入式LInux的人脸识别系统
需积分: 50 143 浏览量
2017-06-23
10:46:00
上传
评论 21
收藏 19KB RAR 举报
H_W_L_321
- 粉丝: 0
- 资源: 1
最新资源
- 老飞飞搭建基础通用数据库V19数据库.rar
- jquery.js
- 机械设计多工位ACF贴胶带&预压设备sw18可编辑非常好的设计图纸100%好用.zip
- 基于Pytorch复现Point-Transformer,用于ShapeNet数据集点云分割
- 【医学影像分析】2D超声图像的分割检测(Ultrasound Nerve Segmentation - Kaggle数据集)
- 嘎嘎香的五款神仙谷歌插件
- .arch书源导入教程.mp4
- 贪心算法介绍及代码示例讲解
- CR13SP35MSI64 Crystal 水晶报表运行组件最后版本64位
- 图像分类数据集:玉米叶是否感染分类数据集(2分类,包含训练集、验证集)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈