vivid驱动 —— virtual video test driver

结构体

struct vivid_dev

解析:
unsigned inst: 实例序号
struct v4l2_device v4l2_dev: v4l2设备

#ifdef CONFIG_MEDIA_CONTROLLER
	struct media_device		mdev;
	struct media_pad		vid_cap_pad;
	struct media_pad		vid_out_pad;
	struct media_pad		vbi_cap_pad;
	struct media_pad		vbi_out_pad;
	struct media_pad		sdr_cap_pad;
#endif

media设备以及各个节点的media_pad。

	struct v4l2_ctrl_handler	ctrl_hdl_user_gen;
	struct v4l2_ctrl_handler	ctrl_hdl_user_vid;
	struct v4l2_ctrl_handler	ctrl_hdl_user_aud;
	struct v4l2_ctrl_handler	ctrl_hdl_streaming;
	struct v4l2_ctrl_handler	ctrl_hdl_sdtv_cap;
	struct v4l2_ctrl_handler	ctrl_hdl_loop_cap;
	struct v4l2_ctrl_handler	ctrl_hdl_fb;
	struct video_device		vid_cap_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_vid_cap;
	struct video_device		vid_out_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_vid_out;
	struct video_device		vbi_cap_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_vbi_cap;
	struct video_device		vbi_out_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_vbi_out;
	struct video_device		radio_rx_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_radio_rx;
	struct video_device		radio_tx_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_radio_tx;
	struct video_device		sdr_cap_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_sdr_cap;
	spinlock_t			slock;
	struct mutex			mutex;

一些v4l2控制句柄以及要创建的video设备节点,vivid驱动 中所有类型的设备都有video设备节点。

	/* capabilities */
	u32				vid_cap_caps;
	u32				vid_out_caps;
	u32				vbi_cap_caps;
	u32				vbi_out_caps;
	u32				sdr_cap_caps;
	u32				radio_rx_caps;
	u32				radio_tx_caps;

每个类型的设备节点的能力集,组合起来就是当前vivid设备的能力集。
bool multiplanar: 是否支持多planar
unsigned num_inputs: 有几个输入设备,默认4个:0 = WEBCAM, 1 = TV, 2 = SVID, 3 = HDMI
u8 input_type[MAX_INPUTS];: 输入设备的类型,最多16个
u8 input_name_counter[MAX_INPUTS];: 每个输入类型设备的数量

	bool				has_audio_inputs;
	bool				has_audio_outputs;
	bool				has_vid_cap;
	bool				has_vid_out;
	bool				has_vbi_cap;
	bool				has_raw_vbi_cap;
	bool				has_sliced_vbi_cap;
	bool				has_vbi_out;
	bool				has_raw_vbi_out;
	bool				has_sliced_vbi_out;
	bool				has_radio_rx;
	bool				has_radio_tx;
	bool				has_sdr_cap;
	bool				has_fb;

