Hi Rogerio,
I figured out what numbers to put there to get me where I want to be. I did that by treating it as a black box and derived relationships between inputs and outputs. It is my understanding that the documentation improperly describes encoding of negative coefficients in both cases: for Cxx terms and for Ax terms. Positive coefficients seem to be OK. I was waiting for you to post a more comprehensive reply on the community than me just providing a fix that works for me. I need to do a conversion both ways between RGB and YUV. I found that G2D YUV->RGB conversion runs quite a bit faster than on IPU even when using both IPU's on iMX6. It would be great if G2D could provide both ways conversion and also using libjpeg coefficients. Here is my patch that applies the same CSC coefficients as used in libjpeg if it can be useful for somebody else.
diff --git a/drivers/mxc/ipu3/ipu_ic.c b/drivers/mxc/ipu3/ipu_ic.c
index 09cd04e..7d24f22 100644
--- a/drivers/mxc/ipu3/ipu_ic.c
+++ b/drivers/mxc/ipu3/ipu_ic.c
@@ -732,15 +732,15 @@ static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in
ipu_color_space_t out_format, int csc_index)
{
/*
- * Y = 0.257 * R + 0.504 * G + 0.098 * B + 16;
- * U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
- * V = 0.439 * R - 0.368 * G - 0.071 * B + 128;
+ * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
+ * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128
+ * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128
*/
static const uint32_t rgb2ycbcr_coeff[4][3] = {
- {0x0042, 0x0081, 0x0019},
- {0x01DA, 0x01B6, 0x0070},
- {0x0070, 0x01A2, 0x01EE},
- {0x0040, 0x0200, 0x0200}, /* A0, A1, A2 */
+ {77, 150, 29},
+ {469, 427, 128}, /* 469 and 427 had to be fudged to produce required results, do not agree with documented calculation in imx6 ref. manual */
+ {128, 405, 491}, /* 405 and 491 had to be fudged */
+ {0, 512, 512}, /* A0, A1, A2 */
};
/* transparent RGB->RGB matrix for combining
@@ -752,14 +752,14 @@ static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in
{0x0000, 0x0000, 0x0000}, /* A0, A1, A2 */
};
-/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
- G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
- B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
+ /* R = Y + 1.40200 * Cr
+ * G = Y - 0.34414 * Cb - 0.71414 * Cr
+ * B = Y + 1.77200 * Cb */
static const uint32_t ycbcr2rgb_coeff[4][3] = {
- {149, 0, 204},
- {149, 462, 408},
- {149, 255, 0},
- {8192 - 446, 266, 8192 - 554}, /* A0, A1, A2 */
+ {128, 0, 179},
+ {128, 468, 421}, /* 468 and 421 had to be fudged */
+ {128, 227, 0},
+ {8192-359, 270, 8192-454}, /* A0, A1, A2; A0 and A2 had to be fudged */
};
uint32_t param;
Regards,
Alex