您的位置:首页 > 其它

Davinci V4L2视频采集框架分析

2013-07-28 18:16 429 查看
这里只是记录一些日志,难免有些错误,欢迎批评指正。Davinci V4L2视频采集框架主要是分析davinci_capture.c这个模块。

 

V4L2简介

 

Davinci V4L2视频采集驱动其是根据V4L2采集驱动来编写的,想要熟悉其驱动流程,也就比先要了解V4L2德的一些相关知识。我们这里只了解它的采集部分

 

V4L2(video for linux) 可以支持多种设备,它可以有以下5种接口:

 

1、视频采集接口(video capture interface):这种应用的设备可以是高频头或者摄像头.V4L2的最初设计就是应用于这种功能的.下面也是着重讲解这种应用;

 

2、视频输出接口(video output interface):可以驱动计算机的外围视频图像设备——像可以输出电视信号格式的设备;

 

3、直接传输视频接口(video overlay interface):它的主要工作是把从视频采集设备采集过来的信号直接输出到输出设备之上,而不用经过系统的CPU;

 

4、视频间隔消隐信号接口(VBI interface):它可以使应用可以访问传输消隐期的视频信号;

 

5、收音机接口(radio interface):可用来处理从AM或FM高频头设备接收来的音频流;

 

V4L2驱动的主要功能是使程序有发现设备的能力和操作设备.它主要是用过一系列的回调函数来实现这些功能.像设置高频头的频率,帧频,视频压缩格式和图像像参数等等.

 

关于它的采集流程可以查看http://blog.csdn.net/piaozhiye/article/details/7537419这里我就不罗嗦了。

模块注册与注销

 

3290module_init(vpif_init);

 

3291 module_exit(vpif_cleanup);

 

另外向其他模块提供了两个导出函数,提供给视频设备注册和注销。

 

3286 EXPORT_SYMBOL(vpif_register_decoder);

 

3287 EXPORT_SYMBOL(vpif_unregister_decoder);

 

vpif_initVPIF采集接口的初始化工作

 

主要是分配缓冲,检查设备类型,分配内存给channel objects,建立VBI处理的工作队列,注册vpif_driver,注册_vpif_device,申请request_irq,引脚复用的设置。在注册的时候会使用vpif_driver 的probe来进行注册,注册一些相关的ioctrol等。

 

01.    具体如下: 

02.2979 /* vpif_init : This function registers device and driver to

03.2980  * the kernel, requests irq handler and allocates memory

04.2981  * for channel objects

05.2982  */ 

06.2983 static __init int vpif_init(void) 

07.2984 { 

08.2985         intfree_irq_no_index; 

09.2986         int err = 0, i,j; 

10.2987         intfree_channel_objects_index; 

11.2988         intfree_buffer_channel_index; 

12.2989         intfree_buffer_index; 

13.2990         u8 *addr; 

14.2991         u32 size; 

15.2992  

16.2993         /* Default number ofbuffers should be 3 */ 

17.2994         if((channel0_numbuffers > 0) && 

18.2995            (channel0_numbuffers < config_params.min_numbuffers)) 

19.2996                channel0_numbuffers = config_params.min_numbuffers; 

20.2997         if((channel1_numbuffers > 0) && 

21.2998            (channel1_numbuffers < config_params.min_numbuffers)) 

22.2999                channel1_numbuffers = config_params.min_numbuffers; 

23.3000  

24.3001         /* Set buffer size tomin buffers size if invalid buffer size is

25.3002          * given */ 

26.3003         if (channel0_bufsize< config_params.min_bufsize[VPIF_CHANNEL0_VIDEO]) 

27.3004                channel0_bufsize = 

28.3005                    config_params.min_bufsize[VPIF_CHANNEL0_VIDEO]; 

29.3006         if (channel1_bufsize< config_params.min_bufsize[VPIF_CHANNEL1_VIDEO]) 

30.3007                channel1_bufsize = 

31.3008                    config_params.min_bufsize[VPIF_CHANNEL1_VIDEO]; 

32.3009  

33.3010        config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = channel0_numbuffers; 

34.3011        config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = channel1_numbuffers; 

35.3012         if(channel0_numbuffers) { 

36.3013                config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO] 

37.3014                    = channel0_bufsize; 

38.3015         } 

