Web lists-archives.com

[Spca50x-devs] [PATCH] VC0323 YVYU and rotation quirks




Hi,

Please ignore my previous patch for this extra-quirky camera. The
attached patches make it work without breaking regular VC0323 cameras
with JPGV output by adding two module parameters, one to force YVYU
decoding for VC0323 (much like the VC0321, but it identifies itself as
0ac8:0323 and uses a different image offset) and other to decode to
YUV, RGB15, RGB24 and RGB32 while rotating the image 180 degrees
(since the sensor seems to be mounted upside-down in the camera).

For the record, this is a no-brand, very cheap-looking black/silver
plastic camera with four white leds and a foldable claw-like tripod.
One quirk still remains: it produces RGB when it's supposed to produce
BGR and vice versa, so force_rgb=1 is needed by spcaview but not
gqcam. I'm not sure if this is a problem with my camera or all other
cameras using yvyu_translate() are affected, so I didn't try to fix
it.

Best regards,
Claudio
diff -rud gspcav1-20071224-orig/decoder/gspcadecoder.c gspcav1-20071224/decoder/gspcadecoder.c
--- gspcav1-20071224-orig/decoder/gspcadecoder.c	2007-12-24 11:35:27.000000000 -0200
+++ gspcav1-20071224/decoder/gspcadecoder.c	2008-02-03 21:03:15.000000000 -0200
@@ -2692,6 +2692,10 @@
     	memcpy(myframe->tmpbuffer, myframe->data, myframe->scanlength);
     	done= yvyu_translate(myframe,bgr);
     	break;
+    case YUY3:
+    	memcpy(myframe->tmpbuffer, myframe->data + 0x20, myframe->scanlength);
+    	done= yvyu_translate(myframe, bgr);
+    	break;
     case PGBRG:
 	done = pixart_decompress(myframe);
 	if (done < 0)
diff -rud gspcav1-20071224-orig/gspca.h gspcav1-20071224/gspca.h
--- gspcav1-20071224-orig/gspca.h	2007-12-24 14:56:47.000000000 -0200
+++ gspcav1-20071224/gspca.h	2008-02-03 21:33:45.000000000 -0200
@@ -177,6 +177,7 @@
 	S561,			// Sunplus Compressed stream
 	PGBRG,			// Pixart RGGB bayer
 	YUY2, 			// YUYV packed
+	YUY3,			// Vimicro VC0323 YUYV packed
 	PJPG, 			// Pixart jpeg used with PAC7311
 	JPGV, 			// Vimicro VC0323
 };
@@ -258,6 +259,7 @@
 	int GRed;
 	int GBlue;
 	int GGreen;
+	int rotate;
 };
 #define MAXCOMP 4
 struct dec_hufftbl;
diff -rud gspcav1-20071224-orig/gspca_core.c gspcav1-20071224/gspca_core.c
--- gspcav1-20071224-orig/gspca_core.c	2007-12-24 14:56:47.000000000 -0200
+++ gspcav1-20071224/gspca_core.c	2008-02-03 21:05:06.000000000 -0200
@@ -82,6 +82,7 @@
 /* Force image to be read in RGB instead of BGR. This option allow
 * programs that expect RGB data (e.g. gqcam) to work with this driver. */
 static int force_rgb = 0;
+static int force_yuv = 0;
 static int gamma = 3;
 static int OffRed = 0;
 static int OffBlue = 0;
@@ -108,6 +109,7 @@
 module_param(autoexpo, int, 0644);
 module_param(debug, int, 0644);
 module_param(force_rgb, int, 0644);
+module_param(force_yuv, int, 0644);
 module_param(gamma, int, 0644);
 module_param(OffRed, int, 0644);
 module_param(OffBlue, int, 0644);
@@ -133,6 +135,7 @@
 MODULE_PARM_DESC(debug,
 		 "Debug level: 0=none, 1=init/detection, 2=warning, 3=config/control, 4=function call, 5=max");
 MODULE_PARM_DESC(force_rgb, "Read RGB instead of BGR");
+MODULE_PARM_DESC(force_yuv, "Force YUV decoding in VC0323");
 MODULE_PARM_DESC(gamma, "gamma setting range 0 to 7 3-> gamma=1");
 MODULE_PARM_DESC(OffRed, "OffRed setting range -128 to 128");
 MODULE_PARM_DESC(OffBlue, "OffBlue setting range -128 to 128");
