V4L2(video for linux) 可以支持多種設(shè)備,它可以有以下5種接口: 1、視頻采集接口(video capture interface):這種應(yīng)用的設(shè)備可以是高頻頭或者攝像頭.V4L2的最初設(shè)計(jì)就是應(yīng)用于這種功能的.下面也是著重講解這種應(yīng)用; 2、視頻輸出接口(video output interface):可以驅(qū)動(dòng)計(jì)算機(jī)的外圍視頻圖像設(shè)備——像可以輸出電視信號(hào)格式的設(shè)備; 3、直接傳輸視頻接口(video overlay interface):它的主要工作是把從視頻采集設(shè)備采集過來的信號(hào)直接輸出到輸出設(shè)備之上,而不用經(jīng)過系統(tǒng)的CPU; 4、視頻間隔消隱信號(hào)接口(VBI interface):它可以使應(yīng)用可以訪問傳輸消隱期的視頻信號(hào); 5、收音機(jī)接口(radio interface):可用來處理從AM或FM高頻頭設(shè)備接收來的音頻流; V4L2驅(qū)動(dòng)的主要功能是使程序有發(fā)現(xiàn)設(shè)備的能力和操作設(shè)備.它主要是用過一系列的回調(diào)函數(shù)來實(shí)現(xiàn)這些功能.像設(shè)置高頻頭的頻率,幀頻,視頻壓縮格式和圖像像參數(shù)等等. 一、V4L2的移植V4L2提供了三種不同的API來傳輸外圍設(shè)備和用戶空間的數(shù)據(jù)。下面就vivi(drivers/media/video/vivi.c)來講解一個(gè)V4L2驅(qū)動(dòng)的編寫。注意它是一個(gè)虛擬的設(shè)備驅(qū)動(dòng),沒有與實(shí)際的硬件打交道。 在v4l2-dev.h中定義了結(jié)構(gòu)體video_device和v4l2_file_operations; 在v4l2-ioctl.h中定義了結(jié)構(gòu)體v4l2_ioctl_ops; 在v4l2-device.h中定義了結(jié)構(gòu)體v4l2_device; 1) vivi_fops static const struct v4l2_file_operations vivi_fops = { .owner = THIS_MODULE, .open = vivi_open, .release = vivi_close, .read = vivi_read, .poll = vivi_poll, .ioctl = video_ioctl2, /* V4L2 ioctl handler */ .mmap = vivi_mmap, }; 2) vivi_ioctl_ops static const struct v4l2_ioctl_ops vivi_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .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, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, .vidioc_s_std = vidioc_s_std, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, .vidioc_queryctrl = vidioc_queryctrl, .vidioc_g_ctrl = vidioc_g_ctrl, .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, #ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidiocgmbuf, #endif }; 3) vivi_template static struct video_device vivi_template = { .name = "vivi", .fops = &vivi_fops, .ioctl_ops = &vivi_ioctl_ops, .minor = -1, .release = video_device_release,
.tvnorms = V4L2_STD_525_60, .current_norm = V4L2_STD_NTSC_M, }; 其中函數(shù)vivi_xxx和vidioc_xxx都是在vivi.c中實(shí)現(xiàn)的。如果要基于某個(gè)硬件來實(shí)現(xiàn)V4L2的接口,那這些函數(shù)就需要調(diào)用硬件的驅(qū)動(dòng)去實(shí)現(xiàn)。 4) vivi_dev 2)直接的內(nèi)存訪問,可以通過其映射方式來傳輸(IO數(shù)據(jù)流,交換指向緩沖區(qū)指針的方法);這是視頻設(shè)備通常用的方法,采用mmap()的方法,即有內(nèi)核空間里開辟內(nèi)存,再在程序里把這部分的內(nèi)存映射到程序空間。如果有設(shè)備內(nèi)存,即直接映射到設(shè)備的內(nèi)核,這種性能更高。 http://blog.csdn.net/wxzking/article/details/6225170 |
|