On Mon, Oct 23, 2017 at 10:05 AM, Tim Harvey tharvey@gateworks.com wrote:
On Fri, Oct 20, 2017 at 9:23 AM, Hans Verkuil hverkuil@xs4all.nl wrote:
I see the AVI infoframe has hdmi_quantization_range and hdmi_ycc_quantization_range along with vid_code.
I'm not at all clear what to do with this information. Is there anything you see in the datasheet [1] that points to something I need to be doing?
You can ignore hdmi_ycc_quantization_range, it is the hdmi_quantization_range that you need to read out.
The TDA can receive the following formats:
RGB Full Range RGB Limited Range YUV Bt.601 (aka SMPTE 170M) YUV Rec.709
The YUV formats are always limited range.
The TDA can transmit RGB and YUV to the SoC. You want RGB to be full range and YUV to be limited range. YUV can be either 601 or 709.
So if the TDA transmits RGB then you need to support the following conversions:
RGB Full -> RGB Full RGB Limited -> RGB Full YUV 601 -> RGB Full YUV 709 -> RGB Full
And if the TDA transmits YUV then you need these conversions:
RGB Full -> YUV601 or YUV709 RGB Limited -> YUV601 or YUV709 YUV601 -> YUV601 YUV709 -> YUV709
For the RGB to YUV conversion you have a choice of converting to YUV601 or 709. I recommend to either always convert to YUV601 or to let it depend on the resolution (SDTV YUV601, HDTV YUV709).
Ok - this is a good explanation that I should be able to follow. I will make sure to take into account hdmi_quantization_range when I setup the colorspace conversion matrix for v3.
Hans,
I'm having trouble figuring out the conversion matrix to use between limited and full.
Currently I have the following conversion matrices, the values which came from some old vendor code:
/* Colorspace conversion matrix coefficients and offsets */ struct color_matrix_coefs { /* Input offsets */ s16 offint1; s16 offint2; s16 offint3; /* Coeficients */ s16 p11coef; s16 p12coef; s16 p13coef; s16 p21coef; s16 p22coef; s16 p23coef; s16 p31coef; s16 p32coef; s16 p33coef; /* Output offsets */ s16 offout1; s16 offout2; s16 offout3; }; /* Conversion matrixes */ enum { ITU709_RGBLIMITED, ITU601_RGBLIMITED, RGBLIMITED_ITU601, }; static const struct color_matrix_coefs conv_matrix[] = { /* ITU709 -> RGBLimited */ { -256, -2048, -2048, 4096, -1875, -750, 4096, 6307, 0, 4096, 0, 7431, 256, 256, 256, }, /* YUV601 limited -> RGB limited */ { -256, -2048, -2048, 4096, -2860, -1378, 4096, 5615, 0, 4096, 0, 7097, 256, 256, 256, }, /* RGB limited -> ITU601 */ { -256, -256, -256, 2404, 1225, 467, -1754, 2095, -341, -1388, -707, 2095, 256, 2048, 2048, }, };
Assuming the above are correct this leaves me missing RGB limitted -> RGB full, YUV601 -> RGB full, YUV709 -> RGB full, and RGB Full -> YUV601.
I don't have documentation for the registers but I'm assuming the input offset is applied first, then the multiplication by the coef, then the output offset is applied. I'm looking over https://en.wikipedia.org/wiki/YUV for colorspace conversion matrices but I'm unable to figure out how to apply those to the above. Any ideas?
Thanks,
Tim