cx2341x.c

来自「linux 内核源代码」· C语言 代码 · 共 1,012 行 · 第 1/3 页

C
1,012
字号
/* * cx2341x - generic code for cx23415/6 based devices * * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl> * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <linux/module.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/types.h>#include <linux/videodev2.h>#include <media/tuner.h>#include <media/cx2341x.h>#include <media/v4l2-common.h>MODULE_DESCRIPTION("cx23415/6 driver");MODULE_AUTHOR("Hans Verkuil");MODULE_LICENSE("GPL");static int debug = 0;module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "Debug level (0-1)");const u32 cx2341x_mpeg_ctrls[] = {	V4L2_CID_MPEG_CLASS,	V4L2_CID_MPEG_STREAM_TYPE,	V4L2_CID_MPEG_STREAM_VBI_FMT,	V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,	V4L2_CID_MPEG_AUDIO_ENCODING,	V4L2_CID_MPEG_AUDIO_L2_BITRATE,	V4L2_CID_MPEG_AUDIO_MODE,	V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,	V4L2_CID_MPEG_AUDIO_EMPHASIS,	V4L2_CID_MPEG_AUDIO_CRC,	V4L2_CID_MPEG_AUDIO_MUTE,	V4L2_CID_MPEG_VIDEO_ENCODING,	V4L2_CID_MPEG_VIDEO_ASPECT,	V4L2_CID_MPEG_VIDEO_B_FRAMES,	V4L2_CID_MPEG_VIDEO_GOP_SIZE,	V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,	V4L2_CID_MPEG_VIDEO_BITRATE_MODE,	V4L2_CID_MPEG_VIDEO_BITRATE,	V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,	V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,	V4L2_CID_MPEG_VIDEO_MUTE,	V4L2_CID_MPEG_VIDEO_MUTE_YUV,	V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,	V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,	V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,	V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,	V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,	V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,	V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,	V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,	V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,	V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,	V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,	V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,	0};/* Map the control ID to the correct field in the cx2341x_mpeg_params   struct. Return -EINVAL if the ID is unknown, else return 0. */static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,		struct v4l2_ext_control *ctrl){	switch (ctrl->id) {	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:		ctrl->value = params->audio_sampling_freq;		break;	case V4L2_CID_MPEG_AUDIO_ENCODING:		ctrl->value = params->audio_encoding;		break;	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:		ctrl->value = params->audio_l2_bitrate;		break;	case V4L2_CID_MPEG_AUDIO_MODE:		ctrl->value = params->audio_mode;		break;	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:		ctrl->value = params->audio_mode_extension;		break;	case V4L2_CID_MPEG_AUDIO_EMPHASIS:		ctrl->value = params->audio_emphasis;		break;	case V4L2_CID_MPEG_AUDIO_CRC:		ctrl->value = params->audio_crc;		break;	case V4L2_CID_MPEG_AUDIO_MUTE:		ctrl->value = params->audio_mute;		break;	case V4L2_CID_MPEG_VIDEO_ENCODING:		ctrl->value = params->video_encoding;		break;	case V4L2_CID_MPEG_VIDEO_ASPECT:		ctrl->value = params->video_aspect;		break;	case V4L2_CID_MPEG_VIDEO_B_FRAMES:		ctrl->value = params->video_b_frames;		break;	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:		ctrl->value = params->video_gop_size;		break;	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:		ctrl->value = params->video_gop_closure;		break;	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:		ctrl->value = params->video_bitrate_mode;		break;	case V4L2_CID_MPEG_VIDEO_BITRATE:		ctrl->value = params->video_bitrate;		break;	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:		ctrl->value = params->video_bitrate_peak;		break;	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:		ctrl->value = params->video_temporal_decimation;		break;	case V4L2_CID_MPEG_VIDEO_MUTE:		ctrl->value = params->video_mute;		break;	case V4L2_CID_MPEG_VIDEO_MUTE_YUV:		ctrl->value = params->video_mute_yuv;		break;	case V4L2_CID_MPEG_STREAM_TYPE:		ctrl->value = params->stream_type;		break;	case V4L2_CID_MPEG_STREAM_VBI_FMT:		ctrl->value = params->stream_vbi_fmt;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:		ctrl->value = params->video_spatial_filter_mode;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:		ctrl->value = params->video_spatial_filter;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:		ctrl->value = params->video_luma_spatial_filter_type;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:		ctrl->value = params->video_chroma_spatial_filter_type;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:		ctrl->value = params->video_temporal_filter_mode;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:		ctrl->value = params->video_temporal_filter;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:		ctrl->value = params->video_median_filter_type;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:		ctrl->value = params->video_luma_median_filter_top;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:		ctrl->value = params->video_luma_median_filter_bottom;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:		ctrl->value = params->video_chroma_median_filter_top;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:		ctrl->value = params->video_chroma_median_filter_bottom;		break;	case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:		ctrl->value = params->stream_insert_nav_packets;		break;	default:		return -EINVAL;	}	return 0;}/* Map the control ID to the correct field in the cx2341x_mpeg_params   struct. Return -EINVAL if the ID is unknown, else return 0. */static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,		struct v4l2_ext_control *ctrl){	switch (ctrl->id) {	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:		if (busy)			return -EBUSY;		params->audio_sampling_freq = ctrl->value;		break;	case V4L2_CID_MPEG_AUDIO_ENCODING:		params->audio_encoding = ctrl->value;		break;	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:		if (busy)			return -EBUSY;		params->audio_l2_bitrate = ctrl->value;		break;	case V4L2_CID_MPEG_AUDIO_MODE:		params->audio_mode = ctrl->value;		break;	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:		params->audio_mode_extension = ctrl->value;		break;	case V4L2_CID_MPEG_AUDIO_EMPHASIS:		params->audio_emphasis = ctrl->value;		break;	case V4L2_CID_MPEG_AUDIO_CRC:		params->audio_crc = ctrl->value;		break;	case V4L2_CID_MPEG_AUDIO_MUTE:		params->audio_mute = ctrl->value;		break;	case V4L2_CID_MPEG_VIDEO_ASPECT:		params->video_aspect = ctrl->value;		break;	case V4L2_CID_MPEG_VIDEO_B_FRAMES: {		int b = ctrl->value + 1;		int gop = params->video_gop_size;		params->video_b_frames = ctrl->value;		params->video_gop_size = b * ((gop + b - 1) / b);		/* Max GOP size = 34 */		while (params->video_gop_size > 34)			params->video_gop_size -= b;		break;	}	case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {		int b = params->video_b_frames + 1;		int gop = ctrl->value;		params->video_gop_size = b * ((gop + b - 1) / b);		/* Max GOP size = 34 */		while (params->video_gop_size > 34)			params->video_gop_size -= b;		ctrl->value = params->video_gop_size;		break;	}	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:		params->video_gop_closure = ctrl->value;		break;	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:		if (busy)			return -EBUSY;		/* MPEG-1 only allows CBR */		if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&		    ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)			return -EINVAL;		params->video_bitrate_mode = ctrl->value;		break;	case V4L2_CID_MPEG_VIDEO_BITRATE:		if (busy)			return -EBUSY;		params->video_bitrate = ctrl->value;		break;	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:		if (busy)			return -EBUSY;		params->video_bitrate_peak = ctrl->value;		break;	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:		params->video_temporal_decimation = ctrl->value;		break;	case V4L2_CID_MPEG_VIDEO_MUTE:		params->video_mute = (ctrl->value != 0);		break;	case V4L2_CID_MPEG_VIDEO_MUTE_YUV:		params->video_mute_yuv = ctrl->value;		break;	case V4L2_CID_MPEG_STREAM_TYPE:		if (busy)			return -EBUSY;		params->stream_type = ctrl->value;		params->video_encoding =			(params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||			 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?			V4L2_MPEG_VIDEO_ENCODING_MPEG_1 : V4L2_MPEG_VIDEO_ENCODING_MPEG_2;		if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {			/* MPEG-1 implies CBR */			params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;		}		break;	case V4L2_CID_MPEG_STREAM_VBI_FMT:		params->stream_vbi_fmt = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:		params->video_spatial_filter_mode = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:		params->video_spatial_filter = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:		params->video_luma_spatial_filter_type = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:		params->video_chroma_spatial_filter_type = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:		params->video_temporal_filter_mode = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:		params->video_temporal_filter = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:		params->video_median_filter_type = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:		params->video_luma_median_filter_top = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:		params->video_luma_median_filter_bottom = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:		params->video_chroma_median_filter_top = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:		params->video_chroma_median_filter_bottom = ctrl->value;		break;	case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:		params->stream_insert_nav_packets = ctrl->value;		break;	default:		return -EINVAL;	}	return 0;}static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def){

⌨️ 快捷键说明

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