v4l2的应用程序编写

来源:互联网 发布:正规的淘宝兼职网站 编辑:程序博客网 时间:2024/05/15 06:12
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/videodev2.h>
#include <linux/ioctl.h>
/*#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
#define VIDIO_G_FMT _IOWR('V', 4, struct v4l2_format)
#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers)
#define VIDIOC_G_FBUF _IOW('V', 10, struct v4l2_buffersfer)
#define VIDIOC_S_BUF _IOW('V', 11, struct v4l2_buffersfer)
#define VIDIOC_OVERLAY _IOW('V', 14, int)
#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
#define VIDIOC_DQBUF _IOWR('V', 17, strut v4l2_buffer)
#define VIDIOC_STREAMON _IOW('V', 18, int)
#define VIDIOC_STREAMOFF _IOW('V', 19, int)
#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
*/
#define COUNT 1
#define CAPTURE_FILE "frame.jpg"
struct v4l2_capability cap;

struct v4l2_requestbuffers req;
typedef struct VideoBuffer { char * start; size_t length; } VideoBuffer;
int main(void){
char *dev_name="/dev/video0";
int fd=0;
int ret=0;


//fd=open(dev_name, O_RDWR|O_NONBLOCK, 0);
fd=open(dev_name, O_RDWR, 0);

ret=ioctl(fd,_IOR('V', 0, struct v4l2_capability) ,&cap);  
if (ret < 0) {  
        perror("VIDIOC_QUERYCAP failed ");  
        return ret;  
    }  
printf("%d\n",fd);
printf("\n****Capability informations****\n");  
    printf("driver:   %s\n", cap.driver);  
      
    if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)  
        printf("Capture capability is supported\n");  
 
    if (cap.capabilities & V4L2_CAP_STREAMING)   
        printf("Streaming capability is supported\n");  
          
    if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)   
        printf("Overlay capability is supported\n");  


    struct v4l2_format fmt;  
    memset(&fmt,0,sizeof(fmt));  
    fmt.type            =   V4L2_BUF_TYPE_VIDEO_CAPTURE;  
    fmt.fmt.pix.width   =   640;  
    fmt.fmt.pix.height  =   480;  
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;//for PAL   
    fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;  
      
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);  
    if (ret < 0) {  
        perror("VIDIOC_S_FMT");  
        return ret;  
    }



//struct v4l2_buffer * buffers=0;
    int n_buffers=0;
    memset(&req, 0, sizeof (req));
    req.count = COUNT;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;

    ret=ioctl(fd,VIDIOC_REQBUFS,&req);
    if (ret == -1)
    {

     perror("VIDIOC_REQBUFS error n");

     //return -1;

    }




    if (req.count < 2)  
        printf("insufficient buffer memory\n");  
        printf("Number of buffers allocated = %d\n", req.count);  
          
    /*******step 2*****Getting Physical Address  *******/  
     VideoBuffer * buffers =calloc(req.count, sizeof(*buffers));  
    

    struct v4l2_buffer buf;//......   
    for ( n_buffers = 0; n_buffers < req.count; ++n_buffers)  
    {  
        memset(&buf,0,sizeof(buf));  
        buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
        buf.memory  = V4L2_MEMORY_MMAP;  
        buf.index   = n_buffers;  
          
        ret = ioctl(fd, VIDIOC_QUERYBUF, &buf);  
        if (ret < 0) {  
            perror("VIDIOC_QUERYBUF");  
            return ret;  
        }  
    /*******step 3*****Mapping Kernel Space Address to User Space*******/  
        buffers[n_buffers].length = buf.length;  
        buffers[n_buffers].start=   (char*)
        mmap(NULL,  
            buf.length,  
            PROT_READ | PROT_WRITE,  
            MAP_SHARED,  
            fd,  
            buf.m.offset);  
              
        if (MAP_FAILED == buffers[n_buffers].start)   
        perror("mmap failed n");   
        ret = ioctl(fd , VIDIOC_QBUF, &buf);
        if (ret < 0) {
           printf("VIDIOC_QBUF (%d) failed (%d)\n", n_buffers, ret);
           return -1;
        }
        printf("Frame buffer %d: address=0x%x, length=%d\n", n_buffers, (unsigned int)buffers[n_buffers].start, buffers[n_buffers].length);

     }  
/************requestbuffers in queue***********/  
        /*
         int i=0;    
          //struct v4l2_buffer buf;  
        //for (i = 0; i < n_buffers; ++i) {  
          
        memset(&buf,0,sizeof(buf));  
        buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
        buf.memory  = V4L2_MEMORY_MMAP;  
        buf.index = i;  
          
        ret = ioctl(fd, VIDIOC_QBUF, &buf);//.........   
        if (ret < 0) {  
            perror("VIDIOC_QBUF");  
            return ret;  
            }     
          }  

    */
    /************start stream on***********/  
 
      enum v4l2_buf_type types;//........   
      types = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
      ret = ioctl(fd, VIDIOC_STREAMON, &types);  
      if (ret < 0) {  
        perror("VIDIOC_STREAMON");  
        return ret;  
       }
      // Get frame
        ret = ioctl(fd, VIDIOC_DQBUF, &buf);
        if (ret < 0) {
            printf("VIDIOC_DQBUF failed (%d)\n", ret);
            return ret;
        }

        // Process the frame
        FILE *fp = fopen(CAPTURE_FILE, "wb");
        if (fp < 0) {
            printf("open frame data file failed\n");
            return -1;
        }
        fwrite(buffers[buf.index].start, 1, buf.length, fp);
        printf("buff.index=%d\n",buf.index);        
        fclose(fp);
        printf("Capture one frame saved in %s\n", CAPTURE_FILE);

        // Re-queen buffer
        ret = ioctl(fd, VIDIOC_QBUF, &buf);
        if (ret < 0) {
            printf("VIDIOC_QBUF failed (%d)\n", ret);
            return ret;
        }

        // Release the resource
        
           int i=0;
           for ( i=0; i< COUNT; i++)
        {
            munmap(buffers[i].start, buffers[i].length);
        }

        close(fd);
        printf("Camera test Done.\n");
     return 0;




}

原创粉丝点击