@@ -190,6 +193,7 @@
 	{S561, "S561"},
 	{PGBRG,"GBRG"},
 	{YUY2, "YUYV"},
+	{YUY3, "YUYV"},
 	{PJPG, "JPEG"},
 	{-1, NULL}
 };
@@ -2917,7 +2921,7 @@
 		break;
 	case BRIDGE_VC0323:
 		spca50x->epadr = 2;
-		spca50x->cameratype = JPGV;
+		spca50x->cameratype = force_yuv ? YUY3 : JPGV;
 		info("USB GSPCA camera found.(VC0323) ");
 		memcpy(&spca50x->funct, &fvc0321,
 		       sizeof (struct cam_operation));
diff -rud gspcav1-20071224-orig/decoder/gspcadecoder.c gspcav1-20071224/decoder/gspcadecoder.c
--- gspcav1-20071224-orig/decoder/gspcadecoder.c	2008-02-03 23:19:23.000000000 -0200
+++ gspcav1-20071224/decoder/gspcadecoder.c	2008-02-03 23:04:13.000000000 -0200
@@ -2508,6 +2508,7 @@
 
 
 static int bgr = 0;
+static int rot = 0;
 
 
 
@@ -2557,6 +2558,7 @@
 
 	    }
 	    bgr = gCorrect->force_rgb;
+	    rot = gCorrect->rotate;
 	    gCorrect->change = 0x00;
 	}
 	if (gCorrect->change == 0x02) {
@@ -4239,6 +4241,7 @@
 	char u, v;
     char r, g, b;
     int framesize, frameUsize;
+    int step = 1;
 
     framesize = softwidth * softheight;
     frameUsize = framesize >> 2;
@@ -4259,12 +4262,14 @@
 	g_offset = 1;
 	b_offset = 0;
     }
+
     /* initialize input pointer */
     inl = 0;
     inl1= width << 1;
     pic1= pic+softwidth;
     nextinline = width << 1;
     nextoutline = softwidth;
