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

📄 av7110_av.c

📁 linux环境下的dvb驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;	unsigned long arg = (unsigned long) parg;	int ret = 0;	DEB_EE(("av7110: %p\n", av7110));	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {		if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&		     cmd != VIDEO_GET_SIZE ) {			return -EPERM;		}	}	switch (cmd) {	case VIDEO_STOP:		av7110->videostate.play_state = VIDEO_STOPPED;		if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)			av7110_av_stop(av7110, RP_VIDEO);		else			vidcom(av7110, 0x000e,			       av7110->videostate.video_blank ? 0 : 1);		av7110->trickmode = TRICK_NONE;		break;	case VIDEO_PLAY:		av7110->trickmode = TRICK_NONE;		if (av7110->videostate.play_state == VIDEO_FREEZED) {			av7110->videostate.play_state = VIDEO_PLAYING;			vidcom(av7110, 0x000d, 0);		}		if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {			if (av7110->playing == RP_AV) {				av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);				av7110->playing &= ~RP_VIDEO;			}			av7110_av_start_play(av7110, RP_VIDEO);			vidcom(av7110, 0x000d, 0);		} else {			//av7110_av_stop(av7110, RP_VIDEO);			vidcom(av7110, 0x000d, 0);		}		av7110->videostate.play_state = VIDEO_PLAYING;		break;	case VIDEO_FREEZE:		av7110->videostate.play_state = VIDEO_FREEZED;		if (av7110->playing & RP_VIDEO)			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);		else			vidcom(av7110, 0x0102, 1);		av7110->trickmode = TRICK_FREEZE;		break;	case VIDEO_CONTINUE:		if (av7110->playing & RP_VIDEO)			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);		vidcom(av7110, 0x000d, 0);		av7110->videostate.play_state = VIDEO_PLAYING;		av7110->trickmode = TRICK_NONE;		break;	case VIDEO_SELECT_SOURCE:		av7110->videostate.stream_source = (video_stream_source_t) arg;		break;	case VIDEO_SET_BLANK:		av7110->videostate.video_blank = (int) arg;		break;	case VIDEO_GET_STATUS:		memcpy(parg, &av7110->videostate, sizeof(struct video_status));		break;	case VIDEO_GET_EVENT:		ret=dvb_video_get_event(av7110, parg, file->f_flags);		break;	case VIDEO_GET_SIZE:		memcpy(parg, &av7110->video_size, sizeof(video_size_t));		break;	case VIDEO_SET_DISPLAY_FORMAT:	{		video_displayformat_t format = (video_displayformat_t) arg;		u16 val = 0;		switch (format) {		case VIDEO_PAN_SCAN:			val = VID_PAN_SCAN_PREF;			break;		case VIDEO_LETTER_BOX:			val = VID_VC_AND_PS_PREF;			break;		case VIDEO_CENTER_CUT_OUT:			val = VID_CENTRE_CUT_PREF;			break;		default:			ret = -EINVAL;		}		if (ret < 0)			break;		av7110->videostate.video_format = format;		ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,				    1, (u16) val);		break;	}	case VIDEO_SET_FORMAT:		if (arg > 1) {			ret = -EINVAL;			break;		}		av7110->display_ar = arg;		ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,				    1, (u16) arg);		break;	case VIDEO_STILLPICTURE:	{		struct video_still_picture *pic =			(struct video_still_picture *) parg;		av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;		dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);		ret = play_iframe(av7110, pic->iFrame, pic->size,				  file->f_flags & O_NONBLOCK);		break;	}	case VIDEO_FAST_FORWARD:		//note: arg is ignored by firmware		if (av7110->playing & RP_VIDEO)			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,				      __Scan_I, 2, AV_PES, 0);		else			vidcom(av7110, 0x16, arg);		av7110->trickmode = TRICK_FAST;		av7110->videostate.play_state = VIDEO_PLAYING;		break;	case VIDEO_SLOWMOTION:		if (av7110->playing&RP_VIDEO) {			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);			vidcom(av7110, 0x22, arg);		} else {			vidcom(av7110, 0x0d, 0);			vidcom(av7110, 0x0e, 0);			vidcom(av7110, 0x22, arg);		}		av7110->trickmode = TRICK_SLOW;		av7110->videostate.play_state = VIDEO_PLAYING;		break;	case VIDEO_GET_CAPABILITIES:		*(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 |			VIDEO_CAP_SYS | VIDEO_CAP_PROG;		break;	case VIDEO_CLEAR_BUFFER:		dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);		av7110_ipack_reset(&av7110->ipack[1]);		if (av7110->playing == RP_AV) {			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,				      __Play, 2, AV_PES, 0);			if (av7110->trickmode == TRICK_FAST)				av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,					      __Scan_I, 2, AV_PES, 0);			if (av7110->trickmode == TRICK_SLOW) {				av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,					      __Slow, 2, 0, 0);				vidcom(av7110, 0x22, arg);			}			if (av7110->trickmode == TRICK_FREEZE)				vidcom(av7110, 0x000e, 1);		}		break;	case VIDEO_SET_STREAMTYPE:		break;	default:		ret = -ENOIOCTLCMD;		break;	}	return ret;}static int dvb_audio_ioctl(struct inode *inode, struct file *file,			   unsigned int cmd, void *parg){	struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;	struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;	unsigned long arg = (unsigned long) parg;	int ret = 0;	DEB_EE(("av7110: %p\n", av7110));	if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&	    (cmd != AUDIO_GET_STATUS))		return -EPERM;	switch (cmd) {	case AUDIO_STOP:		if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)			av7110_av_stop(av7110, RP_AUDIO);		else			audcom(av7110, 1);		av7110->audiostate.play_state = AUDIO_STOPPED;		break;	case AUDIO_PLAY:		if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)			av7110_av_start_play(av7110, RP_AUDIO);		audcom(av7110, 2);		av7110->audiostate.play_state = AUDIO_PLAYING;		break;	case AUDIO_PAUSE:		audcom(av7110, 1);		av7110->audiostate.play_state = AUDIO_PAUSED;		break;	case AUDIO_CONTINUE:		if (av7110->audiostate.play_state == AUDIO_PAUSED) {			av7110->audiostate.play_state = AUDIO_PLAYING;			audcom(av7110, 0x12);		}		break;	case AUDIO_SELECT_SOURCE:		av7110->audiostate.stream_source = (audio_stream_source_t) arg;		break;	case AUDIO_SET_MUTE:	{		audcom(av7110, arg ? 1 : 2);		av7110->audiostate.mute_state = (int) arg;		break;	}	case AUDIO_SET_AV_SYNC:		av7110->audiostate.AV_sync_state = (int) arg;		audcom(av7110, arg ? 0x0f : 0x0e);		break;	case AUDIO_SET_BYPASS_MODE:		ret = -EINVAL;		break;	case AUDIO_CHANNEL_SELECT:		av7110->audiostate.channel_select = (audio_channel_select_t) arg;		switch(av7110->audiostate.channel_select) {		case AUDIO_STEREO:			audcom(av7110, 0x80);			break;		case AUDIO_MONO_LEFT:			audcom(av7110, 0x100);			break;		case AUDIO_MONO_RIGHT:			audcom(av7110, 0x200);			break;		default:			ret = -EINVAL;			break;		}		break;	case AUDIO_GET_STATUS:		memcpy(parg, &av7110->audiostate, sizeof(struct audio_status));		break;	case AUDIO_GET_CAPABILITIES:		*(int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2;		break;	case AUDIO_CLEAR_BUFFER:		dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);		av7110_ipack_reset(&av7110->ipack[0]);		if (av7110->playing == RP_AV)			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,			       __Play, 2, AV_PES, 0);		break;	case AUDIO_SET_ID:		break;	case AUDIO_SET_MIXER:	{		struct audio_mixer *amix = (struct audio_mixer *)parg;		av7110_set_volume(av7110, amix->volume_left, amix->volume_right);		break;	}	case AUDIO_SET_STREAMTYPE:		break;	default:		ret = -ENOIOCTLCMD;	}	return ret;}static int dvb_video_open(struct inode *inode, struct file *file){	struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;	struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;	int err;	DEB_EE(("av7110: %p\n", av7110));	if ((err = dvb_generic_open(inode, file)) < 0)		return err;	if ((file->f_flags & O_ACCMODE) != O_RDONLY) {		dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);		dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);		av7110->video_blank = 1;		av7110->audiostate.AV_sync_state = 1;		av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;		/*  empty event queue */		av7110->video_events.eventr = av7110->video_events.eventw = 0;	}	return 0;}static int dvb_video_release(struct inode *inode, struct file *file){	struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;	struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;	DEB_EE(("av7110: %p\n", av7110));	if ((file->f_flags & O_ACCMODE) != O_RDONLY) {		av7110_av_stop(av7110, RP_VIDEO);	}	return dvb_generic_release(inode, file);}static int dvb_audio_open(struct inode *inode, struct file *file){	struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;	struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;	int err=dvb_generic_open(inode, file);	DEB_EE(("av7110: %p\n", av7110));	if (err < 0)		return err;	dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);	av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;	return 0;}static int dvb_audio_release(struct inode *inode, struct file *file){	struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;	struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;	DEB_EE(("av7110: %p\n", av7110));	av7110_av_stop(av7110, RP_AUDIO);	return dvb_generic_release(inode, file);}/****************************************************************************** * driver registration ******************************************************************************/static struct file_operations dvb_video_fops = {	.owner		= THIS_MODULE,	.write		= dvb_video_write,	.ioctl		= dvb_generic_ioctl,	.open		= dvb_video_open,	.release	= dvb_video_release,	.poll		= dvb_video_poll,};static struct dvb_device dvbdev_video = {	.priv		= 0,	.users		= 6,	.readers	= 5,	/* arbitrary */	.writers	= 1,	.fops		= &dvb_video_fops,	.kernel_ioctl	= dvb_video_ioctl,};static struct file_operations dvb_audio_fops = {	.owner		= THIS_MODULE,	.write		= dvb_audio_write,	.ioctl		= dvb_generic_ioctl,	.open		= dvb_audio_open,	.release	= dvb_audio_release,	.poll		= dvb_audio_poll,};static struct dvb_device dvbdev_audio = {	.priv		= 0,	.users		= 1,	.writers	= 1,	.fops		= &dvb_audio_fops,	.kernel_ioctl	= dvb_audio_ioctl,};int av7110_av_register(struct av7110 *av7110){	av7110->audiostate.AV_sync_state = 0;	av7110->audiostate.mute_state = 0;	av7110->audiostate.play_state = AUDIO_STOPPED;	av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;	av7110->audiostate.channel_select = AUDIO_STEREO;	av7110->audiostate.bypass_mode = 0;	av7110->videostate.video_blank = 0;	av7110->videostate.play_state = VIDEO_STOPPED;	av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;	av7110->videostate.video_format = VIDEO_FORMAT_4_3;	av7110->videostate.display_format = VIDEO_CENTER_CUT_OUT;	av7110->display_ar = VIDEO_FORMAT_4_3;	init_waitqueue_head(&av7110->video_events.wait_queue);	spin_lock_init(&av7110->video_events.lock);	av7110->video_events.eventw = av7110->video_events.eventr = 0;	av7110->video_events.overflow = 0;	memset(&av7110->video_size, 0, sizeof (video_size_t));	dvb_register_device(av7110->dvb_adapter, &av7110->video_dev,			    &dvbdev_video, av7110, DVB_DEVICE_VIDEO);	dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev,			    &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);	return 0;}void av7110_av_unregister(struct av7110 *av7110){	dvb_unregister_device(av7110->audio_dev);	dvb_unregister_device(av7110->video_dev);}int av7110_av_init(struct av7110 *av7110){	av7110->vidmode = VIDEO_MODE_PAL;	av7110_ipack_init(&av7110->ipack[0], IPACKS, play_audio_cb);	av7110->ipack[0].data = (void *) av7110;	av7110_ipack_init(&av7110->ipack[1], IPACKS, play_video_cb);	av7110->ipack[1].data = (void *) av7110;	dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN);	dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN);	av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN);	av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS;	return 0;}int av7110_av_exit(struct av7110 *av7110){	av7110_ipack_free(&av7110->ipack[0]);	av7110_ipack_free(&av7110->ipack[1]);	return 0;}

⌨️ 快捷键说明

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