有没有对应的设备。

	/* controls */
	struct v4l2_ctrl		*brightness;
	struct v4l2_ctrl		*contrast;
	struct v4l2_ctrl		*saturation;
	struct v4l2_ctrl		*hue;
	struct {
		/* autogain/gain cluster */
		struct v4l2_ctrl	*autogain;
		struct v4l2_ctrl	*gain;
	};
	struct v4l2_ctrl		*volume;
	struct v4l2_ctrl		*mute;
	struct v4l2_ctrl		*alpha;
	struct v4l2_ctrl		*button;
	struct v4l2_ctrl		*boolean;
	struct v4l2_ctrl		*int32;
	struct v4l2_ctrl		*int64;
	struct v4l2_ctrl		*menu;
	struct v4l2_ctrl		*string;
	struct v4l2_ctrl		*bitmask;
	struct v4l2_ctrl		*int_menu;
	struct v4l2_ctrl		*test_pattern;
	struct v4l2_ctrl		*colorspace;
	struct v4l2_ctrl		*rgb_range_cap;
	struct v4l2_ctrl		*real_rgb_range_cap;
	struct {
		/* std_signal_mode/standard cluster */
		struct v4l2_ctrl	*ctrl_std_signal_mode;
		struct v4l2_ctrl	*ctrl_standard;
	};
	struct {
		/* dv_timings_signal_mode/timings cluster */
		struct v4l2_ctrl	*ctrl_dv_timings_signal_mode;
		struct v4l2_ctrl	*ctrl_dv_timings;
	};
	struct v4l2_ctrl		*ctrl_display_present;
	struct v4l2_ctrl		*ctrl_has_crop_cap;
	struct v4l2_ctrl		*ctrl_has_compose_cap;
	struct v4l2_ctrl		*ctrl_has_scaler_cap;
	struct v4l2_ctrl		*ctrl_has_crop_out;
	struct v4l2_ctrl		*ctrl_has_compose_out;
	struct v4l2_ctrl		*ctrl_has_scaler_out;
	struct v4l2_ctrl		*ctrl_tx_mode;
	struct v4l2_ctrl		*ctrl_tx_rgb_range;
	struct v4l2_ctrl		*ctrl_tx_edid_present;
	struct v4l2_ctrl		*ctrl_tx_hotplug;
	struct v4l2_ctrl		*ctrl_tx_rxsense;

	struct v4l2_ctrl		*ctrl_rx_power_present;

	struct v4l2_ctrl		*radio_tx_rds_pi;
	struct v4l2_ctrl		*radio_tx_rds_pty;
	struct v4l2_ctrl		*radio_tx_rds_mono_stereo;
	struct v4l2_ctrl		*radio_tx_rds_art_head;
	struct v4l2_ctrl		*radio_tx_rds_compressed;
	struct v4l2_ctrl		*radio_tx_rds_dyn_pty;
	struct v4l2_ctrl		*radio_tx_rds_ta;
	struct v4l2_ctrl		*radio_tx_rds_tp;
	struct v4l2_ctrl		*radio_tx_rds_ms;
	struct v4l2_ctrl		*radio_tx_rds_psname;
	struct v4l2_ctrl		*radio_tx_rds_radiotext;

	struct v4l2_ctrl		*radio_rx_rds_pty;
	struct v4l2_ctrl		*radio_rx_rds_ta;
	struct v4l2_ctrl		*radio_rx_rds_tp;
	struct v4l2_ctrl		*radio_rx_rds_ms;
	struct v4l2_ctrl		*radio_rx_rds_psname;
	struct v4l2_ctrl		*radio_rx_rds_radiotext;

v4l2_ctrl节点,与v4l2_ctrl_ref以及ctrl_handler关系参考以下链接:
链接: V4L2 control结构框架图
unsigned input_brightness[MAX_INPUTS];: 构造图像入参

	/* Framebuffer */
	unsigned long			video_pbase;
	void				*video_vbase;
	u32				video_buffer_size;
	int				display_width;
	int				display_height;
	int				display_byte_stride;
	int				bits_per_pixel;
	int				bytes_per_pixel;
	struct fb_info			fb_info;
	struct fb_var_screeninfo	fb_defined;
	struct fb_fix_screeninfo	fb_fix;

frame buffer相关参数,物理地址、虚拟地址、长宽、pixel

结构体原型:

struct vivid_dev {
	unsigned			inst;
	struct v4l2_device		v4l2_dev;
#ifdef CONFIG_MEDIA_CONTROLLER
	struct media_device		mdev;
	struct media_pad		vid_cap_pad;
	struct media_pad		vid_out_pad;
	struct media_pad		vbi_cap_pad;
	struct media_pad		vbi_out_pad;
	struct media_pad		sdr_cap_pad;
#endif
	struct v4l2_ctrl_handler	ctrl_hdl_user_gen;
	struct v4l2_ctrl_handler	ctrl_hdl_user_vid;
	struct v4l2_ctrl_handler	ctrl_hdl_user_aud;
	struct v4l2_ctrl_handler	ctrl_hdl_streaming;
	struct v4l2_ctrl_handler	ctrl_hdl_sdtv_cap;
	struct v4l2_ctrl_handler	ctrl_hdl_loop_cap;
	struct v4l2_ctrl_handler	ctrl_hdl_fb;
	struct video_device		vid_cap_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_vid_cap;
	struct video_device		vid_out_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_vid_out;
	struct video_device		vbi_cap_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_vbi_cap;
	struct video_device		vbi_out_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_vbi_out;
	struct video_device		radio_rx_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_radio_rx;
	struct video_device		radio_tx_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_radio_tx;
	struct video_device		sdr_cap_dev;
	struct v4l2_ctrl_handler	ctrl_hdl_sdr_cap;
	spinlock_t			slock;
	struct mutex			mutex;

	/* capabilities */
	u32				vid_cap_caps;
	u32				vid_out_caps;
	u32				vbi_cap_caps;
	u32				vbi_out_caps;
	u32				sdr_cap_caps;
	u32				radio_rx_caps;
	u32				radio_tx_caps;

