aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 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 */
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.