Thread (23 messages) 23 messages, 5 authors, 2017-12-18

Re: [PATCH 3/5] media: i2c: Add TDA1997x HDMI receiver driver

From: Tim Harvey <hidden>
Date: 2017-11-23 04:27:17
Also in: alsa-devel, linux-media, lkml

On Mon, Nov 20, 2017 at 7:39 AM, Hans Verkuil [off-list ref] wrote:
Hi Tim,

Some more review comments:

On 11/09/2017 07:45 PM, Tim Harvey wrote:
quoted
Add support for the TDA1997x HDMI receivers.
<snip>
quoted
+ */
+struct color_matrix_coefs {
+     const char *name;
+     /* 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;
+};
+
+enum {
+     ITU709_RGBLIMITED,
+     ITU709_RGBFULL,
+     ITU601_RGBLIMITED,
+     ITU601_RGBFULL,
+     RGBLIMITED_RGBFULL,
+     RGBLIMITED_ITU601,
+     RGBFULL_ITU601,
This can't be right.
ITU709_RGBLIMITED
You have these conversions:

ITU709_RGBFULL
ITU601_RGBFULL
RGBLIMITED_RGBFULL
RGBLIMITED_ITU601
RGBFULL_ITU601
RGBLIMITED_ITU709
RGBFULL_ITU709

I.e. on the HDMI receiver side you can receive RGB full/limited or ITU601/709.
On the output side you have RGB full or ITU601/709.

So something like ITU709_RGBLIMITED makes no sense.
I misunderstood the V4L2_CID_DV_RX_RGB_RANGE thinking that it allowed
you to configure the output range. If output to the SoC is only ever
full quant range for RGB then I can drop the
ITU709_RGBLIMITED/ITU601_RGBLIMITED conversions.

However, If the output is YUV how do I know if I need to convert to
ITU709 or ITU601 and what are my conversion matrices for
RGBLIMITED_ITU709/RGBFULL_ITU709?

Sorry for all the questions, the colorspace/colorimetry options
confuse the heck out of me.
quoted
+};
+
<snip>
quoted
+
+/* parse an infoframe and do some sanity checks on it */
+static unsigned int
+tda1997x_parse_infoframe(struct tda1997x_state *state, u16 addr)
+{
+     struct v4l2_subdev *sd = &state->sd;
+     union hdmi_infoframe frame;
+     u8 buffer[40];
+     u8 reg;
+     int len, err;
+
+     /* read data */
+     len = io_readn(sd, addr, sizeof(buffer), buffer);
+     err = hdmi_infoframe_unpack(&frame, buffer);
+     if (err) {
+             v4l_err(state->client,
+                     "failed parsing %d byte infoframe: 0x%04x/0x%02x\n",
+                     len, addr, buffer[0]);
+             return err;
+     }
+     hdmi_infoframe_log(KERN_INFO, &state->client->dev, &frame);
+     switch (frame.any.type) {
+     /* Audio InfoFrame: see HDMI spec 8.2.2 */
+     case HDMI_INFOFRAME_TYPE_AUDIO:
+             /* sample rate */
+             switch (frame.audio.sample_frequency) {
+             case HDMI_AUDIO_SAMPLE_FREQUENCY_32000:
+                     state->audio_samplerate = 32000;
+                     break;
+             case HDMI_AUDIO_SAMPLE_FREQUENCY_44100:
+                     state->audio_samplerate = 44100;
+                     break;
+             case HDMI_AUDIO_SAMPLE_FREQUENCY_48000:
+                     state->audio_samplerate = 48000;
+                     break;
+             case HDMI_AUDIO_SAMPLE_FREQUENCY_88200:
+                     state->audio_samplerate = 88200;
+                     break;
+             case HDMI_AUDIO_SAMPLE_FREQUENCY_96000:
+                     state->audio_samplerate = 96000;
+                     break;
+             case HDMI_AUDIO_SAMPLE_FREQUENCY_176400:
+                     state->audio_samplerate = 176400;
+                     break;
+             case HDMI_AUDIO_SAMPLE_FREQUENCY_192000:
+                     state->audio_samplerate = 192000;
+                     break;
+             default:
+             case HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM:
+                     break;
+             }
+
+             /* sample size */
+             switch (frame.audio.sample_size) {
+             case HDMI_AUDIO_SAMPLE_SIZE_16:
+                     state->audio_samplesize = 16;
+                     break;
+             case HDMI_AUDIO_SAMPLE_SIZE_20:
+                     state->audio_samplesize = 20;
+                     break;
+             case HDMI_AUDIO_SAMPLE_SIZE_24:
+                     state->audio_samplesize = 24;
+                     break;
+             case HDMI_AUDIO_SAMPLE_SIZE_STREAM:
+             default:
+                     break;
+             }
+
+             /* Channel Count */
+             state->audio_channels = frame.audio.channels;
+             if (frame.audio.channel_allocation &&
+                 frame.audio.channel_allocation != state->audio_ch_alloc) {
+                     /* use the channel assignment from the infoframe */
+                     state->audio_ch_alloc = frame.audio.channel_allocation;
+                     tda1997x_configure_audout(sd, state->audio_ch_alloc);
+                     /* reset the audio FIFO */
+                     tda1997x_hdmi_info_reset(sd, RESET_AUDIO, false);
+             }
+             break;
+
+     /* Auxiliary Video information (AVI) InfoFrame: see HDMI spec 8.2.1 */
+     case HDMI_INFOFRAME_TYPE_AVI:
+             state->colorspace = frame.avi.colorspace;
+             state->colorimetry = frame.avi.colorimetry;
+             state->range = frame.avi.quantization_range;
This should be ignored if it is overridden by the RGB Quantization Range
control, or am I missing something?
Ok. Sounds like I should only use the range from the infoframe if
range == V4L2_DV_RGB_RANGE_AUTO:

                /* Quantization Range */
                if (state->range == V4L2_DV_RGB_RANGE_AUTO)
                        state->range = frame.avi.quantization_range;
                if (state->range == HDMI_QUANTIZATION_RANGE_DEFAULT) {
                        if (frame.avi.video_code <= 1)
                                state->range = HDMI_QUANTIZATION_RANGE_FULL;
                        else
                                state->range = HDMI_QUANTIZATION_RANGE_LIMITED;
                }

quoted
+             state->content = frame.avi.content_type;
+             /*
+              * If colorimetry not specified, conversion depends on res type:
+              *  - SDTV: ITU601 for SD (480/576/240/288 line resolution)
+              *  - HDTV: ITU709 for HD (720/1080 line resolution)
+              *  -   PC: sRGB
+              * see HDMI specification section 6.7
+              */
+             if ((state->colorspace == HDMI_COLORSPACE_YUV422 ||
+                  state->colorspace == HDMI_COLORSPACE_YUV444) &&
+                 (state->colorimetry == HDMI_COLORIMETRY_EXTENDED ||
+                  state->colorimetry == HDMI_COLORIMETRY_NONE)) {
+                     switch (state->timings.bt.height) {
+                     case 480:
+                     case 576:
+                     case 240:
+                     case 288:
+                             state->colorimetry = HDMI_COLORIMETRY_ITU_601;
+                             break;
+                     case 720:
+                     case 1080:
+                             state->colorimetry = HDMI_COLORIMETRY_ITU_709;
+                             break;
+                     default:
+                             state->colorimetry = HDMI_COLORIMETRY_NONE;
+                             break;
+                     }
+             }
+             /* if range not specified */
+             if (state->range == HDMI_QUANTIZATION_RANGE_DEFAULT) {
+                     if (frame.avi.video_code == 0)
This should be:

                        if (frame.avi.video_code <= 1)

VIC code 1 (VGA) is also full range. It's an exception to the rule.
ok

Thanks,

Tim
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help