I was testing IPU + MJPEG encoder and I encountered a small problem.
I took a 2592x1944 bitmap picture and extracted RGB raw data. I ran that data through RGB->YUV in IPU and then to MJPEG to generate one JPEG image. The output image appeared to be dull in contrast (as if looking through dirty glass).
Turns out IPU was not using the right RGB->YUV conversion coefficients. The current driver has generates Y in range of 16 to 235 using the following equations.
Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16
Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128
Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128
However, JPEG compression expects YUV (YCbCr) values to be in 0-255 range using the following conversion equation:
Y = (0.299 * R) + (0.587 * G) + (0.114 * B)
Cr = (0.5 * R) - (0.418688 * G) - (0.081312 * B) + 128
Cb = -(0.168736 * R) - (0.331264 * G) + (0.5 * B) + 128
Q1: My conclusion is that the currently included IPU driver is not compatible with MJPEG encoder as is and would require modification to use the right registers. Encoder will work but the colors will be incorrect. Is that right?
Q2: I noticed that IPU driver had 3 color spaces defined (ipu_color_space_t in ipu-v3.h): RGB, YUV, YCbCr. However, it appeared to interpret YUV pixel formats (ex. IPU_PIX_FMT_YUV422P) as YCbCr color space and YUV does not appear to be used (format_to_colorspace() function is ipu_common.c). There is even a comment line in ipu_ic.c file that says
/* TODO: Support YUV<->YCbCr conversion? */
What color space in the driver does YUV refer to? What about YCbCr? There seems to be mixing of color spaces because IPU_PIX_FMT_YUV... pixel formats are interpreted as in YCbCr color space instead of YUV.
Q3: What is the requirement for the H.264 encoder? What range of YUV values does it expect?