	/* supported features */
	bool				multiplanar;
	unsigned			num_inputs;
	unsigned int			num_hdmi_inputs;
	u8				input_type[MAX_INPUTS];
	u8				input_name_counter[MAX_INPUTS];
	unsigned			num_outputs;
	unsigned int			num_hdmi_outputs;
	u8				output_type[MAX_OUTPUTS];
	u8				output_name_counter[MAX_OUTPUTS];
	bool				has_audio_inputs;
	bool				has_audio_outputs;
	bool				has_vid_cap;
	bool				has_vid_out;
	bool				has_vbi_cap;
	bool				has_raw_vbi_cap;
	bool				has_sliced_vbi_cap;
	bool				has_vbi_out;
	bool				has_raw_vbi_out;
	bool				has_sliced_vbi_out;
	bool				has_radio_rx;
	bool				has_radio_tx;
	bool				has_sdr_cap;
	bool				has_fb;

	bool				can_loop_video;

	/* controls */
	struct v4l2_ctrl		*brightness;
	struct v4l2_ctrl		*contrast;
	struct v4l2_ctrl		*saturation;
	struct v4l2_ctrl		*hue;
	struct {
		/* autogain/gain cluster */
		struct v4l2_ctrl	*autogain;
		struct v4l2_ctrl	*gain;
	};
	struct v4l2_ctrl		*volume;
	struct v4l2_ctrl		*mute;
	struct v4l2_ctrl		*alpha;
	struct v4l2_ctrl		*button;
	struct v4l2_ctrl		*boolean;
	struct v4l2_ctrl		*int32;
	struct v4l2_ctrl		*int64;
	struct v4l2_ctrl		*menu;
	struct v4l2_ctrl		*string;
	struct v4l2_ctrl		*bitmask;
	struct v4l2_ctrl		*int_menu;
	struct v4l2_ctrl		*test_pattern;
	struct v4l2_ctrl		*colorspace;
	struct v4l2_ctrl		*rgb_range_cap;
	struct v4l2_ctrl		*real_rgb_range_cap;
	struct {
		/* std_signal_mode/standard cluster */
		struct v4l2_ctrl	*ctrl_std_signal_mode;
		struct v4l2_ctrl	*ctrl_standard;
	};
	struct {
		/* dv_timings_signal_mode/timings cluster */
		struct v4l2_ctrl	*ctrl_dv_timings_signal_mode;
		struct v4l2_ctrl	*ctrl_dv_timings;
	};
	struct v4l2_ctrl		*ctrl_display_present;
	struct v4l2_ctrl		*ctrl_has_crop_cap;
	struct v4l2_ctrl		*ctrl_has_compose_cap;
	struct v4l2_ctrl		*ctrl_has_scaler_cap;
	struct v4l2_ctrl		*ctrl_has_crop_out;
	struct v4l2_ctrl		*ctrl_has_compose_out;
	struct v4l2_ctrl		*ctrl_has_scaler_out;
	struct v4l2_ctrl		*ctrl_tx_mode;
	struct v4l2_ctrl		*ctrl_tx_rgb_range;
	struct v4l2_ctrl		*ctrl_tx_edid_present;
	struct v4l2_ctrl		*ctrl_tx_hotplug;
	struct v4l2_ctrl		*ctrl_tx_rxsense;

	struct v4l2_ctrl		*ctrl_rx_power_present;

	struct v4l2_ctrl		*radio_tx_rds_pi;
	struct v4l2_ctrl		*radio_tx_rds_pty;
	struct v4l2_ctrl		*radio_tx_rds_mono_stereo;
	struct v4l2_ctrl		*radio_tx_rds_art_head;
	struct v4l2_ctrl		*radio_tx_rds_compressed;
	struct v4l2_ctrl		*radio_tx_rds_dyn_pty;
	struct v4l2_ctrl		*radio_tx_rds_ta;
	struct v4l2_ctrl		*radio_tx_rds_tp;
	struct v4l2_ctrl		*radio_tx_rds_ms;
	struct v4l2_ctrl		*radio_tx_rds_psname;
	struct v4l2_ctrl		*radio_tx_rds_radiotext;

	struct v4l2_ctrl		*radio_rx_rds_pty;
	struct v4l2_ctrl		*radio_rx_rds_ta;
	struct v4l2_ctrl		*radio_rx_rds_tp;
	struct v4l2_ctrl		*radio_rx_rds_ms;
	struct v4l2_ctrl		*radio_rx_rds_psname;
	struct v4l2_ctrl		*radio_rx_rds_radiotext;