39.3016         if (channel1_numbuffers){ 

40.3017                config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO] 

41.3018                    = channel1_bufsize; 

42.3019         } 

43.3020  

44.3021         /* Check the correctvalue of device_type */ 

45.3022         if ((device_type >config_params.max_device_type) || (device_type < 0)) { 

46.3023                config_params.device_type = 0; 

47.3024         } else { 

48.3025                config_params.device_type = device_type; 

49.3026         } 

50.3027         /* Allocate memory forsix channel objects */ 

51.3028         for (i = 0; i <VPIF_CAPTURE_MAX_DEVICES; i++) { 

52.3029                vpif_obj.dev[i] = 

53.3030                    kmalloc(sizeof(struct channel_obj), GFP_KERNEL); 

54.3031                /* If memory allocation fails, return error */ 

55.3032                if (!vpif_obj.dev[i]) { 

56.3033                        free_channel_objects_index = i; 

57.3034                        goto vpif_init_free_channel_objects; 

58.3035                        err = -ENOMEM; 

59.3036                } 

60.3037         } 

61.3038        free_channel_objects_index = VPIF_CAPTURE_MAX_DEVICES; 

62.3039  

63.3040         /* Allocate memory forbuffers */ 

64.3041         for (i = 0; i <VPIF_CAPTURE_NUM_CHANNELS; i++) { 

65.3042                size = config_params.channel_bufsize[i]; 

66.3043                for (j = 0; j < config_params.numbuffers[i]; j++) { 

67.3044                        addr = (u8 *) vpif_alloc_buffer(size); 

68.3045                        if (!addr) { 

69.3046                                free_buffer_channel_index = i; 

70.3047                                free_buffer_index = j; 

71.3048                                err = -ENOMEM; 

72.3049                                goto vpif_init_free_buffers; 

73.3050                        } 

74.3051                        vpif_obj.dev[i]->common[VPIF_VIDEO_INDEX].fbuffers[j] = 

75.3052                            addr; 

76.3053                } 

77.3054         } 

78.3055        free_buffer_channel_index = VPIF_CAPTURE_NUM_CHANNELS; 

79.3056         free_buffer_index =config_params.numbuffers[i - 1]; 

80.3057  

81.3058         /* Create the workqueue*/ 

82.3059         vbi_workqueue =create_singlethread_workqueue("vbi"); 

83.3060         if (!vbi_workqueue){ 

84.3061                err = -ENOMEM; 

85.3062                goto vpif_init_free_buffers; 

86.3063         } 

87.3064  

88.3065         /* Register driver tothe kernel */ 

89.3066         err =driver_register(&vpif_driver); 

90.3067         if (0 != err) { 

91.3068                goto vpif_init_free_buffers; 

92.3069         } 

93.3070         /* register device as aplatform device to the kernel */ 

94.3071         err = platform_device_register(&_vpif_device); 

95.3072         if (0 != err) { 

96.3073                goto vpif_init_unregister_vpif_driver; 

97.3074         } 

98.3075         for (j = 0; j <VPIF_CAPTURE_NUM_CHANNELS; j++) { 

99.3076                err = 

100.3077                    request_irq(vpif_get_irq_number(j), 

101.3078                                vpif_channel_isr, SA_INTERRUPT, 

102.3079                                "DM646x_Capture", 

103.3080                                (void *)(&(vpif_obj.dev[j]->channel_id))); 

104.3081                if (0 != err) { 

105.3082                        if (j == 0) { 

106.3083                                goto vpif_init_unregister_vpif_device; 

107.3084                        } else { 

108.3085                                free_irq_no_index = j; 

109.3086                                goto vpif_init_free_irq; 

110.3087                        } 

111.3088         
fd3d
       } 

112.3089         } 

113.3090         free_irq_no_index =VPIF_CAPTURE_NUM_CHANNELS; 

114.3091  

115.3092         /*err = request_irq(4,vpif_err_isr, SA_INTERRUPT, "DM646x_Capture_err",*/ 

116.3093         /*(void*)NULL);*/ 

117.3094         /*if (0 !=err)*/ 

