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

📄 omap24xxcam.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
 * also be adjusted to maintain the rescaling ratios.  If successful, cam->crop  * and cam->win are updated. * Returns zero if succesful, or -EINVAL if the requested cropping rectangle is  * impossible and cannot reasonably be adjusted. */static intomap24xxcam_new_crop_rect(struct omap24xxcam_device *cam, 	const struct v4l2_rect *new_crop){	struct v4l2_pix_format *pix = &cam->pix;	struct v4l2_window *win = &cam->win;	struct v4l2_framebuffer *fbuf = &cam->fbuf;	struct v4l2_rect *crop = &cam->crop;	struct v4l2_rect try_crop;	unsigned long vresize, hresize;	/* make a working copy of the new_crop rectangle */	try_crop = *new_crop;	/* adjust the cropping rectangle so it fits in the image */	if (try_crop.left < 0) {		try_crop.width += try_crop.left;		try_crop.left = 0;	}	if (try_crop.top < 0) {		try_crop.height += try_crop.top;		try_crop.top = 0;	}	try_crop.width = (try_crop.width < pix->width) ? 		try_crop.width : pix->width;	try_crop.height = (try_crop.height < pix->height) ? 		try_crop.height : pix->height;	if (try_crop.left + try_crop.width > pix->width)		try_crop.width = pix->width - try_crop.left;	if (try_crop.top + try_crop.height > pix->height)		try_crop.height = pix->height - try_crop.top;	try_crop.width &= ~1;	try_crop.height &= ~1;	if (try_crop.width <= 0 || try_crop.height <= 0)		return -EINVAL;	if (crop->height != win->w.height) {		/* If we're resizing vertically, we can't support a crop width 		 * wider than 768 pixels.		 */		if (try_crop.width > 768)			try_crop.width = 768;	}	/* vertical resizing */	vresize = (1024*crop->height)/win->w.height;	if (vresize > 2048)		vresize = 2048;	else if (vresize == 0)		vresize = 1;	win->w.height = ((1024*try_crop.height)/vresize) & ~1;	if (win->w.height == 0)		win->w.height = 2;	if (win->w.height + win->w.top > fbuf->fmt.height) {		/* We made the preview window extend below the bottom of the 		 * display, so clip it to the display boundary and resize the 		 * cropping height to maintain the vertical resizing ratio.		 */		win->w.height = (fbuf->fmt.height - win->w.top) & ~1;		try_crop.height = ((vresize*win->w.height)/1024) & ~1;		if (try_crop.height == 0)			try_crop.height = 2;	}	/* horizontal resizing */	hresize = (1024*crop->width)/win->w.width;	if (hresize > 2048)		hresize = 2048;	else if (hresize == 0)		hresize = 1;	win->w.width = ((1024*try_crop.width)/hresize) & ~1;	if (win->w.width == 0)		win->w.width = 2;	if (win->w.width + win->w.left > fbuf->fmt.width) {		/* We made the preview window extend past the right side of the  		 * display, so clip it to the display boundary and resize the 		 * cropping width to maintain the horizontal resizing ratio.		 */		win->w.width = (fbuf->fmt.width - win->w.left) & ~1;		try_crop.width = ((hresize*win->w.width)/1024) & ~1;		if (try_crop.width == 0)			try_crop.width = 2;	}	/* update our cropping rectangle and we're done */	*crop = try_crop;	return 0;}/* Given a new preview window in new_win, adjust the preview window to the  * nearest supported configuration.  The adjusted preview window parameters are  * returned in new_win. * Returns zero if succesful, or -EINVAL if the requested preview window is  * impossible and cannot reasonably be adjusted. */static intomap24xxcam_try_preview_window(struct omap24xxcam_device *cam, 	struct v4l2_window *new_win){	struct v4l2_framebuffer *fbuf = &cam->fbuf;	struct v4l2_rect try_win;	/* make a working copy of the new_win rectangle */	try_win = new_win->w;	/* adjust the preview window so it fits on the display by clipping any 	 * offscreen areas	 */	if (try_win.left < 0) {		try_win.width += try_win.left;		try_win.left = 0;	}	if (try_win.top < 0) {		try_win.height += try_win.top;		try_win.top = 0;	}	try_win.width = (try_win.width < fbuf->fmt.width) ? 		try_win.width : fbuf->fmt.width;	try_win.height = (try_win.height < fbuf->fmt.height) ? 		try_win.height : fbuf->fmt.height;	if (try_win.left + try_win.width > fbuf->fmt.width)		try_win.width = fbuf->fmt.width - try_win.left;	if (try_win.top + try_win.height > fbuf->fmt.height)		try_win.height = fbuf->fmt.height - try_win.top;	try_win.width &= ~1;	try_win.height &= ~1;	if (try_win.width <= 0 || try_win.height <= 0)		return -EINVAL;	/* We now have a valid preview window, so go with it */	new_win->w = try_win;	new_win->field = V4L2_FIELD_NONE;	return 0;}/* Given a new preview window in new_win, adjust the preview window to the  * nearest supported configuration.  The image cropping window cam->crop  * will also be adjusted if necessary.  Preference is given to keeping the  * preview window as close to the requested configuration as possible.  If  * successful, new_win, cam->win, and cam->crop are updated. * Returns zero if succesful, or -EINVAL if the requested preview window is  * impossible and cannot reasonably be adjusted. */static intomap24xxcam_new_preview_window(struct omap24xxcam_device *cam, 	struct v4l2_window *new_win){	struct v4l2_window *win = &cam->win;	struct v4l2_rect *crop = &cam->crop;	int err;	err = omap24xxcam_try_preview_window(cam, new_win);	if (err)		return err;	/* update our preview window */	win->w = new_win->w;	win->field = new_win->field;	win->chromakey = new_win->chromakey;	/* adjust the cropping window to allow for resizing limitations */	if (crop->height/win->w.height >= 2) {		/* The maximum vertical downsizing ratio is 2:1 */		crop->height = win->w.height*2;	}	if (crop->width/win->w.width >= 2) {		/* The maximum horizontal downsizing ratio is 2:1 */		crop->width = win->w.width*2;	}	if (crop->width > 768) {		/* The OMAP2420 vertical resizing line buffer is 768 pixels 		 * wide.  If the cropped image is wider than 768 pixels then it 		 * cannot be vertically resized.		 */		 if (crop->height != win->w.height)			crop->width = 768;	}	return 0;}/* Given a capture format in cam->pix, the cam->crop, cam->win, and cam->fbuf  * structures are initialized to default values.  cam->fbuf is initialized by  * reading the display controller registers for the graphics window.  cam->crop  * is initialized to the largest window size that will fit on the display.  The  * crop window is centered in the captured image.  cam->win is initialized to  * the same size as cam->crop and is centered on the display. * All sizes and offsets are constrained to be even numbers.   */static voidomap24xxcam_new_capture_format(struct omap24xxcam_device *cam){	struct v4l2_rect *crop = &cam->crop;	struct v4l2_window *win = &cam->win;	struct v4l2_framebuffer *fbuf = &cam->fbuf;	/* get the framebuffer parameters */	omap24xxcam_g_fbuf(cam);	/* crop defines the preview source window in the image capture 	 * buffer	 */	omap24xxcam_default_crop_rect(cam, crop);	/* win defines the preview target window on the display */	win->w.width = crop->width;	win->w.height = crop->height;	win->w.left = ((fbuf->fmt.width - win->w.width) >> 1) & ~1;	win->w.top = ((fbuf->fmt.height - win->w.height) >> 1) & ~1;}/* Program the camera interface xclk for the frequency cam->xclk based on  * the functional clock frequency cam->mclk.  If the specifed cam->xclk  * frequency is not possible based on the value of cam->mclk, then the  * closest xclk frequency lower than the specified xclk will be selected.   * The actual xclk frequency is returned in cam->xclk.  If cam->xclk is zero,  * then xclk is turned off (stable low value). */static voidomap24xxcam_set_xclk(struct omap24xxcam_device *cam){	unsigned long divisor;	if (cam->mclk == 0)		cam->mclk = 96000000;	/* supply a default mclk */	if (cam->xclk == 0) {		cc_reg_out(cam, CC_CTRL_XCLK, CC_CTRL_XCLK_DIV_STABLE_LOW);		return;	}	if (cam->xclk > cam->mclk)		cam->xclk = cam->mclk;	divisor = cam->mclk/cam->xclk;	if (cam->xclk*divisor < cam->mclk)		divisor += 1;	if (divisor > 30)		divisor = 30;	cam->xclk = cam->mclk/divisor;	if (divisor == 1)		cc_reg_out(cam, CC_CTRL_XCLK, CC_CTRL_XCLK_DIV_BYPASS);	else		cc_reg_out(cam, CC_CTRL_XCLK, divisor);}/* Write the color space conversion coefficients to the display controller  * registers.  Each coefficient is a signed 11-bit integer in the range  * [-1024, 1023].  The matrix coefficients are: *	[ RY  RCr  RCb ] *	[ GY  GCr  GCb ] *	[ BY  BCr  BCb ] */static voidomap24xxcam_set_colorconv(struct omap24xxcam_device *cam, 	const short int mtx[3][3], int v){	unsigned long ccreg;	ccreg = (mtx[0][0] & 0x7ff) | ((mtx[0][1] & 0x7ff) << 16);	dispc_reg_out(cam, DISPC_VID_CONV_COEF0(v), ccreg);	ccreg = (mtx[0][2] & 0x7ff) | ((mtx[1][0] & 0x7ff) << 16);	dispc_reg_out(cam, DISPC_VID_CONV_COEF1(v), ccreg);	ccreg = (mtx[1][1] & 0x7ff) | ((mtx[1][2] & 0x7ff) << 16);	dispc_reg_out(cam, DISPC_VID_CONV_COEF2(v), ccreg);	ccreg = (mtx[2][0] & 0x7ff) | ((mtx[2][1] & 0x7ff) << 16);	dispc_reg_out(cam, DISPC_VID_CONV_COEF3(v), ccreg);	ccreg = mtx[2][2] & 0x7ff;	dispc_reg_out(cam, DISPC_VID_CONV_COEF4(v), ccreg);}/* Write the horizontal and vertical resizing coefficients to the display  * controller registers.  Each coefficient is a signed 8-bit integer in the  * range [-128, 127] except for the middle coefficient (vc[1][i] and hc[3][i])  * which is an unsigned 8-bit integer in the range [0, 255].  The first index of * the matrix is the coefficient number (0 to 2 vertical or 0 to 4 horizontal)  * and the second index is the phase (0 to 7). */static voidomap24xxcam_set_resize(struct omap24xxcam_device *cam, 	const short int vc[3][8], const short int hc[5][8], int v){	int i;	unsigned long reg;	for (i = 0; i < 8; i++) {		reg = (hc[0][i] & 0xff) | ((hc[1][i] & 0xff) << 8) 			| ((hc[2][i] & 0xff) << 16) | ((hc[3][i] & 0xff) << 24);		dispc_reg_out(cam, DISPC_VID_FIR_COEF_H(v, i), reg);		reg = (hc[4][i] & 0xff) | ((vc[0][i] & 0xff) << 8) 			| ((vc[1][i] & 0xff) << 16) | ((vc[2][i] & 0xff) << 24);		dispc_reg_out(cam, DISPC_VID_FIR_COEF_HV(v, i), reg);	}}static voidomap24xxcam_configure_overlay(struct omap24xxcam_device *cam, 				struct omap24xx_vid2_format *vid2_format){	int v;	struct v4l2_window *win = &cam->win;	struct v4l2_rect *crop = &cam->crop;	struct v4l2_pix_format *pix;	struct v4l2_framebuffer *fbuf = &cam->fbuf;	int vid_position_x, vid_position_y;	unsigned long vid_position, vid_size, vid_picture_size;	unsigned long vid_attributes;	unsigned long firvinc, firhinc;	/* color space conversion matrices */	const static short int cc_bt601[3][3] =		{ {  298,  409,    0 },		  {  298, -208, -100 },		  {  298,    0,  517 } };	const static short int cc_bt709[3][3] =		{ {  298,  459,    0 },		  {  298, -137,  -55 },		  {  298,    0,  541 } };	const static short int cc_bt601_full[3][3] =		{ {  256,  351,    0 },		  {  256, -179,  -86 },		  {  256,    0,  443 } };	/* vertical resizing matrix */	const static short int vc[3][8] = 		{ {   0,   3,  12,  32,   0,   7,   5,   2 }, 		  { 128, 123, 111,  89,  64,  89, 111, 123 },		  {   0,   2,   5,   7,  64,  32,  12,   3 } };	/* horizontal resizing matrix */	const static short int hc[5][8] = 		{ {   0,  -1,  -2,  -5,   0,  -2,  -1,   0 },		  {   0,  13,  30,  51,  -9, -11, -11,  -8 },		  { 128, 124, 112,  95,  73,  95, 112, 124 },		  {   0,  -8, -11, -11,  73,  51,  30,  13 },		  {   0,   0,  -1,  -2,  -9,  -5,  -2,  -1 } };	if (vid2_format) {		pix = &vid2_format->pix;		v = cam->vid2;	} else {		pix = &cam->pix;		v = cam->vid1;	}	/* make sure the video overlay is disabled before we reconfigure it */	omap24xxcam_disable_vlayer(cam,v);	/* configure the video attributes register */	vid_attributes = 0;	switch (pix->pixelformat) {		case V4L2_PIX_FMT_YUYV:			vid_attributes |= DISPC_VID_ATTRIBUTES_VIDFORMAT_YUV2;			vid_attributes |= 				DISPC_VID_ATTRIBUTES_VIDCOLORCONVENABLE;			break;		case V4L2_PIX_FMT_UYVY:			vid_attributes |= DISPC_VID_ATTRIBUTES_VIDFORMAT_UYVY;			vid_attributes |= 				DISPC_VID_ATTRIBUTES_VIDCOLORCONVENABLE;			break;		case V4L2_PIX_FMT_RGB565:		default:			vid_attributes |= DISPC_VID_ATTRIBUTES_VIDFORMAT_RGB16;			vid_attributes |= ((cam->gfx_attributes & 				DISPC_GFX_ATTRIBUTES_GFXREPLICATIONENABLE)				<< 5);			break;		case V4L2_PIX_FMT_RGB565X:			vid_attributes |= DISPC_VID_ATTRIBUTES_VIDFORMAT_RGB16;			vid_attributes |= DISPC_VID_ATTRIBUTES_VIDENDIANNESS;			vid_attributes |= ((cam->gfx_attributes & 				DISPC_GFX_ATTRIBUTES_GFXREPLICATIONENABLE)				<< 5);			break;	}	if (cam->gfx_attributes & DISPC_GFX_ATTRIBUTES_GFXCHANNELOUT)		vid_attributes |= DISPC_VID_ATTRIBUTES_VIDCHANNELOUT;	vid_attributes |= ((cam->gfx_attributes 		& DISPC_GFX_ATTRIBUTES_GFXBURSTSIZE) << 8);	switch (pix->colorspace) {		case V4L2_COLORSPACE_SMPTE170M:		case V4L2_COLORSPACE_SMPTE240M:		case V4L2_COLORSPACE_BT878:		case V4L2_COLORSPACE_470_SYSTEM_M:		case V4L2_COLORSPACE_470_SYSTEM_BG:			/* luma (Y) range lower limit is 16, BT.601 standard */			omap24xxcam_set_colorconv(cam, cc_bt601, v);			break;		case V4L2_COLORSPACE_REC709:			/* luma (Y) range lower limit is 16, BT.709 standard */			omap24xxcam_set_colorconv(cam, cc_bt709, v);			break;		case V4L2_COLORSPACE_JPEG:		case V4L2_COLORSPACE_SRGB:			/* full luma (Y) range, assume BT.601 standard */			vid_attributes |= DISPC_VID_ATTRIBUTES_VIDFULLRANGE;			omap24xxcam_set_colorconv(cam, cc_bt601_full, v);			break;	}	if (!vid2_format) { /* use win and crop if it is for overlay */		if (win->w.width != crop->width) {			vid_attributes |= DISPC_VID_ATTRIBUTES_VIDRESIZEENABLE_HRESIZE;			if (win->w.width < crop->width)				vid_attributes |= DISPC_VID_ATTRIBUTES_VIDHRESIZECONF;		}		if (win->w.height != crop->height) {			vid_attributes |= DISPC_VID_ATTRIBUTES_VIDRESIZEENABLE_VRESIZE;			if (win->w.height < crop->height)				vid_attributes |= DISPC_VID_ATTRIBUTES_VIDVRESIZECONF;		}	}	dispc_reg_out(cam, DISPC_VID_ATTRIBUTES(v), vid_attributes);	/* configure transparency color key */	if (fbuf->flags & V4L2_FBUF_FLAG_CHROMAKEY) {		/* enable chromakey */		if (vid_attributes & DISPC_VID_ATTRIBUTES_VIDCHANNELOUT) {			/* digital output channel */			dispc_reg_out(cam, DISPC_TRANS_COLOR1, win->chromakey);			dispc_reg_merge(cam, DISPC_CONFIG, 				DISPC_CONFIG_TCKDIGENABLE, 				DISPC_CONFIG_TCKDIGSELECTION 				| DISPC_CONFIG_TCKDIGENABLE);		}		else {			/* LCD */			dispc_reg_out(cam, DISPC_TRANS_COLOR0, win->chromakey);			dispc_reg_merge(cam, DISPC_CONFIG, 				DISPC_CONFIG_TCKLCDENABLE, 				DISPC_CONFIG_TCKLCDSELECTION 				| DISPC_CONFIG_TCKLCDENABLE);		}	}	else {		/* disable chromakey */		if (vid_attributes & DISPC_VID_ATTRIBUTES_VIDCHANNELOUT) {			/* digital output channel */			dispc_reg_merge(cam, DISPC_CONFIG, 0, 				DISPC_CONFIG_TCKDIGSELECTION 				| DISPC_CONFIG_TCKDIGENABLE);		}		else {			/* LCD */			dispc_reg_merge(cam, DISPC_CONFIG, 0, 				DISPC_CONFIG_TCKLCDSELECTION 				| DISPC_CONFIG_TCKLCDENABLE);		}	}	/* initialize the resizing filter */	omap24xxcam_set_resize(cam, vc, hc, v);

⌨️ 快捷键说明

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