V4L2 Wei Dongshan video frame analysis [study notes]

V4l2 basic framework of the following:

. 1      App: Read Write Open IOCtrl
 2      ------------------------------------------ ------------------
 3      mainly provides a standard interface for the upper core layer call:
 . 4      V4L2-dev.c --->
 . 5          static  const  struct the file_operations v4l2_fops = {
 . 6              .owner = THIS_MODULE,
 . 7              .read = v4l2_read,
 . 8              .write = v4l2_write,
 . 9              .Open = v4l2_open,
 10              .get_unmapped_area = v4l2_get_unmapped_area,
 . 11              .mmap = v4l2_mmap,
12             .unlocked_ioctl = v4l2_ioctl,
13         #ifdef CONFIG_COMPAT
14             .compat_ioctl = v4l2_compat_ioctl32,
15         #endif
16             .release = v4l2_release,
17             .poll = v4l2_poll,
18             .llseek = no_llseek,
19         };
20 
21 
22 
23     -------------------------------------------------------------
24     硬件相关:
25                     |---v4l2_device_register  --->重点
26                     |
27     Uvc_driver.c ---|---uvc_register_chains
28                     |        uvc_register_terms
29                     |            uvc_register_video
30                     |                video_device_alloc --->重点
31                     |                    video_register_device ---> 重点

The following case study analysis related to vivi.c call flow

vivi_init main processes:

. 1  vivi_init
 2          vivi_create_instance
 . 3              v4l2_device_register ---> Register This structure: struct v4l2_device
 . 4  
. 5              the dev-> Formats & FMT = [ 0 ]; set image format
 . 6              v4l2_ctrl_handler_init set properties
 . 7              the dev-> Volume = v4l2_ctrl_new_std (HDL, & vivi_ctrl_ops ,
 . 8              V4L2_CID_AUDIO_VOLUME, 0 , 255 , . 1 , 200 is );
 . 9              the dev-> Brightness = v4l2_ctrl_new_std (HDL, & vivi_ctrl_ops,
 10             V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
11             dev->contrast = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
12             V4L2_CID_CONTRAST, 0, 255, 1, 16);
13             dev->saturation = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
14             V4L2_CID_SATURATION, 0, 255, 1, 127);
15             dev->hue = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
16             V4L2_CID_HUE, -128, 127, 1, 0);
17             dev->autogain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
18             V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
19             dev->gain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
20             V4L2_CID_GAIN, 0, 255, 1, 100);
21             dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL);
22             dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL);
23             dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL);
24             dev->boolean = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_boolean, NULL);
25             dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL);
26             dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
27             dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL);
28 
29         vfd = video_device_alloc();   //主要是注册这个结构体;video_device
30         *vfd = vivi_template;//
31         vfd->v4l2_dev = &dev->v4l2_dev;
32 
33         ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
34             __video_register_device
35                 vdev->cdev->ops = &v4l2_fops;
36                 vdev->cdev->owner = owner;
37                 ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);
38                 if (ret < 0) {
39                         the printk (KERN_ERR " % S: cdev_add failed \ n- " , __func__ in);
 40                          kfree (VDEV-> the cdev);
 41 is                          VDEV-> the cdev = NULL;
 42 is                          GOTO Cleanup;
 43 is                  }
 44 is  
45                  video_device [VDEV-> Minor] = VDEV ;   // by associating the array 
46 is  
47                  IF (VDEV-> v4l2_dev) {   // before vivi.c provided with vfd-> v4l2_dev = & dev-> v4l2_dev ; interrelated 
48                      IF (VDEV-> v4l2_dev-> dev)
 49                         vdev->parent = vdev->v4l2_dev->dev;
50                     if (vdev->ctrl_handler == NULL)
51                         vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
52                     /* If the prio state pointer is NULL, then use the v4l2_device
53                        prio state. */
54                     if (vdev->prio == NULL)
55                 }
56 
57 
58         static const struct v4l2_file_operations vivi_fops = {
59             .owner        = THIS_MODULE,
60             .open           = v4l2_fh_open,
61             .release        = vivi_close,
62             .read           = vivi_read,
63             .poll        = vivi_poll,
64             .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
65             .mmap           = vivi_mmap,
66         };
67 
68 
69         static struct video_device vivi_template = {
70             .name        = "vivi",
71             .fops           = &vivi_fops,
72             .ioctl_ops     = &vivi_ioctl_ops,
73             .release    = video_device_release,
74         
75             .tvnorms              = V4L2_STD_525_60,
76             .current_norm         = V4L2_STD_NTSC_M,
77         };

open process:

 

. 1  Open flow:
 2      App: Open ( " / dev / video0 " , ....)
 . 3      --------------------------- -----
 . 4      Open:
 . 5          v4l2_fops.open
 . 6              VDEV = video_devdata (the filp);
 . 7                  video_device [iminor (File-> f_path.dentry-> d_inode)] //     __video_register_device the structure vivi.v registered on video_device the memory array 
8                  VDEV-> fops-> Open transferred fops vivi.c set, the key here is very exciting, we understand about
 9                      vivi_template
 10                          v4l2_fh_open

 

read process:

. 1  Read Process:
 2          v4l2_fops.read
 . 3              struct video_device VDEV * = video_devdata (the filp);
 . 4              VDEV-> fops-> Read

ioctrl process:

 

. 1      App: ioctl can be set by obtaining luminance information, and the driver who receives the management information
 2      v4l2_ctrl information set
 . 3      v4l2_ctrl_handler to manage
 . 4  
. 5      ioctl process:
 . 6      v4l2_fops.v4l2_ioctl
 . 7          struct video_device VDEV * = video_devdata ( the filp);
 . 8              VDEV-> fops-> unlocked_ioctl (the filp, cmd, Arg);
 . 9                  vivi_fops.video_ioctl2
 10                      video_usercopy (File, cmd, Arg, __video_do_ioctl); // pass a callback function into __video_do_ioctl 
. 11                          struct video_device * = VFD video_devdata (File);
 12                          //The APP incoming cmd obtained, set "certain property" 
13 is                          Switch (cmd) {
 14                                                      
15                          }
 16  
. 17  
18 is      or through the v4l2_ctrl
 . 19      for ctrl_handler related setup code
 20 is      vivi_create_instance
 21 is          v4l2_ctrl_handler_init (HDL, . 11 );
 22 is          v4l2_ctrl_new_std (HDL, & vivi_ctrl_ops, V4L2_CID_AUDIO_VOLUME, 0 , 255 , . 1 , 200 is ); 
       ...
23 is the dev-> = v4l2_dev.ctrl_handler HDL; associated with the VDEV 24 video_register_device 25 __video_register_device 26 is IF (VDEV-> ctrl_handler == NULL) 27 VDEV-> = VDEV-ctrl_handler> v4l2_dev-> ctrl_handler; 28 29 __video_do_ioctl 30 Case VIDIOC_QUERYCTRL: 31 is IF (VFH && vfh-> ctrl_handler) 32 RET = v4l2_queryctrl (vfh- > ctrl_handler, P); 33 is REF = find_ref (HDL, ID); // then find the corresponding v4l2_ctrl based on ID, the corresponding structure is then further found to fill

Guess you like

Origin www.cnblogs.com/zzb-Dream-90Time/p/12546925.html