+
     /* Decode to the correct format. */
     switch (format) {
    case VIDEO_PALETTE_RGB565:
@@ -4273,6 +4278,11 @@
 	    /* initialize */
 	    pix = (__u16 *) pic;
 
+            if (rot) {
+	        step = -1;
+	        pix += softwidth * softheight - 1;
+            }
+
 	    for (my = 0; my < height; my ++) {
 		for (mx = 0; mx < width; mx += 2) {
 		    /* test if we need to decode */
@@ -4292,17 +4302,19 @@
 			g = green[CLIP((y - rg))];
 			b = blue[CLIP((y + u1))];
 			if (force_rgb)
-			    *pix++ = PACKRGB16(r, g, b);
+			    *pix = PACKRGB16(r, g, b);
 			else
-			    *pix++ = PACKRGB16(b, g, r);
+			    *pix = PACKRGB16(b, g, r);
+			pix += step;
 			y = buf[inl+mx*2+2];
 			r = red[CLIP((y + v1))];
 		    	g = green[CLIP((y - rg))];
 			b = blue[CLIP((y + u1))];
 			if (force_rgb)
-			    *pix++ = PACKRGB16(r, g, b);
+			    *pix = PACKRGB16(r, g, b);
 			else
-			    *pix++ = PACKRGB16(b, g, r);
+			    *pix = PACKRGB16(b, g, r);
+			pix += step;
 			
 		    }
 		}		// end mx loop
@@ -4316,6 +4328,12 @@
    case VIDEO_PALETTE_RGB24:
 	{
 	    bpp = (format == VIDEO_PALETTE_RGB32) ? 4 : 3;
+
+            if (rot) {
+	        step = -1;
+	        pic += (softwidth * softheight - 1) * bpp;
+            }
+
 	    /* initialize */
 	    nextoutline = bpp * softwidth;
 	    for (my = 0; my < height; my ++ ) {
@@ -4337,12 +4355,12 @@
 			pic[r_offset] = red[CLIP((y + v1))];
 			pic[g_offset] = green[CLIP((y - rg))];
 			pic[b_offset] = blue[CLIP((y + u1))];
-			pic+=bpp;
+			pic+=bpp * step;
 			y = buf[inl+mx*2+2];
 			pic[r_offset] = red[CLIP((y + v1))];
 		    	pic[g_offset] = green[CLIP((y - rg))];
 			pic[b_offset] = blue[CLIP((y + u1))];
-			pic+=bpp;
+			pic+=bpp * step;
 		    }		// end test decode
 		}		// end mx loop
 		inl += nextinline;
@@ -4358,6 +4376,14 @@
 	break;
    case VIDEO_PALETTE_YUV420P:
 	{			/* Not yet implemented */
+            if (rot) {
+	        step = -1;
+	        pic += framesize - 1;
+	        pic1 = pic - softwidth;
+	        U += frameUsize - 1;
+	        V += frameUsize - 1;
+            }
+
 	    for (my = 0; my < height; my +=2) {
 		for (mx = 0; mx < width; mx += 2) {
 		    /* test if we need to decode */
@@ -4365,21 +4391,29 @@
 			&& (my < height - cropy2)
 			&& (mx >= cropx1)
 			&& (mx < width - cropx2)) {
-			*pic++ = buf[inl+mx*2+0];
-			*U++=buf[inl+mx*2+1];
-			*pic++ = buf[inl+mx*2+2];
-			*V++=buf[inl+mx*2+3];
-			*pic1++ = buf[inl1+mx*2+0];
-			*pic1++ = buf[inl1+mx*2+2];
-			
+			if (rot) {
+			    *pic-- = buf[inl+mx*2+0];
+			    *U--=buf[inl+mx*2+1];
+			    *pic-- = buf[inl+mx*2+2];
+			    *V--=buf[inl+mx*2+3];
+			    *pic1-- = buf[inl1+mx*2+0];
+			    *pic1-- = buf[inl1+mx*2+2];
+			} else {
+			    *pic++ = buf[inl+mx*2+0];
+			    *U++=buf[inl+mx*2+1];
+			    *pic++ = buf[inl+mx*2+2];
+			    *V++=buf[inl+mx*2+3];
+			    *pic1++ = buf[inl1+mx*2+0];
+			    *pic1++ = buf[inl1+mx*2+2];
+			}
 		    }		// end test decode
 		}		// end mx loop
 		inl += (nextinline << 1);
 		inl1 += (nextinline << 1);
 		if (my >= cropy1) {
 		    /* are we in a decode surface move the output pointer */
-		    pic += (nextoutline);
-		    pic1 += (nextoutline);
+		    pic += (nextoutline) * step;
+		    pic1 += (nextoutline) * step;
 		}
 
 	    }			// end my loop
diff -rud gspcav1-20071224-orig/gspca_core.c gspcav1-20071224/gspca_core.c
--- gspcav1-20071224-orig/gspca_core.c	2008-02-03 23:19:23.000000000 -0200
+++ gspcav1-20071224/gspca_core.c	2008-02-03 23:22:37.000000000 -0200
@@ -83,6 +83,7 @@
 * programs that expect RGB data (e.g. gqcam) to work with this driver. */
 static int force_rgb = 0;
 static int force_yuv = 0;
+static int rotate = 0;
 static int gamma = 3;
 static int OffRed = 0;
 static int OffBlue = 0;
@@ -110,6 +111,7 @@
 module_param(debug, int, 0644);
 module_param(force_rgb, int, 0644);
 module_param(force_yuv, int, 0644);
+module_param(rotate, int, 0644);
 module_param(gamma, int, 0644);
 module_param(OffRed, int, 0644);
 module_param(OffBlue, int, 0644);
@@ -136,6 +138,7 @@
 		 "Debug level: 0=none, 1=init/detection, 2=warning, 3=config/control, 4=function call, 5=max");
 MODULE_PARM_DESC(force_rgb, "Read RGB instead of BGR");
 MODULE_PARM_DESC(force_yuv, "Force YUV decoding in VC0323");
+MODULE_PARM_DESC(rotate, "Rotate output 180 degrees in YVYU decoding");
 MODULE_PARM_DESC(gamma, "gamma setting range 0 to 7 3-> gamma=1");
 MODULE_PARM_DESC(OffRed, "OffRed setting range -128 to 128");
 MODULE_PARM_DESC(OffBlue, "OffBlue setting range -128 to 128");
@@ -1822,6 +1825,7 @@
 	memset(&spca50x->pictsetting, 0, sizeof (struct pictparam));
 	spca50x->pictsetting.change = 0x01;
 	spca50x->pictsetting.force_rgb = force_rgb;
+	spca50x->pictsetting.rotate = rotate;
 	spca50x->pictsetting.gamma = gamma;
 	spca50x->pictsetting.OffRed = OffRed;
 	spca50x->pictsetting.OffBlue = OffBlue;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Spca50x-devs mailing list
Spca50x-devs@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/spca50x-devs