cx2341x.c

来自「trident tm5600的linux驱动」· C语言 代码 · 共 1,073 行 · 第 1/3 页

C
1,073
字号
/* * 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>#include "compat.h"MODULE_DESCRIPTION("cx23415/6 driver");MODULE_AUTHOR("Hans Verkuil");MODULE_LICENSE("GPL");static int debug;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};EXPORT_SYMBOL(cx2341x_mpeg_ctrls);static const struct cx2341x_mpeg_params default_params = {	/* misc */	.capabilities = 0,	.port = CX2341X_PORT_MEMORY,	.width = 720,	.height = 480,	.is_50hz = 0,	/* stream */	.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,	.stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,	.stream_insert_nav_packets = 0,	/* audio */	.audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,	.audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,	.audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,	.audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,	.audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,	.audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,	.audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,	.audio_mute = 0,	/* video */	.video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,	.video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,	.video_b_frames = 2,	.video_gop_size = 12,	.video_gop_closure = 1,	.video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,	.video_bitrate = 6000000,	.video_bitrate_peak = 8000000,	.video_temporal_decimation = 0,	.video_mute = 0,	.video_mute_yuv = 0x008080,  /* YCbCr value for black */	/* encoding filters */	.video_spatial_filter_mode =		V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,	.video_spatial_filter = 0,	.video_luma_spatial_filter_type =		V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,	.video_chroma_spatial_filter_type =		V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,	.video_temporal_filter_mode =		V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,	.video_temporal_filter = 8,	.video_median_filter_type =		V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,	.video_luma_median_filter_top = 255,	.video_luma_median_filter_bottom = 0,	.video_chroma_median_filter_top = 255,	.video_chroma_median_filter_bottom = 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(const 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;

⌨️ 快捷键说明

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