Ãâ·Ñ×¢²á ²é¿´ÐÂÌû |

Chinaunix

  ƽ̨ ÂÛ̳ ²©¿Í ÎÄ¿â
×î½ü·ÃÎÊ°å¿é ·¢ÐÂÌû
²é¿´: 2153 | »Ø¸´: 0
´òÓ¡ ÉÏÒ»Ö÷Ìâ ÏÂÒ»Ö÷Ìâ

[ͼÐνçÃæ] v4l2 ץȡһ֡ͼÏñ [¸´ÖÆÁ´½Ó]

ÂÛ̳»ÕÕÂ:
0
Ìøתµ½Ö¸¶¨Â¥²ã
1Â¥ [ÊÕ²Ø(0)] [±¨¸æ]
·¢±íÓÚ 2014-03-04 17:56 |Ö»¿´¸Ã×÷Õß |µ¹Ðòä¯ÀÀ
±¾Ìû×îºóÓÉ zuoertu ÓÚ 2014-03-04 18:00 ±à¼­

v4l2ץȡһ֡ͼÏñµÄ³ÌÐò

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/select.h>


#include <linux/videodev2.h>

static char *dev_name = "/dev/video0";

struct buffer {
        void *start;
        size_t length;
};

struct buffer *buffers = NULL;
static unsigned int n_buffers = 0;

int main(int argc, char **argv)
{
        int fd;
        int ret;

        //É豸µÄ´ò¿ª
        fd = open(dev_name, O_RDWR | O_NONBLOCK);
        if (fd < 0) {
                fprintf(stderr, "can not open /dev/video1\n");
                return -1;
        }
        printf("open %s success\n", dev_name);

        // ²éѯÉ豸ÊôÐÔ£º VIDIOC_QUERYCAP
        struct v4l2_capability cap;
        memset(&cap, 0, sizeof(cap));
        ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
        if (ret < 0) {
                fprintf(stderr, "ioctl querycap error\n");
                return -1;
        } else {
                printf("Capability Informations:\n");
                printf("\t%-15s = %s\n", "cap.driver", cap.driver);
                printf("\t%-15s = %s\n", "cap.card", cap.card);
                printf("\t%-15s = %s\n", "cap.bus_info", cap.bus_info);
                printf("\t%-15s = 0x%x\n", "cap.version", cap.version);
        }

        /*===============select input device==================*/
        //struct v4l2_input input;
        //      memset(&input, 0, sizeof(input));
        //      while (ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0) {
        //              printf("\ncmd VIDIOC_ENUMINPUT:\n");
        //              printf(" %-15s = %u\n", "input.index", input.index);
        //              printf(" %-15s = %s\n", "input.name", input.name);
        //              printf(" %-15s = %u\n", "input.type", input.type);
        //              printf(" %-15s = %u\n", "input.audioset", input.audioset);
        //              printf(" %-15s = %u\n", "input.tuner", input.tuner);
        //              //printf("%-15s = %lu\n", "input.std", input.std);
        //              printf(" input.index = %d\n", input.index);
        //              input.index++;
        //      }

        //²éѯ²¢ÏÔʾËùÓÐÖ§³ÖµÄ¸ñʽ£ºVIDIOC_ENUM_FMT
        struct v4l2_fmtdesc fmtdesc;
        memset(&fmtdesc, 0, sizeof(fmtdesc));
        fmtdesc.index = 0;
        fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        printf("Support format:\n");

        while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1) {
                printf("\t%d.%s\n", fmtdesc.index + 1, fmtdesc.description) ;
                fmtdesc.index++;
        }

        //²é¿´»òÉèÖõ±Ç°¸ñʽ£º VIDIOC_G_FMT, VIDIOC_S_FMT
        printf("Set Format\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_MJPEG;
        //fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
        fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
        ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
        if (ret < 0) {
                fprintf(stderr, "ioctl VIDIOC_S_FMT error\n") ;
                return -1;
        }

        ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
        if (ret < 0) {
                fprintf(stderr, "get format failed\n") ;
        }

        printf("Stream Format Informations:\n");
        printf("\t%-15s= %d\n", "type", fmt.type);
        printf("\t%-15s= %d\n", "width", fmt.fmt.pix.width);
        printf("\t%-15s= %d\n", "height", fmt.fmt.pix.height);
        char fmtstr[8];
        memset(fmtstr, 0, 8);
        memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4);
        printf("\t%-15s= %s\n", "pixelformat", fmtstr);
        printf("\t%-15s= %d\n", "field", fmt.fmt.pix.field);
        printf("\t%-15s= %d\n", "bytesperline", fmt.fmt.pix.bytesperline);
        printf("\t%-15s= %d\n", "sizeimage", fmt.fmt.pix.sizeimage);
        printf("\t%-15s= %d\n", "colorspace", fmt.fmt.pix.colorspace);
        printf("\t%-15s= %d\n", "priv", fmt.fmt.pix.priv);
        //printf(" raw_date: %s\n", fmt.fmt.raw_data);

        //ÉêÇëºÍ¹ÜÀí»º³åÇø
        //ÏòÉ豸ÉêÇ뻺³åÇø VIDIOC_REQBUFS
        struct v4l2_requestbuffers req;
        memset(&req, 0, sizeof(req));
        req.count = 4;
        req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        req.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(fd, VIDIOC_REQBUFS, &req);        //ÉêÇëÒ»¸öÓµÓÐËĸö»º³åÖ¡µÄ»º³åÇø
        if (ret < 0) {
                fprintf(stderr, "ioctl VIDIOC_REQBUFS error\n");
                return -1;
        }

        //½«ËĸöÒÑÉêÇëµ½µÄ»º³åÖ¡Ó³Éäµ½Ó¦ÓóÌÐò£¬ÓÃbuffers Ö¸Õë¼Ç¼
        buffers = calloc(req.count, sizeof(*buffers));        //ÄÚ´æÖн¨Á¢¶ÔÓ¦¿Õ¼ä
        if (!buffers) {
                fprintf(stderr, "Out of memory\n");
                return 0;
        }

        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;
                //²éѯÐòºÅΪn_buffers µÄ»º³åÇø£¬µÃµ½ÆäÆðʼÎïÀíµØÖ·ºÍ´óС
                if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) {
                        printf("ioctl VIDIOC_QUERYBUF failed\n");
                        return -1;
                }
                printf("buf.length = %d\n", buf.length);
                buffers[n_buffers].length = buf.length;

                //Ó³ÉäÄÚ´æ
                buffers[n_buffers].start =
                    mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED,
                         fd, buf.m.offset);
                if (MAP_FAILED == buffers[n_buffers].start)
                        printf("map buffers failed\n");

