aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Hilvert <dhilvert@gmail.com>2008-04-16 03:27:09 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:40 -0400
commit1d3104b819979784df1da6ad76acef33cd9736e4 (patch)
tree7a6f1a303bf849c2c5e1f061f26ec76d758b5737 /drivers
parent17de9a4e53567912735105e189535f5d83e74a81 (diff)
V4L/DVB (7589): ibmcam: improve support for the IBM PC Camera Pro
This patch modifies Dmitri's original ibmcam driver for Linux to improve support for the IBM PC Camera Pro. It may also offer improved support for other models classified by the driver as 'Model 3', such as the IBM PC Camera Pro Max. See http://auricle.dyndns.org/xvp610/ Signed-off-by: David Hilvert <dhilvert@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/usbvideo/ibmcam.c62
1 files changed, 47 insertions, 15 deletions
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c
index 84ee6b1d9fd..59166b76010 100644
--- a/drivers/media/video/usbvideo/ibmcam.c
+++ b/drivers/media/video/usbvideo/ibmcam.c
@@ -802,6 +802,21 @@ static enum ParseState ibmcam_model2_320x240_parse_lines(
802 return scan_Continue; 802 return scan_Continue;
803} 803}
804 804
805/*
806 * ibmcam_model3_parse_lines()
807 *
808 * | Even lines | Odd Lines |
809 * -----------------------------------|
810 * |YYY........Y|UYVYUYVY.........UYVY|
811 * |YYY........Y|UYVYUYVY.........UYVY|
812 * |............|.....................|
813 * |YYY........Y|UYVYUYVY.........UYVY|
814 * |------------+---------------------|
815 *
816 * There is one (U, V) chroma pair for every four luma (Y) values. This
817 * function reads a pair of lines at a time and obtains missing chroma values
818 * from adjacent pixels.
819 */
805static enum ParseState ibmcam_model3_parse_lines( 820static enum ParseState ibmcam_model3_parse_lines(
806 struct uvd *uvd, 821 struct uvd *uvd,
807 struct usbvideo_frame *frame, 822 struct usbvideo_frame *frame,
@@ -816,6 +831,7 @@ static enum ParseState ibmcam_model3_parse_lines(
816 const int ccm = 128; /* Color correction median - see below */ 831 const int ccm = 128; /* Color correction median - see below */
817 int i, u, v, rw, data_w=0, data_h=0, color_corr; 832 int i, u, v, rw, data_w=0, data_h=0, color_corr;
818 static unsigned char lineBuffer[640*3]; 833 static unsigned char lineBuffer[640*3];
834 int line;
819 835
820 color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ 836 color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
821 RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1); 837 RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);
@@ -869,15 +885,15 @@ static enum ParseState ibmcam_model3_parse_lines(
869 return scan_NextFrame; 885 return scan_NextFrame;
870 } 886 }
871 887
872 /* Make sure there's enough data for the entire line */ 888 /* Make sure that lineBuffer can store two lines of data */
873 len = 3 * data_w; /* <y-data> <uv-data> */ 889 len = 3 * data_w; /* <y-data> <uyvy-data> */
874 assert(len <= sizeof(lineBuffer)); 890 assert(len <= sizeof(lineBuffer));
875 891
876 /* Make sure there's enough data for the entire line */ 892 /* Make sure there's enough data for two lines */
877 if (RingQueue_GetLength(&uvd->dp) < len) 893 if (RingQueue_GetLength(&uvd->dp) < len)
878 return scan_Out; 894 return scan_Out;
879 895
880 /* Suck one line out of the ring queue */ 896 /* Suck two lines of data out of the ring queue */
881 RingQueue_Dequeue(&uvd->dp, lineBuffer, len); 897 RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
882 898
883 data = lineBuffer; 899 data = lineBuffer;
@@ -887,15 +903,23 @@ static enum ParseState ibmcam_model3_parse_lines(
887 rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1; 903 rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1;
888 RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1); 904 RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1);
889 905
890 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) { 906 /* Iterate over two lines. */
891 int y, rv, gv, bv; /* RGB components */ 907 for (line = 0; line < 2; line++) {
908 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
909 int y;
910 int rv, gv, bv; /* RGB components */
892 911
893 if (i < data_w) { 912 if (i >= data_w) {
894 y = data[i]; /* Luminosity is the first line */ 913 RGB24_PUTPIXEL(frame, i, rw, 0, 0, 0);
914 continue;
915 }
916
917 /* first line is YYY...Y; second is UYVY...UYVY */
918 y = data[(line == 0) ? i : (i*2 + 1)];
895 919
896 /* Apply static color correction */ 920 /* Apply static color correction */
897 u = color[i*2] + hue_corr; 921 u = color[(i/2)*4] + hue_corr;
898 v = color[i*2 + 1] + hue2_corr; 922 v = color[(i/2)*4 + 2] + hue2_corr;
899 923
900 /* Apply color correction */ 924 /* Apply color correction */
901 if (color_corr != 0) { 925 if (color_corr != 0) {
@@ -903,13 +927,21 @@ static enum ParseState ibmcam_model3_parse_lines(
903 u = 128 + ((ccm + color_corr) * (u - 128)) / ccm; 927 u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;
904 v = 128 + ((ccm + color_corr) * (v - 128)) / ccm; 928 v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;
905 } 929 }
906 } else
907 y = 0, u = v = 128;
908 930
909 YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv); 931
910 RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* Done by deinterlacing now */ 932 YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);
933 RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* No deinterlacing */
934 }
935
936 /* Check for the end of requested data */
937 if (rw == 0)
938 break;
939
940 /* Prepare for the second line */
941 rw--;
942 data = lineBuffer + data_w;
911 } 943 }
912 frame->deinterlace = Deinterlace_FillEvenLines; 944 frame->deinterlace = Deinterlace_None;
913 945
914 /* 946 /*
915 * Account for number of bytes that we wrote into output V4L frame. 947 * Account for number of bytes that we wrote into output V4L frame.