How to Learn about camera driver in Linux: (2) how to analyze camera driver by Using Virtual Drive vivi, linuxvivi

Source: Internet
Author: User

How to Learn about camera driver in Linux: (2) how to analyze camera driver by Using Virtual Drive vivi, linuxvivi

1. Run the "strace-o xawtv. log xawtv" command to obtain the following call information:
// 1 ~ 7 is called in v4l2_open
1. open
2. ioctl (4, VIDIOC_QUERYCAP

// 3 ~ 7 is called in get_device_capabilities
3. ()
Ioctl (4, VIDIOC_ENUMINPUT // lists the input sources. VIDIOC_ENUMINPUT/VIDIOC_G_INPUT/VIDIOC_S_INPUT is not required.
4. ()
Ioctl (4, VIDIOC_ENUMSTD // list standard (standard), not required
5. ()
Ioctl (4, VIDIOC_ENUM_FMT // List format

6. ioctl (4, VIDIOC_G_PARM
7. ()
Ioctl (4, VIDIOC_QUERYCTRL // query attributes (such as the Minimum brightness value, maximum value, and default value)

// 8 ~ 10 is called through v4l2_read_attr.
8. ioctl (4, VIDIOC_G_STD // obtain the currently used standard (standard), not required
9. ioctl (4, VIDIOC_G_INPUT
10. ioctl (4, VIDIOC_G_CTRL // obtain the current attribute, such as the brightness

11. ioctl (4, VIDIOC_TRY_FMT // try to see if some format is supported
12. ioctl (4, VIDIOC_S_FMT // set the camera to use a certain format


// 13 ~ 16 In v4l2_start_streaming
13. ioctl (4, VIDIOC_REQBUFS // request the system to allocate a buffer
14. ()
Ioctl (4, VIDIOC_QUERYBUF // query the allocated buffer
Mmap
15. ()
Ioctl (4, VIDIOC_QBUF // put the buffer into the queue
16. ioctl (4, VIDIOC_STREAMON // start the camera


// 17 is called through v4l2_write_attr.
17. ()
Ioctl (4, VIDIOC_S_CTRL // set attributes
Ioctl (4, VIDIOC_S_INPUT // sets the Input Source
Ioctl (4, VIDIOC_S_STD // set standard (standard), not required

// V4l2_nextframe> v4l2_waiton
18. v4l2_queue_all // put all into the buffer
V4l2_waiton
For ()
{
Select (5, [4], NULL, NULL, {5, 0}) = 1 (in [4], left {4, 985979 })
Ioctl (4, VIDIOC_DQBUF // de-queue, fetch the buffer from the queue
// Processing. You can directly access the data by obtaining the buffer address through mmap.
Ioctl (4, VIDIOC_QBUF // put the buffer into the queue
}

Several Functions of xawtv:
1. v4l2_open
2. v4l2_read_attr/v4l2_write_attr // read/write attributes
3. v4l2_start_streaming // apply for a buffer
4. v4l2_nextframe/v4l2_waiton

 

2. 11 ioctl required by the camera driver:/drivers/media/video/vivi. c-> vivi_ioctl_ops (struct). The modification test shows that:
. Vidioc_querycap = vidioc_querycap, // indicates that it is a camera device.

/* Used to list, obtain, test, and set the format of the camera data */
. Vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
. Vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
. Vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
. Vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,

/* Buffer operation: Apply for/query/put in queue/retrieve queue */
. Vidioc_reqbufs = vidioc_reqbufs,
. Vidioc_querybuf = vidioc_querybuf,
. Vidioc_qbuf = vidioc_qbuf,
. Vidioc_dqbuf = vidioc_dqbuf,

// Start/stop
. Vidioc_streamon = vidioc_streamon,
. Vidioc_streamoff = vidioc_streamoff,

Continue to analyze the data acquisition process:
1. Request allocation Buffer: ioctl (4, VIDIOC_REQBUFS // request system allocation Buffer
Videobuf_reqbufs (queue, v4l2_requestbuffers) // The queue is initialized using videobuf_queue_vmalloc_init in the open function.
// Note: This IOCTL only allocates the header information of the buffer, and the real cache has not been allocated.

2. query the ing Buffer:
Ioctl (4, VIDIOC_QUERYBUF // query the allocated buffer
Videobuf_querybuf // obtain the data format, size, length, and height of the buffer.
Mmap (the parameter contains "size") // cache is allocated here
V4l2_mmap
Vivi_mmap
Videobuf_mmap_mapper
_ Videobuf_mmap_mapper in the videobuf-vmalloc.c
Mem-> vmalloc = vmalloc_user (pages); // The buffer space is allocated here.

3. Put the buffer into the queue:
Ioctl (4, VIDIOC_QBUF // put the buffer into the queue
Videobuf_qbuf
Q-> ops-> buf_prepare (q, buf, field); // call the functions provided by the driver for preprocessing.
List_add_tail (& buf-> stream, & q-> stream); // put the buffer zone at the end of the queue
Q-> ops-> buf_queue (q, buf); // call the "inbound queue function" provided by the driver"

4. Start the camera
Ioctl (4, VIDIOC_STREAMON
Videobuf_streamon
Q-> streaming = 1;

5. use select to query data: select (5, [4], NULL, NULL, {5, 0}) = 1 (in [4], left {4, 985979 })
// The driver must include: generate data and wake up the process.
V4l2_poll
Vdev-> fops-> poll
Vivi_poll
Videobuf_poll_stream
// Obtain the buffer from the queue Header
Buf = list_entry (q-> stream. next, struct videobuf_buffer, stream );

// Sleep if no data exists
Poll_wait (file, & buf-> done, wait );

Who will generate data and who will wake it up?
The kernel thread vivi_thread is executed every 30 ms, and it calls
Vivi_thread_tick
Vivi_fillbuff (fh, buf); // construct data
Wake_up (& buf-> vb. done); // wake up the process


6. Fetch the buffer from the queue after data is available
// With so many buffers, how does the APP know which buffer zone has data? Call VIDIOC_DQBUF
Ioctl (4, VIDIOC_DQBUF
Vidioc_dqbuf
// Obtain a buffer with data in the queue
Retval = stream_next_buffer (q, & buf, nonblocking );

// Delete it from the queue
List_del (& buf-> stream );

// Return the status of the buffer to the APP
Videobuf_status (q, B, buf, q-> type );

7. The application obtains the buffer status based on VIDIOC_DQBUF and knows which buffer has data.
Read the corresponding address (the address comes from the previous mmap ).

==> Vivi. c buffer operation process: ① VIDIOC_REQBUFS (allocating header information)-> ② VIDIOC_QUERYBUF (returning attribute)/mmap (ing address, allocating actual space)->

③ VIDIOC_QBUF (put the buffer in the queue)-> ④ VIDIOC_STREAMON (start the camera)-> ⑤ use select to query whether data exists: operate on the first buf of the queue->

⑥ VIDIOC_DQBUF (return the buf of the queue header and delete it from the queue)-> 7 VIDIOC_DQBUF (put it back to the queue again-③)

How to write the camera driver:
1. assign a struct: video_device: video_device_alloc
2. Set
. Fops
. Ioctl_ops (11 items need to be set in it)
If you want to use the buffer operation function provided by the kernel, you also need to construct a videobuf_queue_ops
3. Register: video_register_device

Related Article

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.