diff options
author | David Hilvert <dhilvert@gmail.com> | 2008-04-16 03:27:09 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:09:40 -0400 |
commit | 1d3104b819979784df1da6ad76acef33cd9736e4 (patch) | |
tree | 7a6f1a303bf849c2c5e1f061f26ec76d758b5737 /drivers/media | |
parent | 17de9a4e53567912735105e189535f5d83e74a81 (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/media')
-rw-r--r-- | drivers/media/video/usbvideo/ibmcam.c | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c index 84ee6b1d9fd2..59166b760104 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 | */ | ||
805 | static enum ParseState ibmcam_model3_parse_lines( | 820 | static 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. |