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

📄 buz.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* insert constant params */	params->major_version = MAJOR_VERSION;	params->minor_version = MINOR_VERSION;	/* Check input and norm */	if (params->input != 0 && params->input != 1) {		err++;	}	if (params->norm != VIDEO_MODE_PAL && params->norm != VIDEO_MODE_NTSC) {		err++;	}	/* Check decimation, set default values for decimation = 1, 2, 4 */	switch (params->decimation) {	case 1:		params->HorDcm = 1;		params->VerDcm = 1;		params->TmpDcm = 1;		params->field_per_buff = 2;		params->img_x = 0;		params->img_y = 0;		params->img_width = 720;		params->img_height = tvnorms[params->norm].Ha / 2;		break;	case 2:		params->HorDcm = 2;		params->VerDcm = 1;		params->TmpDcm = 2;		params->field_per_buff = 1;		params->img_x = 8;		params->img_y = 0;		params->img_width = 704;		params->img_height = tvnorms[params->norm].Ha / 2;		break;	case 4:		params->HorDcm = 4;		params->VerDcm = 2;		params->TmpDcm = 2;		params->field_per_buff = 1;		params->img_x = 8;		params->img_y = 0;		params->img_width = 704;		params->img_height = tvnorms[params->norm].Ha / 2;		break;	case 0:		/* We have to check the data the user has set */		if (params->HorDcm != 1 && params->HorDcm != 2 && params->HorDcm != 4)			err0++;		if (params->VerDcm != 1 && params->VerDcm != 2)			err0++;		if (params->TmpDcm != 1 && params->TmpDcm != 2)			err0++;		if (params->field_per_buff != 1 && params->field_per_buff != 2)			err0++;		if (params->img_x < 0)			err0++;		if (params->img_y < 0)			err0++;		if (params->img_width < 0)			err0++;		if (params->img_height < 0)			err0++;		if (params->img_x + params->img_width > 720)			err0++;		if (params->img_y + params->img_height > tvnorms[params->norm].Ha / 2)			err0++;		if (params->img_width % (16 * params->HorDcm) != 0)			err0++;		if (params->img_height % (8 * params->VerDcm) != 0)			err0++;		if (err0) {			err++;		}		break;	default:		err++;		break;	}	if (params->quality > 100)		params->quality = 100;	if (params->quality < 5)		params->quality = 5;	if (params->APPn < 0)		params->APPn = 0;	if (params->APPn > 15)		params->APPn = 15;	if (params->APP_len < 0)		params->APP_len = 0;	if (params->APP_len > 60)		params->APP_len = 60;	if (params->COM_len < 0)		params->COM_len = 0;	if (params->COM_len > 60)		params->COM_len = 60;	if (err)		return -EINVAL;	return 0;}static void zoran_open_init_params(struct zoran *zr){	int i;	/* Per default, map the V4L Buffers */	zr->map_mjpeg_buffers = 0;	/* User must explicitly set a window */	zr->window_set = 0;	zr->window.x = 0;	zr->window.y = 0;	zr->window.width = 0;	zr->window.height = 0;	zr->window.chromakey = 0;	zr->window.flags = 0;	zr->window.clips = NULL;	zr->window.clipcount = 0;	zr->video_interlace = 0;	zr->v4l_memgrab_active = 0;	zr->v4l_overlay_active = 0;	zr->v4l_grab_frame = NO_GRAB_ACTIVE;	zr->v4l_grab_seq = 0;	zr->gwidth = 0;	zr->gheight = 0;	zr->gformat = 0;	zr->gbpl = 0;	/* DMA ring stuff for V4L */	zr->v4l_pend_tail = 0;	zr->v4l_pend_head = 0;	for (i = 0; i < v4l_nbufs; i++) {		zr->v4l_gbuf[i].state = BUZ_STATE_USER;	/* nothing going on */	}	/* Set necessary params and call zoran_check_params to set the defaults */	zr->params.decimation = 1;	zr->params.quality = 50;	/* default compression factor 8 */	zr->params.odd_even = 1;	zr->params.APPn = 0;	zr->params.APP_len = 0;	/* No APPn marker */	for (i = 0; i < 60; i++)		zr->params.APP_data[i] = 0;	zr->params.COM_len = 0;	/* No COM marker */	for (i = 0; i < 60; i++)		zr->params.COM_data[i] = 0;	zr->params.VFIFO_FB = 0;	memset(zr->params.reserved, 0, sizeof(zr->params.reserved));	zr->params.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT;	i = zoran_check_params(zr, &zr->params);	if (i)		printk(KERN_ERR "%s: zoran_open_init_params internal error\n", zr->name);}/* *   Open a buz card. Right now the flags stuff is just playing */static int zoran_open(struct video_device *dev, int flags){	struct zoran *zr = (struct zoran *) dev;	DEBUG(printk(KERN_INFO ": zoran_open\n"));	switch (flags) {	case 0:		if (zr->user)			return -EBUSY;		zr->user++;		if (v4l_fbuffer_alloc(zr) < 0) {			zr->user--;			return -ENOMEM;		}		/* default setup */		zoran_open_init_params(zr);		zr36057_enable_jpg(zr, BUZ_MODE_IDLE);		btwrite(IRQ_MASK, ZR36057_ISR);		// Clears interrupts		btor(ZR36057_ICR_IntPinEn, ZR36057_ICR);		break;	default:		return -EBUSY;	}	MOD_INC_USE_COUNT;	return 0;}static void zoran_close(struct video_device *dev){	struct zoran *zr = (struct zoran *) dev;	DEBUG(printk(KERN_INFO ": zoran_close\n"));		/* disable interrupts */	btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);	/* wake up sleeping beauties */	wake_up_interruptible(&zr->v4l_capq);	wake_up_interruptible(&zr->jpg_capq);	zr36057_enable_jpg(zr, BUZ_MODE_IDLE);	zr36057_set_memgrab(zr, 0);	if (zr->v4l_overlay_active)		zr36057_overlay(zr, 0);	zr->user--;	v4l_fbuffer_free(zr);	jpg_fbuffer_free(zr);	zr->jpg_nbufs = 0;	MOD_DEC_USE_COUNT;	DEBUG(printk(KERN_INFO ": zoran_close done\n"));}static long zoran_read(struct video_device *dev, char *buf, unsigned long count, int nonblock){	return -EINVAL;}static long zoran_write(struct video_device *dev, const char *buf, unsigned long count, int nonblock){	return -EINVAL;}/* *   ioctl routine */static int zoran_ioctl(struct video_device *dev, unsigned int cmd, void *arg){	struct zoran *zr = (struct zoran *) dev;	switch (cmd) {	case VIDIOCGCAP:		{			struct video_capability b;			IOCTL_DEBUG(printk("buz ioctl VIDIOCGCAP\n"));			strncpy(b.name, zr->video_dev.name, sizeof(b.name));			b.type = VID_TYPE_CAPTURE |			    VID_TYPE_OVERLAY |			    VID_TYPE_CLIPPING |			    VID_TYPE_FRAMERAM |			    VID_TYPE_SCALES;			/* theoretically we could also flag VID_TYPE_SUBCAPTURE			   but this is not even implemented in the BTTV driver */			b.channels = 2;		/* composite, svhs */			b.audios = 0;			b.maxwidth = BUZ_MAX_WIDTH;			b.maxheight = BUZ_MAX_HEIGHT;			b.minwidth = BUZ_MIN_WIDTH;			b.minheight = BUZ_MIN_HEIGHT;			if (copy_to_user(arg, &b, sizeof(b))) {				return -EFAULT;			}			return 0;		}	case VIDIOCGCHAN:		{			struct video_channel v;			if (copy_from_user(&v, arg, sizeof(v))) {				return -EFAULT;			}			IOCTL_DEBUG(printk("buz ioctl VIDIOCGCHAN for channel %d\n", v.channel));			switch (v.channel) {			case 0:				strcpy(v.name, "Composite");				break;			case 1:				strcpy(v.name, "SVHS");				break;			default:				return -EINVAL;			}			v.tuners = 0;			v.flags = 0;			v.type = VIDEO_TYPE_CAMERA;			v.norm = zr->params.norm;			if (copy_to_user(arg, &v, sizeof(v))) {				return -EFAULT;			}			return 0;		}		/* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says:		 * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input."		 *                                 ^^^^^^^		 * The famos BTTV driver has it implemented with a struct video_channel argument		 * and we follow it for compatibility reasons		 *		 * BTW: this is the only way the user can set the norm!		 */	case VIDIOCSCHAN:		{			struct video_channel v;			int input;			int on, res;			if (copy_from_user(&v, arg, sizeof(v))) {				return -EFAULT;			}			IOCTL_DEBUG(printk("buz ioctl VIDIOCSCHAN: channel=%d, norm=%d\n", v.channel, v.norm));			switch (v.channel) {			case 0:				input = 3;				break;			case 1:				input = 7;				break;			default:				return -EINVAL;			}			if (v.norm != VIDEO_MODE_PAL			    && v.norm != VIDEO_MODE_NTSC) {				return -EINVAL;			}			zr->params.norm = v.norm;			zr->params.input = v.channel;			/* We switch overlay off and on since a change in the norm			   needs different VFE settings */			on = zr->v4l_overlay_active && !zr->v4l_memgrab_active;			if (on)				zr36057_overlay(zr, 0);			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &input);			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &zr->params.norm);			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_NORM, &zr->params.norm);			if (on)				zr36057_overlay(zr, 1);			/* Make sure the changes come into effect */			res = wait_grab_pending(zr);			if (res)				return res;			return 0;		}	case VIDIOCGTUNER:	case VIDIOCSTUNER:			return -EINVAL;	case VIDIOCGPICT:		{			struct video_picture p = zr->picture;			IOCTL_DEBUG(printk("buz ioctl VIDIOCGPICT\n"));			p.depth = zr->buffer.depth;			switch (zr->buffer.depth) {			case 15:				p.palette = VIDEO_PALETTE_RGB555;				break;			case 16:				p.palette = VIDEO_PALETTE_RGB565;				break;			case 24:				p.palette = VIDEO_PALETTE_RGB24;				break;			case 32:				p.palette = VIDEO_PALETTE_RGB32;				break;			}			if (copy_to_user(arg, &p, sizeof(p))) {				return -EFAULT;			}			return 0;		}	case VIDIOCSPICT:		{			struct video_picture p;			if (copy_from_user(&p, arg, sizeof(p))) {				return -EFAULT;			}			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &p);			IOCTL_DEBUG(printk("buz ioctl VIDIOCSPICT bri=%d hue=%d col=%d con=%d dep=%d pal=%d\n",					   p.brightness, p.hue, p.colour, p.contrast, p.depth, p.palette));			/* The depth and palette values have no meaning to us,			   should we return  -EINVAL if they don't fit ? */			zr->picture = p;			return 0;		}	case VIDIOCCAPTURE:		{			int v, res;			if (copy_from_user(&v, arg, sizeof(v))) {				return -EFAULT;			}			IOCTL_DEBUG(printk("buz ioctl VIDIOCCAPTURE: %d\n", v));			/* If there is nothing to do, return immediatly */			if ((v && zr->v4l_overlay_active) || (!v && !zr->v4l_overlay_active))				return 0;			if (v == 0) {				zr->v4l_overlay_active = 0;				if (!zr->v4l_memgrab_active)					zr36057_overlay(zr, 0);				/* When a grab is running, the video simply won't be switched on any more */			} else {				if (!zr->buffer_set || !zr->window_set) {					return -EINVAL;				}				zr->v4l_overlay_active = 1;				if (!zr->v4l_memgrab_active)					zr36057_overlay(zr, 1);				/* When a grab is running, the video will be switched on when grab is finished */			}			/* Make sure the changes come into effect */			res = wait_grab_pending(zr);			if (res)				return res;			return 0;		}	case VIDIOCGWIN:		{			IOCTL_DEBUG(printk("buz ioctl VIDIOCGWIN\n"));			if (copy_to_user(arg, &zr->window, sizeof(zr->window))) {				return -EFAULT;			}			return 0;		}	case VIDIOCSWIN:		{			struct video_clip *vcp;			struct video_window vw;			int on, end, res;			if (copy_from_user(&vw, arg, sizeof(vw))) {				return -EFAULT;			}			IOCTL_DEBUG(printk("buz ioctl VIDIOCSWIN: x=%d y=%d w=%d h=%d clipcount=%d\n", vw.x, vw.y, vw.width, vw.height, vw.clipcount));			if (!zr->buffer_set) {				return -EINVAL;			}			/*			 * The video front end needs 4-byte alinged line sizes, we correct that			 * silently here if necessary			 */			if (zr->buffer.depth == 15 || zr->buffer.depth == 16) {				end = (vw.x + vw.width) & ~1;	/* round down */				vw.x = (vw.x + 1) & ~1;		/* round up */				vw.width = end - vw.x;			}			if (zr->buffer.depth == 24) {				end = (vw.x + vw.wid

⌨️ 快捷键说明

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