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

📄 ivtv-ioctl.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
				"Stereo",				"Left",				"Right",				"Mono",				"Swapped"			};			static const char * const alpha_mode[4] = {				"None",				"Global",				"Local",				"Global and Local"			};			static const char * const pixel_format[16] = {				"ARGB Indexed",				"RGB 5:6:5",				"ARGB 1:5:5:5",				"ARGB 1:4:4:4",				"ARGB 8:8:8:8",				"5",				"6",				"7",				"AYUV Indexed",				"YUV 5:6:5",				"AYUV 1:5:5:5",				"AYUV 1:4:4:4",				"AYUV 8:8:8:8",				"13",				"14",				"15",			};			ivtv_get_output(itv, itv->active_output, &vidout);			ivtv_get_audio_output(itv, 0, &audout);			IVTV_INFO("Video Output: %s\n", vidout.name);			IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,				audio_modes[itv->audio_stereo_mode],				audio_modes[itv->audio_bilingual_mode]);			if (mode < 0 || mode > OUT_PASSTHROUGH)				mode = OUT_NONE;			IVTV_INFO("Output Mode:  %s\n", output_modes[mode]);			ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);			data[0] |= (read_reg(0x2a00) >> 7) & 0x40;			IVTV_INFO("Overlay:      %s, Alpha: %s, Pixel Format: %s\n",				data[0] & 1 ? "On" : "Off",				alpha_mode[(data[0] >> 1) & 0x3],				pixel_format[(data[0] >> 3) & 0xf]);		}		IVTV_INFO("Tuner:  %s\n",			test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");		cx2341x_log_status(&itv->params, itv->name);		IVTV_INFO("Status flags:    0x%08lx\n", itv->i_flags);		for (i = 0; i < IVTV_MAX_STREAMS; i++) {			struct ivtv_stream *s = &itv->streams[i];			if (s->v4l2dev == NULL || s->buffers == 0)				continue;			IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,					(s->buffers - s->q_free.buffers) * 100 / s->buffers,					(s->buffers * s->buf_size) / 1024, s->buffers);		}		IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);		IVTV_INFO("==================  END STATUS CARD #%d  ==================\n", itv->num);		break;	}	default:		return -EINVAL;	}	return 0;}static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg){	struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;	struct ivtv *itv = id->itv;	int nonblocking = filp->f_flags & O_NONBLOCK;	struct ivtv_stream *s = &itv->streams[id->type];	switch (cmd) {	case IVTV_IOC_DMA_FRAME: {		struct ivtv_dma_frame *args = arg;		IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");		if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))			return -EINVAL;		if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)			return -EINVAL;		if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)			return 0;		if (ivtv_claim_stream(id, id->type)) {			return -EBUSY;		}		if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {			ivtv_release_stream(s);			return -EBUSY;		}		/* Mark that this file handle started the UDMA_YUV mode */		id->yuv_frames = 1;		if (args->y_source == NULL)			return 0;		return ivtv_yuv_prep_frame(itv, args);	}	case VIDEO_GET_PTS: {		u32 data[CX2341X_MBOX_MAX_DATA];		u64 *pts = arg;		IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");		if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {			*pts = s->dma_pts;			break;		}		if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))			return -EINVAL;		if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {			*pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |					(u64)itv->last_dec_timing[1];			break;		}		*pts = 0;		if (atomic_read(&itv->decoding)) {			if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {				IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");				return -EIO;			}			memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));			set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);			*pts = (u64) ((u64) data[2] << 32) | (u64) data[1];			/*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/		}		break;	}	case VIDEO_GET_FRAME_COUNT: {		u32 data[CX2341X_MBOX_MAX_DATA];		u64 *frame = arg;		IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");		if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {			*frame = 0;			break;		}		if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))			return -EINVAL;		if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {			*frame = itv->last_dec_timing[0];			break;		}		*frame = 0;		if (atomic_read(&itv->decoding)) {			if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {				IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");				return -EIO;			}			memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));			set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);			*frame = data[0];		}		break;	}	case VIDEO_PLAY: {		struct video_command vc;		IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");		memset(&vc, 0, sizeof(vc));		vc.cmd = VIDEO_CMD_PLAY;		return ivtv_video_command(itv, id, &vc, 0);	}	case VIDEO_STOP: {		struct video_command vc;		IVTV_DEBUG_IOCTL("VIDEO_STOP\n");		memset(&vc, 0, sizeof(vc));		vc.cmd = VIDEO_CMD_STOP;		vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;		return ivtv_video_command(itv, id, &vc, 0);	}	case VIDEO_FREEZE: {		struct video_command vc;		IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");		memset(&vc, 0, sizeof(vc));		vc.cmd = VIDEO_CMD_FREEZE;		return ivtv_video_command(itv, id, &vc, 0);	}	case VIDEO_CONTINUE: {		struct video_command vc;		IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");		memset(&vc, 0, sizeof(vc));		vc.cmd = VIDEO_CMD_CONTINUE;		return ivtv_video_command(itv, id, &vc, 0);	}	case VIDEO_COMMAND:	case VIDEO_TRY_COMMAND: {		struct video_command *vc = arg;		int try = (cmd == VIDEO_TRY_COMMAND);		if (try)			IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);		else			IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);		return ivtv_video_command(itv, id, vc, try);	}	case VIDEO_GET_EVENT: {		struct video_event *ev = arg;		DEFINE_WAIT(wait);		IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");		if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))			return -EINVAL;		memset(ev, 0, sizeof(*ev));		set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);		while (1) {			if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))				ev->type = VIDEO_EVENT_DECODER_STOPPED;			else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {				ev->type = VIDEO_EVENT_VSYNC;				ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?					VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;				if (itv->output_mode == OUT_UDMA_YUV &&					(itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==								IVTV_YUV_MODE_PROGRESSIVE) {					ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;				}			}			if (ev->type)				return 0;			if (nonblocking)				return -EAGAIN;			/* Wait for event. Note that serialize_lock is locked,			   so to allow other processes to access the driver while			   we are waiting unlock first and later lock again. */			mutex_unlock(&itv->serialize_lock);			prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);			if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)				schedule();			finish_wait(&itv->event_waitq, &wait);			mutex_lock(&itv->serialize_lock);			if (signal_pending(current)) {				/* return if a signal was received */				IVTV_DEBUG_INFO("User stopped wait for event\n");				return -EINTR;			}		}		break;	}	default:		return -EINVAL;	}	return 0;}static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,			      unsigned int cmd, void *arg){	struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;	struct ivtv *itv = id->itv;	int ret;	/* check priority */	switch (cmd) {	case VIDIOC_S_CTRL:	case VIDIOC_S_STD:	case VIDIOC_S_INPUT:	case VIDIOC_S_OUTPUT:	case VIDIOC_S_TUNER:	case VIDIOC_S_FREQUENCY:	case VIDIOC_S_FMT:	case VIDIOC_S_CROP:	case VIDIOC_S_AUDIO:	case VIDIOC_S_AUDOUT:	case VIDIOC_S_EXT_CTRLS:	case VIDIOC_S_FBUF:	case VIDIOC_OVERLAY:		ret = v4l2_prio_check(&itv->prio, &id->prio);		if (ret)			return ret;	}	switch (cmd) {	case VIDIOC_DBG_G_REGISTER:	case VIDIOC_DBG_S_REGISTER:	case VIDIOC_G_CHIP_IDENT:	case VIDIOC_INT_S_AUDIO_ROUTING:	case VIDIOC_INT_RESET:		if (ivtv_debug & IVTV_DBGFLG_IOCTL) {			printk(KERN_INFO "ivtv%d ioctl: ", itv->num);			v4l_printk_ioctl(cmd);		}		return ivtv_debug_ioctls(filp, cmd, arg);	case VIDIOC_G_PRIORITY:	case VIDIOC_S_PRIORITY:	case VIDIOC_QUERYCAP:	case VIDIOC_ENUMINPUT:	case VIDIOC_G_INPUT:	case VIDIOC_S_INPUT:	case VIDIOC_ENUMOUTPUT:	case VIDIOC_G_OUTPUT:	case VIDIOC_S_OUTPUT:	case VIDIOC_G_FMT:	case VIDIOC_S_FMT:	case VIDIOC_TRY_FMT:	case VIDIOC_ENUM_FMT:	case VIDIOC_CROPCAP:	case VIDIOC_G_CROP:	case VIDIOC_S_CROP:	case VIDIOC_G_FREQUENCY:	case VIDIOC_S_FREQUENCY:	case VIDIOC_ENUMSTD:	case VIDIOC_G_STD:	case VIDIOC_S_STD:	case VIDIOC_S_TUNER:	case VIDIOC_G_TUNER:	case VIDIOC_ENUMAUDIO:	case VIDIOC_S_AUDIO:	case VIDIOC_G_AUDIO:	case VIDIOC_ENUMAUDOUT:	case VIDIOC_S_AUDOUT:	case VIDIOC_G_AUDOUT:	case VIDIOC_G_SLICED_VBI_CAP:	case VIDIOC_LOG_STATUS:	case VIDIOC_G_ENC_INDEX:	case VIDIOC_ENCODER_CMD:	case VIDIOC_TRY_ENCODER_CMD:	case VIDIOC_G_FBUF:	case VIDIOC_S_FBUF:	case VIDIOC_OVERLAY:		if (ivtv_debug & IVTV_DBGFLG_IOCTL) {			printk(KERN_INFO "ivtv%d ioctl: ", itv->num);			v4l_printk_ioctl(cmd);		}		return ivtv_v4l2_ioctls(itv, filp, cmd, arg);	case VIDIOC_QUERYMENU:	case VIDIOC_QUERYCTRL:	case VIDIOC_S_CTRL:	case VIDIOC_G_CTRL:	case VIDIOC_S_EXT_CTRLS:	case VIDIOC_G_EXT_CTRLS:	case VIDIOC_TRY_EXT_CTRLS:		if (ivtv_debug & IVTV_DBGFLG_IOCTL) {			printk(KERN_INFO "ivtv%d ioctl: ", itv->num);			v4l_printk_ioctl(cmd);		}		return ivtv_control_ioctls(itv, cmd, arg);	case IVTV_IOC_DMA_FRAME:	case VIDEO_GET_PTS:	case VIDEO_GET_FRAME_COUNT:	case VIDEO_GET_EVENT:	case VIDEO_PLAY:	case VIDEO_STOP:	case VIDEO_FREEZE:	case VIDEO_CONTINUE:	case VIDEO_COMMAND:	case VIDEO_TRY_COMMAND:		return ivtv_decoder_ioctls(filp, cmd, arg);	case 0x00005401:	/* Handle isatty() calls */		return -EINVAL;	default:		return v4l_compat_translate_ioctl(inode, filp, cmd, arg,						   ivtv_v4l2_do_ioctl);	}	return 0;}static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,		unsigned int cmd, unsigned long arg){	/* Filter dvb ioctls that cannot be handled by video_usercopy */	switch (cmd) {	case VIDEO_SELECT_SOURCE:		IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");		if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))			return -EINVAL;		return ivtv_passthrough_mode(itv, arg == VIDEO_SOURCE_DEMUX);	case AUDIO_SET_MUTE:		IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");		itv->speed_mute_audio = arg;		return 0;	case AUDIO_CHANNEL_SELECT:		IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");		if (arg > AUDIO_STEREO_SWAPPED)			return -EINVAL;		itv->audio_stereo_mode = arg;		ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);		return 0;	case AUDIO_BILINGUAL_CHANNEL_SELECT:		IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");		if (arg > AUDIO_STEREO_SWAPPED)			return -EINVAL;		itv->audio_bilingual_mode = arg;		ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);		return 0;	default:		break;	}	return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);}int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,		    unsigned long arg){	struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;	struct ivtv *itv = id->itv;	int res;	mutex_lock(&itv->serialize_lock);	res = ivtv_serialized_ioctl(itv, inode, filp, cmd, arg);	mutex_unlock(&itv->serialize_lock);	return res;}

⌨️ 快捷键说明

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