V4L2应用程序详解

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/*

* V4L2 video capture example

*

* This program can be used and distributed without restrictions.

*/

#include

#include

#include

#include

#include /* getopt_long() */

#include /* low-level i/o */

#include /*getpid()*/

#include

#include

#include

#include

#include

#include

#include

#include

#include /* for videodev2.h */

#include

#define CLEAR(x) memset(&(x), 0, sizeof (x))

typedef enum {

IO_METHOD_READ,

IO_METHOD_MMAP,

IO_METHOD_USERPTR,

} io_method;

struct buffer {

void *start;

size_t length;

};

static char * dev_name = NULL;

static io_method io = IO_METHOD_MMAP; static int fd = -1;

struct buffer * buffers = NULL;

static unsigned int n_buffers = 0;

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)

{

FILE* fp;

fp = fopen("test","w+"); //w+:打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

fputs(p, fp); //成功,返回一个非负整数;出错,返回EOF。fputs(const char *s,FILE *stream)作用:向指定文件写入一个字符串,缓冲区S中保存的是以‘/0’结尾的字符串,fputs将该字符串写入stream,但不写入结尾的’/0’。

fclose(fp);

// fflush(stdout); // fflush(stdout):清空输出缓冲区,并把缓冲区内容输出

}

static int read_frame(void)//用来读取一帧数据

{

struct v4l2_buffer buf;

unsigned int i;

switch (io)

{

case IO_METHOD_READ:

if (-1 == read(fd, buffers[0].start, buffers[0].length))

{

switch (errno)

{

case EAGAIN: //当使用不可阻断(O_NONBLOCK)打开文件后,read呼叫无可读取的数据

return 0;

case EIO: //设备文件读取文件时发生输出输入错误

/* Could ignore EIO, see spec. */

/* fall through */

default:

errno_exit("read");

}

}

process_image(buffers[0].start); //保存读到的数据

break;

/* V4L2有一个数据缓存,存放req.count数量的缓存数据。数据缓存采用FIFO的方式,当应用程序调用缓存数据时,缓存队列将最先采集到的视频数据缓存送出,并重新采集一张视频数据。这个过程需要用到两个ioctl命令,VIDIOC_DQBUF和VIDIOC_QBUF*/ case IO_METHOD_MMAP:

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:

/* Could ignore EIO, see spec. */

/* fall through */

default:

errno_exit("VIDIOC_DQBUF");

}

}

assert(buf.index < n_buffers); //assert的作用是计算括号内的表达式,如果其值为0,就先向stderr打印一条出错信息,然后通过abort来终止程序运行

process_image(buffers[buf.index].start);

if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) //重新放入缓存队列

errno_exit("VIDIOC_QBUF");

break;

case IO_METHOD_USERPTR:

CLEAR(buf);

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

buf.memory = V4L2_MEMORY_USERPTR;

if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf))

{

switch (errno)

相关文档
最新文档