二十四、V4L2框架主要结构体分析和虚拟摄像头驱动编写
一、V4L2框架主要结构体分析
V4L2(video for linux version 2),是内核中视频设备的驱动框架,为上层访问视频设备提供统一接口。
V4L2整体框架如下图:
图中主要包括两层和三个结构体:
两层是:
1. v4l2驱动核心层:包含video_device和v4l2_device的分配、设置和注册
2. v4l2下层接口层:具体的底层传感器驱动,现在的摄像头可能支持硬件解码,这就需要在摄像头驱动下面提供解码器IC驱动
三个结构体是:
1. v4l2_device:
structv4l2_device {/*dev->driver_data points to this struct.Note: dev might be NULL if there is no parent deviceas is the case with e.g. ISA devices.*/struct device *dev;/*used to keep track of the registered subdevs*/structlist_head subdevs;/*lock this struct; can be used by the driver as well if thisstruct is embedded into a larger struct.*/spinlock_tlock;/*unique device name, by default the driver name + bus ID*/charname[V4L2_DEVICE_NAME_SIZE];/*notify callback called by some sub-devices.*/void (*notify)(struct v4l2_subdev *sd,unsignedint notification, void *arg);/*The control handler. May be NULL.*/struct v4l2_ctrl_handler *ctrl_handler;/*Device's priority state*/structv4l2_prio_state prio;/*BKL replacement mutex. Temporary solution only.*/structmutex ioctl_lock;/*Keep track of the references to this struct.*/struct kref ref;/*Release function that is called when the ref count goes to 0.*/void (*release)(struct v4l2_device *v4l2_dev); };
View Code
2. video_device:
structvideo_device {const struct v4l2_file_operations *fops; /*文件操作函数*/struct device dev; /*v4l device*/struct cdev *cdev; /*character device*/struct device *parent; /*device parent*/struct v4l2_device *v4l2_dev; /*v4l2_device parent*//*Control handler associated with this device node. May be NULL.*/struct v4l2_ctrl_handler *ctrl_handler;/*Priority state. If NULL, then v4l2_dev->prio will be used.*/struct v4l2_prio_state *prio;/*device info*/char name[32];intvfl_type;/*'minor' is set to -1 if the registration failed*/intminor;u16 num; .../*ioctl callbacks*/const struct v4l2_ioctl_ops *ioctl_ops; /*控制函数*//*serialization lock*/struct mutex *lock; };
3. v4l2-subdev:
structv4l2_subdev {#if defined(CONFIG_MEDIA_CONTROLLER)structmedia_entity entity;#endifstructlist_head list;struct module *owner;u32 flags;struct v4l2_device *v4l2_dev;const struct v4l2_subdev_ops *ops;/*Never call these internal ops from within a driver!*/const struct v4l2_subdev_internal_ops *internal_ops;/*The control handler of this subdev. May be NULL.*/struct v4l2_ctrl_handler *ctrl_handler;/*name must be unique*/charname[V4L2_SUBDEV_NAME_SIZE];/*can be used to group similar subdevs, value is driver-specific*/u32 grp_id;/*pointer to private data*/void *dev_priv;void *host_priv;/*subdev device node*/struct video_device *devnode; };
View Code
v4l2_device在v4l2框架中是v4l2_subdev的父设备
video_device是v4l2_device的上层结构体,存储v4l2_device数据和cdev,它会在/dev目录下生成设备节点文件
video_device的struct v4l2_ioctl_ops会在后面分析
在此我给出它的作用方便读者理解函数分析过程:
struct v4l2_ioctl_ops:它会在应用层使用ioctl()时根据传入的宏调用对应操作函数
二、核心层提供的注册函数
1. 注册和注销v4l2_device:
/*注册*/ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)/*注销*/ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
注册函数调用关系如下:
/*将设备与v4l2_device捆绑,并把v4l2设备放到driver data中* 我们可以使用dev_get_drvdata(dev)获取到v4l2设备*/v4l2_device_register(&intf->dev, &dev->vdev)->dev_set_drvdata(dev, v4l2_dev);-> dev->p->driver_data = data; /*device->device_private为v4l2_device*/
2. 注册和注销v4l2_subdev:
/*注册*/ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, struct v4l2_subdev *sd)/*注销*/ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
注册函数调用关系如下:
v4l2_device_register_subdev()/*struct v4l2_ctrl_handler用于控制设备的亮度、饱和度等*/-> v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);-> handler_new_ref(hdl, ctrl); /*设置控制属性*/-> v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0)-> v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);-> v4l2_ctrl_new(hdl, ops, ...); /*ops为v4l2_ctrl_ops,定义控制函数*/-> list_add_tail(&ctrl->node, &hdl->ctrls);-> list_add_tail(&sd->list, &v4l2_dev->subdevs);
v4l2_subdev注册函数主要设置了设备的控制属性和控制函数,并把设备放入列表中
控制函数结构体定义如下,读者有印象即可
structv4l2_ctrl_ops {int (*g_volatile_ctrl)(struct v4l2_ctrl *ctrl); /*获取控制器值*/int (*try_ctrl)(struct v4l2_ctrl *ctrl); /*测试控制器值是否有效*/int (*s_ctrl)(struct v4l2_ctrl *ctrl); /*设置控制器值*/};
3. 注册和注销video_device:
/*注册*/ static inline int __must_check video_register_device(struct video_device *vdev, int type, intnr)/*注销*/ void video_unregister_device(struct video_device *vdev)
注册函数调用关系如下:
video_register_device(vdev, VFL_TYPE_GRABBER, -1);-> __video_register_device(vdev, type, nr, 1, vdev->fops->owner);-> case VFL_TYPE_GRABBER: /*摄像头设备*/-> name_base = "video";-> caseVFL_TYPE_GRABBER:-> minor_offset = 0;-> minor_cnt = 64;-> vdev->minor = i +minor_offset;-> vdev->cdev =cdev_alloc();-> vdev->cdev->ops = &v4l2_fops;-> cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1); /*依据次设备号分配cdev*/-> dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num); /*设备名为video%d*/-> device_register(&vdev->dev);-> device_add(dev);
video_register_device()函数主要分配、设置并注册了cdev和device。
三、v4l2_device和video_device的file_operations分析
分析到这里,产生了两个问题:
1. register_chrdev_region()和创建class在哪里被调用的?
2. v4l2_fops函数都做了什么?
我们先来决解第一个问题,两函数应该在初始化框架时被调用,初始化函数定义在v4l2-dev.c文件中:
1 static int __init videodev_init(void)2 {3 dev_t dev = MKDEV(VIDEO_MAJOR, 0); /*VIDEO_MAJOR = 81*/ 4 intret;5 6 ret =register_chrdev_region(dev, VIDEO_NUM_DEVICES, VIDEO_NAME);7 ...8 ret = class_register(&video_class);9 ...10 return 0;11 }
现在我们来看v4l2_fops的定义:
static const struct file_operations v4l2_fops ={.owner=THIS_MODULE,.read=v4l2_read,.write=v4l2_write,.open=v4l2_open,.get_unmapped_area=v4l2_get_unmapped_area,.mmap=v4l2_mmap,.unlocked_ioctl=v4l2_ioctl,.release=v4l2_release,.poll=v4l2_poll,.llseek=no_llseek, };
首先从open()函数分析:
1 static int v4l2_open(struct inode *inode, struct file *filp)2 {3 struct video_device *vdev;4 int ret = 0;5 ...6 vdev =video_devdata(filp);7 ...8 if (vdev->fops->open) {9 ...10 if(video_is_registered(vdev))11 ret = vdev->fops->open(filp); /*最终会调用video_device->fops的open()函数*/ 12 ...13 }14 ...15 }
read()和其他函数亦是如此:
1 static ssize_t v4l2_read(struct file *filp, char __user *buf, size_t sz, loff_t *off)2 {3 struct video_device *vdev =video_devdata(filp);4 ...5 if(video_is_registered(vdev))6 ret = vdev->fops->read(filp, buf, sz, off);7 ...8 }9 10 static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned longarg)11 {12 struct video_device *vdev =video_devdata(filp);13 int ret = -ENODEV;14 15 if (vdev->fops->unlocked_ioctl) {16 ...17 if(video_is_registered(vdev))18 ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);19 ...20 }21 ...22 }
可以看到v4l2_fops定义的函数在底层都会调用video_device的fops函数,因此我们可以在SI4内核项目中搜索“struct v4l2_file_operations ”:
在此我以drivers/staging/media/solo6x10/v4l2.c文件为例分析
若读者使用它其他文件分析,可能在后面会遇到struct vb2_buffer、struct vb2_queue、struct vb2_ops和struct vb2_mem_ops,其实vb2就是videobuf2,是videobuf的新版本,在此不做介绍
文件链接:
https://files.cnblogs.com/files/Lioker/24_v4l2_xawtv.zip
static const struct v4l2_file_operations solo_v4l2_fops ={.owner=THIS_MODULE,.open=solo_v4l2_open,.release=solo_v4l2_release,.read=solo_v4l2_read,.poll=solo_v4l2_poll,.mmap=solo_v4l2_mmap,.ioctl=video_ioctl2, };
首先从open()函数分析:
solo_v4l2_open-> INIT_LIST_HEAD(&fh->vidq_active); /*初始化用于存放queue的list_head*/-> solo_start_thread(fh); /*启动线程查询是否有数据*/-> solo_thread /*等待数据*/->DECLARE_WAITQUEUE(wait, current);-> add_wait_queue(&solo_dev->disp_thread_wait, &wait);->schedule_timeout_interruptible(HZ);-> solo_thread_try(fh); /*如果有数据*//*取出等待队列头的第一个队列*/-> struct videobuf_buffer * vb = list_first_entry(&fh->vidq_active, structvideobuf_buffer, queue);-> list_del(&vb->queue);->solo_fillbuf(fh, vb);-> wake_up(&vb->done); /*唤醒上层读写操作*/-> remove_wait_queue(&solo_dev->disp_thread_wait, &wait);-> videobuf_queue_sg_init(&fh->vidq,&solo_video_qops, /*solo_video_qops为struct videobuf_queue_ops*/...,&fh->slock, /*fh->slock为spinlock_t用于保护队列*/V4L2_BUF_TYPE_VIDEO_CAPTURE,/*是摄像头*/SOLO_DISP_PIX_FIELD,sizeof(struct videobuf_buffer), fh,...);
函数所使用的struct videobuf_queue、struct videobuf_queue_ops和struct videobuf_buffer会在后面分析
在此我给出它们的作用方便读者理解函数分析过程:
struct videobuf_queue:在数据传输过程中,首先把buffer放入queue,然后把queue放入list_head中,读写函数会通过操作list_head来操作queue中的buffer
struct videobuf_queue_ops:提供设置videobuf_buffer函数,添加queue到list_head函数,释放内存函数等
struct videobuf_buffer:用于数据传输,是数据传输的基本单位
函数所使用的videobuf_queue_sg_init()函数用于初始化queue,除此函数外,还有两函数可以用来初始化queue:
void videobuf_queue_vmalloc_init(struct videobuf_queue *q,struct videobuf_queue_ops *ops,struct device *dev,spinlock_t*irqlock,enumv4l2_buf_type type,enumv4l2_field field,unsignedintmsize,void *priv);void videobuf_queue_dma_contig_init(struct videobuf_queue *q,struct videobuf_queue_ops *ops,struct device *dev,spinlock_t*irqlock,enumv4l2_buf_type type,enumv4l2_field field,unsignedintmsize,void *priv);
videobuf_queue_sg_init():物理上和虚拟地址都是离散的buffer
videobuf_queue_vmalloc_init():物理上离散的,但虚拟地址是连续的buffer
videobuf_queue_dma_contig_init():物理上和虚拟地址都是连续的buffer
read()函数的调用关系如下:
solo_v4l2_read/*从videobuf_queue fh->vidq取出数据*/-> videobuf_read_stream(&fh->vidq, data, count, ppos, 0, file->f_flags &O_NONBLOCK);-> q->read_buf = list_entry(q->stream.next, structvideobuf_buffer, stream);-> list_del(&q->read_buf->stream);
ioctl()函数的调用关系如下:
video_ioctl2/*根据cmd,调用__video_do_ioctl()将数据拷贝到内核空间*/->__video_do_ioctl-> struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;-> case VIDIOC_QUERYCAP: /*设备支持的能力*/-> ops->vidioc_querycap(file, fh, cap);-> case VIDIOC_G_FMT: /*获取格式、分辨率等*/-> ps->vidioc_g_fmt_vid_cap(file, fh, f);-> case VIDIOC_QBUF: /*把缓存区放入传输队列*/-> ops->vidioc_qbuf(file, fh, p);-> case VIDIOC_DQBUF: /*把缓存从队列中取出*/-> ops->vidioc_dqbuf(file, fh, p);-> case VIDIOC_STREAMON: /*启动视频传输*/-> ops->vidioc_streamon(file, fh, i);-> case VIDIOC_STREAMOFF: /*关闭视频传输*/-> ops->vidioc_streamoff(file, fh, i);
分析完了这两个问题,下面我们来分析v4l2.c的init()函数
四、v4l2.c的init()函数分析
init()函数的调用关系:
solo_v4l2_init/*初始化open()等函数使用的wait_queue_head_t*/-> init_waitqueue_head(&solo_dev->disp_thread_wait);/*分配、设置和注册video_device*/-> solo_dev->vfd =video_device_alloc();-> *solo_dev->vfd = solo_v4l2_template; /*struct video_device*/-> video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, video_nr);
根据上述过程,我们可以得到下图:
五、数据传输和控制结构体分析
我在前几节有几个结构体没有介绍,在此我还是以v4l2.c文件的实例进行介绍
数据控制相关:
1. struct v4l2_ioctl_ops
static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops ={/*表示它是一个摄像头设备*/.vidioc_querycap=solo_querycap,/*列举、获取、设置标准* 列举、获取标准使用的是* video_device的tvnorms和current_norm*/.vidioc_s_std=solo_s_std,/*列举、获取、设置输入源*/.vidioc_enum_input=solo_enum_input,.vidioc_s_input=solo_set_input,.vidioc_g_input=solo_get_input,/*列举、获得、测试、设置摄像头的数据格式*/.vidioc_enum_fmt_vid_cap=solo_enum_fmt_cap,.vidioc_try_fmt_vid_cap=solo_try_fmt_cap,.vidioc_s_fmt_vid_cap=solo_set_fmt_cap,.vidioc_g_fmt_vid_cap=solo_get_fmt_cap,/*缓冲区操作:申请、查询、放入队列、取出队列*/.vidioc_reqbufs=solo_reqbufs,.vidioc_querybuf=solo_querybuf,.vidioc_qbuf=solo_qbuf,.vidioc_dqbuf=solo_dqbuf,/*启动、停止视频流*/.vidioc_streamon=solo_streamon,.vidioc_streamoff=solo_streamoff,/*Controls*/.vidioc_queryctrl=solo_disp_queryctrl,.vidioc_g_ctrl=solo_disp_g_ctrl,.vidioc_s_ctrl=solo_disp_s_ctrl, };
数据传输相关:
1. struct videobuf_buffer
structvideobuf_buffer {unsignedinti;u32 magic;/*info about the buffer*/unsignedint width; /*摄像头图像像素长度*/unsignedint height; /*宽度*/unsignedint bytesperline; /*一行的字节数*/unsignedlong size; /*size = height * bytesperline*/unsignedintinput;enumv4l2_field field;enum videobuf_state state; /*用于存储状态*/struct list_head stream; /*QBUF/DQBUF list*//*touched by irq handler*/structlist_head queue;wait_queue_head_t done;unsignedintfield_count;structtimeval ts;/*Memory type*/enumv4l2_memory memory;/*buffer size*/size_t bsize;/*buffer offset (mmap + overlay)*/size_t boff;/*buffer addr (userland ptr!)*/unsignedlongbaddr;/*for mmap'ed buffers*/struct videobuf_mapping *map;/*Private pointer to allow specific methods to store their data*/intprivsize;void *priv; };
View Code
2. struct videobuf_queue
structvideobuf_queue {structmutex vb_lock;struct mutex *ext_lock;spinlock_t*irqlock;struct device *dev;wait_queue_head_t wait;/*wait if queue is empty*/enumv4l2_buf_type type;unsignedint inputs; /*for V4L2_BUF_FLAG_INPUT*/unsignedintmsize;enumv4l2_field field;enum v4l2_field last; /*for field=V4L2_FIELD_ALTERNATE*/struct videobuf_buffer *bufs[VIDEO_MAX_FRAME];const struct videobuf_queue_ops *ops;struct videobuf_qtype_ops *int_ops;unsignedint streaming:1;unsignedint reading:1;/*capture via mmap() + ioctl(QBUF/DQBUF)*/structlist_head stream;/*capture via read()*/unsignedintread_off;struct videobuf_buffer *read_buf;/*driver private data*/void *priv_data; };
View Code
3. struct videobuf_queue_ops
static struct videobuf_queue_ops solo_video_qops ={/*被v4l2_ioctl_ops->vidioc_reqbufs调用,用于重新调整count和size*/.buf_setup=solo_buf_setup,/*被v4l2_ioctl_ops->vidioc_qbuf调用,用于设置videobuf_buffer成员*/.buf_prepare=solo_buf_prepare,/*被v4l2_ioctl_ops->vidioc_qbuf调用,用于把queue放到list_head*/.buf_queue=solo_buf_queue,/*被v4l2_ioctl_ops->vidioc_streamoff调用,用于释放内存*/.buf_release=solo_buf_release, };
当开始流I/O时,摄像头的图像会在应用和驱动间传输,它可能会有三个状态:
1. 在驱动的传入队列中,用户空间通过ioctl(..., VIDIOC_QBUF, ...)填充缓冲区,把缓冲区放入队列。
2. 在驱动的传出队列中,缓冲区已经填充了视频数据,等待用户空间读取
3. 在用户空间的队列中,用户空间已经通过ioctl(..., VIDIOC_DQBUF, ...)读取缓冲区了,此时驱动无法访问缓冲区
这三种状态的切换如下图:
六、虚拟摄像头驱动vivi.c虚拟机测试
本节我通过应用程序xawtv对vivi.c的系统调用的关系进行分析,我们需要做的有以下几步:
1. 执行$ sudo apt-get install xawtv在虚拟机中安装xawtv
2. 在网站https://www.kraxel.org/releases/xawtv/下载源码xawtv-3.95.tar.gz,并创建SI4工程
3. 虚拟机连接摄像头,执行$ ls /dev/video*可以看到生成了/dev/video0,执行xawtv即可看到图像
4. 执行$ uname -a,根据虚拟机内核版本去http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/下载同版本的内核
5. 解压后把drivers/media/video目录单独取出,修改它的Makefile为:
KERN_DIR = /work/vmware/tools/linux-4.8all:make-C $(KERN_DIR) M=`pwd` modulesclean:make-C $(KERN_DIR) M=`pwd` modules cleanrm-rf modules.orderobj-m +=vivi.o obj-m += videobuf-core.o obj-m += videobuf-vmalloc.o obj-m += v4l2-common.o
6. 编译后,由于vivi.ko模块涉及较多文件,为防止有模块未被载入,我们可以使用$ sudo modprobe vivi加载内核自带vivi驱动及其所需框架和文件,然后依次执行$ sudo rmmod vivi和$ sudo insmod ./vivi.ko安装我们编译的vivi模块
7. 执行$ ls /dev/video*查看虚拟摄像头,然后执行$ xawtv -c /dev/videox打开虚拟摄像头
七、ioctl()执行过程和v4l2_ioctl_ops必需函数指针的确定
在可以看到图像后,我们就可以通过应用程序xawtv对应用程序ioctl()执行过程进行分析。
查看程序系统调用过程可以使用strace命令实现:
$ strace -o xawtv.log xawtv /* 执行xawtv命令,调用过程会存储在xawtv.log文件中 */
xawtv.log文件会放在上面的百度网盘分享链接中
首先,我们搜索“open("/dev/video”,我们只需要关注第二次open(),因为第一次open()后面有close(),可以看到文件描述符为4
接下来,我们搜索“(4, ”,查看有哪些对应文件描述符的操作:
1 fstat64(4, {st_mode=S_IFREG|0600, st_size=57, ...}) = 0 2 read(4, "\1\0\0\fbook-desktop\0\0010\0\22MIT-MAGIC-C"..., 4096) = 57 3 read(4, "", 4096) = 0 4 fstat64(4, {st_mode=S_IFREG|0644, st_size=82376, ...}) = 0 5 read(4, "#\t$XdotOrg: lib/X11/nls/locale.a"..., 4096) = 4096 6 read(4, "\t\t\t\t\tbg_BG.UTF-8\nbn_IN.utf8\t\t\t\t\t"..., 4096) = 4096 7 read(4, "8859-15\t\t\t\tde_CH.ISO8859-15\nde_C"..., 4096) = 4096 8 read(4, "_ZA.ISO8859-1\nen_ZA.ISO-8859-1\t\t"..., 4096) = 4096 9 read(4, "85915\t\t\t\teu_ES.ISO8859-15\neu_ES."..., 4096) = 4096 10 read(4, "14\ngv_GB.ISO-8859-14\t\t\t\tgv_GB.IS"..., 4096) = 4096 11 read(4, "w_GB.ISO8859-1\nkw_GB.ISO-8859-1\t"..., 4096) = 4096 12 read(4, ".ISO8859-1\noc\t\t\t\t\t\toc_FR.ISO8859"..., 4096) = 4096 13 read(4, "r_RS.UTF-8\nsr_YU.UTF-8@cyrillic\t"..., 4096) = 4096 14 read(4, "yi_US.CP1255\nzh_CN\t\t\t\t\t\tzh_CN.gb"..., 4096) = 4096 15 read(4, ":00 dawes Exp $\n#\n\nPOSIX:\t\t\t\t\t\tC"..., 4096) = 4096 16 read(4, "4:\t\t\t\tbr_FR.ISO8859-14\nbr_FR.ISO"..., 4096) = 4096 17 read(4, "de_DE.88591.en:\t\t\t\t\tde_DE.ISO885"..., 4096) = 4096 18 read(4, "59-1:\t\t\t\ten_ZA.ISO8859-1\nen_ZA.I"..., 4096) = 4096 19 read(4, "_ES.ISO8859-1\neu_ES.iso88591:\t\t\t"..., 4096) = 4096 20 read(4, "F-8\ngu_IN.utf8:\t\t\t\t\tgu_IN.UTF-8\n"..., 4096) = 4096 21 read(4, "o_KR.utf8:\t\t\t\t\tko_KR.UTF-8\nKO_KR"..., 4096) = 4096 22 read(4, "o_NO.utf8:\t\t\t\t\tno_NO.UTF-8\nnr:\t\t"..., 4096) = 4096 23 read(4, "O8859-2\nsl_SI.iso88592:\t\t\t\t\tsl_S"..., 4096) = 4096 24 read(4, "N\nvi_VN.tcvn5712:\t\t\t\t\tvi_VN.TCVN"..., 4096) = 4096 25 read(4, "9-9\nturkish.iso88599:\t\t\t\ttr_TR.I"..., 4096) = 456 26 read(4, "", 4096) = 0 27 fstat64(4, {st_mode=S_IFREG|0644, st_size=40344, ...}) = 0 28 read(4, "#\t$XdotOrg: lib/X11/nls/locale.d"..., 4096) = 4096 29 read(4, "59-1/XLC_LOCALE\t\t\tes_AR.ISO8859-"..., 4096) = 4096 30 read(4, "_FR.ISO8859-1\niso8859-15/XLC_LOC"..., 4096) = 4096 31 read(4, "8/XLC_LOCALE\t\t\tbe_BY.UTF-8\nen_US"..., 4096) = 4096 32 read(4, "en_US.UTF-8/XLC_LOCALE\t\t\tlo_LA.U"..., 4096) = 4096 33 fstat64(4, {st_mode=S_IFREG|0644, st_size=772, ...}) = 0 34 read(4, "# $Xorg: C,v 1.3 2000/08/17 19:"..., 4096) = 772 35 read(4, "", 4096) = 0 36 fstat64(4, {st_mode=S_IFREG|0644, st_size=82376, ...}) = 0 37 read(4, "#\t$XdotOrg: lib/X11/nls/locale.a"..., 4096) = 4096 38 read(4, "\t\t\t\t\tbg_BG.UTF-8\nbn_IN.utf8\t\t\t\t\t"..., 4096) = 4096 39 read(4, "8859-15\t\t\t\tde_CH.ISO8859-15\nde_C"..., 4096) = 4096 40 read(4, "_ZA.ISO8859-1\nen_ZA.ISO-8859-1\t\t"..., 4096) = 4096 41 read(4, "85915\t\t\t\teu_ES.ISO8859-15\neu_ES."..., 4096) = 4096 42 read(4, "14\ngv_GB.ISO-8859-14\t\t\t\tgv_GB.IS"..., 4096) = 4096 43 read(4, "w_GB.ISO8859-1\nkw_GB.ISO-8859-1\t"..., 4096) = 4096 44 read(4, ".ISO8859-1\noc\t\t\t\t\t\toc_FR.ISO8859"..., 4096) = 4096 45 read(4, "r_RS.UTF-8\nsr_YU.UTF-8@cyrillic\t"..., 4096) = 4096 46 read(4, "yi_US.CP1255\nzh_CN\t\t\t\t\t\tzh_CN.gb"..., 4096) = 4096 47 read(4, ":00 dawes Exp $\n#\n\nPOSIX:\t\t\t\t\t\tC"..., 4096) = 4096 48 read(4, "4:\t\t\t\tbr_FR.ISO8859-14\nbr_FR.ISO"..., 4096) = 4096 49 read(4, "de_DE.88591.en:\t\t\t\t\tde_DE.ISO885"..., 4096) = 4096 50 read(4, "59-1:\t\t\t\ten_ZA.ISO8859-1\nen_ZA.I"..., 4096) = 4096 51 read(4, "_ES.ISO8859-1\neu_ES.iso88591:\t\t\t"..., 4096) = 4096 52 read(4, "F-8\ngu_IN.utf8:\t\t\t\t\tgu_IN.UTF-8\n"..., 4096) = 4096 53 read(4, "o_KR.utf8:\t\t\t\t\tko_KR.UTF-8\nKO_KR"..., 4096) = 4096 54 read(4, "o_NO.utf8:\t\t\t\t\tno_NO.UTF-8\nnr:\t\t"..., 4096) = 4096 55 read(4, "O8859-2\nsl_SI.iso88592:\t\t\t\t\tsl_S"..., 4096) = 4096 56 read(4, "N\nvi_VN.tcvn5712:\t\t\t\t\tvi_VN.TCVN"..., 4096) = 4096 57 read(4, "9-9\nturkish.iso88599:\t\t\t\ttr_TR.I"..., 4096) = 456 58 read(4, "", 4096) = 0 59 fstat64(4, {st_mode=S_IFREG|0644, st_size=40344, ...}) = 0 60 read(4, "#\t$XdotOrg: lib/X11/nls/locale.d"..., 4096) = 4096 61 read(4, "59-1/XLC_LOCALE\t\t\tes_AR.ISO8859-"..., 4096) = 4096 62 read(4, "_FR.ISO8859-1\niso8859-15/XLC_LOC"..., 4096) = 4096 63 read(4, "8/XLC_LOCALE\t\t\tbe_BY.UTF-8\nen_US"..., 4096) = 4096 64 read(4, "en_US.UTF-8/XLC_LOCALE\t\t\tlo_LA.U"..., 4096) = 4096 65 fstat64(4, {st_mode=S_IFREG|0644, st_size=772, ...}) = 0 66 read(4, "# $Xorg: C,v 1.3 2000/08/17 19:"..., 4096) = 772 67 read(4, "", 4096) = 0 68 fstat64(4, {st_mode=S_IFREG|0644, st_size=2570, ...}) = 0 69 read(4, "# Locale name alias data base.\n#"..., 4096) = 2570 70 read(4, "", 4096) = 0 71 fstat64(4, {st_mode=S_IFREG|0644, st_size=373, ...}) = 0 72 fstat64(4, {st_mode=S_IFREG|0644, st_size=26048, ...}) = 0 73 fstat64(4, {st_mode=S_IFREG|0644, st_size=23, ...}) = 0 74 fstat64(4, {st_mode=S_IFREG|0644, st_size=59, ...}) = 0 75 fstat64(4, {st_mode=S_IFREG|0644, st_size=155, ...}) = 0 76 fstat64(4, {st_mode=S_IFREG|0644, st_size=77, ...}) = 0 77 fstat64(4, {st_mode=S_IFREG|0644, st_size=34, ...}) = 0 78 fstat64(4, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 79 fstat64(4, {st_mode=S_IFREG|0644, st_size=52, ...}) = 0 80 fstat64(4, {st_mode=S_IFREG|0644, st_size=286, ...}) = 0 81 fstat64(4, {st_mode=S_IFREG|0644, st_size=966938, ...}) = 0 82 fstat64(4, {st_mode=S_IFREG|0644, st_size=2454, ...}) = 0 83 fstat64(4, {st_mode=S_IFREG|0644, st_size=54, ...}) = 0 84 fstat64(4, {st_mode=S_IFREG|0644, st_size=256316, ...}) = 0 85 fstat64(4, {st_mode=S_IFREG|0644, st_size=82376, ...}) = 0 86 read(4, "#\t$XdotOrg: lib/X11/nls/locale.a"..., 4096) = 4096 87 read(4, "\t\t\t\t\tbg_BG.UTF-8\nbn_IN.utf8\t\t\t\t\t"..., 4096) = 4096 88 read(4, "8859-15\t\t\t\tde_CH.ISO8859-15\nde_C"..., 4096) = 4096 89 read(4, "_ZA.ISO8859-1\nen_ZA.ISO-8859-1\t\t"..., 4096) = 4096 90 read(4, "85915\t\t\t\teu_ES.ISO8859-15\neu_ES."..., 4096) = 4096 91 read(4, "14\ngv_GB.ISO-8859-14\t\t\t\tgv_GB.IS"..., 4096) = 4096 92 read(4, "w_GB.ISO8859-1\nkw_GB.ISO-8859-1\t"..., 4096) = 4096 93 read(4, ".ISO8859-1\noc\t\t\t\t\t\toc_FR.ISO8859"..., 4096) = 4096 94 read(4, "r_RS.UTF-8\nsr_YU.UTF-8@cyrillic\t"..., 4096) = 4096 95 read(4, "yi_US.CP1255\nzh_CN\t\t\t\t\t\tzh_CN.gb"..., 4096) = 4096 96 read(4, ":00 dawes Exp $\n#\n\nPOSIX:\t\t\t\t\t\tC"..., 4096) = 4096 97 read(4, "4:\t\t\t\tbr_FR.ISO8859-14\nbr_FR.ISO"..., 4096) = 4096 98 read(4, "de_DE.88591.en:\t\t\t\t\tde_DE.ISO885"..., 4096) = 4096 99 read(4, "59-1:\t\t\t\ten_ZA.ISO8859-1\nen_ZA.I"..., 4096) = 4096 100 read(4, "_ES.ISO8859-1\neu_ES.iso88591:\t\t\t"..., 4096) = 4096 101 read(4, "F-8\ngu_IN.utf8:\t\t\t\t\tgu_IN.UTF-8\n"..., 4096) = 4096 102 read(4, "o_KR.utf8:\t\t\t\t\tko_KR.UTF-8\nKO_KR"..., 4096) = 4096 103 read(4, "o_NO.utf8:\t\t\t\t\tno_NO.UTF-8\nnr:\t\t"..., 4096) = 4096 104 read(4, "O8859-2\nsl_SI.iso88592:\t\t\t\t\tsl_S"..., 4096) = 4096 105 read(4, "N\nvi_VN.tcvn5712:\t\t\t\t\tvi_VN.TCVN"..., 4096) = 4096 106 read(4, "9-9\nturkish.iso88599:\t\t\t\ttr_TR.I"..., 4096) = 456 107 read(4, "", 4096) = 0 108 fstat64(4, {st_mode=S_IFREG|0644, st_size=82376, ...}) = 0 109 read(4, "#\t$XdotOrg: lib/X11/nls/locale.a"..., 4096) = 4096 110 read(4, "\t\t\t\t\tbg_BG.UTF-8\nbn_IN.utf8\t\t\t\t\t"..., 4096) = 4096 111 read(4, "8859-15\t\t\t\tde_CH.ISO8859-15\nde_C"..., 4096) = 4096 112 read(4, "_ZA.ISO8859-1\nen_ZA.ISO-8859-1\t\t"..., 4096) = 4096 113 read(4, "85915\t\t\t\teu_ES.ISO8859-15\neu_ES."..., 4096) = 4096 114 read(4, "14\ngv_GB.ISO-8859-14\t\t\t\tgv_GB.IS"..., 4096) = 4096 115 read(4, "w_GB.ISO8859-1\nkw_GB.ISO-8859-1\t"..., 4096) = 4096 116 read(4, ".ISO8859-1\noc\t\t\t\t\t\toc_FR.ISO8859"..., 4096) = 4096 117 read(4, "r_RS.UTF-8\nsr_YU.UTF-8@cyrillic\t"..., 4096) = 4096 118 read(4, "yi_US.CP1255\nzh_CN\t\t\t\t\t\tzh_CN.gb"..., 4096) = 4096 119 read(4, ":00 dawes Exp $\n#\n\nPOSIX:\t\t\t\t\t\tC"..., 4096) = 4096 120 read(4, "4:\t\t\t\tbr_FR.ISO8859-14\nbr_FR.ISO"..., 4096) = 4096 121 read(4, "de_DE.88591.en:\t\t\t\t\tde_DE.ISO885"..., 4096) = 4096 122 fstat64(4, {st_mode=S_IFREG|0644, st_size=40344, ...}) = 0 123 read(4, "#\t$XdotOrg: lib/X11/nls/locale.d"..., 4096) = 4096 124 read(4, "59-1/XLC_LOCALE\t\t\tes_AR.ISO8859-"..., 4096) = 4096 125 read(4, "_FR.ISO8859-1\niso8859-15/XLC_LOC"..., 4096) = 4096 126 read(4, "8/XLC_LOCALE\t\t\tbe_BY.UTF-8\nen_US"..., 4096) = 4096 127 read(4, "en_US.UTF-8/XLC_LOCALE\t\t\tlo_LA.U"..., 4096) = 4096 128 read(4, "LE:\t\t\taf_ZA.ISO8859-1\niso8859-15"..., 4096) = 4096 129 read(4, "LE:\t\t\tes_MX.ISO8859-1\niso8859-1/"..., 4096) = 4096 130 read(4, "9-2/XLC_LOCALE:\t\t\tpl_PL.ISO8859-"..., 4096) = 4096 131 read(4, "byn_ER.UTF-8\nen_US.UT"..., 4096) = 4096 132 fstat64(4, {st_mode=S_IFREG|0644, st_size=4287, ...}) = 0 133 read(4, "# $XFree86: xc/nls/XLC_LOCALE/e"..., 4096) = 4096 134 read(4, "GB2312.1980-0:GL; GB2312.1980-0:"..., 4096) = 191 135 read(4, "", 4096) = 0 136 fstat64(4, {st_mode=S_IFREG|0644, st_size=18236, ...}) = 0 137 read(4, "\n! -----------------------------"..., 18236) = 18236 138 fcntl64(4, F_GETFD) = 0x1(flags FD_CLOEXEC)139 getdents64(4, /*19 entries*/, 32768) = 640 140 getdents64(4, /*0 entries*/, 32768) = 0 141 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240\3\0\0004\0\0\0"..., 512) = 512 142 fstat64(4, {st_mode=S_IFREG|0644, st_size=5396, ...}) = 0 143 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320\v\0\0004\0\0\0"..., 512) = 512 144 fstat64(4, {st_mode=S_IFREG|0644, st_size=13944, ...}) = 0 145 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220\3\0\0004\0\0\0"..., 512) = 512 146 fstat64(4, {st_mode=S_IFREG|0644, st_size=5396, ...}) = 0 147 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240\17\0\0004\0\0\0"..., 512) = 512 148 fstat64(4, {st_mode=S_IFREG|0644, st_size=22128, ...}) = 0 149 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0000'\0\0004\0\0\0"..., 512) = 512 150 fstat64(4, {st_mode=S_IFREG|0644, st_size=75356, ...}) = 0 151 fstat64(4, {st_mode=S_IFREG|0644, st_size=71399, ...}) = 0 152 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\0\17\0\0004\0\0\0"..., 512) = 512 153 fstat64(4, {st_mode=S_IFREG|0644, st_size=38144, ...}) = 0 154 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0@\22\0\0004\0\0\0"..., 512) = 512 155 fstat64(4, {st_mode=S_IFREG|0644, st_size=103964, ...}) = 0 156 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360\30\0\0004\0\0\0"..., 512) = 512 157 fstat64(4, {st_mode=S_IFREG|0644, st_size=44184, ...}) = 0 158 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\0\6\0\0004\0\0\0"..., 512) = 512 159 fstat64(4, {st_mode=S_IFREG|0644, st_size=5640, ...}) = 0 160 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240\4\0\0004\0\0\0"..., 512) = 512 161 fstat64(4, {st_mode=S_IFREG|0644, st_size=5496, ...}) = 0 162 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0P\4\0\0004\0\0\0"..., 512) = 512 163 fstat64(4, {st_mode=S_IFREG|0644, st_size=5400, ...}) = 0 164 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`\4\0\0004\0\0\0"..., 512) = 512 165 fstat64(4, {st_mode=S_IFREG|0644, st_size=9640, ...}) = 0 166 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240\3\0\0004\0\0\0"..., 512) = 512 167 fstat64(4, {st_mode=S_IFREG|0644, st_size=5400, ...}) = 0 168 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240\3\0\0004\0\0\0"..., 512) = 512 169 fstat64(4, {st_mode=S_IFREG|0644, st_size=5400, ...}) = 0 170 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\200\10\0\0004\0\0\0"..., 512) = 512 171 fstat64(4, {st_mode=S_IFREG|0644, st_size=9640, ...}) = 0 172 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260\n\0\0004\0\0\0"..., 512) = 512 173 fstat64(4, {st_mode=S_IFREG|0644, st_size=9704, ...}) = 0 174 fstat64(4, {st_mode=S_IFREG|0644, st_size=71399, ...}) = 0 175 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\3405\0\0004\0\0\0"..., 512) = 512 176 fstat64(4, {st_mode=S_IFREG|0644, st_size=121640, ...}) = 0 177 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220\r\0\0004\0\0\0"..., 512) = 512 178 fstat64(4, {st_mode=S_IFREG|0644, st_size=13992, ...}) = 0 179 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220\10\0\0004\0\0\0"..., 512) = 512 180 fstat64(4, {st_mode=S_IFREG|0644, st_size=13776, ...}) = 0 181 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240\7\0\0004\0\0\0"..., 512) = 512 182 fstat64(4, {st_mode=S_IFREG|0644, st_size=9588, ...}) = 0 183 fstat64(4, {st_mode=S_IFREG|0644, st_size=8982, ...}) = 0 184 read(4, "! $Xorg: XKeysymDB,v 1.3 2000/08"..., 8982) = 8982 185 ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0x9b40998) = -1EINVAL (Invalid argument)186 ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0xbfaccd44) = 0 187 ioctl(4, VIDIOC_G_FMT or VT_SENDSIG, 0xbfaccc78) = 0 188 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0 189 ioctl(4, 0xc02c564a, 0xbfaccb58) = -1EINVAL (Invalid argument)190 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0 191 ioctl(4, 0xc02c564a, 0xbfaccb58) = -1EINVAL (Invalid argument)192 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0 193 ioctl(4, 0xc02c564a, 0xbfaccb58) = -1EINVAL (Invalid argument)194 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0 195 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0 196 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0 197 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = -1EINVAL (Invalid argument)198 ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0xbfaccb84) = 0 199 ioctl(4, VIDIOC_G_INPUT, 0xbfacca2c) = 0 200 ioctl(4, VIDIOC_ENUMINPUT, 0xbfacca2c) = 0 201 fstat64(4, {st_mode=S_IFCHR|0660, st_rdev=makedev(81, 0), ...}) = 0 202 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0xbfacca78) = -1EINVAL (Invalid argument)203 ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0x9b40998) = 0 204 fcntl64(4, F_SETFD, FD_CLOEXEC) = 0 205 ioctl(4, VIDIOC_ENUMINPUT, 0x9b40acc) = 0 206 ioctl(4, VIDIOC_ENUMINPUT, 0x9b40b18) = 0 207 ioctl(4, VIDIOC_ENUMINPUT, 0x9b40b64) = 0 208 ioctl(4, VIDIOC_ENUMINPUT, 0x9b40bb0) = 0 209 ioctl(4, VIDIOC_ENUMINPUT, 0x9b40bfc) = -1EINVAL (Invalid argument)210 ioctl(4, VIDIOC_ENUMSTD, 0x9b40f8c) = 0 211 ioctl(4, VIDIOC_ENUMSTD, 0x9b40fcc) = 0 212 ioctl(4, VIDIOC_ENUMSTD, 0x9b4100c) = 0 213 ioctl(4, VIDIOC_ENUMSTD, 0x9b4104c) = 0 214 ioctl(4, VIDIOC_ENUMSTD, 0x9b4108c) = 0 215 ioctl(4, VIDIOC_ENUMSTD, 0x9b410cc) = 0 216 ioctl(4, VIDIOC_ENUMSTD, 0x9b4110c) = 0 217 ioctl(4, VIDIOC_ENUMSTD, 0x9b4114c) = -1EINVAL (Invalid argument)218 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b4138c) = 0 219 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b413cc) = 0 220 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b4140c) = 0 221 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b4144c) = 0 222 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b4148c) = 0 223 ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b414cc) = 0 224 ioctl(4, VIDIOC_G_PARM, 0x9b40a00) = 0 225 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41b8c) = 0 226 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41bd0) = 0 227 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41c14) = 0 228 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41c58) = 0 229 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41c9c) = -1EINVAL (Invalid argument)230 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41ce0) = 0 231 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41d24) = -1EINVAL (Invalid argument)232 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41d68) = -1EINVAL (Invalid argument)233 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41dac) = -1EINVAL (Invalid argument)234 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41df0) = -1EINVAL (Invalid argument)235 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41e34) = -1EINVAL (Invalid argument)236 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41e78) = -1EINVAL (Invalid argument)237 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41ebc) = -1EINVAL (Invalid argument)238 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41f00) = -1EINVAL (Invalid argument)239 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41f44) = -1EINVAL (Invalid argument)240 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41f88) = -1EINVAL (Invalid argument)241 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41fcc) = -1EINVAL (Invalid argument)242 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42010) = -1EINVAL (Invalid argument)243 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42054) = -1EINVAL (Invalid argument)244 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42098) = -1EINVAL (Invalid argument)245 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b420dc) = -1EINVAL (Invalid argument)246 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42120) = -1EINVAL (Invalid argument)247 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42164) = -1EINVAL (Invalid argument)248 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b421a8) = -1EINVAL (Invalid argument)249 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b421ec) = -1EINVAL (Invalid argument)250 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42230) = -1EINVAL (Invalid argument)251 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42274) = -1EINVAL (Invalid argument)252 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b422b8) = -1EINVAL (Invalid argument)253 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b422fc) = -1EINVAL (Invalid argument)254 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42340) = -1EINVAL (Invalid argument)255 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42384) = -1EINVAL (Invalid argument)256 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b423c8) = -1EINVAL (Invalid argument)257 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b4240c) = -1EINVAL (Invalid argument)258 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42450) = -1EINVAL (Invalid argument)259 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42494) = -1EINVAL (Invalid argument)260 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b424d8) = -1EINVAL (Invalid argument)261 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b4251c) = -1EINVAL (Invalid argument)262 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42560) = -1EINVAL (Invalid argument)263 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b425a4) = -1EINVAL (Invalid argument)264 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b425e8) = -1EINVAL (Invalid argument)265 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b4262c) = -1EINVAL (Invalid argument)266 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42670) = -1EINVAL (Invalid argument)267 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b426b4) = -1EINVAL (Invalid argument)268 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b426f8) = -1EINVAL (Invalid argument)269 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b4273c) = -1EINVAL (Invalid argument)270 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42780) = -1EINVAL (Invalid argument)271 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b427c4) = -1EINVAL (Invalid argument)272 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42808) = -1EINVAL (Invalid argument)273 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b4284c) = -1EINVAL (Invalid argument)274 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42890) = -1EINVAL (Invalid argument)275 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b428d4) = -1EINVAL (Invalid argument)276 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42918) = -1EINVAL (Invalid argument)277 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b4295c) = -1EINVAL (Invalid argument)278 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b429a0) = -1EINVAL (Invalid argument)279 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b429e4) = -1EINVAL (Invalid argument)280 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42a28) = -1EINVAL (Invalid argument)281 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42a6c) = -1EINVAL (Invalid argument)282 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42ab0) = -1EINVAL (Invalid argument)283 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42af4) = -1EINVAL (Invalid argument)284 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42b38) = -1EINVAL (Invalid argument)285 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42b7c) = -1EINVAL (Invalid argument)286 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42bc0) = -1EINVAL (Invalid argument)287 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42c04) = -1EINVAL (Invalid argument)288 ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42c48) = -1EINVAL (Invalid argument)289 ioctl(4, VIDIOC_G_STD, 0xbfacce08) = 0 290 ioctl(4, VIDIOC_G_INPUT, 0xbfacce1c) = 0 291 ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbfacce14) = 0 292 ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbfacce14) = 0 293 ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbfacce14) = 0 294 ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbfacce14) = 0 295 ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbfacce24) = 0 296 ioctl(4, VIDIOC_TRY_FMT, 0x9b42ca4) = 0 297 ioctl(4, VIDIOC_S_FMT or VT_RELDISP, 0xbfacc754) = 0 298 ioctl(4, VIDIOC_TRY_FMT, 0x9b42ca4) = 0 299 ioctl(4, VIDIOC_REQBUFS or VT_DISALLOCATE, 0x9b42d80) = 0 300 ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0x9b42d94) = 0 301 ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0x9b42dd8) = 0 302 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 303 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 304 ioctl(4, VIDIOC_STREAMON, 0xbfacca2c) = 0 305 ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbfacce10) = 0 306 ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbfacce10) = 0 307 ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbfacce10) = 0 308 ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbfacce10) = 0 309 ioctl(4, VIDIOC_S_INPUT, 0xbfacce84) = 0 310 ioctl(4, VIDIOC_S_STD, 0x9b40f90) = 0 311 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 312 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 313 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 314 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 315 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 316 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 317 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 318 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 319 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 320 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 321 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 322 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 323 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 324 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 325 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 326 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 327 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 328 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 329 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 330 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 331 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 332 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 333 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 334 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 335 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 336 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 337 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 338 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 339 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 340 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 341 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 342 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 343 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 344 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 345 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 346 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 347 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 348 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 349 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 350 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 351 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 352 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 353 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 354 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 355 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 356 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 357 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 358 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 359 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 360 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 361 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 362 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 363 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 364 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 365 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 366 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 367 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 368 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 369 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 370 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 371 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 372 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 373 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 374 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 375 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 376 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 377 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 378 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 379 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 380 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 381 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 382 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 383 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 384 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 385 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 386 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 387 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 388 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 389 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 390 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 391 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 392 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 393 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 394 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 395 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 396 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 397 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 398 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 399 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 400 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 401 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 402 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 403 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 404 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 405 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 406 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 407 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 408 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 409 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 410 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 411 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 412 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 413 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 414 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 415 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 416 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 417 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 418 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 419 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 420 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 421 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 422 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 423 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 424 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 425 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 426 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 427 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 428 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 429 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 430 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 431 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 432 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 433 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 434 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 435 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 436 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 437 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 438 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 439 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 440 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 441 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 442 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 443 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 444 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 445 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 446 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 447 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 448 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 449 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 450 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 451 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 452 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 453 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 454 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 455 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 456 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 457 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 458 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 459 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 460 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 461 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 462 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 463 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 464 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 465 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 466 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 467 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 468 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 469 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 470 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 471 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 472 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 473 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 474 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 475 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 476 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 477 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 478 ioctl(4, VIDIOC_QBUF, 0x9b42dd8) = 0 479 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 480 ioctl(4, VIDIOC_QBUF, 0x9b42d94) = 0 481 ioctl(4, VIDIOC_DQBUF, 0xbfaccd00) = 0 482 ioctl(4, VIDIOC_STREAMOFF, 0xbfacc53c) = 0 483 ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0xbfacc48c) = 0 484 ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0xbfacc48c) = 0 485 ioctl(4, VIDIOC_REQBUFS or VT_DISALLOCATE, 0x9b42d80) = -1EINVAL (Invalid argument)486 ioctl(4, VIDIOC_TRY_FMT, 0x9b42ca4) = -1EINVAL (Invalid argument)487 ioctl(4, VIDIOC_TRY_FMT, 0xbfacc000) = 0 488 ioctl(4, VIDIOC_TRY_FMT, 0xbfacc000) = 0 489 ioctl(4, VIDIOC_TRY_FMT, 0xbfacc000) = 0 490 ioctl(4, VIDIOC_TRY_FMT, 0xbfacc000) = 0 491 ioctl(4, VIDIOC_TRY_FMT, 0xbfacc000) = 0 492 ioctl(4, VIDIOC_TRY_FMT, 0xbfacc000) = 0 493 ioctl(4, VIDIOC_REQBUFS or VT_DISALLOCATE, 0xbfacc70c) = 0 494 ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0xbfacc61c) = 0 495 ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0xbfacc61c) = 0 496 ioctl(4, VIDIOC_QBUF, 0xbfacc61c) = 0 497 ioctl(4, VIDIOC_QBUF, 0xbfacc61c) = 0 498 ioctl(4, VIDIOC_STREAMON, 0xbfacc65c) = 0 499 ioctl(4, VIDIOC_DQBUF, 0xbfacc6c8) = 0 500 ioctl(4, VIDIOC_QBUF, 0xbfacc61c) = 0
View Code
xawtv.log文件中open()函数之后调用了ioctl(4, VIDIOC_QUERYCAP, ...),因此文件描述符操作ioctl(4, VIDIOC_QUERYCAP, ...)上面的所有行不会涉及驱动底层
最后,我们可以根据文件描述符操作文件、xawtv.log和SI4工程确定ioctl()执行过程:
open("/dev/video0", O_RDWR|O_LARGEFILE) /*1. 打开video0*/ioctl(4, VIDIOC_QUERYCAP /*2. 列举性能*/ioctl(4, VIDIOC_G_FMT /*3. 获得格式*/ for()-> ioctl(4, VIDIOC_ENUM_FMT /*4. 列举格式*/ioctl(4, VIDIOC_QUERYCAP /*5.*/ioctl(4, VIDIOC_G_INPUT /*6. 获取当前输入源*/ioctl(4, VIDIOC_ENUMINPUT /*7. 列举输入源*/ioctl(4, VIDIOC_QUERYCTRL /*8. 查询属性,如亮度范围、对比度范围*/ioctl(4, VIDIOC_QUERYCAP /*9.*/ioctl(4, VIDIOC_ENUMINPUT /*10.*/ for()-> ioctl(4, VIDIOC_ENUMINPUT /*11.*/ for()-> ioctl(4, VIDIOC_ENUMSTD /*12.列举标准*/ for()-> ioctl(4, VIDIOC_ENUM_FMT /*13.*/ioctl(4, VIDIOC_G_PARM /*14.*/ for()-> ioctl(4, VIDIOC_QUERYCTRL /*15.*/ioctl(4, VIDIOC_G_STD /*16.获取当前使用的标准*/ioctl(4, VIDIOC_G_INPUT /*17.*/ioctl(4, VIDIOC_G_CTRL /*18.获取当前所使用的属性*/ioctl(4, VIDIOC_TRY_FMT /*19.测试摄像头支持的格式*/ioctl(4, VIDIOC_S_FMT /*20.设置摄像头格式*/ioctl(4, VIDIOC_REQBUFS /*21.请求系统分配缓冲区*/ioctl(4, VIDIOC_QUERYBUF /*22.查询所分配的缓冲区*/ for()-> ioctl(4, VIDIOC_QBUF /*23.把缓冲区放入队列*/ioctl(4, VIDIOC_STREAMON /*24.启动摄像头*/ for()-> ioctl(4, VIDIOC_S_CTRL /*25.设置属性*/ioctl(4, VIDIOC_S_INPUT /*26.设置输入源*/ioctl(4, VIDIOC_S_STD /*27.设置标准*/ for()-> select(5, [4] /*28.查询文件描述符4是否有数据*/-> ioctl(4, VIDIOC_DQBUF /*29.把缓冲区从队列中取出*/-> /*处理数据*/-> ioctl(4, VIDIOC_QBUF /*30.把缓冲区放入队列*/ioctl(4, VIDIOC_STREAMOFF /*31.关闭摄像头*/
View Code
在分析完ioctl()的执行过程后,我们需要在SI4工程文件drv0-v4l2.c文件中搜索ioctl()各个宏,确定v4l2_ioctl_ops必需的函数指针:
/** 1~2被v4l2_open(char *device)调用*/open("/dev/video0", O_RDWR|O_LARGEFILE) /*1. 打开video0*/ioctl(4, VIDIOC_QUERYCAP /*2. 列举性能*//** 3~10没有看到调用过程,可能源码和应用程序不一致,略*//** 11~15被get_device_capabilities(h)调用*/ for()-> ioctl(4, VIDIOC_ENUMINPUT /*11.*/ for()-> ioctl(4, VIDIOC_ENUMSTD /*12.列举标准*/ for()-> ioctl(4, VIDIOC_ENUM_FMT /*13.*/ioctl(4, VIDIOC_G_PARM /*14.*/ for()-> ioctl(4, VIDIOC_QUERYCTRL /*15.*//** 16~18被v4l2_read_attr()调用*/ioctl(4, VIDIOC_G_STD /*16.获取当前使用的标准*/ioctl(4, VIDIOC_G_INPUT /*17.*/ioctl(4, VIDIOC_G_CTRL /*18.获取当前所使用的属性*//** 19~20被v4l2_overlay()调用*/ioctl(4, VIDIOC_TRY_FMT /*19.测试摄像头支持的格式*/ioctl(4, VIDIOC_S_FMT /*20.设置摄像头格式*//** 21~24被v4l2_start_streaming()调用*/ioctl(4, VIDIOC_REQBUFS /*21.请求系统分配缓冲区*/ioctl(4, VIDIOC_QUERYBUF /*22.查询所分配的缓冲区*/ for()-> ioctl(4, VIDIOC_QBUF /*23.把缓冲区放入队列*/-> h->buf_me[i].data =mmap(...); ioctl(4, VIDIOC_STREAMON /*24.启动摄像头*//** 25~27被v4l2_write_attr()调用*/ ioctl(4, VIDIOC_S_CTRL /*25.设置属性*/ioctl(4, VIDIOC_S_INPUT /*26.设置输入源*/ioctl(4, VIDIOC_S_STD /*27.设置标准*//** 28~29被v4l2_waiton()调用* 30被v4l2_queue_buffer()调用* v4l2_waiton()和v4l2_queue_buffer()被v4l2_nextframe()调用*/ for()-> select(5, [4] /*28.查询文件描述符4是否有数据*/-> ioctl(4, VIDIOC_DQBUF /*29.把缓冲区从队列中取出*/-> /*处理数据,之前使用mmap()获得了缓冲区的地址*/-> ioctl(4, VIDIOC_QBUF /*30.把缓冲区放入队列*/ /** 31被v4l2_stop_streaming()调用*/ioctl(4, VIDIOC_STREAMOFF /*31.关闭摄像头*/
剩下这么多宏,有哪个是可以省略的呢?
我们现在要回到虚拟机内核的vivi.c中vivi_ioctl_ops逐个测试,测试方法为:注释某个函数指针,重新编译挂载,测试是否可以正常使用。
我在此不再一一测试,最终结果如下:
static const struct v4l2_ioctl_ops vivi_ioctl_ops ={/*表示它是一个摄像头设备。不可省略*/.vidioc_querycap=vidioc_querycap,#if 0/*列举、获取、设置输入源。可以省略,使用默认输入源*/.vidioc_enum_input=vidioc_enum_input,.vidioc_g_input=vidioc_g_input,.vidioc_s_input=vidioc_s_input,#endif/*列举、获得、测试、设置摄像头的数据格式。不可省略*/.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,#if 0/*列举、获取、设置标准。可以省略* 列举、获取标准使用的是* video_device的tvnorms和current_norm*/.vidioc_s_std=vidioc_s_std,#endif/*启动、停止视频流。不可省略*/.vidioc_streamon=vidioc_streamon,.vidioc_streamoff=vidioc_streamoff,#if 0/*在内核日志中记录状态。可以省略*/.vidioc_log_status=v4l2_ctrl_log_status,/*子系统事件。可以省略*/.vidioc_subscribe_event=v4l2_ctrl_subscribe_event,.vidioc_unsubscribe_event=v4l2_event_unsubscribe,#endif};
八、数据的获取过程
本节使用v4l2.c进行分析,读者若对vb2感兴趣也可以分析vivi.c
1. 请求分配缓冲区,但此阶段其实只分配了videobuf_buffer
ioctl(4, VIDIOC_REQBUFS->solo_reqbufs-> videobuf_reqbufs(&fh->vidq, req);-> *size = solo_image_size(solo_dev); /*设置图片size*/-> __videobuf_mmap_setup(q, count, size, req->memory);-> q->bufs[i] = videobuf_alloc_vb(q); /*分配设置videobuf_buffer*/
2. 查询映射缓冲区,通过videobuf_buffer设置供上层使用的v4l2_buffer
ioctl(4, VIDIOC_QUERYBUF->videobuf_querybuf-> videobuf_status(q, b, q->bufs[b->index], q->type);-> b->flags |=V4L2_BUF_FLAG_MAPPED;-> b->field = vb->field;-> b->timestamp = vb->ts; /*v4l2_buffer*/
3. 真正分配缓冲区
mmap(NULL, h->buf_v4l2[i].length, ...)->solo_v4l2_mmap-> videobuf_mmap_mapper(&fh->vidq, vma);-> CALL(q, mmap_mapper, q, buf, vma)
4. 把缓冲区放入队列
ioctl(4, VIDIOC_QBUF-> videobuf_qbuf(&fh->vidq, buf);-> buf = q->bufs[b->index];-> solo_buf_prepare /*设置video_device成员*/-> vb->width = solo_dev->video_hsize;-> vb->height =solo_vlines(solo_dev);-> list_add_tail(&buf->stream, &q->stream)-> solo_buf_queue /*把queue放到list_head*/-> list_add_tail(&vb->queue, &fh->vidq_active);
5. 启动摄像头
ioctl(4, VIDIOC_STREAMON->solo_streamon-> videobuf_streamon(&fh->vidq);-> solo_buf_queue /*把queue放到list_head*/-> list_add_tail(&vb->queue, &fh->vidq_active);-> wake_up_interruptible_sync(&q->wait);
6. 查询是否有数据
select(h->fd + 1, &rdset, NULL, NULL, &tv)->solo_v4l2_poll-> videobuf_poll_stream(file, &fh->vidq, wait);-> poll_wait(file, &buf->done, wait);
唤醒此进程的是open()函数注册的solo_thread()函数
7. 从缓冲区中取数据
ioctl(4, VIDIOC_DQBUF->solo_dqbuf-> videobuf_dqbuf(&fh->vidq, buf, file->f_flags &O_NONBLOCK);-> stream_next_buffer(q, &buf, nonblocking); /*在queue中获取有数据的缓冲区*/-> videobuf_status(q, b, buf, q->type); /*把缓冲区的状态返回给应用层*/-> list_del(&buf->stream);
九、虚拟摄像头驱动程序编写过程
1. 使用video_device_alloc()分配video_device
2. 设置结构体成员
.fops
.ioctl_ops(里面需要设置11项)
如果要用内核提供的缓冲区操作函数,还需要构造一个videobuf_queue_ops
3. 使用video_register_device()注册video_device
我们可以仿照v4l2.c写一个虚拟摄像头驱动程序
源代码:
1 #include <linux/module.h> 2 #include <linux/delay.h> 3 #include <linux/errno.h> 4 #include <linux/fs.h> 5 #include <linux/kernel.h> 6 #include <linux/slab.h> 7 #include <linux/mm.h> 8 #include <linux/ioport.h> 9 #include <linux/init.h> 10 #include <linux/sched.h> 11 #include <linux/pci.h> 12 #include <linux/random.h> 13 #include <linux/version.h> 14 #include <linux/mutex.h> 15 #include <linux/videodev2.h> 16 #include <linux/dma-mapping.h> 17 #include <linux/interrupt.h> 18 #include <linux/kthread.h> 19 #include <linux/highmem.h> 20 #include <linux/freezer.h> 21 #include <media/videobuf-vmalloc.h> 22 #include <media/v4l2-device.h> 23 #include <media/v4l2-ioctl.h> 24 25 #define USE_DMA 0 26 27 static struct video_device *myvivi;28 static structv4l2_format myvivi_format;29 static structvideobuf_queue myvivi_vb_vidq;30 staticspinlock_t myvivi_slock;31 static structtimer_list myvivi_timer;32 static structlist_head myvivi_list_head;33 34 /**35 * videobuf_queue_ops36 **/ 37 /*ioctl VIDIOC_REQBUFS导致此函数被调用38 * 用于重新调整count和size39 */ 40 static int myvivi_buf_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)41 {42 *size =myvivi_format.fmt.pix.sizeimage;43 44 if (*count < 4)45 *count = 4;46 47 return 0;48 }49 50 /*ioctl VIDIOC_QBUF导致此函数被调用51 * 它会填充video_buffer结构体并调用videobuf_iolock来分配内存52 */ 53 static int myvivi_buf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enumv4l2_field field)54 {55 vb->size =myvivi_format.fmt.pix.sizeimage;56 57 /*XXX: These properties only change when queue is idle*/ 58 vb->width =myvivi_format.fmt.pix.width;59 vb->height =myvivi_format.fmt.pix.height;60 vb->bytesperline =myvivi_format.fmt.pix.bytesperline;61 vb->field =field;62 #if USE_DMA 63 if (vb->state ==VIDEOBUF_NEEDS_INIT) {64 int rc =videobuf_iolock(vq, vb, NULL);65 if (rc < 0) {66 struct videobuf_dmabuf *dma =videobuf_to_dma(vb);67 videobuf_dma_unmap(vq->dev, dma);68 videobuf_dma_free(dma);69 vb->state =VIDEOBUF_NEEDS_INIT;70 returnrc;71 }72 }73 #endif 74 vb->state =VIDEOBUF_PREPARED;75 76 return 0;77 }78 79 /*ioctl VIDIOC_QBUF时:80 * 1. 调用buf_prepare()做准备工作81 * 2. 把buf放入stream队列82 * 3. 调用buf_queue(起通知、记录作用)83 */ 84 static void myvivi_buf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)85 {86 vb->state =VIDEOBUF_QUEUED;87 list_add_tail(&vb->queue, &myvivi_list_head);88 /*使用的定时器,不需要唤醒*/ 89 //wake_up_interruptible(&solo_dev->disp_thread_wait); 90 }91 92 /*APP不再使用队列时,用它来释放内存*/ 93 static void myvivi_buf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb)94 {95 #if USE_DMA 96 struct videobuf_dmabuf *dma =videobuf_to_dma(vb);97 98 videobuf_dma_unmap(vq->dev, dma);99 videobuf_dma_free(dma);100 #endif 101 vb->state =VIDEOBUF_NEEDS_INIT;102 }103 104 105 static struct videobuf_queue_ops solo_video_qops ={106 .buf_setup =myvivi_buf_setup,107 .buf_prepare =myvivi_buf_prepare,108 .buf_queue =myvivi_buf_queue,109 .buf_release =myvivi_buf_release,110 };111 112 /**113 * v4l2_file_operations114 **/ 115 static int myvivi_open(struct file *file)116 {117 videobuf_queue_vmalloc_init(&myvivi_vb_vidq, &solo_video_qops,118 NULL, &myvivi_slock,119 V4L2_BUF_TYPE_VIDEO_CAPTURE,120 V4L2_FIELD_INTERLACED,121 sizeof(structvideobuf_buffer), NULL, NULL);122 /*其他程序在此处执行thread,本程序在此处执行定时器*/ 123 myvivi_timer.expires = jiffies + 1;124 add_timer(&myvivi_timer);125 126 return 0;127 }128 129 static int myvivi_close(struct file *file)130 {131 del_timer(&myvivi_timer);132 videobuf_stop(&myvivi_vb_vidq);133 videobuf_mmap_free(&myvivi_vb_vidq);134 135 return 0;136 }137 138 static ssize_t myvivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)139 {140 return videobuf_read_stream(&myvivi_vb_vidq, data, count, ppos, 0, file->f_flags &O_NONBLOCK);141 }142 143 static unsigned int myvivi_poll(struct file *file, struct poll_table_struct *wait)144 {145 return videobuf_poll_stream(file, &myvivi_vb_vidq, wait);146 }147 148 extern int videobuf_mmap_mapper(struct videobuf_queue *, struct vm_area_struct *);149 static int myvivi_mmap(struct file *file, struct vm_area_struct *vma)150 {151 return videobuf_mmap_mapper(&myvivi_vb_vidq, vma);152 }153 154 static const struct v4l2_file_operations myvivi_fops ={155 .owner =THIS_MODULE,156 .open =myvivi_open,157 .release =myvivi_close,158 .read =myvivi_read,159 .poll =myvivi_poll,160 .unlocked_ioctl =video_ioctl2,161 .mmap =myvivi_mmap,162 };163 164 /**165 * v4l2_ioctl_ops166 **/ 167 static int myvivi_querycap(struct file *file, void *priv, struct v4l2_capability *cap)168 {169 strcpy(cap->driver, "myvivi");170 strcpy(cap->card, "myvivi");171 cap->version = 0x01;172 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |V4L2_CAP_STREAMING;173 return 0;174 }175 176 static int myvivi_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f)177 {178 if (f->index)179 return -EINVAL;180 181 f->pixelformat =V4L2_PIX_FMT_YUYV;182 strlcpy(f->description, "4:2:2, packed, YUYV", sizeof(f->description));183 184 return 0;185 }186 187 static int myvivi_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)188 {189 memcpy(f, &myvivi_format, sizeof(myvivi_format));190 return 0;191 }192 193 static int myvivi_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)194 {195 enumv4l2_field field;196 unsigned intmax_width, max_height;197 198 if (f->fmt.pix.pixelformat !=V4L2_PIX_FMT_YUYV)199 return -EINVAL;200 201 field = f->fmt.pix.field;202 if (field ==V4L2_FIELD_ANY) {203 field =V4L2_FIELD_INTERLACED;204 }205 else if (V4L2_FIELD_INTERLACED !=field) {206 return -EINVAL;207 }208 f->fmt.pix.field =field;209 210 max_width = 1024;211 max_height = 768;212 213 v4l_bound_align_image(&f->fmt.pix.width, 48, max_width, 2,214 &f->fmt.pix.height, 32, max_height, 0, 0);215 f->fmt.pix.bytesperline = 216 (f->fmt.pix.width * 16) >> 3;217 f->fmt.pix.sizeimage = 218 f->fmt.pix.height * f->fmt.pix.bytesperline;219 f->fmt.pix.colorspace =V4L2_COLORSPACE_SMPTE170M;220 221 return 0;222 }223 224 static int myvivi_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)225 {226 intret;227 if (videobuf_queue_is_busy(&myvivi_vb_vidq))228 return -EBUSY;229 230 ret =myvivi_try_fmt_vid_cap(file, priv, f);231 if (ret < 0)232 returnret;233 234 memcpy(&myvivi_format, f, sizeof(myvivi_format));235 236 return 0;237 }238 239 static int myvivi_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)240 {241 return videobuf_reqbufs(&myvivi_vb_vidq, p);242 }243 244 static int myvivi_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)245 {246 return videobuf_querybuf(&myvivi_vb_vidq, p);247 }248 249 static int myvivi_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)250 {251 return videobuf_qbuf(&myvivi_vb_vidq, p);252 }253 254 static int myvivi_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)255 {256 return videobuf_dqbuf(&myvivi_vb_vidq, p, file->f_flags &O_NONBLOCK);257 }258 259 static int myvivi_streamon(struct file *file, void *priv, enumv4l2_buf_type i)260 {261 return videobuf_streamon(&myvivi_vb_vidq);262 }263 264 static int myvivi_streamoff(struct file *file, void *priv, enumv4l2_buf_type i)265 {266 videobuf_streamoff(&myvivi_vb_vidq);267 return 0;268 }269 270 static const struct v4l2_ioctl_ops myvivi_ioctl_ops ={271 .vidioc_querycap =myvivi_querycap,272 .vidioc_enum_fmt_vid_cap =myvivi_enum_fmt_vid_cap,273 .vidioc_g_fmt_vid_cap =myvivi_g_fmt_vid_cap,274 .vidioc_try_fmt_vid_cap =myvivi_try_fmt_vid_cap,275 .vidioc_s_fmt_vid_cap =myvivi_s_fmt_vid_cap,276 .vidioc_reqbufs =myvivi_reqbufs,277 .vidioc_querybuf =myvivi_querybuf,278 .vidioc_qbuf =myvivi_qbuf,279 .vidioc_dqbuf =myvivi_dqbuf,280 .vidioc_streamon =myvivi_streamon,281 .vidioc_streamoff =myvivi_streamoff,282 };283 284 static void myvivi_release(struct video_device *vdev)285 {286 /*myvivi_exit()中调用了video_device_release()287 * 因此myvivi->release不需要设置为video_device_release288 */ 289 }290 291 /*此函数用于实现其他文件的thread()*/ 292 static void myvivi_timerfunc(unsigned longarg)293 {294 struct videobuf_buffer *vb;295 void *vbuf;296 297 if (list_empty(&myvivi_list_head))298 gotofail;299 300 vb = list_first_entry(&myvivi_list_head, structvideobuf_buffer,301 queue);302 303 if (!waitqueue_active(&vb->done))304 gotofail;305 306 /*Fill buffer*/ 307 vbuf =videobuf_to_vmalloc(vb);308 if (!vbuf)309 gotofail;310 311 /*由于是虚拟摄像头驱动,所以假装有数据*/ 312 memset(vbuf, 0, vb->size);313 314 vb->field_count++;315 do_gettimeofday(&vb->ts);316 vb->state =VIDEOBUF_DONE;317 318 /*把videobuf从队列中删除*/ 319 list_del(&vb->queue);320 321 /*唤醒videobuf->done上的进程*/ 322 wake_up(&vb->done);323 324 fail:325 /*30帧/秒*/ 326 mod_timer(&myvivi_timer, jiffies + HZ / 30);327 }328 329 static int __init myvivi_init(void)330 {331 intret;332 333 myvivi =video_device_alloc();334 335 myvivi->release =myvivi_release,336 myvivi->fops = &myvivi_fops;337 myvivi->ioctl_ops = &myvivi_ioctl_ops;338 339 /*初始化spinlock*/ 340 spin_lock_init(&myvivi_slock);341 /*初始化timer_list*/ 342 init_timer(&myvivi_timer);343 myvivi_timer.function =myvivi_timerfunc;344 /*初始化list_head*/ 345 INIT_LIST_HEAD(&myvivi_list_head);346 347 ret = video_register_device(myvivi, VFL_TYPE_GRABBER, -1);348 if (ret < 0) {349 video_device_release(myvivi);350 returnret;351 }352 353 return 0;354 }355 356 static void __exit myvivi_exit(void)357 {358 video_unregister_device(myvivi);359 video_device_release(myvivi);360 }361 362 module_init(myvivi_init);363 module_exit(myvivi_exit);364 MODULE_LICENSE("GPL");
View Code
Makefile:
1 KERN_DIR = /work/itop4412/tools/linux-3.5 2 3 all:4 make -C $(KERN_DIR) M=`pwd` modules5 6 clean:7 make -C $(KERN_DIR) M=`pwd` modules clean8 rm -rf modules.order9 10 obj-m += videobuf-vmalloc.o11 obj-m += myvivi.o
View Code
由于是虚拟摄像头,所以源代码中的摄像头参数和数据格式是根据内核规则随意选择的,参数的确定和选取会在下一章进行介绍
本章内容较为混乱,推荐读者自行分析linux/drivers/staging/media/solo6x10/v4l2.c和第八节:数据的获取过程体验各个过程的调用关系
转载于:https://www.cnblogs.com/Lioker/p/11323630.html
二十四、V4L2框架主要结构体分析和虚拟摄像头驱动编写相关推荐
- 【C语言进阶深度学习记录】二十四 指针与数组的本质分析一
文章目录 1 回顾--数组的本质 2 指针的运算 2.1 指针运算代码案例分析 3 指针的比较 3.1 指针运算的应用代码案例分析 4 总结 1 回顾–数组的本质 在之前的文章,已经学习了数组的本质分 ...
- BetaFlight模块设计之二十四:transponder任务分析
BetaFlight模块设计之二十四:transponder任务分析 transponder任务 配置情况 硬件配置 驱动配置 业务配置 初始化 MSP协议 三种IR transponder type ...
- 【软件开发底层知识修炼】二十五 ABI之函数调用约定二之函数返回值为结构体时的约定
上一篇文章学习了几种函数调用约定的区别,点击链接查看上一篇文章:[软件开发底层知识修炼]二十四 ABI之函数调用约定 本篇文章继续学习函数调用约定中,关于函数返回值的问题.当函数返回值为结构体时,函数 ...
- C语言试题五十二之学生的记录由学号和成绩组称个,n名大学生得数据已在主函数中放入结构体数组a中,请编写函数fun,它的功能时:按分数的高低排列学生的记录,高分在前。
1. 题目 请编写一个函数void function(Student a[], int n),其功能时:学生的记录由学号和成绩组称个,n名大学生得数据已在主函数中放入结构体数组a中,请编写函数fun, ...
- [系统安全] 二十四.逆向分析之OllyDbg调试INT3断点、反调试、硬件断点与内存断点
您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列.因此,我重新开设了这个专栏,准备系统整理和深入学习系统安全.逆向分 ...
- 华文行楷字帖欣赏_任政书法:行楷字帖《二十四孝组诗》集字版,美不胜收!...
原标题:任政书法:行楷字帖<二十四孝组诗>集字版,美不胜收! 本次小编分享:任政行楷书法字帖欣赏<二十四孝组诗>集字版图片24张,<二十四孝>集虞舜.黄庭坚等二十四 ...
- java从入门到精通二十四(三层架构完成增删改查)
java从入门到精通二十四(三层架构完成增删改查) 前言 环境准备 创建web项目结构 导入依赖和配置文件 创建层次模型 实现查询 实现添加 实现修改 完成删除 做一个用户登录验证 会话技术 cook ...
- 【Visual C++】游戏开发五十七 浅墨DirectX教程二十四 打造游戏GUI界面(二)
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/16922703 作者:毛星 ...
- J2EE进阶(二十四)JBoss Web和 Tomcat的区别
J2EE进阶(二十四)JBoss Web和 Tomcat的区别 在Web2.0的浪潮中,各种页面技术和框架不断涌现,为服务器端的基础架构提出了更高的稳定性和可扩展性的要求.近年来,作为开源中间件的全球 ...
最新文章
- FPGA逻辑设计回顾(8)单比特信号的CDC处理方式之Toggle同步器
- 时间被空间和运动度量
- PHP多种序列化/反序列化的方法 json_encode json_decode
- Redis事务与监控
- .NET开发人员如何开始使用ML.NET
- java获取主机信息大全,网络编程:Java获取网络主机信息
- 【CodeForces - 569B】Inventory (标记,乱搞)
- PYTHON网络爬虫与信息提取[网络爬虫协议](单元二)
- tomcat 使用 memcached管理session ,并且实现统一登录
- Go语言基础进阶—程序结构—包和文件
- windows 8 Skydrive
- Promise及其应用
- html人物属性代码,辐射4初始人物超强属性代码一览
- 使用Graham扫描法获取一个平面点集的凸包
- python制作有道翻译软件
- ViewBinding 与 Kotlin 委托双剑合璧
- 九招教你完全了解液晶拼接屏
- sdut 1309 不老的传说问题(区间DP,难,值得好好看)
- 2020-2021的瞻前顾后
- 【数据可视化】条形统计图