📄 usbvision.c
字号:
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 + -