//                //°ÑËĸö»º³åÖ¡·ÅÈë¶ÓÁÐ
//                if (ioctl(fd, VIDIOC_QBUF, &buf) < 0)
//                        printf("ioctl VIDIOC_QBUF failed\n");
        }


        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;
                if (ioctl(fd, VIDIOC_QBUF, &buf) < 0)
                        printf("ioctl VIDIOC_QBUF failed\n");
        }

        //»º³åÇø´¦ÀíºÃÖ®ºó£¬¾Í¿ÉÒÔ¿ªÊ¼»ñÈ¡Êý¾ÝÁË
        //Æô¶¯ »ò Í£Ö¹Êý¾ÝÁ÷ VIDIOC_STREAMON£¬ VIDIOC_STREAMOFF
        enum v4l2_buf_type type;
        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        ret = ioctl(fd, VIDIOC_STREAMON, &type);
        if (ret < 0)
                printf("ioctl VIDIOC_STREAMON failed\n");

        fd_set fds;
        struct timeval tv;
        FD_ZERO(&fds);
        FD_SET(fd, &fds);
        tv.tv_sec = 2;
        tv.tv_usec = 0;
        ret = select(fd + 1, &fds, NULL, NULL, &tv);
        if (-1 == ret) {
                if (EINTR == errno)
                printf("fail to select\n");
        }
        if (0 == ret) {
                fprintf(stderr, "select Timeout\n");
        }

        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        //È¡³öÒ»Ö¡
        ret = ioctl(fd, VIDIOC_DQBUF, &buf);
        if (ret < 0)
                printf("ioctl VIDIOC_DQBUF\n");

        //´¦ÀíÒ»Ö¡
        FILE *file_fd;
        file_fd = fopen("frame.jpg", "w");
        if (file_fd < 0)
                printf("create file failed\n");

        fwrite(buffers[buf.index].start, 1, buffers[buf.index].length, file_fd);
        printf("buffers[buf.index].length = %d\n", buffers[buf.index].length);
        usleep(500);
        fclose(file_fd);

        if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
                return -1;
        }

        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
        if (ret < 0)
                printf("ioctl VIDIOC_STREAMOFF failed\n");

        for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
                munmap(buffers[n_buffers].start, buffers[n_buffers].length);
        }
        free(buffers);

        close(fd);
        return 0;
}




ÉÏÃæµÄ³ÌÐòÊÇusbcamera ÔÚlinuxץȡһ֡ͼÏñµÄ³ÌÐò£¬ ³ÌÐòÖÐselect£¨£©º¯ÊýµÄ×÷ÓÃÊÇʲô£¬ Ϊʲôȥµôselect£¨£©×¥È¡µÄÊý¾Ý¾Í²»ÕýÈ·¡£
ÄúÐèÒªµÇ¼ºó²Å¿ÉÒÔ»ØÌû µÇ¼ | ×¢²á

±¾°æ»ý·Ö¹æÔò ·¢±í»Ø¸´

  

±±¾©Ê¢ÍØÓÅѶÐÅÏ¢¼¼ÊõÓÐÏÞ¹«Ë¾. °æȨËùÓÐ ¾©ICP±¸16024965ºÅ-6 ±±¾©Êй«°²¾Öº£µí·Ö¾ÖÍø¼àÖÐÐı¸°¸±àºÅ£º11010802020122 niuxiaotong@pcpop.com 17352615567
δ³ÉÄê¾Ù±¨×¨Çø
Öйú»¥ÁªÍøЭ»á»áÔ±  ÁªÏµÎÒÃÇ£ºhuangweiwei@itpub.net
¸ÐлËùÓйØÐĺÍÖ§³Ö¹ýChinaUnixµÄÅóÓÑÃÇ ×ªÔر¾Õ¾ÄÚÈÝÇë×¢Ã÷Ô­×÷ÕßÃû¼°³ö´¦

Çå³ý Cookies - ChinaUnix - Archiver - WAP - TOP