118.3095         /*{*/ 

119.3096         /*printk("requesterror interrupt is err!\n");*/ 

120.3097         /*return err;*/ 

121.3098         /*}*/ 

122.3099  

123.3100         /*//initialize errorinterrupt register.*/ 

124.3101        /*init_int_err();*/ 

125.3102  

126.3103         /* Set the pinmuxsettings */ 

127.3104        set_vpif_pinmux(); 

128.3105        set_vpif_capture_pinmux(); 

129.3106  

130.3107         return 0; 

131.3108  

132.3109 vpif_init_free_irq: 

133.3110         for (j = 0; j <free_irq_no_index; j++) { 

134.3111                free_irq(vpif_get_irq_number(j), 

135.3112                         (void *)(&(vpif_obj.dev[j]->channel_id))); 

136.3113         } 

137.3114 vpif_init_unregister_vpif_device: 

138.3115        platform_device_unregister(&_vpif_device); 

139.3116  

140.3117 vpif_init_unregister_vpif_driver: 

141.3118        driver_unregister(&vpif_driver); 

142.3119  

143.3120 vpif_init_free_buffers: 

144.3121         for (i = 0; i <free_buffer_channel_index; i++) { 

145.3122                for (j = 0; j < config_params.numbuffers[i]; j++) { 

146.3123                        addr = vpif_obj.dev[i]->common[VPIF_VIDEO_INDEX]. 

147.3124                            fbuffers[j]; 

148.3125                        if (addr) { 

149.3126                                vpif_free_buffer((unsigned long)addr, 

150.3127                                                 config_params. 

151.3128                                                 channel_bufsize[i] 

152.3129                                    ); 

153.3130                                vpif_obj.dev[i]->common[VPIF_VIDEO_INDEX]. 

154.3131                                    fbuffers[j] = NULL; 

155.3132                        } 

156.3133                } 

157.3134         } 

158.3135         for (j = 0; j <free_buffer_index; j++) { 

159.3136                addr = 

160.3137                    vpif_obj.dev[free_buffer_channel_index]-> 

161.3138                    common[VPIF_VIDEO_INDEX].fbuffers[j]; 

162.3139                if (addr) { 

163.3140                        vpif_free_buffer((unsigned long)addr, 

164.3141                                         config_params.channel_bufsize[i]); 

165.3142                        vpif_obj.dev[free_buffer_channel_index]-> 

166.3143                            common[VPIF_VIDEO_INDEX].fbuffers[j] 

167.3144                            = NULL; 

168.3145                } 

169.3146         } 

170.3147  

171.3148 vpif_init_free_channel_objects: 

172.3149         for (j = 0; j <free_channel_objects_index; j++) { 

173.3150                if (vpif_obj.dev[i]) { 

174.3151                        kfree(vpif_obj.dev[j]); 

175.3152                        vpif_obj.dev[i] = NULL; 

176.3153                } 

177.3154         } 

178.3155         return err; 

179.3156 }  

其中的一些关键结构:

 

01.vpif_driver 

02.2950 static struct device_driver vpif_driver = { 

03.2951         .name = "vpifcapture", 

04.2952         .bus =&platform_bus_type, 

05.2953         .probe =vpif_probe, 

06.2954         .remove =vpif_remove, 

07.2955 };       

08.2956 static struct platform_device _vpif_device = { 

09.2957         .name = "vpifcapture", 

10.2958         .id = 1, 

11.2959         .dev = { 

12.2960                .release = vpif_platform_release, 

13.2961                } 

14.2962};               

 

vpif_probe

 

用video_device_alloc(); 给video_device *vfd 分配内存,并初始化,然后channel->video_dev指向vfd,初始化channel objects,最后使用video_register_device注册video_dev。

 

具体如下:

 

01.2816 /* vpif_probe : This function creates device entries by register

02.2817  * itself to the V4L2 driver and initializes fields of each

03.2818  * channel objects */ 

04.2819 static __init int vpif_probe(struct device *device) 

