This section describes how to program TV cards in Linux.
As mentioned at the beginning, video
Linux driver, v4l for short. In fact, the video for Linux Two driver is now available.
V4l2 solves some problems in v4l and improves hardware performance. However, v4l2 is still not integrated into the Linux kernel. To use v4l2, you only need to download the v4l2 patch. Unless otherwise specified, the content is only applicable to v4l devices.
We all know that in Linux, in order to avoid the complexity of users' access to devices, we use device files, that is, we can access and read devices in the same way as accessing common files. The TV is stuck in Linux and the printer, the same as the mouse, is a character device. The main device number is 81. In actual operation, the access control video card is no different from the general device file. Open the device with open,
Int FD;
FD = open ("/dev/video0", o_rdwr );
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, usually, 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 hardware to capture images. mm is video_mmap.
Structure, set the information to be set to capture the image. Struct
Definition:
Struct video_mmap
{
Unsigned int frame;/* frame (0-N)
Double Buffer */
Int height, width;
Unsigned int format;/* shoshould 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, and 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 );
}
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.