	unsigned			input_brightness[MAX_INPUTS];
	unsigned			osd_mode;
	unsigned			button_pressed;
	bool				sensor_hflip;
	bool				sensor_vflip;
	bool				hflip;
	bool				vflip;
	bool				vbi_cap_interlaced;
	bool				loop_video;
	bool				reduced_fps;

	/* Framebuffer */
	unsigned long			video_pbase;
	void				*video_vbase;
	u32				video_buffer_size;
	int				display_width;
	int				display_height;
	int				display_byte_stride;
	int				bits_per_pixel;
	int				bytes_per_pixel;
	struct fb_info			fb_info;
	struct fb_var_screeninfo	fb_defined;
	struct fb_fix_screeninfo	fb_fix;

	/* Error injection */
	bool				queue_setup_error;
	bool				buf_prepare_error;
	bool				start_streaming_error;
	bool				dqbuf_error;
	bool				req_validate_error;
	bool				seq_wrap;
	bool				time_wrap;
	u64				time_wrap_offset;
	unsigned			perc_dropped_buffers;
	enum vivid_signal_mode		std_signal_mode[MAX_INPUTS];
	unsigned int			query_std_last[MAX_INPUTS];
	v4l2_std_id			query_std[MAX_INPUTS];
	enum tpg_video_aspect		std_aspect_ratio[MAX_INPUTS];

	enum vivid_signal_mode		dv_timings_signal_mode[MAX_INPUTS];
	char				**query_dv_timings_qmenu;
	char				*query_dv_timings_qmenu_strings;
	unsigned			query_dv_timings_size;
	unsigned int			query_dv_timings_last[MAX_INPUTS];
	unsigned int			query_dv_timings[MAX_INPUTS];
	enum tpg_video_aspect		dv_timings_aspect_ratio[MAX_INPUTS];

	/* Input */
	unsigned			input;
	v4l2_std_id			std_cap[MAX_INPUTS];
	struct v4l2_dv_timings		dv_timings_cap[MAX_INPUTS];
	int				dv_timings_cap_sel[MAX_INPUTS];
	u32				service_set_cap;
	struct vivid_vbi_gen_data	vbi_gen;
	u8				*edid;
	unsigned			edid_blocks;
	unsigned			edid_max_blocks;
	unsigned			webcam_size_idx;
	unsigned			webcam_ival_idx;
	unsigned			tv_freq;
	unsigned			tv_audmode;
	unsigned			tv_field_cap;
	unsigned			tv_audio_input;

	u32				power_present;

	/* Capture Overlay */
	struct v4l2_framebuffer		fb_cap;
	struct v4l2_fh			*overlay_cap_owner;
	void				*fb_vbase_cap;
	int				overlay_cap_top, overlay_cap_left;
	enum v4l2_field			overlay_cap_field;
	void				*bitmap_cap;
	struct v4l2_clip		clips_cap[MAX_CLIPS];
	struct v4l2_clip		try_clips_cap[MAX_CLIPS];
	unsigned			clipcount_cap;

	/* Output */
	unsigned			output;
	v4l2_std_id			std_out;
	struct v4l2_dv_timings		dv_timings_out;
	u32				colorspace_out;
	u32				ycbcr_enc_out;
	u32				hsv_enc_out;
	u32				quantization_out;
	u32				xfer_func_out;
	u32				service_set_out;
	unsigned			bytesperline_out[TPG_MAX_PLANES];
	unsigned			tv_field_out;
	unsigned			tv_audio_output;
	bool				vbi_out_have_wss;
	u8				vbi_out_wss[2];
	bool				vbi_out_have_cc[2];
	u8				vbi_out_cc[2][2];
	bool				dvi_d_out;
	u8				*scaled_line;
	u8				*blended_line;
	unsigned			cur_scaled_line;
	bool				display_present[MAX_OUTPUTS];

	/* Output Overlay */
	void				*fb_vbase_out;
	bool				overlay_out_enabled;
	int				overlay_out_top, overlay_out_left;
	void				*bitmap_out;
	struct v4l2_clip		clips_out[MAX_CLIPS];
	struct v4l2_clip		try_clips_out[MAX_CLIPS];
	unsigned			clipcount_out;
	unsigned			fbuf_out_flags;
	u32				chromakey_out;
	u8				global_alpha_out;