05.2820 { 

06.2821         struct common_obj*common = NULL; 

07.2822         int i, j = 0, k, err =0, index = 0; 

08.2823         struct video_device*vfd = NULL; 

09.2824         struct channel_obj*channel = NULL; 

10.2825         struct video_obj*vid_ch = NULL; 

11.2826         vpif_dev =device; 

12.2827  

13.2828         for (i = 0; i <VPIF_CAPTURE_MAX_DEVICES; i++) { 

14.2829                /* Get the pointer to the channel object */ 

15.2830                channel = vpif_obj.dev[i]; 

16.2831                /* Allocate memory for video device */ 

17.2832                vfd = video_device_alloc(); 

18.2833                if (ISNULL(vfd)) { 

19.2834                        for (j = 0; j < i; j++) { 

20.2835                                video_device_release(vpif_obj.dev[j]-> 

21.2836                                                     video_dev); 

22.2837                        } 

23.2838                        return -ENOMEM; 

24.2839                } 

25.2840  

26.2841                /* Initialize field of video device */ 

27.2842                *vfd = vpif_video_template; 

28.2843                vfd->dev = device; 

29.2844                vfd->release = video_device_release; 

30.2845                snprintf(vfd->name, sizeof(vfd->name), 

31.2846                         "DM646x_VPIFCapture_DRIVER_V%d.%d.%d", 

32.2847                         (VPIF_CAPTURE_VERSION_CODE >> 16) & 0xff, 

33.2848                         (VPIF_CAPTURE_VERSION_CODE >> 8) & 0xff, 

34.2849                         (VPIF_CAPTURE_VERSION_CODE) & 0xff); 

35.2850                /* Set video_dev to the video device */ 

36.2851                channel->video_dev = vfd; 

37.2852         } 

38.2853  

39.2854         for (j = 0; j <VPIF_CAPTURE_MAX_DEVICES; j++) { 

40.2855                channel = vpif_obj.dev[j]; 

41.2856                channel->usrs = 0; 

42.2857                for (k = VPIF_VIDEO_INDEX; k <= VPIF_HBI_INDEX; k++) { 

43.2858                        common = &(channel->common[k]); 

44.2859                        common->io_usrs = 0; 

45.2860                        common->started = 0; 

46.2861                        spin_lock_init(&common->irqlock); 

47.2862                        init_MUTEX(&common->lock); 

48.2863                        common->numbuffers = 0; 

49.2864                        common->set_addr = NULL; 

50.2865                        common->ytop_off = common->ybtm_off = 0; 

51.2866                        common->ctop_off = common->cbtm_off = 0; 

52.2867                        common->curFrm = common->nextFrm = NULL; 

53.2868                        memset(&common->fmt, 0, sizeof(struct v4l2_format)); 

54.2869                } 

55.2870                channel->video.std = 0; 

56.2871                channel->initialized = 0; 

57.2872                channel->channel_id = j; 

58.2873  

59.2874                common = &(channel->common[VPIF_VIDEO_INDEX]); 

60.2875                vid_ch = &(channel->video); 

61.2876                /* Initialize field of the channel objects */ 

62.2877                channel->usrs = common->io_usrs = vid_ch->std = 0; 

63.2878                common->started = channel->initialized = 0; 

64.2879                channel->channel_id = j; 

65.2880                common->numbuffers = 

66.2881                    config_params.numbuffers[channel->channel_id]; 

67.2882  

68.2883                channel->numdecoders = 0; 

69.2884                channel->current_decoder = 0; 

70.2885                for (index = 0; index < VPIF_CAPTURE_NUM_DECODERS; index++) { 

71.2886                        channel->decoder[index] = NULL; 

72.2887                } 

73.2888  

74.2889                memset(&(channel->vpifparams), 0, sizeof(struct vpif_params)); 

75.2890                /* Initialize prio member of channel object */ 

76.2891                v4l2_prio_init(&channel->prio); 

77.2892  

78.2893                /* Set the tasklet handler in the tasklet struct */ 

79.2894                channel->vbi.vbi_tasklet.func = vbi_work_handler; 

80.2895                /* Set Timer counter */ 

81.2896                channel->vbi.timer_counter = VPIF_TIMER_COUNT; 

82.2897                /* Initialize the work structure */ 

83.2898                INIT_WORK(&vbi_work[channel->channel_id], 

84.2899                          (void (*)(void *))vbi_work_handler, (void *)channel); 

85.2900                /* register video device */ 

86.2901                dev_dbg(vpif_dev, "trying to register vpif device.\n"); 

87.2902                dev_dbg(vpif_dev, "channel=%x,channel->video_dev=%x\n", 

88.2903                        (int)channel, (int)&channel->video_dev); 

89.2904                channel->common[VPIF_VIDEO_INDEX].fmt.type = 

90.2905                    V4L2_BUF_TYPE_VIDEO_OUTPUT; 

91.2906                channel->common[VPIF_VBI_INDEX].fmt.type = 

92.2907                    V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 

93.2908                channel->common[VPIF_HBI_INDEX].fmt.type = 

94.2909                    V4L2_BUF_TYPE_HBI_CAPTURE; 

95.2910                err = video_register_device(channel->video_dev, 

96.2911                                            VFL_TYPE_GRABBER, vpif_nr[j]); 

97.2912                if (err) 

98.2913                        goto probe_out; 

99.2914         } 

100.2915         return 0; 

101.2916  

102.2917 probe_out: 

103.2918         for (k = 0; k < j;k++) { 

104.2919                /* Get the pointer to the channel object */ 

105.2920                channel = vpif_obj.dev[k]; 

106.2921                /* Unregister video device */ 

107.2922                video_unregister_device(channel->video_dev); 

108.2923                /* Release video device */ 

109.2924                video_device_release(channel->video_dev); 

110.2925                channel->video_dev = NULL; 

111.2926         } 

112.2927         dev_dbg(vpif_dev,"</vpif_probe>\n"); 

113.2928         return err; 

114.2929 } 

