Test Program for obtaining a single image from a v4l2 camera (MMAP Mode)

Source: Internet
Author: User

# Added some notes

# Rockie Cheng

# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <assert. h>

# Include <getopt. h>

# Include <fcntl. h>
# 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>
# Include <Linux/videodev2.h>

# Define clear (x) memset (& (x), 0, sizeof (x ))

Struct buffer {
Void * start;
Size_t length;
};

Static char * dev_name = "/dev/video0"; // The Name Of The camera device.
Static int FD =-1;
Struct buffer * buffers = NULL;
Static unsigned int n_buffers = 0;

File * file_fd;
Static unsigned long file_length;
Static unsigned char * file_name;
//////////////////////////////////////// //////////////
// Obtain a frame of data
//////////////////////////////////////// //////////////
Static int read_frame (void)
{
Struct v4l2_buffer Buf;
Unsigned int I;

Clear (BUF );
Buf. type = v4l2_buf_type_video_capture;
Buf. Memory = v4l2_memory_mmap;

IOCTL (FD, vidioc_dqbuf, & BUF); // frame buffering for column-collected data

Assert (BUF. index <n_buffers );
Printf ("Buf. Index DQ is % d, \ n", Buf. Index );

Fwrite (buffers [Buf. Index]. Start, buffers [Buf. Index]. length, 1, file_fd); // write it to the file

IOCTL (FD, vidioc_qbuf, & BUF); // Add it to the column

Return 1;
}

Int main (INT argc, char ** argv)
{
Struct v4l2_capability cap;
Struct v4l2_format FMT;
Unsigned int I;
Enum v4l2_buf_type;

File_fd = fopen ("test-mmap.jpg", "W"); // Image File Name

FD = open (dev_name, o_rdwr/* required */| o_nonblock, 0); // open the device

IOCTL (FD, vidioc_querycap, & Cap); // obtain camera parameters

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;
IOCTL (FD, vidioc_s_fmt, & FMT); // sets the image format

File_length = FMT. FMT. pix. bytesperline * FMT. FMT. pix. height; // calculate the image size.

Struct v4l2_requestbuffers req;
Clear (req );
Req. Count = 4;
Req. type = v4l2_buf_type_video_capture;
Req. Memory = v4l2_memory_mmap;

IOCTL (FD, vidioc_reqbufs, & req); // Request Buffer. Count indicates the number of requests.

If (req. Count <2)
Printf ("insufficient buffer memory \ n ");

Buffers = calloc (req. Count, sizeof (* buffers); // create the corresponding space in the memory

For (n_buffers = 0; n_buffers <Req. Count; ++ n_buffers)
{
Struct v4l2_buffer Buf; // one frame in the driver
Clear (BUF );
Buf. type = v4l2_buf_type_video_capture;
Buf. Memory = v4l2_memory_mmap;
Buf. Index = n_buffers;

If (-1 = IOCTL (FD, vidioc_querybuf, & BUF) // map the user space
Printf ("vidioc_querybuf error \ n ");

Buffers [n_buffers]. Length = Buf. length;
Buffers [n_buffers]. Start =
MMAP (null/* start anywhere */, // establishes a ing through MMAP
Buf. length,
Prot_read | prot_write/* required */,
Map_shared/* Recommended */,
FD, Buf. M. offset );

If (map_failed = buffers [n_buffers]. Start)
Printf ("MMAP failed \ n ");
}

For (I = 0; I <n_buffers; ++ I)
{
Struct v4l2_buffer Buf;
Clear (BUF );

Buf. type = v4l2_buf_type_video_capture;
Buf. Memory = v4l2_memory_mmap;
Buf. Index = I;

If (-1 = IOCTL (FD, vidioc_qbuf, & BUF) // The requested buffer enters the queue
Printf ("vidioc_qbuf failed \ n ");
}

Type = v4l2_buf_type_video_capture;

If (-1 = IOCTL (FD, vidioc_streamon, & type) // start capturing image data
Printf ("vidioc_streamon failed \ n ");

For (;) // This section involves asynchronous Io
{
Fd_set FDS;
Struct timeval TV;
Int R;

Fd_zero (& FDs); // clears the specified file descriptor set
Fd_set (FD, & FDs); // Add a new file descriptor to the file descriptor set.

/* Timeout .*/
TV. TV _sec = 2;
TV. TV _usec = 0;

R = select (FD + 1, & FDS, null, null, & TV); // determines whether the camera is readable (that is, whether the camera is ready), and TV is timed

If (-1 = r ){
If (eintr = errno)
Continue;
Printf ("select err \ n ");
}
If (0 = r ){
Fprintf (stderr, "select timeout \ n ");
Exit (exit_failure );
}

If (read_frame () // if it is readable, execute the read_frame () function and exit the loop.
Break;
}

Unmap:
For (I = 0; I <n_buffers; ++ I)
If (-1 = munmap (buffers [I]. Start, buffers [I]. Length ))
Printf ("munmap error ");
Close (FD );
Fclose (file_fd );
Exit (exit_success );
Return 0;
}

This article from the Linux community website (www.linuxidc.com) original link: http://www.linuxidc.com/Linux/2011-03/33020.htm

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.