Video Transmission

A video transmission mode: In IIC protocol, through the IO port transport stream:

Video transmission way: usb interface to transmit the video stream:

Drivers: character device drivers

How to write drivers: construction file_operations

                             To tell the kernel

                             Entry function

                             Export function

v4l2 drive frame: the core layer -> file_operations

                         Hardware-related layers:

1, the camera device into the usb on pc with a virtual machine, dmesg prints found some usb camera equipment information, grep to find specific location information printed in the kernel;

2, look for the print information

3, open the file with source insight uvc_driver.c or other reading software

      3.1 -->struct uvc_driver

                 --> uvc_probe:

                       v4l2_device_register

                       uvc_register_chains ---uvc_register_video--video_device  video_register_device

                                                          ---struct video_device *vdev;

                                                                       struct uvc_device *dev,

                                                                 vdev->v4l2_dev = &dev->vdev;
                                                                 vdev->fops = &uvc_fops;

                       media_device_register

4, there v4l2-framework.txt document may refer to the kernel

5, can analyze the virtual camera driver: vivi.c

vivi_init-->vivi_create_instance-->video_device_alloc-->video_register_device-->__video_register_device-->vdev->cdev = cdev_alloc();--> cdev_add()

6, in the kernel already provides some basic functions file_operations v4l2_fops, so we do not need to write character device functions. When the application layer calls the ioctl function, the call file_operations ioctl ---. Unlocked_ioctl = v4l2_ioctl,

v4l2_ioctl------

             if (video_is_registered(vdev))
                      ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);

If video_device already registered, call video_device inside fops function inside unlocked_ioctl function.

The unlocked_ioctl function in the kernel has been written, we do not need to write --- video_usercopy

----cmd_input_size(cmd);

----check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);

---- get what we want

static unsigned long cmd_input_size(unsigned int cmd)
{
    /* Size of structure up to and including 'field' */
#define CMDINSIZE(cmd, type, field)                 \
    case VIDIOC_##cmd:                     \
        return offsetof(struct v4l2_##type, field) +     \
            sizeof(((struct v4l2_##type *)0)->field);

    switch (cmd) {
        CMDINSIZE(ENUM_FMT,        fmtdesc,    type);
        CMDINSIZE(G_FMT,        format,        type);
        CMDINSIZE(QUERYBUF,        buffer,        length);
        CMDINSIZE(G_PARM,        streamparm,    type);
        CMDINSIZE(ENUMSTD,        standard,    index);
        CMDINSIZE(ENUMINPUT,        input,        index);
        CMDINSIZE(G_CTRL,        control,    id);
        CMDINSIZE(G_TUNER,        tuner,        index);
        CMDINSIZE(QUERYCTRL,        queryctrl,    id);
        CMDINSIZE(QUERYMENU,        querymenu,    index);
        CMDINSIZE(ENUMOUTPUT,        output,        index);
        CMDINSIZE(G_MODULATOR,        modulator,    index);
        CMDINSIZE(G_FREQUENCY,        frequency,    tuner);
        CMDINSIZE(CROPCAP,        cropcap,    type);
        CMDINSIZE(G_CROP,        crop,        type);
        CMDINSIZE(ENUMAUDIO,        audio,         index);
        CMDINSIZE(ENUMAUDOUT,        audioout,     index);
        CMDINSIZE(ENCODER_CMD,        encoder_cmd,    flags);
        CMDINSIZE(TRY_ENCODER_CMD,    encoder_cmd,    flags);
        CMDINSIZE(G_SLICED_VBI_CAP,    sliced_vbi_cap,    type);
        CMDINSIZE(ENUM_FRAMESIZES,    frmsizeenum,    pixel_format);
        CMDINSIZE(ENUM_FRAMEINTERVALS,    frmivalenum,    height);
    default:
        return _IOC_SIZE(cmd);
    }
}

with

static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
                void * __user *user_ptr, void ***kernel_ptr)
{
    int ret = 0;

    switch (cmd) {
    case VIDIOC_QUERYBUF:
    case VIDIOC_QBUF:
    case VIDIOC_DQBUF: {
        struct v4l2_buffer *buf = parg;

        if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
            if (buf->length > VIDEO_MAX_PLANES) {
                ret = -EINVAL;
                break;
            }
            *user_ptr = (void __user *)buf->m.planes;
            *kernel_ptr = (void *)&buf->m.planes;
            *array_size = sizeof(struct v4l2_plane) * buf->length;
            ret = 1;
        }
        break;
    }

    case VIDIOC_S_EXT_CTRLS:
    case VIDIOC_G_EXT_CTRLS:
    case VIDIOC_TRY_EXT_CTRLS: {
        struct v4l2_ext_controls *ctrls = parg;

        if (ctrls->count != 0) {
            if (ctrls->count > V4L2_CID_MAX_CTRLS) {
                ret = -EINVAL;
                break;
            }
            *user_ptr = (void __user *)ctrls->controls;
            *kernel_ptr = (void *)&ctrls->controls;
            *array_size = sizeof(struct v4l2_ext_control)
                    * ctrls->count;
            ret = 1;
        }
        break;
    }
    } 

    Return right; 
}

7, strace can be obtained by calling the system during program execution

strace -o xawtv.log xawtv

xawtv involved in the system call will be recorded in xawtv.log

 

 

 

 

 

          

 

 

                                         

 

Guess you like

Origin www.cnblogs.com/zhu-g5may/p/9970364.html