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

📄 ibmcam.c

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	case 0x0268:	/* 320x240, best frame rate compression */	case 0x02CA:	/* 160x120, best quality compression */	case 0x02EA:	/* 160x120, best frame rate compression */		/* Do nothing with this - not supported */		err("Unsupported mode $%04lx", frame->header);		return scan_NextFrame;	default:		/* Catch unknown headers, may help in learning new headers */		err("Strange frame->header=$%08lx", frame->header);		return scan_NextFrame;	}	/*	 * Make sure that our writing into output buffer	 * will not exceed the buffer. Note that we may write	 * not into current output scanline but in several after	 * it as well (if we enlarge image vertically.)	 */	if ((frame->curline + 1) >= data_h) {		if (uvd->debug >= 3)			info("Reached line %d. (frame is done)", frame->curline);		return scan_NextFrame;	}	/* Make sure there's enough data for the entire line */	len = 3 * data_w; /* <y-data> <uv-data> */	assert(len <= sizeof(lineBuffer));	/* Make sure there's enough data for the entire line */	if (RingQueue_GetLength(&uvd->dp) < len)		return scan_Out;	/* Suck one line out of the ring queue */	RingQueue_Dequeue(&uvd->dp, lineBuffer, len);	data = lineBuffer;	color = data + data_w;		/* Point to where color planes begin */	/* Bottom-to-top scanning */	rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1;	RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1);	for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {		int y, rv, gv, bv;	/* RGB components */		if (i < data_w) {			y = data[i];	/* Luminosity is the first line */			/* Apply static color correction */			u = color[i*2] + hue_corr;			v = color[i*2 + 1] + hue2_corr;			/* Apply color correction */			if (color_corr != 0) {				/* Magnify up to 2 times, reduce down to zero saturation */				u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;				v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;			}		} else			y = 0, u = v = 128;		YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);		RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* Done by deinterlacing now */	}	frame->deinterlace = Deinterlace_FillEvenLines;	/*	 * Account for number of bytes that we wrote into output V4L frame.	 * We do it here, after we are done with the scanline, because we	 * may fill more than one output scanline if we do vertical	 * enlargement.	 */	frame->curline += 2;	*pcopylen += 2 * v4l_linesize;	if (frame->curline >= VIDEOSIZE_Y(frame->request)) {		if (uvd->debug >= 3) {			info("All requested lines (%ld.) done.",			     VIDEOSIZE_Y(frame->request));		}		return scan_NextFrame;	} else		return scan_Continue;}/* * ibmcam_model4_128x96_parse_lines() * * This decoder is for one strange data format that is produced by Model 4 * camera only in 128x96 mode. This is RGB format and here is its description. * First of all, this is non-interlaced stream, meaning that all scan lines * are present in the datastream. There are 96 consecutive blocks of data * that describe all 96 lines of the image. Each block is 5*128 bytes long * and carries R, G, B components. The format of the block is shown in the * code below. First 128*2 bytes are interleaved R and G components. Then * we have a gap (junk data) 64 bytes long. Then follow B and something * else, also interleaved (this makes another 128*2 bytes). After that * probably another 64 bytes of junk follow. * * History: * 10-Feb-2001 Created. */static ParseState_t ibmcam_model4_128x96_parse_lines(	uvd_t *uvd,	usbvideo_frame_t *frame,	long *pcopylen){	const unsigned char *data_rv, *data_gv, *data_bv;	unsigned int len;	int i, v4l_linesize; /* V4L line offset */	const int data_w=128, data_h=96;	static unsigned char lineBuffer[128*5];	v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;	/*	 * Make sure that our writing into output buffer	 * will not exceed the buffer. Note that we may write	 * not into current output scanline but in several after	 * it as well (if we enlarge image vertically.)	 */	if ((frame->curline + 1) >= data_h) {		if (uvd->debug >= 3)			info("Reached line %d. (frame is done)", frame->curline);		return scan_NextFrame;	}	/*	 * RGRGRG .... RGRG_____________B?B?B? ... B?B?____________	 * <---- 128*2 ---><---- 64 ---><--- 128*2 ---><--- 64 --->	 */	/* Make sure there's enough data for the entire line */	len = 5 * data_w;	assert(len <= sizeof(lineBuffer));	/* Make sure there's enough data for the entire line */	if (RingQueue_GetLength(&uvd->dp) < len)		return scan_Out;	/* Suck one line out of the ring queue */	RingQueue_Dequeue(&uvd->dp, lineBuffer, len);	data_rv = lineBuffer;	data_gv = lineBuffer + 1;	data_bv = lineBuffer + data_w*2 + data_w/2;	for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {		int rv, gv, bv;	/* RGB components */		if (i < data_w) {			const int j = i * 2;			gv = data_rv[j];			rv = data_gv[j];			bv = data_bv[j];			if (flags & FLAGS_MONOCHROME) {				unsigned long y;				y = rv + gv + bv;				y /= 3;				if (y > 0xFF)					y = 0xFF;				rv = gv = bv = (unsigned char) y;			}		} else {			rv = gv = bv = 0;		}		RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);	}	frame->deinterlace = Deinterlace_None;	frame->curline++;	*pcopylen += v4l_linesize;	if (frame->curline >= VIDEOSIZE_Y(frame->request)) {		if (uvd->debug >= 3) {			info("All requested lines (%ld.) done.",			     VIDEOSIZE_Y(frame->request));		}		return scan_NextFrame;	} else		return scan_Continue;}/* * ibmcam_ProcessIsocData() * * Generic routine to parse the ring queue data. It employs either * ibmcam_find_header() or ibmcam_parse_lines() to do most * of work. * * History: * 1/21/00  Created. */void ibmcam_ProcessIsocData(uvd_t *uvd, usbvideo_frame_t *frame){	ParseState_t newstate;	long copylen = 0;	int mod = IBMCAM_T(uvd)->camera_model;	while (1) {		newstate = scan_Out;		if (RingQueue_GetLength(&uvd->dp) > 0) {			if (frame->scanstate == ScanState_Scanning) {				newstate = ibmcam_find_header(uvd);			} else if (frame->scanstate == ScanState_Lines) {				if ((mod == IBMCAM_MODEL_2) &&				    ((uvd->videosize == VIDEOSIZE_352x288) ||				     (uvd->videosize == VIDEOSIZE_320x240) ||				     (uvd->videosize == VIDEOSIZE_352x240)))				{					newstate = ibmcam_model2_320x240_parse_lines(						uvd, frame, &copylen);				} else if (mod == IBMCAM_MODEL_4) {					/*					 * Model 4 cameras (IBM NetCamera) use Model 2 decoder (RGB)					 * for 320x240 and above; 160x120 and 176x144 uses Model 1					 * decoder (YUV), and 128x96 mode uses ???					 */					if ((uvd->videosize == VIDEOSIZE_352x288) ||					    (uvd->videosize == VIDEOSIZE_320x240) ||					    (uvd->videosize == VIDEOSIZE_352x240))					{						newstate = ibmcam_model2_320x240_parse_lines(uvd, frame, &copylen);					} else if (uvd->videosize == VIDEOSIZE_128x96) {						newstate = ibmcam_model4_128x96_parse_lines(uvd, frame, &copylen);					} else {						newstate = ibmcam_parse_lines(uvd, frame, &copylen);					}				} else if (mod == IBMCAM_MODEL_3) {					newstate = ibmcam_model3_parse_lines(uvd, frame, &copylen);				} else {					newstate = ibmcam_parse_lines(uvd, frame, &copylen);				}			}		}		if (newstate == scan_Continue)			continue;		else if ((newstate == scan_NextFrame) || (newstate == scan_Out))			break;		else			return; /* scan_EndParse */	}	if (newstate == scan_NextFrame) {		frame->frameState = FrameState_Done;		uvd->curframe = -1;		uvd->stats.frame_num++;		if ((mod == IBMCAM_MODEL_2) || (mod == IBMCAM_MODEL_4)) {			/* Need software contrast adjustment for those cameras */			frame->flags |= USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST;		}	}	/* Update the frame's uncompressed length. */	frame->seqRead_Length += copylen;#if 0	{		static unsigned char j=0;		memset(frame->data, j++, uvd->max_frame_size);		frame->frameState = FrameState_Ready;	}#endif}/* * ibmcam_veio() * * History: * 1/27/00  Added check for dev == NULL; this happens if camera is unplugged. */static int ibmcam_veio(	uvd_t *uvd,	unsigned char req,	unsigned short value,	unsigned short index){	static const char proc[] = "ibmcam_veio";	unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;	int i;	if (!CAMERA_IS_OPERATIONAL(uvd))		return 0;	if (req == 1) {		i = usb_control_msg(			uvd->dev,			usb_rcvctrlpipe(uvd->dev, 0),			req,			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,			value,			index,			cp,			sizeof(cp),			HZ);#if 0		info("USB => %02x%02x%02x%02x%02x%02x%02x%02x "		       "(req=$%02x val=$%04x ind=$%04x)",		       cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],		       req, value, index);#endif	} else {		i = usb_control_msg(			uvd->dev,			usb_sndctrlpipe(uvd->dev, 0),			req,			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,			value,			index,			NULL,			0,			HZ);	}	if (i < 0) {		err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.",		    proc, i);		uvd->last_error = i;	}	return i;}/* * ibmcam_calculate_fps() * * This procedure roughly calculates the real frame rate based * on FPS code (framerate=NNN option). Actual FPS differs * slightly depending on lighting conditions, so that actual frame * rate is determined by the camera. Since I don't know how to ask * the camera what FPS is now I have to use the FPS code instead. * * The FPS code is in range [0..6], 0 is slowest, 6 is fastest. * Corresponding real FPS should be in range [3..30] frames per second. * The conversion formula is obvious: * * real_fps = 3 + (fps_code * 4.5) * * History: * 1/18/00  Created. */static int ibmcam_calculate_fps(uvd_t *uvd){	return 3 + framerate*4 + framerate/2;}/* * ibmcam_send_FF_04_02() * * This procedure sends magic 3-command prefix to the camera. * The purpose of this prefix is not known. * * History: * 1/2/00   Created. */static void ibmcam_send_FF_04_02(uvd_t *uvd){	ibmcam_veio(uvd, 0, 0x00FF, 0x0127);	ibmcam_veio(uvd, 0, 0x0004, 0x0124);	ibmcam_veio(uvd, 0, 0x0002, 0x0124);}static void ibmcam_send_00_04_06(uvd_t *uvd){	ibmcam_veio(uvd, 0, 0x0000, 0x0127);	ibmcam_veio(uvd, 0, 0x0004, 0x0124);	ibmcam_veio(uvd, 0, 0x0006, 0x0124);}static void ibmcam_send_x_00(uvd_t *uvd, unsigned short x){	ibmcam_veio(uvd, 0, x,      0x0127);	ibmcam_veio(uvd, 0, 0x0000, 0x0124);}static void ibmcam_send_x_00_05(uvd_t *uvd, unsigned short x){	ibmcam_send_x_00(uvd, x);	ibmcam_veio(uvd, 0, 0x0005, 0x0124);}static void ibmcam_send_x_00_05_02(uvd_t *uvd, unsigned short x){	ibmcam_veio(uvd, 0, x,      0x0127);	ibmcam_veio(uvd, 0, 0x0000, 0x0124);	ibmcam_veio(uvd, 0, 0x0005, 0x0124);	ibmcam_veio(uvd, 0, 0x0002, 0x0124);}static void ibmcam_send_x_01_00_05(uvd_t *uvd, unsigned short x){	ibmcam_veio(uvd, 0, x,      0x0127);	ibmcam_veio(uvd, 0, 0x0001, 0x0124);	ibmcam_veio(uvd, 0, 0x0000, 0x0124);	ibmcam_veio(uvd, 0, 0x0005, 0x0124);}static void ibmcam_send_x_00_05_02_01(uvd_t *uvd, unsigned short x){	ibmcam_veio(uvd, 0, x,      0x0127);	ibmcam_veio(uvd, 0, 0x0000, 0x0124);	ibmcam_veio(uvd, 0, 0x0005, 0x0124);	ibmcam_veio(uvd, 0, 0x0002, 0x0124);	ibmcam_veio(uvd, 0, 0x0001, 0x0124);}static void ibmcam_send_x_00_05_02_08_01(uvd_t *uvd, unsigned short x){	ibmcam_veio(uvd, 0, x,      0x0127);	ibmcam_veio(uvd, 0, 0x0000, 0x0124);	ibmcam_veio(uvd, 0, 0x0005, 0x0124);	ibmcam_veio(uvd, 0, 0x0002, 0x0124);	ibmcam_veio(uvd, 0, 0x0008, 0x0124);	ibmcam_veio(uvd, 0, 0x0001, 0x0124);}static void ibmcam_Packet_Format1(uvd_t *uvd, unsigned char fkey, unsigned char val){	ibmcam_send_x_01_00_05(uvd, unknown_88);	ibmcam_send_x_00_05(uvd, fkey);	ibmcam_send_x_00_05_02_08_01(uvd, val);	ibmcam_send_x_00_05(uvd, unknown_88);	ibmcam_send_x_00_05_02_01(uvd, fkey);	ibmcam_send_x_00_05(uvd, unknown_89);	ibmcam_send_x_00(uvd, fkey);	ibmcam_send_00_04_06(uvd);	ibmcam_veio(uvd, 1, 0x0000, 0x0126);	ibmcam_send_FF_04_02(uvd);}static void ibmcam_PacketFormat2(uvd_t *uvd, unsigned char fkey, unsigned char val){	ibmcam_send_x_01_00_05	(uvd, unknown_88);	ibmcam_send_x_00_05	(uvd, fkey);

⌨️ 快捷键说明

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