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

📄 ov511 v1.28.c

📁 linux下ov511驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        for (l = 0; l < 8; l++) {                for (m=0; m<8; m++) {                        int v   = *(pIn+64);                        int u   = *pIn++;                                                *pOut = u;                        *(pOut+2) = v;                        *(pOut+iWidth) = u;                        *(pOut+iWidth+2) = v;                        pOut += 4;                }                pOut += (iWidth*4 - 32);        }}static voidov511_parse_data_yuv420(unsigned char *pIn0, unsigned char *pOut0,                        int iOutY, int iOutUV, int iWidth, int iHeight){        int k, l, m;        unsigned char *pIn;        unsigned char *pOut, *pOut1;        unsigned a = iWidth * iHeight;        unsigned w = iWidth / 2;        pIn = pIn0;        pOut = pOut0 + iOutUV + a;        for (k = 0; k < 8; k++) {                pOut1 = pOut;                for (l = 0; l < 8; l++) *pOut1++ = *pIn++;                pOut += w;        }        pIn = pIn0 + 64;        pOut = pOut0 + iOutUV + a + a/4;        for (k = 0; k < 8; k++) {                pOut1 = pOut;                for (l = 0; l < 8; l++) *pOut1++ = *pIn++;                pOut += w;        }        pIn = pIn0 + 128;        pOut = pOut0 + iOutY;        for (k = 0; k < 4; k++) {                pOut1 = pOut;                for (l = 0; l < 8; l++) {                        for (m = 0; m < 8; m++)                                *pOut1++ =*pIn++;                        pOut1 += iWidth - 8;                }                pOut += 8;        }}static voidov511_parse_data_yuv422p(unsigned char *pIn0, unsigned char *pOut0,                       int iOutY, int iOutUV, int iWidth, int iHeight){        int k, l, m;        unsigned char *pIn;        unsigned char *pOut, *pOut1;        unsigned a = iWidth * iHeight;        unsigned w = iWidth / 2;        pIn = pIn0;        pOut = pOut0 + iOutUV + a;        for (k = 0; k < 8; k++) {                pOut1 = pOut;                for (l = 0; l < 8; l++) {                        *pOut1 = *(pOut1 + w) = *pIn++;                        pOut1++;                }                pOut += iWidth;        }        pIn = pIn0 + 64;        pOut = pOut0 + iOutUV + a + a/2;        for (k = 0; k < 8; k++) {                pOut1 = pOut;                for (l = 0; l < 8; l++) {                        *pOut1 = *(pOut1 + w) = *pIn++;                        pOut1++;                }                pOut += iWidth;        }        pIn = pIn0 + 128;        pOut = pOut0 + iOutY;        for (k = 0; k < 4; k++) {                pOut1 = pOut;                for (l = 0; l < 8; l++) {                        for (m = 0; m < 8; m++)                                *pOut1++ =*pIn++;                        pOut1 += iWidth - 8;                }                pOut += 8;        }}/* * For 640x480 RAW BW images, data shows up in 1200 256 byte segments. * The segments represent 4 squares of 8x8 pixels as follows: * *      0  1 ...  7    64  65 ...  71   ...  192 193 ... 199 *      8  9 ... 15    72  73 ...  79        200 201 ... 207 *           ...              ...                    ... *     56 57 ... 63   120 121 ... 127        248 249 ... 255 * */ static voidov511_parse_data_grey(unsigned char *pIn0, unsigned char *pOut0,                      int iOutY, int iWidth)                {        int k, l, m;        unsigned char *pIn;        unsigned char *pOut, *pOut1;        pIn = pIn0;        pOut = pOut0 + iOutY;        for (k = 0; k < 4; k++) {                pOut1 = pOut;                for (l = 0; l < 8; l++) {                        for (m = 0; m < 8; m++) {                                *pOut1++ = *pIn++;                        }                        pOut1 += iWidth - 8;                }                pOut += 8;        }}/* * fixFrameRGBoffset-- * My camera seems to return the red channel about 1 pixel * low, and the blue channel about 1 pixel high. After YUV->RGB * conversion, we can correct this easily. OSL 2/24/2000. */static void fixFrameRGBoffset(struct ov511_frame *frame){        int x, y;        int rowBytes = frame->width*3, w = frame->width;        unsigned char *rgb = frame->data;        const int shift = 1;  /* Distance to shift pixels by, vertically */        /* Don't bother with little images */        if (frame->width < 400)                 return;        /* Shift red channel up */        for (y = shift; y < frame->height; y++) {                int lp = (y-shift)*rowBytes;     /* Previous line offset */                int lc = y*rowBytes;             /* Current line offset */                for (x = 0; x < w; x++)                        rgb[lp+x*3+2] = rgb[lc+x*3+2]; /* Shift red up */        }        /* Shift blue channel down */        for (y = frame->height-shift-1; y >= 0; y--) {                int ln = (y + shift) * rowBytes;  /* Next line offset */                int lc = y * rowBytes;            /* Current line offset */                for (x = 0; x < w; x++)                        rgb[ln+x*3+0] = rgb[lc+x*3+0]; /* Shift blue down */        }}/********************************************************************** * * OV511 data transfer, IRQ handler * **********************************************************************/static int ov511_move_data(struct usb_ov511 *ov511, urb_t *urb){        unsigned char *cdata;        int i, totlen = 0;        int aPackNum[10];        struct ov511_frame *frame;        unsigned char *pData;        int iPix;        PDEBUG (4, "Moving %d packets", urb->number_of_packets);        for (i = 0; i < urb->number_of_packets; i++) {                int n = urb->iso_frame_desc[i].actual_length;                int st = urb->iso_frame_desc[i].status;                urb->iso_frame_desc[i].actual_length = 0;                urb->iso_frame_desc[i].status = 0;                cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;                aPackNum[i] = n ? cdata[ov511->packet_size - 1] : -1;                if (!n || ov511->curframe == -1)                        continue;                if (st)                        PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);                frame = &ov511->frame[ov511->curframe];                                /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th                 * byte non-zero. The EOF packet has image width/height in the                 * 10th and 11th packets. The 9th bit is given as follows:                 *                 * bit 7: EOF                 *     6: compression enabled                 *     5: 422/420/400 modes                 *     4: 422/420/400 modes                 *     3: 1                 *     2: snapshot bottom on                 *     1: snapshot frame                 *     0: even/odd field                 */                /* Check for SOF/EOF packet */                if ((cdata[0] | cdata[1] | cdata[2] | cdata[3] |                      cdata[4] | cdata[5] | cdata[6] | cdata[7]) ||                     (~cdata[8] & 0x08))                        goto check_middle;                /* Frame end */                if (cdata[8] & 0x80) {                        struct timeval *ts;                        ts = (struct timeval *)(frame->data + MAX_FRAME_SIZE);                        do_gettimeofday (ts);                        PDEBUG(4, "Frame end, curframe = %d, packnum=%d, hw=%d, vw=%d",                                ov511->curframe, (int)(cdata[ov511->packet_size - 1]),                                (int)(cdata[9]), (int)(cdata[10]));                        if (frame->scanstate == STATE_LINES) {                                int iFrameNext;                                if (fix_rgb_offset)                                        fixFrameRGBoffset(frame);                                frame->grabstate = FRAME_DONE;                                if (waitqueue_active(&frame->wq)) {                                        frame->grabstate = FRAME_DONE;                                        wake_up_interruptible(&frame->wq);                                }                                /* If next frame is ready or grabbing,                                 * point to it */                                iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;                                if (ov511->frame[iFrameNext].grabstate == FRAME_READY                                    || ov511->frame[iFrameNext].grabstate == FRAME_GRABBING) {                                        ov511->curframe = iFrameNext;                                        ov511->frame[iFrameNext].scanstate = STATE_SCANNING;                                } else {                                        if (frame->grabstate == FRAME_DONE) {                                                PDEBUG(4, "Frame done! congratulations");                                        } else {                                                PDEBUG(4, "Frame not ready? state = %d",                                                        ov511->frame[iFrameNext].grabstate);                                        }                                        ov511->curframe = -1;                                }                        }                        /* Image corruption caused by misplaced frame->segment = 0                         * fixed by carlosf@conectiva.com.br                         */                } else {                        /* Frame start */                        PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);#if 0                        /* Make sure no previous data carries over; necessary                         * for compression experimentation */                        memset(frame->data, 0, MAX_DATA_SIZE);#endif                        output_offset = 0;                        /* Check to see if it's a snapshot frame */                        /* FIXME?? Should the snapshot reset go here? Performance? */                        if (cdata[8] & 0x02) {                                frame->snapshot = 1;                                PDEBUG(3, "snapshot detected");                        }                        frame->scanstate = STATE_LINES;                        frame->segment = 0;                }check_middle:                /* Are we in a frame? */                if (frame->scanstate != STATE_LINES)                        continue;                /* Deal with leftover from last segment, if any */                if (frame->segment) {                        pData = ov511->scratch;                        iPix = -ov511->scratchlen;                        memmove(pData + ov511->scratchlen, cdata,                                iPix+frame->segsize);                } else {                        pData = &cdata[iPix = 9];                }                /* Parse the segments */                while (iPix <= (ov511->packet_size - 1) - frame->segsize &&                    frame->segment < frame->width * frame->height / 256) {                        int iSegY, iSegUV;                        int iY, jY, iUV, jUV;                        int iOutY, iOutYP, iOutUV, iOutUVP;                        unsigned char *pOut;                        iSegY = iSegUV = frame->segment;                        pOut = frame->data;                        frame->segment++;                        iPix += frame->segsize;                        /* Handle subwindow */                        if (frame->sub_flag) {                                int iSeg1;                                iSeg1 = iSegY / (ov511->subw / 32);                                iSeg1 *= frame->width / 32;                                iSegY = iSeg1 + (iSegY % (ov511->subw / 32));                                if (iSegY >= frame->width * ov511->subh / 256)                                        break;                                iSeg1 = iSegUV / (ov511->subw / 16);                                iSeg1 *= frame->width / 16;                                iSegUV = iSeg1 + (iSegUV % (ov511->subw / 16));                                pOut += (ov511->subx + ov511->suby * frame->width) *                                        (frame->depth >> 3);                        }                        /*                          * i counts segment lines                         * j counts segment columns                         * iOut is the offset (in bytes) of the upper left corner                         */                        iY = iSegY / (frame->width / WDIV);                        jY = iSegY - iY * (frame->width / WDIV);                        iOutYP = iY*HDIV*frame->width + jY*WDIV;                        iOutY = iOutYP * (frame->depth >> 3);                        iUV = iSegUV / (frame->width / WDIV * 2);                        jUV = iSegUV - iUV * (frame->width / WDIV * 2);                        iOutUVP = iUV*HDIV*2*frame->width + jUV*WDIV/2;                        iOutUV = iOutUVP * (frame->depth >> 3);                        switch (frame->format) {                        case VIDEO_PALETTE_GREY:                                ov511_parse_data_grey (pData, pOut, iOutY, frame->width);                                break;                        case VIDEO_PALETTE_RGB24:                                if (dumppix)                                        ov511_dumppix(pData, pOut, iOutY, iOutUV,                                                iY & 1, frame->width);                                else if (sensor_gbr)                                        ov511_parse_gbr422_to_rgb24(pData, pOut, iOutY, iOutUV,                                                iY & 1, frame->width);                                else                                        ov511_parse_yuv420_to_rgb(pData, pOut, iOutY, iOutUV,                                                iY & 1, frame->width, 24);                                break;        

⌨️ 快捷键说明

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