structvideo_device  *vfd = vpif_video_template;

 

01.    vfd = vpif_video_template;是V4L2里面的video_device结构, 

02.    在drivers/media/video/davinci/davinci_capture.c中 

03.2809 static struct video_device vpif_video_template = { 

04.2810         .name ="vpif",  

05.2811         .type =VID_TYPE_CAPTURE, 

06.2812         .hardware = 0, 

07.2813         .fops =&vpif_fops,.minor = -1, 

08.2814 };  

09. 

10.2801 static struct file_operations vpif_fops = { 

11.2802         .owner =THIS_MODULE, 

12.2803         .open = vpif_open,//打开设备做一些初始化工作 

13.2804         .release =vpif_release, //释放资源 

14.2805         .ioctl = vpif_ioctl,//控制命令包括V4L2的命令和自定义的命令 

15.2806         .mmap = vpif_mmap,//映射内核空间内存到用户空间 

16.2807         .poll =vpif_poll        

17.2808};                        

 

vpif_ioctl的一些控制命令

 

vpif_ioctl封装了一些自定义的命了和V4L2的命令,其中V4L2的命令主要在vpif_doioctl实现。

 

01./* If the case is for querying capabilities */ 

02.           caseVIDIOC_QUERYCAP: 

03.              /* If the case is for enumerating inputs */ 

04.           caseVIDIOC_ENUMINPUT: 

05.              /* If the case is for getting input */ 

06.           caseVIDIOC_G_INPUT: 

07.              /* If the case is for setting input */ 

08.           caseVIDIOC_S_INPUT: 

09.              /* If the case is for enumerating standards */ 

10.           caseVIDIOC_ENUMSTD: 

11.              /* If the case is for querying standards */ 

12.           caseVIDIOC_QUERYSTD: 

13.              /* If the case is for getting standard */ 

14.           caseVIDIOC_G_STD: 

15.              /* If the case is for setting standard */ 

16.           caseVIDIOC_S_STD: 

17.              /* If the case is for enumerating formats */ 

18.           caseVIDIOC_ENUM_FMT: 

19.              /* If the case is for getting formats */ 

20.           caseVIDIOC_G_FMT: 

21.              /* If the case is for setting formats */ 

22.           caseVIDIOC_S_FMT: 

23.              /* If the case is for trying formats */ 

24.           caseVIDIOC_TRY_FMT: 

25.              /* If the case is for querying controls */ 

26.           caseVIDIOC_QUERYCTRL: 

27.              /* If the case is for getting controls value */ 

