iPassion Webcam hint. Maybe building a driver for linux.

So the market is flooded with chinesse tech which disregards standards and drivers are often for windows 7 (or XP) and nobody knows how to make them work.

I have a webcam from iPassion, the lsusb reads:
Bus 001 Device 003: ID 1b3b:2936 iPassion Technology Inc. PC Camera/Webcam controller

Googling around I found this little post in chinesse, it might be a hint. Apparently, the v4l driver can be used with the cam but nobody knows how.
People tried to recompile kernel and stuff. I dont know if it’s necessary, i mean, compiling kernel for using a webcam seems like too much work.
OTOH, i dont really want to bother with windows.

2010–09–07 15:19

First, what is video4linux 
 Video4linux (referred to as V4L), is linux on the video device kernel driver, now has Video4linux2, has not joined the linux kernel, the need to use their own download patch. In Linux, a video device is a device file that can be read and written as if it were an ordinary file. The camera may be 0, 1, 2, 3, … in general under / dev / videoN.

Also, it is recommended to play raw raw data collected from the camera RawPlayer, only need to save the collected data to the file ***. Yuv on OK.

Second, V4L2 acquisition video process

1. Open the device file. Int fd = open (“/ dev / video0”, O_RDWR); 
 2. Obtain the capability of the device to see what the device has, such as whether the video input, or audio input and output. VIDIOC_QUERYCAP, struct v4l2_capability 
 3. Select Video Input. A video device can have multiple video inputs. VIDIOC_S_INPUT, struct v4l2_input 
 4. Set the video format and frame format, including PAL, NTSC, frame format, including the width and height, and so on. 
 VIDIOC_S_STD, VIDIOC_S_FMT, struct v4l2_std_id, struct v4l2_format 
 5. Apply a frame buffer to the driver, typically no more than five. Struct v4l2_requestbuffers 
 6. The frame buffer will be mapped to the user space, so you can operate directly to the collected frames, without having to copy. Mmap 
 7. will apply to the frame buffer into the queue all in order to store the collected data. VIDIOC_QBUF, struct v4l2_buffer 
 8. Start the video capture. VIDIOC_STREAMON 
 9. Queue to obtain the data has been collected frame buffer to obtain the original acquisition data. VIDIOC_DQBUF 
 10. Buffer re-entry queue tail, so you can cycle collection. VIDIOC_QBUF 
 11. Stop the video capture. VIDIOC_STREAMOFF 
 12. Turn off the video equipment. Close (fd); 
 Third, the commonly used structure (see /usr/include/linux/videodev2.h):

Struct v4l2_requestbuffers reqbufs; / / request to the driver to request a frame buffer, which contains the number of applications 
 Struct v4l2_capability cap; / / the function of this device, such as whether the video input device 
 Struct v4l2_input input; // Video input 
 Struct v4l2_standard; // video standard, such as PAL, NTSC 
 Struct v4l2_format fmt; // Format of the frame, such as width, height, etc.

Struct v4l2_buffer buf; / / behalf of the drive in a frame 
 V4l2_std_id stdid; // Video format, for example: V4L2_STD_PAL_B 
 Struct v4l2_queryctrl query; // Control of the query 
 Struct v4l2_control control; / / specific control of the value

The following specific description of the development process (the Internet to find the friends, are also learning Mody)

Turn on the video device

In V4L2, the video device is treated as a file. Use the open function to open the device:

// Open the camera device in nonblocking mode

Int cameraFd;

CameraFd = open (“/ dev / video0”, O_RDWR | O_NONBLOCK, 0);

// If you open the camera device in blocking mode, the above code changes to:

// cameraFd = open (“/ dev / video0”, O_RDWR, 0);

About blocking mode and non-blocking mode

The application can open the video device in blocking mode or nonblocking mode. If the video device is invoked in nonblocking mode, the driver will still return anything in the cache (DQBUFF) to the application, even if the information has not been captured.

Set the properties and acquisition methods

When you open a video device, you can set the properties of the video device, such as crop, zoom, and so on. This step is optional. In Linux programming, the general use of ioctl function to the device I / O channel management:

Extern int ioctl (int __fd, unsigned long int __request, …) __THROW;

__fd: ID of the device, for example, just use the open function to open the video channel and return to the cameraFd;

__request: specific command identifier.

In the V4L2 development, the general will use the following command designator:

VIDIOC_REQBUFS: Allocates memory 
 VIDIOC_QUERYBUF: Convert the data buffer allocated in VIDIOC_REQBUFS to a physical address 
 VIDIOC_QUERYCAP: Query the driver function 
 VIDIOC_ENUM_FMT: Get the current video format supported by the driver 
 VIDIOC_S_FMT: set the current drive frequency capture format 
 VIDIOC_G_FMT: Reads the current drive capture format 
 VIDIOC_TRY_FMT: Verifies the current driver display format 
 VIDIOC_CROPCAP: query-driven pruning capacity 
 VIDIOC_S_CROP: Sets the border of the video signal 
 VIDIOC_G_CROP: Reads the border of the video signal 
 VIDIOC_QBUF: Read the data from the cache 
 VIDIOC_DQBUF: Put the data back into the cache queue 
 VIDIOC_STREAMON: Starts the video display function 
 VIDIOC_STREAMOFF: End the video display function 
 VIDIOC_QUERYSTD: Checks the standard supported by the current video device, such as PAL or NTSC. 
 Some of these IO calls, some are optional, some are optional.