	/* video capture */
	struct tpg_data			tpg;
	unsigned			ms_vid_cap;
	bool				must_blank[VIDEO_MAX_FRAME];

	const struct vivid_fmt		*fmt_cap;
	struct v4l2_fract		timeperframe_vid_cap;
	enum v4l2_field			field_cap;
	struct v4l2_rect		src_rect;
	struct v4l2_rect		fmt_cap_rect;
	struct v4l2_rect		crop_cap;
	struct v4l2_rect		compose_cap;
	struct v4l2_rect		crop_bounds_cap;
	struct vb2_queue		vb_vid_cap_q;
	struct list_head		vid_cap_active;
	struct vb2_queue		vb_vbi_cap_q;
	struct list_head		vbi_cap_active;

	/* thread for generating video capture stream */
	struct task_struct		*kthread_vid_cap;
	unsigned long			jiffies_vid_cap;
	u64				cap_stream_start;
	u64				cap_frame_period;
	u64				cap_frame_eof_offset;
	u32				cap_seq_offset;
	u32				cap_seq_count;
	bool				cap_seq_resync;
	u32				vid_cap_seq_start;
	u32				vid_cap_seq_count;
	bool				vid_cap_streaming;
	u32				vbi_cap_seq_start;
	u32				vbi_cap_seq_count;
	bool				vbi_cap_streaming;
	bool				stream_sliced_vbi_cap;

	/* video output */
	const struct vivid_fmt		*fmt_out;
	struct v4l2_fract		timeperframe_vid_out;
	enum v4l2_field			field_out;
	struct v4l2_rect		sink_rect;
	struct v4l2_rect		fmt_out_rect;
	struct v4l2_rect		crop_out;
	struct v4l2_rect		compose_out;
	struct v4l2_rect		compose_bounds_out;
	struct vb2_queue		vb_vid_out_q;
	struct list_head		vid_out_active;
	struct vb2_queue		vb_vbi_out_q;
	struct list_head		vbi_out_active;

	/* video loop precalculated rectangles */

	/*
	 * Intersection between what the output side composes and the capture side
	 * crops. I.e., what actually needs to be copied from the output buffer to
	 * the capture buffer.
	 */
	struct v4l2_rect		loop_vid_copy;
	/* The part of the output buffer that (after scaling) corresponds to loop_vid_copy. */
	struct v4l2_rect		loop_vid_out;
	/* The part of the capture buffer that (after scaling) corresponds to loop_vid_copy. */
	struct v4l2_rect		loop_vid_cap;
	/*
	 * The intersection of the framebuffer, the overlay output window and
	 * loop_vid_copy. I.e., the part of the framebuffer that actually should be
	 * blended with the compose_out rectangle. This uses the framebuffer origin.
	 */
	struct v4l2_rect		loop_fb_copy;
	/* The same as loop_fb_copy but with compose_out origin. */
	struct v4l2_rect		loop_vid_overlay;
	/*
	 * The part of the capture buffer that (after scaling) corresponds
	 * to loop_vid_overlay.
	 */
	struct v4l2_rect		loop_vid_overlay_cap;

	/* thread for generating video output stream */
	struct task_struct		*kthread_vid_out;
	unsigned long			jiffies_vid_out;
	u32				out_seq_offset;
	u32				out_seq_count;
	bool				out_seq_resync;
	u32				vid_out_seq_start;
	u32				vid_out_seq_count;
	bool				vid_out_streaming;
	u32				vbi_out_seq_start;
	u32				vbi_out_seq_count;
	bool				vbi_out_streaming;
	bool				stream_sliced_vbi_out;

	/* SDR capture */
	struct vb2_queue		vb_sdr_cap_q;
	struct list_head		sdr_cap_active;
	u32				sdr_pixelformat; /* v4l2 format id */
	unsigned			sdr_buffersize;
	unsigned			sdr_adc_freq;
	unsigned			sdr_fm_freq;
	unsigned			sdr_fm_deviation;
	int				sdr_fixp_src_phase;
	int				sdr_fixp_mod_phase;

	bool				tstamp_src_is_soe;
	bool				has_crop_cap;
	bool				has_compose_cap;
	bool				has_scaler_cap;
	bool				has_crop_out;
	bool				has_compose_out;
	bool				has_scaler_out;

	/* thread for generating SDR stream */
	struct task_struct		*kthread_sdr_cap;
	unsigned long			jiffies_sdr_cap;
	u32				sdr_cap_seq_offset;
	u32				sdr_cap_seq_count;
	bool				sdr_cap_seq_resync;

