⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 v4l1-compat.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * *	Video for Linux Two *	Backward Compatibility Layer * *	Support subroutines for providing V4L2 drivers with backward *	compatibility with applications using the old API. * *	This program is free software; you can redistribute it and/or *	modify it under the terms of the GNU General Public License *	as published by the Free Software Foundation; either version *	2 of the License, or (at your option) any later version. * * Author:	Bill Dirks <bill@thedirks.org> *		et al. * */#include <linux/init.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/fs.h>#include <linux/file.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/videodev.h>#include <media/v4l2-common.h>#include <media/v4l2-ioctl.h>#include <asm/uaccess.h>#include <asm/system.h>#include <asm/pgtable.h>#include "compat.h"static unsigned int debug;module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "enable debug messages");MODULE_AUTHOR("Bill Dirks");MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");MODULE_LICENSE("GPL");#define dprintk(fmt, arg...) \	do { \		if (debug) \			printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg);\	} while (0)/* *	I O C T L   T R A N S L A T I O N * *	From here on down is the code for translating the numerous *	ioctl commands from the old API to the new API. */static intget_v4l_control(struct file             *file,		int			cid,		v4l2_kioctl             drv){	struct v4l2_queryctrl	qctrl2;	struct v4l2_control	ctrl2;	int			err;	qctrl2.id = cid;	err = drv(file, VIDIOC_QUERYCTRL, &qctrl2);	if (err < 0)		dprintk("VIDIOC_QUERYCTRL: %d\n", err);	if (err == 0 && !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) {		ctrl2.id = qctrl2.id;		err = drv(file, VIDIOC_G_CTRL, &ctrl2);		if (err < 0) {			dprintk("VIDIOC_G_CTRL: %d\n", err);			return 0;		}		return ((ctrl2.value - qctrl2.minimum) * 65535			 + (qctrl2.maximum - qctrl2.minimum) / 2)			/ (qctrl2.maximum - qctrl2.minimum);	}	return 0;}static intset_v4l_control(struct file             *file,		int			cid,		int			value,		v4l2_kioctl             drv){	struct v4l2_queryctrl	qctrl2;	struct v4l2_control	ctrl2;	int			err;	qctrl2.id = cid;	err = drv(file, VIDIOC_QUERYCTRL, &qctrl2);	if (err < 0)		dprintk("VIDIOC_QUERYCTRL: %d\n", err);	if (err == 0 &&	    !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&	    !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED)) {		if (value < 0)			value = 0;		if (value > 65535)			value = 65535;		if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)			value = 65535;		ctrl2.id = qctrl2.id;		ctrl2.value =			(value * (qctrl2.maximum - qctrl2.minimum)			 + 32767)			/ 65535;		ctrl2.value += qctrl2.minimum;		err = drv(file, VIDIOC_S_CTRL, &ctrl2);		if (err < 0)			dprintk("VIDIOC_S_CTRL: %d\n", err);	}	return 0;}/* ----------------------------------------------------------------- */static const unsigned int palette2pixelformat[] = {	[VIDEO_PALETTE_GREY]    = V4L2_PIX_FMT_GREY,	[VIDEO_PALETTE_RGB555]  = V4L2_PIX_FMT_RGB555,	[VIDEO_PALETTE_RGB565]  = V4L2_PIX_FMT_RGB565,	[VIDEO_PALETTE_RGB24]   = V4L2_PIX_FMT_BGR24,	[VIDEO_PALETTE_RGB32]   = V4L2_PIX_FMT_BGR32,	/* yuv packed pixel */	[VIDEO_PALETTE_YUYV]    = V4L2_PIX_FMT_YUYV,	[VIDEO_PALETTE_YUV422]  = V4L2_PIX_FMT_YUYV,	[VIDEO_PALETTE_UYVY]    = V4L2_PIX_FMT_UYVY,	/* yuv planar */	[VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,	[VIDEO_PALETTE_YUV420]  = V4L2_PIX_FMT_YUV420,	[VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,	[VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,	[VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,};static unsigned int __purepalette_to_pixelformat(unsigned int palette){	if (palette < ARRAY_SIZE(palette2pixelformat))		return palette2pixelformat[palette];	else		return 0;}static unsigned int __attribute_const__pixelformat_to_palette(unsigned int pixelformat){	int	palette = 0;	switch (pixelformat) {	case V4L2_PIX_FMT_GREY:		palette = VIDEO_PALETTE_GREY;		break;	case V4L2_PIX_FMT_RGB555:		palette = VIDEO_PALETTE_RGB555;		break;	case V4L2_PIX_FMT_RGB565:		palette = VIDEO_PALETTE_RGB565;		break;	case V4L2_PIX_FMT_BGR24:		palette = VIDEO_PALETTE_RGB24;		break;	case V4L2_PIX_FMT_BGR32:		palette = VIDEO_PALETTE_RGB32;		break;	/* yuv packed pixel */	case V4L2_PIX_FMT_YUYV:		palette = VIDEO_PALETTE_YUYV;		break;	case V4L2_PIX_FMT_UYVY:		palette = VIDEO_PALETTE_UYVY;		break;	/* yuv planar */	case V4L2_PIX_FMT_YUV410:		palette = VIDEO_PALETTE_YUV420;		break;	case V4L2_PIX_FMT_YUV420:		palette = VIDEO_PALETTE_YUV420;		break;	case V4L2_PIX_FMT_YUV411P:		palette = VIDEO_PALETTE_YUV411P;		break;	case V4L2_PIX_FMT_YUV422P:		palette = VIDEO_PALETTE_YUV422P;		break;	}	return palette;}/* ----------------------------------------------------------------- */static int poll_one(struct file *file, struct poll_wqueues *pwq){	int retval = 1;	poll_table *table;	poll_initwait(pwq);	table = &pwq->pt;	for (;;) {		int mask;		set_current_state(TASK_INTERRUPTIBLE);		mask = file->f_op->poll(file, table);		if (mask & POLLIN)			break;		table = NULL;		if (signal_pending(current)) {			retval = -ERESTARTSYS;			break;		}		schedule();	}	set_current_state(TASK_RUNNING);	poll_freewait(pwq);	return retval;}static int count_inputs(			struct file *file,			v4l2_kioctl drv){	struct v4l2_input input2;	int i;	for (i = 0;; i++) {		memset(&input2, 0, sizeof(input2));		input2.index = i;		if (0 != drv(file, VIDIOC_ENUMINPUT, &input2))			break;	}	return i;}static int check_size(		struct file *file,		v4l2_kioctl drv,		int *maxw,		int *maxh){	struct v4l2_fmtdesc desc2;	struct v4l2_format  fmt2;	memset(&desc2, 0, sizeof(desc2));	memset(&fmt2, 0, sizeof(fmt2));	desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;	if (0 != drv(file, VIDIOC_ENUM_FMT, &desc2))		goto done;	fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;	fmt2.fmt.pix.width       = 10000;	fmt2.fmt.pix.height      = 10000;	fmt2.fmt.pix.pixelformat = desc2.pixelformat;	if (0 != drv(file, VIDIOC_TRY_FMT, &fmt2))		goto done;	*maxw = fmt2.fmt.pix.width;	*maxh = fmt2.fmt.pix.height;done:	return 0;}/* ----------------------------------------------------------------- */static noinline int v4l1_compat_get_capabilities(					struct video_capability *cap,					struct file *file,					v4l2_kioctl drv){	int err;	struct v4l2_framebuffer fbuf;	struct v4l2_capability *cap2;	cap2 = kzalloc(sizeof(*cap2), GFP_KERNEL);	if (!cap2) {		err = -ENOMEM;		return err;	}	memset(cap, 0, sizeof(*cap));	memset(&fbuf, 0, sizeof(fbuf));	err = drv(file, VIDIOC_QUERYCAP, cap2);	if (err < 0) {		dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n", err);		goto done;	}	if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {		err = drv(file, VIDIOC_G_FBUF, &fbuf);		if (err < 0) {			dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n", err);			memset(&fbuf, 0, sizeof(fbuf));		}		err = 0;	}	memcpy(cap->name, cap2->card,	       min(sizeof(cap->name), sizeof(cap2->card)));	cap->name[sizeof(cap->name) - 1] = 0;	if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)		cap->type |= VID_TYPE_CAPTURE;	if (cap2->capabilities & V4L2_CAP_TUNER)		cap->type |= VID_TYPE_TUNER;	if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)		cap->type |= VID_TYPE_TELETEXT;	if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)		cap->type |= VID_TYPE_OVERLAY;	if (fbuf.capability & V4L2_FBUF_CAP_LIST_CLIPPING)		cap->type |= VID_TYPE_CLIPPING;	cap->channels  = count_inputs(file, drv);	check_size(file, drv,		   &cap->maxwidth, &cap->maxheight);	cap->audios    =  0; /* FIXME */	cap->minwidth  = 48; /* FIXME */	cap->minheight = 32; /* FIXME */done:	kfree(cap2);	return err;}static noinline int v4l1_compat_get_frame_buffer(					struct video_buffer *buffer,					struct file *file,					v4l2_kioctl drv){	int err;	struct v4l2_framebuffer fbuf;	memset(buffer, 0, sizeof(*buffer));	memset(&fbuf, 0, sizeof(fbuf));	err = drv(file, VIDIOC_G_FBUF, &fbuf);	if (err < 0) {		dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n", err);		goto done;	}	buffer->base   = fbuf.base;	buffer->height = fbuf.fmt.height;	buffer->width  = fbuf.fmt.width;	switch (fbuf.fmt.pixelformat) {	case V4L2_PIX_FMT_RGB332:		buffer->depth = 8;		break;	case V4L2_PIX_FMT_RGB555:		buffer->depth = 15;		break;	case V4L2_PIX_FMT_RGB565:		buffer->depth = 16;		break;	case V4L2_PIX_FMT_BGR24:		buffer->depth = 24;		break;	case V4L2_PIX_FMT_BGR32:		buffer->depth = 32;		break;	default:		buffer->depth = 0;	}	if (fbuf.fmt.bytesperline) {		buffer->bytesperline = fbuf.fmt.bytesperline;		if (!buffer->depth && buffer->width)			buffer->depth   = ((fbuf.fmt.bytesperline<<3)					  + (buffer->width-1))					  / buffer->width;	} else {		buffer->bytesperline =			(buffer->width * buffer->depth + 7) & 7;		buffer->bytesperline >>= 3;	}done:	return err;}static noinline int v4l1_compat_set_frame_buffer(					struct video_buffer *buffer,					struct file *file,					v4l2_kioctl drv){	int err;	struct v4l2_framebuffer fbuf;	memset(&fbuf, 0, sizeof(fbuf));	fbuf.base       = buffer->base;	fbuf.fmt.height = buffer->height;	fbuf.fmt.width  = buffer->width;	switch (buffer->depth) {	case 8:		fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB332;		break;	case 15:		fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB555;		break;	case 16:		fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB565;		break;	case 24:		fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR24;		break;	case 32:		fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR32;		break;	}	fbuf.fmt.bytesperline = buffer->bytesperline;	err = drv(file, VIDIOC_S_FBUF, &fbuf);	if (err < 0)		dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n", err);	return err;}static noinline int v4l1_compat_get_win_cap_dimensions(					struct video_window *win,					struct file *file,					v4l2_kioctl drv){	int err;	struct v4l2_format *fmt;	fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -