[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-usb
Subject: [linux-usb] [patch] ov511 1.18
From: Mark McClelland <mmcclelland () delphi ! com>
Date: 2000-06-29 4:25:48
[Download RAW message or body]
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
mmcclelland@delphi.com
["ov511_1.18-2.4.0-test2-ac2.patch" (text/plain)]
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: linux-usb-unsubscribe@suse.com
For additional commands, e-mail: linux-usb-help@suse.com
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic