⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_capture_example.cpp

📁 Linux下视频捕捉的例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      CLEAR (req);
      req.count = 4;
      req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      req.memory = V4L2_MEMORY_MMAP;
      if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
        if (EINVAL == errno) {
          fprintf (stderr, "%s does not support memory mapping\n", dev_name);
          exit (EXIT_FAILURE);
        } else {
          errno_exit ("VIDIOC_REQBUFS");
        }
      }
      if (req.count < 2) {
        fprintf (stderr, "Insufficient buffer memory on %s\n",dev_name);
        exit (EXIT_FAILURE);
      }
      buffers = calloc (req.count, sizeof (*buffers));
      if (!buffers) {
        fprintf (stderr, "Out of memory\n");
        exit (EXIT_FAILURE);
      }
      for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
        struct v4l2_buffer buf;
        CLEAR (buf);
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = n_buffers;
        if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf))
          errno_exit ("VIDIOC_QUERYBUF");
          buffers[n_buffers].length = buf.length;
          buffers[n_buffers].start = mmap (NULL /* start anywhere */,
                                           buf.length,
                                           PROT_READ | PROT_WRITE /* required */,
                                           MAP_SHARED /* recommended */,
                                           fd, buf.m.offset);
          if (MAP_FAILED == buffers[n_buffers].start)
            errno_exit ("mmap");
      }
}

static void
init_userp (unsigned int buffer_size)
{
      struct v4l2_requestbuffers req;
      unsigned int page_size;
      page_size = getpagesize ();
      buffer_size = (buffer_size + page_size - 1) & ~(page_size - 1);
      CLEAR (req);
      req.count = 4;
      req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      req.memory = V4L2_MEMORY_USERPTR;
      if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
        if (EINVAL == errno) {
          fprintf (stderr, "%s does not support user pointer i/o\n", dev_name);
          exit (EXIT_FAILURE);
        } else {
          errno_exit ("VIDIOC_REQBUFS");
        }
      }
      buffers = calloc (4, sizeof (*buffers));
      if (!buffers) {
        fprintf (stderr, "Out of memory\n");
        exit (EXIT_FAILURE);
      }
      for (n_buffers = 0; n_buffers < 4; ++n_buffers) {
        buffers[n_buffers].length = buffer_size;
        buffers[n_buffers].start = memalign (/* boundary */ page_size,
        buffer_size);
        if (!buffers[n_buffers].start) {
          fprintf (stderr, "Out of memory\n");
          exit (EXIT_FAILURE);
        }
      }
}

static void
init_device (void)
{
      struct v4l2_capability cap;
      struct v4l2_cropcap cropcap;
      struct v4l2_crop crop;
      struct v4l2_format fmt;
      unsigned int min;
      if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) {
        if (EINVAL == errno) {
          fprintf (stderr, "%s is no V4L2 device\n",dev_name);
          exit (EXIT_FAILURE);
        } else {
          errno_exit ("VIDIOC_QUERYCAP");
        }
      }
      if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        fprintf (stderr, "%s is no video capture device\n",dev_name);
        exit (EXIT_FAILURE);
      }
      switch (io) {
        case IO_METHOD_READ:
          if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
            fprintf (stderr, "%s does not support read i/o\n",dev_name);
            exit (EXIT_FAILURE);
          }
          break;
        case IO_METHOD_MMAP:
        case IO_METHOD_USERPTR:
          if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
            fprintf (stderr, "%s does not support streaming i/o\n",dev_name);
            exit (EXIT_FAILURE);
          }
          break;
      }
      /* Select video input, video standard and tune here. */
      CLEAR (cropcap);
      cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
        crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        crop.c = cropcap.defrect; /* reset to default */
        if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) {
          switch (errno) {
            case EINVAL:
              /* Cropping not supported. */
              break;
            default:
              /* Errors ignored. */
              break;
          }
        }
      } else {
      /* Errors ignored. */
      }
      CLEAR (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_YUYV;
      fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
      if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt))
        errno_exit ("VIDIOC_S_FMT");
      /* Note VIDIOC_S_FMT may change width and height. */
      /* Buggy driver paranoia. */
      min = fmt.fmt.pix.width * 2;
      if (fmt.fmt.pix.bytesperline < min)
        fmt.fmt.pix.bytesperline = min;
      min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
      if (fmt.fmt.pix.sizeimage < min)
        fmt.fmt.pix.sizeimage = min;
      switch (io) {
        case IO_METHOD_READ:
          init_read (fmt.fmt.pix.sizeimage);
          break;
        case IO_METHOD_MMAP:
          init_mmap ();
          break;
        case IO_METHOD_USERPTR:
          init_userp (fmt.fmt.pix.sizeimage);
          break;
      }
}

static void
close_device (void)
{
      if (-1 == close (fd))
        errno_exit ("close");
      fd = -1;
}

static void
open_device (void)
{
      struct stat st;
      if (-1 == stat (dev_name, &st)) {
        fprintf (stderr, "Cannot identify ’%s’: %d, %s\n",dev_name, errno, strerror (errno));
        exit (EXIT_FAILURE);
      }
      if (!S_ISCHR (st.st_mode)) {
        fprintf (stderr, "%s is no device\n", dev_name);
        exit (EXIT_FAILURE);
      }
      fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
      if (-1 == fd) {
        fprintf (stderr, "Cannot open ’%s’: %d, %s\n",dev_name, errno, strerror (errno));
        exit (EXIT_FAILURE);
      }
}

static void
usage (FILE * fp,
       int argc,
       char ** argv)
{
      fprintf (fp,
              "Usage: %s [options]\n\n"
              "Options:\n"
              "-d  | --device name Video device name [/dev/video]\n"
              "-h  | --help Print this message\n"
              "-m | --mmap Use memory mapped buffers\n"
              "-r   | --read Use read() calls\n"
              "-u  | --userp Use application allocated buffers\n"
              "",
              argv[0]);
}

static const char short_options [] = "d:hmru";
static const struct option
long_options [] = {
                  { "device", required_argument, NULL, ’d’ },
                  { "help", no_argument, NULL, ’h’ },
                  { "mmap", no_argument, NULL, ’m’ },
                  { "read", no_argument, NULL, ’r’ },
                  { "userp", no_argument, NULL, ’u’ },
                  { 0, 0, 0, 0 }
                  };
int
main (int argc,
      char ** argv)
{
      dev_name = "/dev/video";
      for (;;) {
        int index;
        int c;
        c = getopt_long (argc, argv,
                         short_options, long_options,
                         &index);
        if (-1 == c)
          break;
        switch (c) {
          case 0: /* getopt_long() flag */
            break;
          case ’d’:
            dev_name = optarg;
            break;
          case ’h’:
            usage (stdout, argc, argv);
            exit (EXIT_SUCCESS);
          case ’m’:
            io = IO_METHOD_MMAP;
            break;
          case ’r’:
            io = IO_METHOD_READ;
            break;
          case ’u’:
            io = IO_METHOD_USERPTR;
            break;
          default:
            usage (stderr, argc, argv);
            exit (EXIT_FAILURE);
        }
      }
      open_device ();
      init_device ();
      start_capturing ();
      mainloop ();
      stop_capturing ();
      uninit_device ();
      close_device ();
      exit (EXIT_SUCCESS);
      return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -