diff options
-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. |