V4L2驱动的移植与应用(三)

三、V4L2demo

capture.c是官方示例程序。

capture.c 程序中的 process_image 函数:

       capture.c 程序主要是用来演示怎样使用 v4l2 接口,并没有对采集到的视频帧数据做任何实际的处理,仅仅用 process_image 函数表示了处理图像的代码位置。

       process_image 函数只有一个参数,就是存储视频帧的内存的地址指针,但是在真正的应用中,通常还需要知道该指针指向的数据的大小。

       因此可以修改函数,改成 void process_image ( const void * p, int len ) ,但是每次调用 process_image 的时候,第 2 个参数该传递什么值? 

考虑到程序中对 buffer 的定义

  struct buffer {

  void * start;

  size_t length};  

       如果将 buffer.length 作为第 2 个参数传递到修改后的 process_image 函数中,这样做是不正确的。 process_image 需要的第二个参数应该是每帧图像的大小,仔细阅读代码后会发现, buffer.length 并不一定就等于图像帧的大小。 (buffer 的大小,还需要考虑其他的一些因素,比如内存对齐等 )

capture.c只是一个示例程序,仅仅是演示怎样使用v4l2中最基本的接口。尤其是在main函数中的那几个函数调用,表明了在使用v4l2时的最基本的一个流程,包括 open_deviceinit_devicestart_capturingmainloopstop_capturinguninit_deviceclose_device。在写程序的时候,可以充分的利用这几个基本模块,把他们分散在不同的代码位置上,灵活的调用,有兴趣的可以看一下gstreamerv4l2src的源代码或者其他的大型程序的相关部分。

总之一句话,capture.c仅仅是一个演示程序,不要局限于它的代码结构,要灵活的使用。

       下面是capture.c的源代码:

 

#include <stdio.h>  

#include <stdlib.h>  

#include <string.h>  

#include <assert.h>  

#include <getopt.h>             /* getopt_long() */  

#include <fcntl.h>              /* low-level i/o */  

#include <unistd.h>  

#include <errno.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 <asm/types.h>          /* for videodev2.h */  

#include <linux/videodev2.h>  

#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;//buffer's length is different from cap_image_size  

};  

static char * dev_name = NULL;  

static io_method io = IO_METHOD_MMAP;//IO_METHOD_READ;//IO_METHOD_MMAP;  

static int fd = -1;  

struct buffer * buffers = NULL;  

static unsigned int n_buffers = 0;  

static FILE * outf = 0;  

static unsigned int cap_image_size = 0;//to keep the real image size!!  

//  

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 len) {  

    //  static char[115200] Outbuff ;  

    fputc('.', stdout);  

    if (len > 0) {  

        fputc('.', stdout);  

        fwrite(p, 1, len, outf);  

    }  

    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) {  

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值