This is against 2.4.0test2-ac2 SUMMARY: o Preliminary support for YUV422 and YUV422P V4L modes CHANGES: >From Claudio's 1.17cm1 patch: - Added support to YUV422P - Enforced width/height limits in VIDIOCMCAPTURE - Minor cleanup Mark's changes: - Added ov511_parse_data_yuv422() (Still needs some work) - Modified ov511_move_data(), GET_DEPTH(), and VIDIOCMCAPTURE for YUV422 -- Mark McClelland [EMAIL PROTECTED]
diff -Naur linux-2.4.0-test2-ac2-orig/Documentation/usb/ov511.txt linux/Documentation/usb/ov511.txt --- linux-2.4.0-test2-ac2-orig/Documentation/usb/ov511.txt Wed Jun 28 17:48:17 2000 +++ linux/Documentation/usb/ov511.txt Wed Jun 28 17:48:28 2000 @@ -6,7 +6,7 @@ Homepage: http://alpha.dyndns.org/ov511 NEW IN THIS VERSION: - o Race conditions and other bugs fixed + o Preliminary support for YUV422 and YUV422P V4L modes INTRODUCTION: @@ -209,7 +209,7 @@ o Setting of contrast and brightness not working with 7620 o Driver/camera state save/restore for when USB supports suspend/resume o Multiple cameras reportedly do not work simultaneously - o Problems with OHCI + o Unstable on SMP systems HOW TO CONTACT ME: diff -Naur linux-2.4.0-test2-ac2-orig/drivers/usb/ov511.c linux/drivers/usb/ov511.c --- linux-2.4.0-test2-ac2-orig/drivers/usb/ov511.c Wed Jun 28 15:40:22 2000 +++ linux/drivers/usb/ov511.c Wed Jun 28 16:02:17 2000 @@ -30,7 +30,7 @@ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -static const char version[] = "1.17"; +static const char version[] = "1.18"; #define __NO_VERSION__ @@ -49,10 +49,6 @@ #include <asm/semaphore.h> #include <linux/wrapper.h> -#ifdef CONFIG_KMOD -#include <linux/kmod.h> -#endif - #include "ov511.h" #undef OV511_GBR422 /* Experimental -- sets the 7610 to GBR422 */ @@ -67,7 +63,7 @@ #define DEFAULT_HEIGHT 480 #define GET_SEGSIZE(p) ((p) == VIDEO_PALETTE_GREY ? 256 : 384) -#define GET_DEPTH(p) ((p) == VIDEO_PALETTE_GREY ? 8 : 24) +#define GET_DEPTH(p) ((p) == VIDEO_PALETTE_GREY ? 8 : ((p) == VIDEO_PALETTE_YUV422 ? +8 : 24)) /* PARAMETER VARIABLES: */ static int autoadjust = 1; /* CCD dynamically changes exposure, etc... */ @@ -626,6 +622,7 @@ ov511_dump_i2c_range(dev, 0x00, 0x38); } +#if 0 static void ov511_dump_reg_range(struct usb_device *dev, int reg1, int regn) { int i; @@ -636,7 +633,6 @@ } } -#if 0 static void ov511_dump_regs(struct usb_device *dev) { PDEBUG(1, "CAMERA INTERFACE REGS"); @@ -1088,7 +1084,7 @@ #ifdef OV511_GBR422 static void ov511_parse_data_rgb24(unsigned char *pIn0, unsigned char *pOut0, - int iOutY, int iOutUV, int iHalf, int iWidth) + int iOutY, int iOutUV, int iHalf, int iWidth) { int k, l, m; unsigned char *pIn; @@ -1138,7 +1134,7 @@ static void ov511_parse_data_rgb24(unsigned char *pIn0, unsigned char *pOut0, - int iOutY, int iOutUV, int iHalf, int iWidth) + int iOutY, int iOutUV, int iHalf, int iWidth) { #ifndef OV511_DUMPPIX int k, l, m; @@ -1231,6 +1227,139 @@ } #endif +static void +ov511_parse_data_yuv422(unsigned char *pIn0, unsigned char *pOut0, + int iOutY, int iOutUV, int iHalf, int iWidth) +{ + int k, l, m; + unsigned char *pIn; + unsigned char *pOut, *pOut1; + + /* Just copy the Y's if in the first stripe */ + if (!iHalf) { + 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++) & 0xF0; + } + pOut1 += iWidth - 8; + } + pOut += 8; + } + } + + /* Use the first half of VUs to calculate value */ + pIn = pIn0; + pOut = pOut0 + iOutUV; + for (l = 0; l < 4; l++) { + for (m=0; m<8; m++) { + unsigned char *p00 = pOut; + unsigned char *p01 = pOut+1; + unsigned char *p10 = pOut+iWidth; + unsigned char *p11 = pOut+iWidth+1; + int v = *(pIn+64) - 128; + int u = *pIn++ - 128; + int uv = ((u >> 4) & 0x0C) + (v >> 6); + + *p00 |= uv; + *p01 |= uv; + *p10 |= uv; + *p11 |= uv; + + pOut += 2; + } + pOut += (iWidth*2 - 16); + } + + /* Just copy the other UV rows */ + for (l = 0; l < 4; l++) { + for (m = 0; m < 8; m++) { + int v = *(pIn + 64) - 128; + int u = (*pIn++) - 128; + int uv = ((u >> 4) & 0x0C) + (v >> 6); + *(pOut) = uv; + pOut += 2; + } + pOut += (iWidth*2 - 16); + } + + /* Calculate values if it's the second half */ + if (iHalf) { + pIn = pIn0 + 128; + pOut = pOut0 + iOutY; + for (k = 0; k < 4; k++) { + pOut1 = pOut; + for (l=0; l<4; l++) { + for (m=0; m<4; m++) { + int y10 = *(pIn+8); + int y00 = *pIn++; + int y11 = *(pIn+8); + int y01 = *pIn++; + int uv = *pOut1; + + *pOut1 = (y00 & 0xF0) | uv; + *(pOut1+1) = (y01 & 0xF0) | uv; + *(pOut1+iWidth) = (y10 & 0xF0) | uv; + *(pOut1+iWidth+1) = (y11 & 0xF0) | uv; + + pOut1 += 2; + } + pOut1 += (iWidth*2 - 8); + pIn += 8; + } + pOut += 8; + } + } +} + +static void +ov511_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: @@ -1432,7 +1561,7 @@ frame->segment < frame->width * frame->height / 256) { int iSegY, iSegUV; int iY, jY, iUV, jUV; - int iOutY, iOutUV; + int iOutY, iOutYP, iOutUV, iOutUVP; unsigned char *pOut; iSegY = iSegUV = frame->segment; @@ -1465,10 +1594,12 @@ */ iY = iSegY / (frame->width / WDIV); jY = iSegY - iY * (frame->width / WDIV); - iOutY = (iY*HDIV*frame->width + jY*WDIV) * (frame->depth >> 3); + 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); - iOutUV = (iUV*HDIV*2*frame->width + jUV*WDIV/2) * (frame->depth >> 3); + iOutUVP = iUV*HDIV*2*frame->width + jUV*WDIV/2; + iOutUV = iOutUVP * (frame->depth >> 3); switch (frame->format) { case VIDEO_PALETTE_GREY: @@ -1478,6 +1609,16 @@ ov511_parse_data_rgb24 (pData, pOut, iOutY, iOutUV, iY & 1, frame->width); break; + case VIDEO_PALETTE_YUV422: + ov511_parse_data_yuv422(pData, pOut, iOutY, iOutUV, + iY & 1, frame->width); + break; + case VIDEO_PALETTE_YUV422P: + ov511_parse_data_yuv422p (pData, pOut, iOutYP, +iOutUVP/2, + frame->width, frame->height); + break; + default: + err("Unsupported format: %d", frame->format); } pData = &cdata[iPix]; @@ -1995,17 +2136,22 @@ if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) return -EFAULT; - PDEBUG(4, "MCAPTURE"); + PDEBUG(4, "CMCAPTURE"); PDEBUG(4, "frame: %d, size: %dx%d, format: %d", vm.frame, vm.width, vm.height, vm.format); if (vm.format != VIDEO_PALETTE_RGB24 && + vm.format != VIDEO_PALETTE_YUV422 && + vm.format != VIDEO_PALETTE_YUV422P && vm.format != VIDEO_PALETTE_GREY) return -EINVAL; if ((vm.frame != 0) && (vm.frame != 1)) return -EINVAL; + if (vm.width > DEFAULT_WIDTH || vm.height > DEFAULT_HEIGHT) + return -EINVAL; + if (ov511->frame[vm.frame].grabstate == FRAME_GRABBING) return -EBUSY;
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