Check the standards supported by the current video device

In Asia, the general use of PAL (720X576) standard camera, and Europe generally use NTSC (720X480), the use of VIDIOC_QUERYSTD to detect:

V4l2_std_id std;

Do {

Ret = ioctl (fd, VIDIOC_QUERYSTD, & std);

} While (ret == -1 && errno == EAGAIN);

Switch (std) {


// …

Case V4L2_STD_PAL:

// …


Sets the video capture format

When the video device supports the standard, you need to set the video capture format:

Struct v4l2_format fmt;

Memset (& fmt, 0, sizeof (fmt));


Fmt.fmt.pix.width = 720;

Fmt.fmt.pix.height = 576;

Fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;

Fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

If (ioctl (fd, VIDIOC_S_FMT, & fmt) == -1) {

Return -1;


The v4l2_format structure is defined as follows:

Struct v4l2_format


Enum v4l2_buf_type type; // data stream type, must always be // V4L2_BUF_TYPE_VIDEO_CAPTURE



Struct v4l2_pix_format pix;

Struct v4l2_window win;

Struct v4l2_vbi_format vbi;

__u8 raw_data [200];

} Fmt;


Struct v4l2_pix_format


__u32 width; // width, must be a multiple of 16

__u32 height; // High, must be a multiple of 16

__u32 pixelformat; // video data storage type, for example, // YUV4: 2: 2 or RGB

Enum v4l2_field field;

__u32 bytesperline;

__u32 sizeimage;

Enum v4l2_colorspace colorspace;

__u32 priv;


Allocate memory

Next, you can allocate memory for video capture:

Struct v4l2_requestbuffers req;

If (ioctl (fd, VIDIOC_REQBUFS, & req) == -1) {

Return -1;


V4l2_requestbuffers are defined as follows:

Struct v4l2_requestbuffers


__u32 count; // The number of buffers, that is, how many pictures are kept in the cache queue

Enum v4l2_buf_type type; // data stream type, must always be V4L2_BUF_TYPE_VIDEO_CAPTURE

Enum v4l2_memory memory; // V4L2_MEMORY_MMAP or V4L2_MEMORY_USERPTR

__u32 reserved [2];


Gets and records the cached physical space

Using VIDIOC_REQBUFS, we get the req.count cache, the next step by calling the VIDIOC_QUERYBUF command to obtain these cached addresses, and then use the mmap function to convert the absolute address in the application, and finally put this cache into the cache queue:

<! — [if! SupportLineBreakNewLine] -> 
 <! — [endif] ->

Typedef struct VideoBuffer {

Void * start;

Size_t length;

} VideoBuffer;

VideoBuffer * buffers = calloc (req.count, sizeof (* buffers));

Struct v4l2_buffer buf;

For (numBufs = 0; numBufs <req.count; numBufs ++) {

Memset (& buf, 0, sizeof (buf));


Buf.memory = V4L2_MEMORY_MMAP;

Buf.index = numBufs;

// Read the cache

If (ioctl (fd, VIDIOC_QUERYBUF, & buf) == -1) {

Return -1;


Buffers [numBufs] .length = buf.length;

// Convert to relative address

Buffers [numBufs] .start = mmap (NULL, buf.length,



Fd, buf.m.offset);

If (buffers [numBufs] .start == MAP_FAILED) {

Return -1;


// In the cache queue

If (ioctl (fd, VIDIOC_QBUF, & buf) == -1) {

Return -1;



Fourth, on the video capture mode

Operating system generally uses the system memory is divided into user space and kernel space, respectively, by the application management and operating system management. Applications can directly access the memory address, and kernel space is stored for the kernel to access the code and data, the user can not directly access. V4l2 capture of data, initially stored in the kernel space, which means that users can not directly access the memory, must be through some means to convert the address.

A total of three video capture mode: use read, write mode; memory mapping mode and the user pointer mode.

Read, write: the user space and kernel space to continue to copy data, taking up a lot of user memory space, the efficiency is not high.

Memory mapping: the device memory mapping to the application of memory control, directly deal with the device memory, which is an effective way. The above mmap function is used in this way.

User Pointer Mode: Memory segments are allocated by the application itself. This requires that the memory field be set to V4L2_MEMORY_USERPTR in v4l2_requestbuffers.

Processing the collected data

V4L2 has a data cache, the number of cache data stored req.count. The data buffer uses the FIFO way, when the application program calls the buffer data, the buffer queue will send out the first video data buffer, and re-capture a video data. This procedure requires the use of two ioctl commands, VIDIOC_DQBUF and VIDIOC_QBUF:

Struct v4l2_buffer buf;

Memset (& buf, 0, sizeof (buf));


Buf.memory = V4L2_MEMORY_MMAP;

Buf.index = 0;

// Read the cache

If (ioctl (cameraFd, VIDIOC_DQBUF, & buf) == -1)


Return -1;


// ………… Video processing algorithms

/ / Re-into the cache queue

If (ioctl (cameraFd, VIDIOC_QBUF, & buf) == -1) {

Return -1;


Turn off your video device

Use the close function to close a video device

Close (cameraFd)

Reprinted from: http://blog.chinaunix.net/u3/108006/showart_2284666.html