	/* RDS generator */
	struct vivid_rds_gen		rds_gen;

	/* Radio receiver */
	unsigned			radio_rx_freq;
	unsigned			radio_rx_audmode;
	int				radio_rx_sig_qual;
	unsigned			radio_rx_hw_seek_mode;
	bool				radio_rx_hw_seek_prog_lim;
	bool				radio_rx_rds_controls;
	bool				radio_rx_rds_enabled;
	unsigned			radio_rx_rds_use_alternates;
	unsigned			radio_rx_rds_last_block;
	struct v4l2_fh			*radio_rx_rds_owner;

	/* Radio transmitter */
	unsigned			radio_tx_freq;
	unsigned			radio_tx_subchans;
	bool				radio_tx_rds_controls;
	unsigned			radio_tx_rds_last_block;
	struct v4l2_fh			*radio_tx_rds_owner;

	/* Shared between radio receiver and transmitter */
	bool				radio_rds_loop;
	ktime_t				radio_rds_init_time;

	/* CEC */
	struct cec_adapter		*cec_rx_adap;
	struct cec_adapter		*cec_tx_adap[MAX_OUTPUTS];
	struct workqueue_struct		*cec_workqueue;
	spinlock_t			cec_slock;
	struct list_head		cec_work_list;
	unsigned int			cec_xfer_time_jiffies;
	unsigned long			cec_xfer_start_jiffies;
	u8				cec_output2bus_map[MAX_OUTPUTS];

	/* CEC OSD String */
	char				osd[14];
	unsigned long			osd_jiffies;
};

函数解析

vivid_init

函数原型:
static int __init vivid_init(void)
vivid驱动入口,注册vivid设备和vivid驱动

vivid_probe

函数原型:
static int vivid_probe(struct platform_device *pdev)
vivid驱动程序probe回调,根据驱动入参创建devs,调用vivid_create_instance创建设备节点。

vivid_create_instance

函数原型:
static int vivid_create_instance(struct platform_device *pdev, int inst)
vivid驱动实际入口,初始化vivid设备框架。
在这里插入图片描述

vivid驱动调用了哪些V4L2接口

  1. v4l2_ctrl_log_status:记录当前ctrl_handler所有控制字的状态。在vidioc_log_status中被调用,是struct v4l2_ioctl_ops vivid_ioctl_ops.vidioc_log_status()的回调。
  2. v4l2_fh_is_singular_file:当前video_device是否只打开了一个filehandle。在vivid_fop_release中被调用。
  3. v4l2_fh_release:release filehandle,在vivid_fop_release中被调用。
  4. v4l2_fh_open:open filehandle,作为struct v4l2_file_operations vivid_fops.open()的回调。
  5. v4l2_event_unsubscribe:解除v4l2_event_subscribed设置的订阅,作为struct v4l2_ioctl_ops vivid_ioctl_ops.vidioc_unsubscribe_event()的回调。
  6. v4l2_disable_ioctl:去使能video_device下挂的ioctl项
  7. v4l2_device_register:注册v4l2主设备
  8. v4l2_device_put:释放v4l2 device。
  9. __v4l2_ctrl_s_ctrl:配置ctrl控制字的值,并更新ctrl。
  10. v4l2_ctrl_s_ctrl:带锁的__v4l2_ctrl_s_ctrl
  11. v4l2_ctrl_handler_init:初始化ctrl_handler。
  12. v4l2_ctrl_new_custom:为ctrl_handler添加自定义控制字。
  13. v4l2_ctrl_new_std:为ctrl_handler添加标准控制字。
  14. v4l2_ctrl_handler_setup:初始化ctrl handler下所有的控制字。
  15. v4l2_ctrl_activate:使能、去使能一个ctrl handler。
  16. v4l2_ctrl_cluster:指定的ctrl 列表中一定数量的ctrl 进行合并,所有合并之后的控制ID 均被指向合并列表中的第一个控制ID 项。
  17. v4l2_ctrl_auto_cluster
  18. v4l2_ctrl_add_handler:把其他handler里的控制字加入到当前handler。
  19. v4l2_ctrl_handler_free
  20. v4l2_rect_intersect:计算两个矩形的交集
  21. v4l2_rect_scale:
  22. v4l2_ctrl_g_ctrl:获取ctrl控制字的值。
  23. v4l2_ctrl_request_setup:
  24. v4l2_ctrl_request_complete:
  25. v4l2_ctrl_grab:使能/去使能ctrl,一般在开关流的时候用。
  26. v4l2_ctrl_poll:调用poll_wait
  27. v4l2_find_nearest_size:
  28. v4l2_rect_set_min_size:
  29. v4l2_rect_set_max_size:
  30. v4l2_rect_map_inside:
  31. v4l2_rect_set_size_to
  32. v4l2_rect_same_size
  33. v4l2_rect_overlap
  34. v4l2_ctrl_modify_range
  35. v4l2_valid_dv_timings
  36. v4l2_detect_cvt
  37. v4l2_detect_gtf
  38. v4l2_find_dv_timings_cap
  39. v4l2_match_dv_timings
  40. v4l2_dv_timings_presets
  41. v4l2_phys_addr_validate:
  42. v4l2_phys_addr_for_input
  43. v4l2_event_queue
  44. v4l2_enum_dv_timings_cap
  45. v4l2_src_change_event_subscribe:
  46. v4l2_ctrl_subscribe_event

