By popularity, the video camera, today, is on a par with a microphone and headphones. It is used in various directions, such as object recognition, augmented reality, video conferencing, and many others. But what is hidden under the hood of these complex programs? How do we get the picture from the camcorder? This series of articles will allow you to look at the ease of working with a video camera at a low level, processing the resulting image.
First, some information about working with devices on a Linux system. Devices in nix systems are a file. With some device files, we can work as with ordinary files. For example:
~$ cat /dev/sda
this command will display the entire sda ​​disk.There are devices with which you can not work directly, they include a video camera. When we try to do this, we will get the following system response:
')
~$ cat: /dev/video0:
* Where / dev / video0 is the best camcorder file device.To work with it, we need the ioctl system function. You can read more about it
[1] . Let's try to apply it. Here is the code that allows you to read information from the device (alternative to the cat command for video devices):
Code here #include <fcntl.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <linux/videodev2.h> int main (int argc,char* argv[]) { char *device_name; if(argc > 1) { device_name = argv[1]; } else { device_name = "/dev/video0"; } int file_device = open(device_name, O_RDWR, 0); if (file_device == -1) { printf ("%s error %d, %s\n",device_name, errno, strerror(errno)); exit(EXIT_FAILURE); } struct v4l2_capability device_params; if (ioctl(file_device, VIDIOC_QUERYCAP, &device_params) == -1) { printf ("\"VIDIOC_QUERYCAP\" error %d, %s\n", errno, strerror(errno)); exit(EXIT_FAILURE); } printf("driver : %s\n",device_params.driver); printf("card : %s\n",device_params.card); printf("bus_info : %s\n",device_params.bus_info); printf("version : %d.%d.%d\n", ((device_params.version >> 16) & 0xFF), ((device_params.version >> 8) & 0xFF), (device_params.version & 0xFF)); printf("capabilities: 0x%08x\n", device_params.capabilities); printf("device capabilities: 0x%08x\n", device_params.device_caps); if (-1 == close (file_device)) { printf ("\"close\" error %d, %s\n", errno, strerror(errno)); exit(EXIT_FAILURE); } file_device = -1; return 0; }
The first lines of code read the parameters from which the application is running. If there are no parameters, then device_name takes the standard value "/ dev / video0".
In the “Open Device” block, the device is opened by the system function open (you need to connect header fcntl.h). The required parameter O_RDWR is responsible for opening the reader / writer. If an error occurs during the connection, the open function returns -1.
The “Read Params From Device” block is the heart of our little program. To use it you need to connect bilioteka
<linux/videodev2.h>
you may have to install it, each distribution has its own package for this libraryThe
ioctl system function has three parameters:
file_device - our device handle
VIDIOC_QUERYCAP is the kernel function that we use for our device.
device_params - the memory area where the result of the function “VIDIOC_QUERYCAP” will be reset.
device_params is a structure consisting of the following fields:
struct v4l2_capability { __u8 driver[16]; // - __u8 card[32]; // __u8 bus_info[32]; // ( usb-) __u32 version; // __u32 capabilities; // (/) __u32 device_caps; // __u32 reserved[3]; // };
if an error occurs ioctl returns -1
The “Close Device” block closes the device descriptor.
Let's see the program in action.
compile
gcc catvd.c -o catdv
run
./catvd /dev/video0 /dev/video0 error 2, No such file or directory
the device was not detected by the kernel or the
cleaning lady was not connected
again, unplugged the wires again .
Connect and re-launch. We get the following information:
./catvd /dev/video0 driver : uvcvideo card : UVC Camera (046d:0804) bus_info : usb-0000:00:12.2-3 version : 3.11.10 capabilities: 0x84000001 device capabilities: 0x04000001
The capabilities and device capabilities can be decrypted using the constants from the videodev2.h file:
V4L2_CAP_DEVICE_CAPS 0x80000000 // . V4L2_CAP_STREAMING 0x04000000 // i/o ioctls. V4L2_CAP_VIDEO_CAPTURE 0x00000001 // .
This introductory article ends. The following reviews will cover topics such as memory-mapping, image video deformats, camera setup, image output to texture, work with several cameras.
Resources used in the article:
- ioctl article
- about working with video for linux (slightly outdated information)
Source of the program used in the article .