Use a series of IOCTL commands to control devices. V4l supports more than 20 IOCTL commands.
Simple image capturing program. Let's take a look at several major commands:
1. IOCTL (FD, vidiocgcap, & Cap );
This command is used to obtain the function information of the video card. For example, the name, type, and channel of the TV card. The CAP parameter is a structure. When the ioctl command returns the value, the members of the structure are assigned a value. The struct is defined:
Struct video_capability
{
Char name [32];
Int type;
Int channels;/* num channels */
Int audios;/* num audio devices */
Int maxwidth;/* supported width */
Int maxheight;/* and height */
Int minwidth;/* supported width */
Int minheight;/* and height */
};
Channel refers to several signal input sources, such as television, composite, and s-video.
2. IOCTL (FD, vidiocgchan, & Vc)
3. IOCTL (FD, vidiocschan. & Vc)
These two commands are used to obtain and set the channel information of the video card, such as the input source and standard.
VC is a video_channel structure, which is defined:
Struct video_capability
{
Char name [32];
Int type;
Int channels;/* num channels */
Int audios;/* num audio devices */
Int maxwidth;/* supported width */
Int maxheight;/* and height */
Int minwidth;/* supported width */
Int minheight;/* and height */
};
Struct video_channel
{
Int channel;
Char name [32];
Int tuners; // Number of Tuners for this input
_ U32 flags;
_ 2010type;
_ 2010norm;
};
The member channel represents the input source. Generally,
0: Television 1: composite1 2: S-video
Name indicates the name of the Input Source.
Norm indicates the standard. Generally,
0: Pal 1: NTSC 2: SECAM 3: Auto
4. IOCTL (FD, vidiocgmbuf, * mbuf)
Obtain the video card cache information. The parameter mbuf is the video_mbuf structure. It is defined as follows:
Struct video_mbuf
{
Int size;/* total memory to map */
Int frames;/* frames */
Int offsets [video_max_frame];
};
Size indicates the cache size. Frames indicates the number of frames that the video card cache can accommodate, and array offsets indicates
Corresponding to the starting position of a frame, 0 corresponding to offsets [0], 1 corresponding to offsets [1]...
After executing this command, you can use the MMAP function to map the cache to the memory. For general usage, refer to the following generation
Code
Struct video_mbuf mbuf;
Unsigned char * buf1, * buf2;
If (IOCTL (FD, vidiocgmbuf, & mbuf) <0)
{
Perror ("vidiocgmbuf ");
Return-1;
}
Printf ("the frame number is % d/N", mbuf. Frames );
Buf1 = (unsigned char *) MMAP (0, mbuf. Size, prot_read | prot_write, map_shared, fd.0 );
Buf1 = buf1 + mbuf. offset [0];
Buf2 = buf1 + mbuf. offset [1]; // Of Course, if mbuf. Frames = 1, the following is not required.
......
5. IOCTL (FD. vidiocmcapture, & mm)
Start the hardware to capture the image. mm is the video_mmap structure and sets the information needed to capture the image. Struct
Definition:
Struct video_mmap
{
Unsigned int frame;/* frame (0-N) for double buffer */
Int height, width;
Unsigned int format;/* shocould be video_palette _**/
};
Frame: Specifies the current frame number.
Height, width: Set the height and width of the image.
Format: color mode
Note that this command is non-blocking, that is, it only sets the hardware, not whether to capture the image.
To determine whether the image is captured, use the next command.
6. IOCTL (FD, vidiocsync, & frame)
Wait for this image to be captured. Frame is the image to be waited. Its value should correspond to the frame set in the previous command.
Well, after talking about this, the reader may have an understanding of video capturing. If you want to try it yourself, let's
Let's start writing the actual program.
Next we will compile a program to save the captured image as a jpeg file. To this end, we also want to introduce a function,
Int write_jpeg (char * filename, unsigned char * Buf, int quality, int width, int height, int gray)
{
Struct performance_compress_struct Cinfo;
Struct performance_error_mgr Jerr;
File * FP;
Int I;
Unsigned char * line;
Int line_length;
If (null = (FP = fopen (filename, "W ")))
{
Fprintf (stderr, "Grab: Can't open % s: % s/n", filename, strerror (errno ));
Return-1;
}
Cinfo. Err = maid (& Jerr );
Pai_create_compress (& Cinfo );
Pai_stdio_dest (& Cinfo, FP );
Cinfo. image_width = width;
Cinfo. image_height = height;
Cinfo. input_components = gray? 1: 3;
Cinfo. in_color_space = gray? Jcs_grayscale: jcs_rgb;
Pai_set_defaults (& Cinfo );
Performance_set_quality (& Cinfo, quality, true );
Performance_start_compress (& Cinfo, true );
Line_length = gray? Width: width * 3;
For (I = 0, line = Buf; I Pai_write_scanlines (& Cinfo, & line, 1 );
Performance_finish_compress (& (Cinfo ));
Pai_destroy_compress (& (Cinfo ));
Fclose (FP );
Return 0;
}
This function is very common, and its function is to compress the data in Buf into JPEG format.
/* The following is a complete program test. c
* GCC test. C-o Test-ljpeg
*/
# Include <stdio. h>
# Include <stdlib. h>
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <fcntl. h>
# Include <sys/IOCTL. h>
# Include <sys/Mman. h>
# Include <errno. h>
# Include <Linux/videodev. h>
# Include <cmdlib. h>
# Define width 320
# Define height 240
# Define v4l_device "/dev/video0"
Main ()
{
Unsigned char * Buf;
Int I, J;
Int FD;
Int re;
Struct video_capability vcap;
Struct video_channel VC;
Struct video_mbuf mbuf;
Struct video_mmap mm;
FD = open (v4l_device, o_rdwr );
If (FD <= 0)
{
Perror ("open ");
Exit (1 );
}
If (IOCTL (FD, vidiocgcap, & vcap) <0)
{
Perror ("vidiocgcap ");
Exit (1 );
}
Fprintf (stderr, "video capture device name: % s/n", vcap. Name );
For (I = 0; I <vcap. channels; I ++)
{
VC. Channel = I;
If (IOCTL (FD, vidiocgchan, & Vc) <0)
{
Perror ("vidiocgchan ");
Exit (1 );
}
Fprintf (stderr, "video source (% d) Name: % s/n", I, VC. Name );
}
VC. Channel = 1;
VC. Norm = 1;
If (IOCTL (FD, vidiocschan, & Vc) <0)
{
Perror ("vidiocschan ");
Exit (1 );
}
If (IOCTL (FD, vidiocgmbuf, & mbuf) <0)
{
Perror ("vidiocgmbuf ");
Exit (1 );
}
Fprintf (stderr, "the frames number is % d/N", mbuf. Frames );
Buf = (unsigned char *) MMAP (0, mbuf. Size, prot_read | prot_write, map_shared, FD, 0 );
If (INT) BUF <0)
{
Perror ("MMAP ");
Exit (1 );
}
Mm. Frame = 0;
Mm. Height = height;
Mm. width = width;
Mm. format = video_palette_rgb24;
If (IOCTL (FD, vidiocmcapture, & mm) <0)
{
Perror ("vidiocmcapture ");
Exit (1 );
}
If (IOCTL (FD, vidiocsync, & mm. Frame) <0)
{
Perror ("vidiocsync ");
Exit (1 );
}
If (-1 = (write_jpeg ("./pic001.jpeg", Buf, 75, width, height, 0 )))
{
Printf ("write_jpeg error/N ");
Exit (1 );
}
Munmap (BUF, mbuf. size );
Close (FD );
}