流程图

vivid ctrl_handle连接关系图

在这里插入图片描述

都有哪些ops

vivid_fops

注册video device时提供的ops,作为文件操作的回调

static const struct v4l2_file_operations vivid_fops = {
	.owner		= THIS_MODULE,
	.open           = v4l2_fh_open,
	.release        = vivid_fop_release,
	.read           = vb2_fop_read,
	.write          = vb2_fop_write,
	.poll		= vb2_fop_poll,
	.unlocked_ioctl = video_ioctl2,
	.mmap           = vb2_fop_mmap,
};

vivid_radio_fops

注册radio的video device时提供的ops,作为文件操作的回调

static const struct v4l2_file_operations vivid_radio_fops = {
	.owner		= THIS_MODULE,
	.open           = v4l2_fh_open,
	.release        = vivid_fop_release,
	.read           = vivid_radio_read,
	.write          = vivid_radio_write,
	.poll		= vivid_radio_poll,
	.unlocked_ioctl = video_ioctl2,
};

vivid_ioctl_ops

注册video device时提供的ops,作为ioctl的回调

static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
	.vidioc_querycap		= vidioc_querycap,

	.vidioc_enum_fmt_vid_cap	= vivid_enum_fmt_vid,
	.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_g_fmt_vid_cap_mplane	= vidioc_g_fmt_vid_cap_mplane,
	.vidioc_try_fmt_vid_cap_mplane	= vidioc_try_fmt_vid_cap_mplane,
	.vidioc_s_fmt_vid_cap_mplane	= vidioc_s_fmt_vid_cap_mplane,

	.vidioc_enum_fmt_vid_out	= vivid_enum_fmt_vid,
	.vidioc_g_fmt_vid_out		= vidioc_g_fmt_vid_out,
	.vidioc_try_fmt_vid_out		= vidioc_try_fmt_vid_out,
	.vidioc_s_fmt_vid_out		= vidioc_s_fmt_vid_out,
	.vidioc_g_fmt_vid_out_mplane	= vidioc_g_fmt_vid_out_mplane,
	.vidioc_try_fmt_vid_out_mplane	= vidioc_try_fmt_vid_out_mplane,
	.vidioc_s_fmt_vid_out_mplane	= vidioc_s_fmt_vid_out_mplane,

	.vidioc_g_selection		= vidioc_g_selection,
	.vidioc_s_selection		= vidioc_s_selection,
	.vidioc_g_pixelaspect		= vidioc_g_pixelaspect,

	.vidioc_g_fmt_vbi_cap		= vidioc_g_fmt_vbi_cap,
	.vidioc_try_fmt_vbi_cap		= vidioc_g_fmt_vbi_cap,
	.vidioc_s_fmt_vbi_cap		= vidioc_s_fmt_vbi_cap,

	.vidioc_g_fmt_sliced_vbi_cap    = vidioc_g_fmt_sliced_vbi_cap,
	.vidioc_try_fmt_sliced_vbi_cap  = vidioc_try_fmt_sliced_vbi_cap,
	.vidioc_s_fmt_sliced_vbi_cap    = vidioc_s_fmt_sliced_vbi_cap,
	.vidioc_g_sliced_vbi_cap	= vidioc_g_sliced_vbi_cap,

	.vidioc_g_fmt_vbi_out		= vidioc_g_fmt_vbi_out,
	.vidioc_try_fmt_vbi_out		= vidioc_g_fmt_vbi_out,
	.vidioc_s_fmt_vbi_out		= vidioc_s_fmt_vbi_out,

	.vidioc_g_fmt_sliced_vbi_out    = vidioc_g_fmt_sliced_vbi_out,
	.vidioc_try_fmt_sliced_vbi_out  = vidioc_try_fmt_sliced_vbi_out,
	.vidioc_s_fmt_sliced_vbi_out    = vidioc_s_fmt_sliced_vbi_out,

	.vidioc_enum_fmt_sdr_cap	= vidioc_enum_fmt_sdr_cap,
	.vidioc_g_fmt_sdr_cap		= vidioc_g_fmt_sdr_cap,
	.vidioc_try_fmt_sdr_cap		= vidioc_try_fmt_sdr_cap,
	.vidioc_s_fmt_sdr_cap		= vidioc_s_fmt_sdr_cap,

	.vidioc_overlay			= vidioc_overlay,
	.vidioc_enum_framesizes		= vidioc_enum_framesizes,
	.vidioc_enum_frameintervals	= vidioc_enum_frameintervals,
	.vidioc_g_parm			= vidioc_g_parm,
	.vidioc_s_parm			= vidioc_s_parm,

	.vidioc_enum_fmt_vid_overlay	= vidioc_enum_fmt_vid_overlay,
	.vidioc_g_fmt_vid_overlay	= vidioc_g_fmt_vid_overlay,
	.vidioc_try_fmt_vid_overlay	= vidioc_try_fmt_vid_overlay,
	.vidioc_s_fmt_vid_overlay	= vidioc_s_fmt_vid_overlay,
	.vidioc_g_fmt_vid_out_overlay	= vidioc_g_fmt_vid_out_overlay,
	.vidioc_try_fmt_vid_out_overlay	= vidioc_try_fmt_vid_out_overlay,
	.vidioc_s_fmt_vid_out_overlay	= vidioc_s_fmt_vid_out_overlay,
	.vidioc_g_fbuf			= vidioc_g_fbuf,
	.vidioc_s_fbuf			= vidioc_s_fbuf,

	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
	.vidioc_querybuf		= vb2_ioctl_querybuf,
	.vidioc_qbuf			= vb2_ioctl_qbuf,
	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
	.vidioc_expbuf			= vb2_ioctl_expbuf,
	.vidioc_streamon		= vb2_ioctl_streamon,
	.vidioc_streamoff		= vb2_ioctl_streamoff,

	.vidioc_enum_input		= vidioc_enum_input,
	.vidioc_g_input			= vidioc_g_input,
	.vidioc_s_input			= vidioc_s_input,
	.vidioc_s_audio			= vidioc_s_audio,
	.vidioc_g_audio			= vidioc_g_audio,
	.vidioc_enumaudio		= vidioc_enumaudio,
	.vidioc_s_frequency		= vidioc_s_frequency,
	.vidioc_g_frequency		= vidioc_g_frequency,
	.vidioc_s_tuner			= vidioc_s_tuner,
	.vidioc_g_tuner			= vidioc_g_tuner,
	.vidioc_s_modulator		= vidioc_s_modulator,
	.vidioc_g_modulator		= vidioc_g_modulator,
	.vidioc_s_hw_freq_seek		= vidioc_s_hw_freq_seek,
	.vidioc_enum_freq_bands		= vidioc_enum_freq_bands,

	.vidioc_enum_output		= vidioc_enum_output,
	.vidioc_g_output		= vidioc_g_output,
	.vidioc_s_output		= vidioc_s_output,
	.vidioc_s_audout		= vidioc_s_audout,
	.vidioc_g_audout		= vidioc_g_audout,
	.vidioc_enumaudout		= vidioc_enumaudout,

	.vidioc_querystd		= vidioc_querystd,
	.vidioc_g_std			= vidioc_g_std,
	.vidioc_s_std			= vidioc_s_std,
	.vidioc_s_dv_timings		= vidioc_s_dv_timings,
	.vidioc_g_dv_timings		= vidioc_g_dv_timings,
	.vidioc_query_dv_timings	= vidioc_query_dv_timings,
	.vidioc_enum_dv_timings		= vidioc_enum_dv_timings,
	.vidioc_dv_timings_cap		= vidioc_dv_timings_cap,
	.vidioc_g_edid			= vidioc_g_edid,
	.vidioc_s_edid			= vidioc_s_edid,

	.vidioc_log_status		= vidioc_log_status,
	.vidioc_subscribe_event		= vidioc_subscribe_event,
	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
};

用户态测试程序


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值