With Ubuntu want to write code, at any time to observe the state behind their own, with cheese do the video is too obvious, but also have to move the mouse, to write a camera with the tool to take pictures. It should be easiest to use V4L2.
header files, including Mem,dev and IOCTL-related header files
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ Mman.h>
#include <linux/videodev2.h>
Define a structure that is easy to pass
struct buffer
{
void* start;
unsigned int length;
};
All the function definitions:
int main () {file* fp;
int fd_video;
struct buffer *buffers;
Turn on the camera device Fd_video = open ("/dev/video0", O_RDWR);
if (Fd_video < 0) {perror ("video capture Open");
return fd_video;
} fp = fopen ("/root/test.jpg", "wb+");
if (FP < 0) {perror ("FB open error.");
return-1;
}//Print supported video formats for struct V4L2_FMTDESC fmtdesc;
fmtdesc.index=0;
Fmtdesc.type=v4l2_buf_type_video_capture;
printf ("Support format:\n"); while (IOCTL (Fd_video, VIDIOC_ENUM_FMT, &fmtdesc)! =-1) {printf ("\t%d.%s, fmtdesc:%d\n", Fmtdesc.index+1,
Fmtdesc.description,fmtdesc.pixelformat);
fmtdesc.index++;
}//Set the format of the video, 720P JPEG struct V4l2_format s_fmt;
S_fmt.fmt.pix.width = 1280;
S_fmt.fmt.pix.height = 720;
S_fmt.fmt.pix.pixelformat = V4l2_pix_fmt_mjpeg;
printf ("s_fmt.fmt.pix.pixelformat:%d\n", S_fmt.fmt.pix.pixelformat);
S_fmt.type = v4l2_buf_type_video_capture;
int flag= IOCTL (FD_VIDEO,VIDIOC_S_FMT,&S_FMT);
if (flag! = 0) {printf ("Set format error\n");
return-1; } priNTF ("jpeg:%d%d\n", s_fmt.fmt.pix.width,s_fmt.fmt.pix.height);
Apply 1 buffers of struct v4l2_requestbuffers req;
Req.count=1;
Req.type=v4l2_buf_type_video_capture;
Req.memory=v4l2_memory_mmap;
IOCTL (FD_VIDEO,VIDIOC_REQBUFS,&REQ);
Buffer associated with application//application 1 struct buffer space buffers = (struct buffer*) calloc (req.count, sizeof (struct buffer));
if (!buffers) {perror ("Out of Memory");
Exit (Exit_failure);
} unsigned int n_buffers;
for (n_buffers = 0; n_buffers < Req.count; n_buffers++) {struct V4l2_buffer buf;
memset (&buf,0,sizeof (BUF));
Buf.type = v4l2_buf_type_video_capture;
Buf.memory = V4l2_memory_mmap;
Buf.index = n_buffers;
if ( -1 = = IOCTL (Fd_video, Vidioc_querybuf, &buf)) exit (-1);
Buffers[n_buffers].length = Buf.length; Buffers[n_buffers].start = Mmap (NULL, Buf.length,prot_read |
Prot_write, Map_shared,fd_video, Buf.m.offset);
if (map_failed = = Buffers[n_buffers].start) exit (-1);
} enum V4l2_buf_type type; for (n_buffers = 0; n_buffers < Req.count;
n_buffers++) {struct V4l2_buffer buf;
Buf.type = v4l2_buf_type_video_capture;
Buf.memory = V4l2_memory_mmap;
Buf.index = n_buffers;
IOCTL (Fd_video, Vidioc_qbuf, &buf);
}//Start capturing image type = V4l2_buf_type_video_capture;
IOCTL (Fd_video, Vidioc_streamon, &type);
struct V4l2_buffer buf;
memset (& (BUF), 0, sizeof (BUF));
Buf.type = v4l2_buf_type_video_capture;
Buf.memory = V4l2_memory_mmap;
Remove image Data ioctl (Fd_video, Vidioc_dqbuf, &buf);
Save Image Fwrite (BUFFERS[BUF.INDEX].START,1,BUFFERS[BUF.INDEX].LENGTH,FP);//mjpeg fflush (FP);
Put back the buffer ioctl (FD_VIDEO,VIDIOC_QBUF,&BUF);
for (n_buffers = 0; n_buffers < req.count; n_buffers++) Munmap (Buffers[n_buffers].start, buffers[n_buffers].length);
Free (buffers);
Close (Fd_video);
Fclose (FP); printf ("Capture jpg finish.
\ n ");
System ("Eog-w/root/test.jpg &"); }
Description
Turn on the camera and picture
Fd_video = open ("/dev/video0", O_RDWR);
fp = fopen ("/root/test.jpg", "wb+");
Query webcam supported formats, my computer supports YUYV and MJPEG
IOCTL (Fd_video, VIDIOC_ENUM_FMT, &fmtdesc)
Set the format of the camera shot, the size is 720P, the format is MJPEG
IOCTL (FD_VIDEO,VIDIOC_S_FMT,&S_FMT)
Request buffer, a picture will need a frame of buffer
IOCTL (FD_VIDEO,VIDIOC_REQBUFS,&REQ);
Using Calloc is to apply for multiple buffers, here to apply for 1 buffers, like malloc, here is the camera based on the change, with calloc will not change.
buffers = (struct buffer*) calloc (req.count, sizeof (struct buffer));
The purpose of mapping memory with MMAP is to eliminate the expense of memcpy, more reasonable
Buffers[n_buffers].start = Mmap (NULL,
buf.length,prot_read | Prot_write, Map_shared,fd_video, Buf.m.offset);
Set the buffer and put it back in the buffer
IOCTL (Fd_video, VIDIOC_QBUF, &buf)
Start capturing images
IOCTL (Fd_video, Vidioc_streamon, &type)
Remove a frame of data from the buffer
IOCTL (Fd_video, VIDIOC_DQBUF, &buf)
Take the data and put it back in the buffer
IOCTL (Fd_video, VIDIOC_QBUF, &buf)
After releasing the resources, we will not repeat them.
The JPG is displayed by the eye of Gnome.
System ("Eog-w/root/test.jpg &");