首页 > 学院 > 开发设计 > 正文

Video4Linux框架简介(4) - v4l2_ioctl_ops

2019-11-09 16:25:09
字体:
来源:转载
供稿:网友

译注:本节主要会介绍一些v4l2常用的ioctl回调函数,每个驱动开发者可根据硬件需要来做具体实现或者不做实现。

1. Input ioctls

vidioc_enum_input,顾名思义就是枚举输入,对于本示例驱动来说,有标准的S-Video输入和HDMI两种。

static int skeleton_enum_input(struct file *file, void *PRiv,struct v4l2_input *i){if (i->index > 1)return -EINVAL;i->type = V4L2_INPUT_TYPE_CAMERA; //指定输入类型,有V4L2_INPUT_TYPE_CAMERA和V4L2_INPUT_TYPE_TUNER两种if (i->index == 0) {i->std = V4L2_STD_ALL;strlcpy(i->name, "S-Video", sizeof(i->name));i->capabilities = V4L2_IN_CAP_STD;} else {i->std = 0;strlcpy(i->name, "HDMI", sizeof(i->name));i->capabilities = V4L2_IN_CAP_DV_TIMINGS;}return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_enum_input = skeleton_enum_input, //可以和之前的vidioc_query_cap放在一起,后面的也一样}; vidioc_g_input 和 vidioc_s_input

应用会调用这两个ioctl来设置和获取当前的input。

static int skeleton_s_input(struct file *file, void *priv, unsigned int i){struct skeleton *skel = video_drvdata(file);if (i > 1)return -EINVAL;skel->input = i;skel->vdev.tvnorms = i ? 0 : V4L2_STD_ALL;skeleton_fill_pix_format(skel, &skel->format); //和硬件相关return 0;}static int skeleton_g_input(struct file *file, void *priv, unsigned int *i){struct skeleton *skel = video_drvdata(file);*i = skel->input;return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_g_input = skeleton_g_input,.vidioc_s_input = skeleton_s_input,}; 2. SDTV Standards ioctls

vidioc_g_std和vidioc_s_std

获取/设置视频标准,在streaming状态下是不能做设置的。

static int skeleton_s_std(struct file *file, void *priv, v4l2_std_id std){struct skeleton *skel = video_drvdata(file);if (skel->input)return -ENODATA;if (std == skel->std)return 0;/* TODO: handle changing std */skel->std = std;skeleton_fill_pix_format(skel, &skel->format);return 0;}static int skeleton_g_std(struct file *file, void *priv, v4l2_std_id *std){struct skeleton *skel = video_drvdata(file);if (skel->input)return -ENODATA;*std = skel->std;return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_g_std = skeleton_g_std,.vidioc_s_std = skeleton_s_std,}; vidioc_querystd

static int skeleton_querystd(struct file *file, void *priv,v4l2_std_id *std){struct skeleton *skel = video_drvdata(file);if (skel->input)return -ENODATA;/* TODO: Query currently seen standard. */return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_querystd = skeleton_querystd,}; 3. DV Timings ioctls

vidioc_dv_timings_cap

static const struct v4l2_dv_timings_cap skel_timings_cap = {.type = V4L2_DV_BT_656_1120,/* keep this initialization for compatibility with GCC < 4.4.6 */.reserved = { 0 },V4L2_INIT_BT_TIMINGS(720, 1920, /* min/max width */480, 1080, /* min/max height */27000000, 74250000, /* min/max pixelclock*/V4L2_DV_BT_STD_CEA861, /* Supported standards *//* capabilities */V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE)};static int skeleton_dv_timings_cap(struct file *file, void *fh,struct v4l2_dv_timings_cap *cap){struct skeleton *skel = video_drvdata(file);if (skel->input == 0)return -ENODATA;*cap = skel_timings_cap;return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_dv_timings_cap = skeleton_dv_timings_cap,}; 

vidioc_s_dv_timings

static int skeleton_s_dv_timings(struct file *file, void *_fh,struct v4l2_dv_timings *timings){struct skeleton *skel = video_drvdata(file);if (skel->input == 0)return -ENODATA;if (!v4l2_valid_dv_timings(timings, &skel_timings_cap, NULL,NULL))return -EINVAL;if (!v4l2_find_dv_timings_cap(timings, &skel_timings_cap, 0, NULL,NULL))return -EINVAL;if (v4l2_match_dv_timings(timings, &skel->timings, 0))return 0;/* TODO: Configure new timings */skel->timings = *timings;skeleton_fill_pix_format(skel, &skel->format);return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_s_dv_timings = skeleton_s_dv_timings,}; vidioc_g_dv_timings & vidioc_enum_dv_timings

static int skeleton_g_dv_timings(struct file *file, void *_fh,struct v4l2_dv_timings *timings){struct skeleton *skel = video_drvdata(file);if (skel->input == 0)return -ENODATA;*timings = skel->timings;return 0;}static int skeleton_enum_dv_timings(struct file *file, void *_fh,struct v4l2_enum_dv_timings *timings){struct skeleton *skel = video_drvdata(file);if (skel->input == 0)return -ENODATA;return v4l2_enum_dv_timings_cap(timings, &skel_timings_cap, NULL, NULL);}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_g_dv_timings = skeleton_g_dv_timings,.vidioc_enum_dv_timings = skeleton_enum_dv_timings,}; vidioc_query_dv_timings

static int skeleton_query_dv_timings(struct file *file, void *_fh,struct v4l2_dv_timings *timings){struct skeleton *skel = video_drvdata(file);if (skel->input == 0)return -ENODATA;/* TODO: Query currently seen timings. */detect_timings();if (no_signal)return -ENOLINK;if (cannot_lock_to_signal)return -ENOLCK;if (signal_out_of_range_of_capabilities)return -ERANGE;/* Useful for debugging */if (debug)v4l2_print_dv_timings(skel->v4l2_dev.name,"query_dv_timings:",timings, true);return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_query_dv_timings = skeleton_query_dv_timings,}; 4. Format ioctls

static int skeleton_s_fmt_vid_cap(struct file *file, void *priv,struct v4l2_format *f){struct skeleton *skel = video_drvdata(file);int ret;ret = skeleton_try_fmt_vid_cap(file, priv, f);if (ret)return ret;/* TODO: change format */skel->format = f->fmt.pix;return 0;}static int skeleton_g_fmt_vid_cap(struct file *file, void *priv,struct v4l2_format *f){struct skeleton *skel = video_drvdata(file);f->fmt.pix = skel->format;return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_s_fmt_vid_cap = skeleton_s_fmt_vid_cap,.vidioc_g_fmt_vid_cap = skeleton_g_fmt_vid_cap,};
static int skeleton_enum_fmt_vid_cap(struct file *file, void *priv,struct v4l2_fmtdesc *f){if (f->index != 0)return -EINVAL;strlcpy(f->description, "4:2:2, packed, UYVY", sizeof(f->description));f->pixelformat = V4L2_PIX_FMT_UYVY;f->flags = 0;return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_enum_fmt_vid_cap = skeleton_enum_fmt_vid_cap,};
static void skeleton_fill_pix_format(struct skeleton *skel, struct v4l2_pix_format *pix){pix->pixelformat = V4L2_PIX_FMT_UYVY;if (skel->input == 0) {pix->width = 720;pix->height = (skel->std & V4L2_STD_525_60) ? 480 : 576;pix->field = V4L2_FIELD_INTERLACED;pix->colorspace = V4L2_COLORSPACE_SMPTE170M;} else {pix->width = skel->timings.bt.width;pix->height = skel->timings.bt.height;if (skel->timings.bt.interlaced)pix->field = V4L2_FIELD_INTERLACED;elsepix->field = V4L2_FIELD_NONE;pix->colorspace = V4L2_COLORSPACE_REC709;}pix->bytesperline = pix->width * 2;pix->sizeimage = pix->bytesperline * pix->height;pix->priv = 0;}static int skeleton_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f){struct skeleton *skel = video_drvdata(file);struct v4l2_pix_format *pix = &f->fmt.pix;if (pix->pixelformat != V4L2_PIX_FMT_UYVY)return -EINVAL;skeleton_fill_pix_format(skel, pix);return 0;}static const struct v4l2_ioctl_ops skel_ioctl_ops = {.vidioc_try_fmt_vid_cap = skeleton_try_fmt_vid_cap,} 


上一篇:aitivity去掉标题栏

下一篇:NDK开发

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表