28.           caseVIDIOC_G_CTRL: 

29.              /* If the case is for getting controls value */ 

30.           caseVIDIOC_S_CTRL: 

31.              /* If the case is for getting decoder parameters */ 

32.           caseVPIF_CMD_G_DECODER_PARAMS: 

33.              /* If the case is for setting decoder parameters */ 

34.           caseVPIF_CMD_S_DECODER_PARAMS: 

35.              /* If the case is for requesting buffer allocation */ 

36.           caseVIDIOC_REQBUFS: 

37.              /* If the case is for en-queing buffer in the buffer

38.               * queue */ 

39.           caseVIDIOC_QBUF: 

40.              /* If the case is for de-queing buffer from the buffer queue */ 

41.           caseVIDIOC_DQBUF: 

42.             /*If the case is for querying information about

43.               *  buffer for memory mapping io */ 

44.           caseVIDIOC_QUERYBUF: 

45.              /* If the case is starting streaming */ 

46.           caseVIDIOC_STREAMON: 

47.              /* If the case is for stopping streaming */ 

48.           caseVIDIOC_STREAMOFF: 

49.              /* If the case is for setting VPIF parameters */ 

50.           caseVPIF_S_VPIF_PARAMS: 

51.              /* If the case is for getting VPIF Parameters */ 

52.           caseVPIF_G_VPIF_PARAMS: 

53.              /* If the case is for getting TVP5146 parameters */ 

54.           caseVPFE_CMD_CONFIG_TVP5146: 

55.              /* If the case is for setting mt9t001 parameters */ 

56.           caseVPFE_S_MT9T001_PARAMS: 

57.              /* If the case is for setting mt9t001 parameters */ 

58.           caseVPFE_G_MT9T001_PARAMS: 

59.           case VIDIOC_S_PRIORITY: 

60.           caseVIDIOC_G_PRIORITY: 

61.              /* If the case is for getting sliced vbi capabilites */ 

62.           caseVIDIOC_G_SLICED_VBI_CAP: 

63.              /* If the case if for getting cropping parameters */ 

64.           caseVIDIOC_CROPCAP: 

65.           caseVPIF_RESYNC: 

66.           caseVPIF_RESET: 

 

例如使用VIDIOC_ENUMSTD查询标准的时候,大概流程是这样的

 

1、首先判断是芯片驱动std_ops和dec->std_ops->enumstd是否有完成,如果没有完成则返回失败。

 

2、判断index是否是合法的

 

3、最后使用dec->std_ops->enumstd(std, dec),这个会函数直接调用芯片驱动的的xxx_enumstd函数(如sii9013_enumstd)。

 

具体代码如下:

 

01.1377                /* If the case is for enumerating standards */ 

02.1378            case VIDIOC_ENUMSTD: 

03.1379                { 

04.1380                    struct v4l2_standard *std = (struct v4l2_standard *)arg; 

05.1381                    struct video_obj *vid_ch = &(channel->video); 

06.1382                    int index = std->index, dec_idx; 

07.1383                    dev_dbg(vpif_dev, "VIDIOC_ENUMSTD\n"); 

08.1384  

09.1385  

10.1386                    /* Call enumstd function of decoder device */ 

11.1387                    if (ISNULL(dec->std_ops) 

12.1388                            || ISNULL(dec->std_ops->enumstd)) { 

13.1389                        dev_err(vpif_dev, "vpif_doioctl:No enumstd\n"); 

14.1390                        return -EINVAL; 

15.1391                    } 

16.1392                    if (index >= vid_ch->count_std) { 

17.1393                        dev_err(vpif_dev, "Invalid index\n"); 

18.1394                        return -EINVAL; 

19.1395                    } 

20.1396                    dec_idx = vid_ch->std_tbl[index].dec_idx; 

21.1397                    dec = channel->decoder[dec_idx]; 

22.1398                    std->index = vid_ch->std_tbl[index].std_idx; 

23.1399                    ret = dec->std_ops->enumstd(std, dec); 

24.1400                    std->index = index; 

25.1401                    break; 

26.1402                } 

 主要是记录了一些流程,具体的问题没有进行分析,相关芯片的驱动分析可以查阅前面的分析记录。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: