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

📄 usbvision.c

📁 这是一个Linux下的USB摄像头捕捉程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	if ((usbvision->curFrameNum < 0)	    || (usbvision->curFrameNum >= USBVISION_NUMFRAMES)) {		printk(KERN_ERR "%s: usbvision->curFrameNum=%d.\n", proc,		       usbvision->curFrameNum);		return;	}	/* Grab the current frame */	frame = &usbvision->frame[usbvision->curFrameNum];	/* Optionally start at the beginning */	if (fullframe) {		frame->curline = 0;		frame->scanlength = 0;	}	/* Form every scan line */	for (; frame->curline < frame->frmheight; frame->curline++) {		int i;		f = frame->data + (usbvision->curwidth * 3 * frame->curline);		for (i = 0; i < usbvision->curwidth; i++) {			unsigned char cb = 0x80;			unsigned char cg = 0;			unsigned char cr = 0;			if (pmode == 1) {				if (frame->curline % 32 == 0)					cb = 0, cg = cr = 0xFF;				else if (i % 32 == 0) {					if (frame->curline % 32 == 1)						num_cell++;					cb = 0, cg = cr = 0xFF;				} else {					cb =					    ((num_cell * 7) +					     num_pass) & 0xFF;					cg =					    ((num_cell * 5) +					     num_pass * 2) & 0xFF;					cr =					    ((num_cell * 3) +					     num_pass * 3) & 0xFF;				}			} else {				/* Just the blue screen */			}			*f++ = cb;			*f++ = cg;			*f++ = cr;			scan_length += 3;		}	}	frame->grabstate = FrameState_Done;	frame->scanlength += scan_length;	++num_pass;	/* We do this unconditionally, regardless of FLAGS_OSD_STATS */	usbvision_osd_stats(usbvision, frame);}/* * Here comes the data parsing stuff that is run as interrupt *//* * usbvision_find_header() * * Locate one of supported header markers in the scratch buffer. */static enum ParseState usbvision_find_header(struct usb_usbvision *usbvision){	struct usbvision_frame *frame;	int foundHeader = 0;	if (usbvision->overlay) {		frame = &usbvision->overlay_frame;	}	else {		frame = &usbvision->frame[usbvision->curFrameNum];	}	while (scratch_get_header(usbvision, &frame->isocHeader) == USBVISION_HEADER_LENGTH) {		// found header in scratch		PDEBUG(DBG_HEADER, "found header: 0x%02x%02x %d %d %d %d %#x 0x%02x %u %u",				frame->isocHeader.magic_2,				frame->isocHeader.magic_1,				frame->isocHeader.headerLength,				frame->isocHeader.frameNum,				frame->isocHeader.framePhase,				frame->isocHeader.frameLatency,				frame->isocHeader.dataFormat,				frame->isocHeader.formatParam,				frame->isocHeader.frameWidth,				frame->isocHeader.frameHeight);		if (usbvision->requestIntra) {			if (frame->isocHeader.formatParam & 0x80) {				foundHeader = 1;				usbvision->lastIsocFrameNum = -1; // do not check for lost frames this time				usbvision_unrequest_intra(usbvision);				break;			}		}		else {			foundHeader = 1;			break;		}	}	if (foundHeader) {		frame->frmwidth = frame->isocHeader.frameWidth * usbvision->stretch_width;		frame->frmheight = frame->isocHeader.frameHeight * usbvision->stretch_height;		frame->v4l_linesize = (frame->frmwidth * usbvision_v4l_format[frame->v4l_format].depth)>> 3;		usbvision->curFrame = frame;	}	else { // no header found		PDEBUG(DBG_HEADER, "skipping scratch data, no header");		scratch_reset(usbvision);		return ParseState_EndParse;	}	// found header	if (frame->isocHeader.dataFormat==ISOC_MODE_COMPRESS) {		//check isocHeader.frameNum for lost frames		if (usbvision->lastIsocFrameNum >= 0) {			if (((usbvision->lastIsocFrameNum + 1) % 32) != frame->isocHeader.frameNum) {				// unexpected frame drop: need to request new intra frame				PDEBUG(DBG_HEADER, "Lost frame before %d on USB", frame->isocHeader.frameNum);				usbvision_request_intra(usbvision);				return ParseState_NextFrame;			}		}		usbvision->lastIsocFrameNum = frame->isocHeader.frameNum;	}	usbvision->header_count++;	frame->scanstate = ScanState_Lines;	frame->curline = 0;	if (flags & FLAGS_FORCE_TESTPATTERN) {		usbvision_testpattern(usbvision, 1, 1);		return ParseState_NextFrame;	}	return ParseState_Continue;}static enum ParseState usbvision_parse_lines_422(struct usb_usbvision *usbvision,					   long *pcopylen){	volatile struct usbvision_frame *frame;	unsigned char *f;	int len;	int i;	unsigned char yuyv[4]={180, 128, 10, 128}; // YUV components	unsigned char rv, gv, bv;	// RGB components	int clipmask_index, bytes_per_pixel;	int overlay = usbvision->overlay;	int stretch_bytes, clipmask_add;	if (overlay) {		frame  = &usbvision->overlay_frame;		if (usbvision->overlay_base == NULL) {			//video_buffer is not set yet			return ParseState_NextFrame;		}		f = usbvision->overlay_win + frame->curline *			usbvision->vid_buf.bytesperline;	}	else {		frame  = &usbvision->frame[usbvision->curFrameNum];		f = frame->data + (frame->v4l_linesize * frame->curline);	}	/* Make sure there's enough data for the entire line */	len = (frame->isocHeader.frameWidth * 2)+5;	if (scratch_len(usbvision) < len) {		PDEBUG(DBG_PARSE, "out of data in line %d, need %u.\n", frame->curline, len);		return ParseState_Out;	}	if ((frame->curline + 1) >= frame->frmheight) {		return ParseState_NextFrame;	}	bytes_per_pixel = usbvision_v4l_format[frame->v4l_format].bytes_per_pixel;	stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel;	clipmask_index = frame->curline * MAX_FRAME_WIDTH;	clipmask_add = usbvision->stretch_width;	for (i = 0; i < frame->frmwidth; i+=(2 * usbvision->stretch_width)) {		scratch_get(usbvision, &yuyv[0], 4);		if((overlay) && (clipped_pixel(clipmask_index))) {			f += bytes_per_pixel;		}		else if (frame->v4l_format == VIDEO_PALETTE_YUV422) {			*f++ = yuyv[0]; // Y			*f++ = yuyv[3]; // U		}		else {			YUV_TO_RGB_BY_THE_BOOK(yuyv[0], yuyv[1], yuyv[3], rv, gv, bv);			switch (frame->v4l_format) {				case VIDEO_PALETTE_RGB565:					*f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 3));					*f++ = (0x07 & (gv >> 5)) | (0xF8 &  rv);					break;				case VIDEO_PALETTE_RGB24:					*f++ = bv;					*f++ = gv;					*f++ = rv;					break;				case VIDEO_PALETTE_RGB32:					*f++ = bv;					*f++ = gv;					*f++ = rv;					f++;					break;				case VIDEO_PALETTE_RGB555:					*f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 2));					*f++ = (0x03 & (gv >> 6)) | (0x7C & (rv >> 1));					break;			}		}		clipmask_index += clipmask_add;		f += stretch_bytes;		if((overlay) && (clipped_pixel(clipmask_index))) {			f += bytes_per_pixel;		}		else if (frame->v4l_format == VIDEO_PALETTE_YUV422) {			*f++ = yuyv[2]; // Y			*f++ = yuyv[1]; // V		}		else {			YUV_TO_RGB_BY_THE_BOOK(yuyv[2], yuyv[1], yuyv[3], rv, gv, bv);			switch (frame->v4l_format) {				case VIDEO_PALETTE_RGB565:					*f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 3));					*f++ = (0x07 & (gv >> 5)) | (0xF8 &  rv);					break;				case VIDEO_PALETTE_RGB24:					*f++ = bv;					*f++ = gv;					*f++ = rv;					break;				case VIDEO_PALETTE_RGB32:					*f++ = bv;					*f++ = gv;					*f++ = rv;					f++;					break;				case VIDEO_PALETTE_RGB555:					*f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 2));					*f++ = (0x03 & (gv >> 6)) | (0x7C & (rv >> 1));					break;			}		}		clipmask_index += clipmask_add;		f += stretch_bytes;	}	frame->curline += usbvision->stretch_height;	*pcopylen += frame->v4l_linesize * usbvision->stretch_height;	if (frame->curline >= frame->frmheight) {		return ParseState_NextFrame;	}	else {		return ParseState_Continue;	}}static int usbvision_decompress(struct usb_usbvision *usbvision,unsigned char *Compressed,								unsigned char *Decompressed, int *StartPos,								int *BlockTypeStartPos, int Len){	int RestPixel, Idx, MaxPos, Pos, ExtraPos, BlockLen, BlockTypePos, BlockTypeLen;	unsigned char BlockByte, BlockCode, BlockType, BlockTypeByte, Integrator;	Integrator = 0;	Pos = *StartPos;	BlockTypePos = *BlockTypeStartPos;	MaxPos = 396; //Pos + Len;	ExtraPos = Pos;	BlockLen = 0;	BlockByte = 0;	BlockCode = 0;	BlockType = 0;	BlockTypeByte = 0;	BlockTypeLen = 0;	RestPixel = Len;	for (Idx = 0; Idx < Len; Idx++) {		if (BlockLen == 0) {			if (BlockTypeLen==0) {				BlockTypeByte = Compressed[BlockTypePos];				BlockTypePos++;				BlockTypeLen = 4;			}			BlockType = (BlockTypeByte & 0xC0) >> 6;			//statistic:			usbvision->ComprBlockTypes[BlockType]++;			Pos = ExtraPos;			if (BlockType == 0) {				if(RestPixel >= 24) {					Idx += 23;					RestPixel -= 24;					Integrator = Decompressed[Idx];				} else {					Idx += RestPixel - 1;					RestPixel = 0;				}			} else {				BlockCode = Compressed[Pos];				Pos++;				if (RestPixel >= 24) {					BlockLen  = 24;				} else {					BlockLen = RestPixel;				}				RestPixel -= BlockLen;				ExtraPos = Pos + (BlockLen / 4);			}			BlockTypeByte <<= 2;			BlockTypeLen -= 1;		}		if (BlockLen > 0) {			if ((BlockLen%4) == 0) {				BlockByte = Compressed[Pos];				Pos++;			}			if (BlockType == 1) { //inter Block				Integrator = Decompressed[Idx];			}			switch (BlockByte & 0xC0) {				case 0x03<<6:					Integrator += Compressed[ExtraPos];					ExtraPos++;					break;				case 0x02<<6:					Integrator += BlockCode;					break;				case 0x00:					Integrator -= BlockCode;					break;			}			Decompressed[Idx] = Integrator;			BlockByte <<= 2;			BlockLen -= 1;		}	}	*StartPos = ExtraPos;	*BlockTypeStartPos = BlockTypePos;	return Idx;}/* * usbvision_parse_compress() * * Parse compressed frame from the scratch buffer, put * decoded RGB value into the current frame buffer and add the written * number of bytes (RGB) to the *pcopylen. * */static enum ParseState usbvision_parse_compress(struct usb_usbvision *usbvision,					   long *pcopylen){#define USBVISION_STRIP_MAGIC		0x5A#define USBVISION_STRIP_LEN_MAX		400#define USBVISION_STRIP_HEADER_LEN	3	struct usbvision_frame *frame;	unsigned char *f,*u = NULL ,*v = NULL;	unsigned char StripData[USBVISION_STRIP_LEN_MAX];	unsigned char StripHeader[USBVISION_STRIP_HEADER_LEN];	int Idx, IdxEnd, StripLen, StripPtr, StartBlockPos, BlockPos, BlockTypePos;	in

⌨️ 快捷键说明

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