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

📄 saa7134-video.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
}static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,			   struct v4l2_format *f){	int err;	switch (f->type) {	case V4L2_BUF_TYPE_VIDEO_CAPTURE:	{		struct saa7134_format *fmt;		enum v4l2_field field;		unsigned int maxw, maxh;		fmt = format_by_fourcc(f->fmt.pix.pixelformat);		if (NULL == fmt)			return -EINVAL;		field = f->fmt.pix.field;		maxw  = min(dev->crop_current.width*4,  dev->crop_bounds.width);		maxh  = min(dev->crop_current.height*4, dev->crop_bounds.height);		if (V4L2_FIELD_ANY == field) {			field = (f->fmt.pix.height > maxh/2)				? V4L2_FIELD_INTERLACED				: V4L2_FIELD_BOTTOM;		}		switch (field) {		case V4L2_FIELD_TOP:		case V4L2_FIELD_BOTTOM:			maxh = maxh / 2;			break;		case V4L2_FIELD_INTERLACED:			break;		default:			return -EINVAL;		}		f->fmt.pix.field = field;		if (f->fmt.pix.width  < 48)			f->fmt.pix.width  = 48;		if (f->fmt.pix.height < 32)			f->fmt.pix.height = 32;		if (f->fmt.pix.width > maxw)			f->fmt.pix.width = maxw;		if (f->fmt.pix.height > maxh)			f->fmt.pix.height = maxh;		f->fmt.pix.width &= ~0x03;		f->fmt.pix.bytesperline =			(f->fmt.pix.width * fmt->depth) >> 3;		f->fmt.pix.sizeimage =			f->fmt.pix.height * f->fmt.pix.bytesperline;		return 0;	}	case V4L2_BUF_TYPE_VIDEO_OVERLAY:		err = verify_preview(dev,&f->fmt.win);		if (0 != err)			return err;		return 0;	case V4L2_BUF_TYPE_VBI_CAPTURE:		saa7134_vbi_fmt(dev,f);		return 0;	default:		return -EINVAL;	}}static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,			 struct v4l2_format *f){	unsigned long flags;	int err;	switch (f->type) {	case V4L2_BUF_TYPE_VIDEO_CAPTURE:		err = saa7134_try_fmt(dev,fh,f);		if (0 != err)			return err;		fh->fmt       = format_by_fourcc(f->fmt.pix.pixelformat);		fh->width     = f->fmt.pix.width;		fh->height    = f->fmt.pix.height;		fh->cap.field = f->fmt.pix.field;		return 0;	case V4L2_BUF_TYPE_VIDEO_OVERLAY:		err = verify_preview(dev,&f->fmt.win);		if (0 != err)			return err;		down(&dev->lock);		fh->win    = f->fmt.win;		fh->nclips = f->fmt.win.clipcount;		if (fh->nclips > 8)			fh->nclips = 8;		if (copy_from_user(fh->clips,f->fmt.win.clips,				   sizeof(struct v4l2_clip)*fh->nclips)) {			up(&dev->lock);			return -EFAULT;		}		if (res_check(fh, RESOURCE_OVERLAY)) {			spin_lock_irqsave(&dev->slock,flags);			stop_preview(dev,fh);			start_preview(dev,fh);			spin_unlock_irqrestore(&dev->slock,flags);		}		up(&dev->lock);		return 0;	case V4L2_BUF_TYPE_VBI_CAPTURE:		saa7134_vbi_fmt(dev,f);		return 0;	default:		return -EINVAL;	}}int saa7134_common_ioctl(struct saa7134_dev *dev,			 unsigned int cmd, void *arg){	int err;	switch (cmd) {	case VIDIOC_QUERYCTRL:	{		const struct v4l2_queryctrl *ctrl;		struct v4l2_queryctrl *c = arg;		if ((c->id <  V4L2_CID_BASE ||		     c->id >= V4L2_CID_LASTP1) &&		    (c->id <  V4L2_CID_PRIVATE_BASE ||		     c->id >= V4L2_CID_PRIVATE_LASTP1))			return -EINVAL;		ctrl = ctrl_by_id(c->id);		*c = (NULL != ctrl) ? *ctrl : no_ctrl;		return 0;	}	case VIDIOC_G_CTRL:		return get_control(dev,arg);	case VIDIOC_S_CTRL:	{		down(&dev->lock);		err = set_control(dev,NULL,arg);		up(&dev->lock);		return err;	}	/* --- input switching --------------------------------------- */	case VIDIOC_ENUMINPUT:	{		struct v4l2_input *i = arg;		unsigned int n;		n = i->index;		if (n >= SAA7134_INPUT_MAX)			return -EINVAL;		if (NULL == card_in(dev,i->index).name)			return -EINVAL;		memset(i,0,sizeof(*i));		i->index = n;		i->type  = V4L2_INPUT_TYPE_CAMERA;		strcpy(i->name,card_in(dev,n).name);		if (card_in(dev,n).tv)			i->type = V4L2_INPUT_TYPE_TUNER;		i->audioset = 1;		if (n == dev->ctl_input) {			int v1 = saa_readb(SAA7134_STATUS_VIDEO1);			int v2 = saa_readb(SAA7134_STATUS_VIDEO2);			if (0 != (v1 & 0x40))				i->status |= V4L2_IN_ST_NO_H_LOCK;			if (0 != (v2 & 0x40))				i->status |= V4L2_IN_ST_NO_SYNC;			if (0 != (v2 & 0x0e))				i->status |= V4L2_IN_ST_MACROVISION;		}		for (n = 0; n < TVNORMS; n++)			i->std |= tvnorms[n].id;		return 0;	}	case VIDIOC_G_INPUT:	{		int *i = arg;		*i = dev->ctl_input;		return 0;	}	case VIDIOC_S_INPUT:	{		int *i = arg;		if (*i < 0  ||  *i >= SAA7134_INPUT_MAX)			return -EINVAL;		if (NULL == card_in(dev,*i).name)			return -EINVAL;		down(&dev->lock);		video_mux(dev,*i);		up(&dev->lock);		return 0;	}	}	return 0;}EXPORT_SYMBOL(saa7134_common_ioctl);/* * This function is _not_ called directly, but from * video_generic_ioctl (and maybe others).  userspace * copying is done already, arg is a kernel pointer. */static int video_do_ioctl(struct inode *inode, struct file *file,			  unsigned int cmd, void *arg){	struct saa7134_fh *fh = file->private_data;	struct saa7134_dev *dev = fh->dev;	unsigned long flags;	int err;	if (video_debug > 1)		saa7134_print_ioctl(dev->name,cmd);	switch (cmd) {	case VIDIOC_S_CTRL:	case VIDIOC_S_STD:	case VIDIOC_S_INPUT:	case VIDIOC_S_TUNER:	case VIDIOC_S_FREQUENCY:		err = v4l2_prio_check(&dev->prio,&fh->prio);		if (0 != err)			return err;	}	switch (cmd) {	case VIDIOC_QUERYCAP:	{		struct v4l2_capability *cap = arg;		unsigned int tuner_type = dev->tuner_type;		memset(cap,0,sizeof(*cap));		strcpy(cap->driver, "saa7134");		strlcpy(cap->card, saa7134_boards[dev->board].name,			sizeof(cap->card));		sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));		cap->version = SAA7134_VERSION_CODE;		cap->capabilities =			V4L2_CAP_VIDEO_CAPTURE |			V4L2_CAP_VIDEO_OVERLAY |			V4L2_CAP_VBI_CAPTURE |			V4L2_CAP_READWRITE |			V4L2_CAP_STREAMING |			V4L2_CAP_TUNER;		if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))			cap->capabilities &= ~V4L2_CAP_TUNER;		return 0;	}	/* --- tv standards ------------------------------------------ */	case VIDIOC_ENUMSTD:	{		struct v4l2_standard *e = arg;		unsigned int i;		i = e->index;		if (i >= TVNORMS)			return -EINVAL;		err = v4l2_video_std_construct(e, tvnorms[e->index].id,					       tvnorms[e->index].name);		e->index = i;		if (err < 0)			return err;		return 0;	}	case VIDIOC_G_STD:	{		v4l2_std_id *id = arg;		*id = dev->tvnorm->id;		return 0;	}	case VIDIOC_S_STD:	{		v4l2_std_id *id = arg;		unsigned int i;		for (i = 0; i < TVNORMS; i++)			if (*id == tvnorms[i].id)				break;		if (i == TVNORMS)			for (i = 0; i < TVNORMS; i++)				if (*id & tvnorms[i].id)					break;		if (i == TVNORMS)			return -EINVAL;		down(&dev->lock);		if (res_check(fh, RESOURCE_OVERLAY)) {			spin_lock_irqsave(&dev->slock,flags);			stop_preview(dev,fh);			set_tvnorm(dev,&tvnorms[i]);			start_preview(dev,fh);			spin_unlock_irqrestore(&dev->slock,flags);		} else			set_tvnorm(dev,&tvnorms[i]);		saa7134_tvaudio_do_scan(dev);		up(&dev->lock);		return 0;	}	case VIDIOC_CROPCAP:	{		struct v4l2_cropcap *cap = arg;		if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&		    cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)			return -EINVAL;		cap->bounds  = dev->crop_bounds;		cap->defrect = dev->crop_defrect;		cap->pixelaspect.numerator   = 1;		cap->pixelaspect.denominator = 1;		if (dev->tvnorm->id & V4L2_STD_525_60) {			cap->pixelaspect.numerator   = 11;			cap->pixelaspect.denominator = 10;		}		if (dev->tvnorm->id & V4L2_STD_625_50) {			cap->pixelaspect.numerator   = 54;			cap->pixelaspect.denominator = 59;		}		return 0;	}	case VIDIOC_G_CROP:	{		struct v4l2_crop * crop = arg;		if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&		    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)			return -EINVAL;		crop->c = dev->crop_current;		return 0;	}	case VIDIOC_S_CROP:	{		struct v4l2_crop *crop = arg;		struct v4l2_rect *b = &dev->crop_bounds;		if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&		    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)			return -EINVAL;		if (crop->c.height < 0)			return -EINVAL;		if (crop->c.width < 0)			return -EINVAL;		if (res_locked(fh->dev,RESOURCE_OVERLAY))			return -EBUSY;		if (res_locked(fh->dev,RESOURCE_VIDEO))			return -EBUSY;		if (crop->c.top < b->top)			crop->c.top = b->top;		if (crop->c.top > b->top + b->height)			crop->c.top = b->top + b->height;		if (crop->c.height > b->top - crop->c.top + b->height)			crop->c.height = b->top - crop->c.top + b->height;		if (crop->c.left < b->left)			crop->c.left = b->left;		if (crop->c.left > b->left + b->width)			crop->c.left = b->left + b->width;		if (crop->c.width > b->left - crop->c.left + b->width)			crop->c.width = b->left - crop->c.left + b->width;		dev->crop_current = crop->c;		return 0;	}	/* --- tuner ioctls ------------------------------------------ */	case VIDIOC_G_TUNER:	{		struct v4l2_tuner *t = arg;		int n;		if (0 != t->index)			return -EINVAL;		memset(t,0,sizeof(*t));		for (n = 0; n < SAA7134_INPUT_MAX; n++)			if (card_in(dev,n).tv)				break;		if (NULL != card_in(dev,n).name) {			strcpy(t->name, "Television");			t->type = V4L2_TUNER_ANALOG_TV;			t->capability = V4L2_TUNER_CAP_NORM |				V4L2_TUNER_CAP_STEREO |				V4L2_TUNER_CAP_LANG1 |				V4L2_TUNER_CAP_LANG2;			t->rangehigh = 0xffffffffUL;			t->rxsubchans = saa7134_tvaudio_getstereo(dev);			t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);		}		if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))			t->signal = 0xffff;		return 0;	}	case VIDIOC_S_TUNER:	{		struct v4l2_tuner *t = arg;		int rx,mode;		mode = dev->thread.mode;		if (UNSET == mode) {			rx   = saa7134_tvaudio_getstereo(dev);			mode = saa7134_tvaudio_rx2mode(t->rxsubchans);		}		if (mode != t->audmode) {			dev->thread.mode = t->audmode;		}		return 0;	}	case VIDIOC_G_FREQUENCY:	{		struct v4l2_frequency *f = arg;		memset(f,0,sizeof(*f));		f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;		f->frequency = dev->ctl_freq;		return 0;	}	case VIDIOC_S_FREQUENCY:	{		struct v4l2_frequency *f = arg;		if (0 != f->tuner)			return -EINVAL;		if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)			return -EINVAL;		if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)			return -EINVAL;		down(&dev->lock);		dev->ctl_freq = f->frequency;		saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);		saa7134_tvaudio_do_scan(dev);		up(&dev->lock);		return 0;	}	/* --- control ioctls ---------------------------------------- */	case VIDIOC_ENUMINPUT:	case VIDIOC_G_INPUT:	case VIDIOC_S_INPUT:	case VIDIOC_QUERYCTRL:	case VIDIOC_G_CTRL:	case VIDIOC_S_CTRL:		return saa7134_common_ioctl(dev, cmd, arg);	case VIDIOC_G_AUDIO:	{		struct v4l2_audio *a = arg;		memset(a,0,sizeof(*a));		strcpy(a->name,"audio");		return 0;	}	case VIDIOC_S_AUDIO:		return 0;	case VIDIOC_G_PARM:	{		struct v4l2_captureparm *parm = arg;		memset(parm,0,sizeof(*parm));		return 0;	}	case VIDIOC_G_PRIORITY:	{		enum v4l2_priority *p = arg;		*p = v4l2_prio_max(&dev->prio);		return 0;	}	case VIDIOC_S_PRIORITY:	{		enum v4l2_priority *prio = arg;		return v4l2_prio_change(&dev->prio, &fh->prio, *prio);	}	/* --- preview ioctls ---------------------------------------- */	case VIDIOC_ENUM_FMT:	{

⌨️ 快捷键说明

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