This is an automatic generated email to let you know that the following patch were queued:
Subject: edid-decode: improve preferred/native video timing reporting Author: Hans Verkuil <hverkuil-ci...@xs4all.nl> Date: Wed May 25 12:31:34 2022 +0200 Depending on which CTA-861 version the EDID parser of the Sink is based on, the results for preferred and native video timing might well be different. Report the various possibilities depending on which CTA-861 version is used in the parser. Signed-off-by: Hans Verkuil <hverkuil-ci...@xs4all.nl> edid-decode.cpp | 37 +++++++++++++++++++- edid-decode.h | 8 +++-- parse-cta-block.cpp | 99 +++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 111 insertions(+), 33 deletions(-) --- diff --git a/edid-decode.cpp b/edid-decode.cpp index b7fe57ad8474..b3c6c088f4cb 100644 --- a/edid-decode.cpp +++ b/edid-decode.cpp @@ -1216,6 +1216,15 @@ void edid_state::print_preferred_timings() print_timings(" ", *iter, true, false); } + if (!cta.preferred_timings_vfpdb.empty()) { + printf("\n----------------\n"); + printf("\nPreferred Video Timing%s if Block 0 and CTA-861 Blocks are parsed with VFPDB support:\n", + cta.preferred_timings_vfpdb.size() > 1 ? "s" : ""); + for (vec_timings_ext::iterator iter = cta.preferred_timings_vfpdb.begin(); + iter != cta.preferred_timings_vfpdb.end(); ++iter) + print_timings(" ", *iter, true, false); + } + if (!dispid.preferred_timings.empty()) { printf("\n----------------\n"); printf("\nPreferred Video Timing%s if Block 0 and DisplayID Blocks are parsed:\n", @@ -1230,7 +1239,7 @@ void edid_state::print_native_res() { typedef std::pair<unsigned, unsigned> resolution; typedef std::set<resolution> resolution_set; - resolution_set native_prog, native_int; + resolution_set native_prog, native_int, native_nvrdb; unsigned native_width = 0, native_height = 0; unsigned native_width_int = 0, native_height_int = 0; @@ -1286,6 +1295,24 @@ void edid_state::print_native_res() } } + for (vec_timings_ext::iterator iter = cta.native_timing_nvrdb.begin(); + iter != cta.native_timing_nvrdb.end(); ++iter) { + if (iter->t.interlaced) { + fail("Interlaced native timing in NVRDB.\n"); + } else { + native_nvrdb.insert(std::pair<unsigned, unsigned>(iter->t.hact, iter->t.vact)); + if (!native_width) { + native_width = iter->t.hact; + native_height = iter->t.vact; + native_mismatch = true; + } else if (native_width && + (iter->t.hact != native_width || + iter->t.vact != native_height)) { + native_mismatch = true; + } + } + } + if (diagonal) { if (image_width) { double w = image_width; @@ -1359,6 +1386,14 @@ void edid_state::print_native_res() printf(" %ux%ui\n", iter->first, iter->second); } + if (!cta.native_timing_nvrdb.empty()) { + printf("\n----------------\n"); + printf("\nNative Video Resolution if Block 0 and CTA-861 Blocks are parsed with NVRDB support:\n"); + for (resolution_set::iterator iter = native_nvrdb.begin(); + iter != native_nvrdb.end(); ++iter) + printf(" %ux%u\n", iter->first, iter->second); + } + if (dispid.native_width) { printf("\n----------------\n"); printf("\nNative Video Resolution if the DisplayID Blocks are parsed:\n"); diff --git a/edid-decode.h b/edid-decode.h index bdc6ab67c752..e075c83d7220 100644 --- a/edid-decode.h +++ b/edid-decode.h @@ -169,7 +169,8 @@ struct edid_state { // CTA-861 block state cta.has_vic_1 = cta.first_svd_might_be_preferred = cta.has_sldb = - cta.has_hdmi = cta.has_vcdb = cta.has_vfpdb = cta.has_cdb = false; + cta.has_hdmi = cta.has_vcdb = cta.has_vfpdb = cta.has_cdb = + cta.has_nvrdb = false; cta.previous_cta_tag = 0xfff; cta.have_hf_vsdb = cta.have_hf_scdb = false; cta.image_width = cta.image_height = 0; @@ -271,12 +272,14 @@ struct edid_state { vec_timings_ext vec_vtdbs; cta_vfd preparsed_first_vfd; vec_timings_ext preferred_timings; + vec_timings_ext preferred_timings_vfpdb; bool preparsed_has_t8vtdb; // Keep track of the found Tag/Extended Tag pairs. // The unsigned value is equal to: (tag) | (OUI enum << 12) or (extended tag) | (tag << 8) | (OUI enum << 12) std::vector<unsigned> found_tags; timings_ext t8vtdb; vec_timings_ext native_timings; + vec_timings_ext native_timing_nvrdb; // in 0.1 mm units unsigned image_width, image_height; bool has_vic_1; @@ -285,6 +288,7 @@ struct edid_state { bool has_hdmi; bool has_vcdb; bool has_vfpdb; + bool has_nvrdb; bool has_cdb; unsigned preparsed_speaker_count; bool preparsed_sld_has_coord; @@ -396,7 +400,7 @@ struct edid_state { void cta_block(const unsigned char *x, std::vector<unsigned> &found_tags); void preparse_cta_block(const unsigned char *x); void parse_cta_block(const unsigned char *x); - void cta_resolve_svr(vec_timings_ext::iterator iter); + void cta_resolve_svr(timings_ext &t_ext); void cta_resolve_svrs(); void check_cta_blocks(); void cta_list_vics(); diff --git a/parse-cta-block.cpp b/parse-cta-block.cpp index bbbec2c6ae1b..83171f190c42 100644 --- a/parse-cta-block.cpp +++ b/parse-cta-block.cpp @@ -858,9 +858,9 @@ void edid_state::cta_vfpdb(const unsigned char *x, unsigned length) fail("Empty Data Block with length %u.\n", length); return; } - cta.preferred_timings.clear(); + cta.preferred_timings_vfpdb.clear(); for (i = 0; i < length; i++) - cta_print_svr(x[i], cta.preferred_timings); + cta_print_svr(x[i], cta.preferred_timings_vfpdb); } void edid_state::cta_nvrdb(const unsigned char *x, unsigned length) @@ -872,8 +872,8 @@ void edid_state::cta_nvrdb(const unsigned char *x, unsigned length) unsigned char flags = length == 1 ? 0 : x[1]; - cta.native_timings.clear(); - cta_print_svr(x[0], cta.native_timings); + cta.native_timing_nvrdb.clear(); + cta_print_svr(x[0], cta.native_timing_nvrdb); if ((flags & 1) && length < 6) { fail("Data Block too short for Image Size (length = %u).\n", length); return; @@ -2570,19 +2570,20 @@ void edid_state::preparse_cta_block(const unsigned char *x) case 0x07: if (x[i + 1] == 0x0d) cta.has_vfpdb = true; - if (x[i + 1] == 0x05) + else if (x[i + 1] == 0x05) cta.has_cdb = true; - if (x[i + 1] == 0x13 && (x[i + 2] & 0x40)) { + else if (x[i + 1] == 0x08) + cta.has_nvrdb = true; + else if (x[i + 1] == 0x13 && (x[i + 2] & 0x40)) { cta.preparsed_speaker_count = 1 + (x[i + 2] & 0x1f); cta.preparsed_sld = x[i + 2] & 0x20; - } - if (x[i + 1] == 0x14) + } else if (x[i + 1] == 0x14) cta_preparse_sldb(x + i + 2, (x[i] & 0x1f) - 1); - if (x[i + 1] == 0x22) + else if (x[i + 1] == 0x22) cta.preparsed_total_vtdbs++; - if (x[i + 1] == 0x23) + else if (x[i + 1] == 0x23) cta.preparsed_has_t8vtdb = true; - if (x[i + 1] == 0x2a) + else if (x[i + 1] == 0x2a) cta.preparsed_total_vtdbs += ((x[i] & 0x1f) - 2) / (6 + ((x[i + 2] & 0x70) >> 4)); if (x[i + 1] != 0x0e) @@ -2724,38 +2725,47 @@ void edid_state::parse_cta_block(const unsigned char *x) warn("Add a Colorimetry Data Block with the sRGB colorimetry bit set to avoid interop issues.\n"); } -void edid_state::cta_resolve_svr(vec_timings_ext::iterator iter) +void edid_state::cta_resolve_svr(timings_ext &t_ext) { - if (iter->svr() == 254) { - iter->flags = cta.t8vtdb.flags; - iter->t = cta.t8vtdb.t; - } else if (iter->svr() <= 144) { - iter->flags = cta.vec_dtds[iter->svr() - 129].flags; - iter->t = cta.vec_dtds[iter->svr() - 129].t; - } else if (iter->svr() <= 160) { - iter->flags = cta.vec_vtdbs[iter->svr() - 145].flags; - iter->t = cta.vec_vtdbs[iter->svr() - 145].t; - } else if (iter->svr() <= 175) { - iter->flags.clear(); + if (t_ext.svr() == 254) { + t_ext.flags = cta.t8vtdb.flags; + add_str(t_ext.flags, ">=CTA-861-H"); + t_ext.t = cta.t8vtdb.t; + } else if (t_ext.svr() <= 144) { + t_ext.flags = cta.vec_dtds[t_ext.svr() - 129].flags; + t_ext.t = cta.vec_dtds[t_ext.svr() - 129].t; + } else if (t_ext.svr() <= 160) { + t_ext.flags = cta.vec_vtdbs[t_ext.svr() - 145].flags; + add_str(t_ext.flags, ">=CTA-861-H"); + t_ext.t = cta.vec_vtdbs[t_ext.svr() - 145].t; + } else if (t_ext.svr() <= 175) { + t_ext.flags.clear(); unsigned char rid = cta.preparsed_first_vfd.rid; - iter->t = calc_ovt_mode(rids[rid].hact, rids[rid].vact, + t_ext.t = calc_ovt_mode(rids[rid].hact, rids[rid].vact, rids[rid].hratio, rids[rid].vratio, - vf_rate_values[iter->svr() - 160]); + vf_rate_values[t_ext.svr() - 160]); + t_ext.flags = ">=CTA-861.6"; } } void edid_state::cta_resolve_svrs() { - for (vec_timings_ext::iterator iter = cta.preferred_timings.begin(); - iter != cta.preferred_timings.end(); ++iter) { + for (vec_timings_ext::iterator iter = cta.preferred_timings_vfpdb.begin(); + iter != cta.preferred_timings_vfpdb.end(); ++iter) { if (iter->has_svr()) - cta_resolve_svr(iter); + cta_resolve_svr(*iter); } for (vec_timings_ext::iterator iter = cta.native_timings.begin(); iter != cta.native_timings.end(); ++iter) { if (iter->has_svr()) - cta_resolve_svr(iter); + cta_resolve_svr(*iter); + } + + for (vec_timings_ext::iterator iter = cta.native_timing_nvrdb.begin(); + iter != cta.native_timing_nvrdb.end(); ++iter) { + if (iter->has_svr()) + cta_resolve_svr(*iter); } } @@ -2782,6 +2792,21 @@ void edid_state::check_cta_blocks() max_pref_prog_vact = iter->t.vact; } } + for (vec_timings_ext::iterator iter = cta.preferred_timings_vfpdb.begin(); + iter != cta.preferred_timings_vfpdb.end(); ++iter) { + if (iter->t.interlaced && + (iter->t.vact > max_pref_ilace_vact || + (iter->t.vact == max_pref_ilace_vact && iter->t.hact >= max_pref_ilace_hact))) { + max_pref_ilace_hact = iter->t.hact; + max_pref_ilace_vact = iter->t.vact; + } + if (!iter->t.interlaced && + (iter->t.vact > max_pref_prog_vact || + (iter->t.vact == max_pref_prog_vact && iter->t.hact >= max_pref_prog_hact))) { + max_pref_prog_hact = iter->t.hact; + max_pref_prog_vact = iter->t.vact; + } + } unsigned native_prog = 0; unsigned native_prog_hact = 0; @@ -2791,6 +2816,8 @@ void edid_state::check_cta_blocks() unsigned native_ilace_hact = 0; unsigned native_ilace_vact = 0; bool native_ilace_mixed_resolutions = false; + unsigned native_nvrdb_hact = 0; + unsigned native_nvrdb_vact = 0; for (vec_timings_ext::iterator iter = cta.native_timings.begin(); iter != cta.native_timings.end(); ++iter) { @@ -2815,6 +2842,12 @@ void edid_state::check_cta_blocks() } } + for (vec_timings_ext::iterator iter = cta.native_timing_nvrdb.begin(); + iter != cta.native_timing_nvrdb.end(); ++iter) { + native_nvrdb_hact = iter->t.hact; + native_nvrdb_vact = iter->t.vact; + } + if (native_prog_mixed_resolutions) fail("Native progressive timings are a mix of several resolutions.\n"); if (native_ilace_mixed_resolutions) @@ -2826,7 +2859,13 @@ void edid_state::check_cta_blocks() if (!native_ilace_mixed_resolutions && native_ilace > 1) warn("Multiple native interlaced timings are defined.\n"); - if (!native_prog_mixed_resolutions && native_prog_vact && + if (native_nvrdb_vact && + (max_pref_prog_vact > native_nvrdb_vact || + (max_pref_prog_vact == native_nvrdb_vact && max_pref_prog_hact > native_nvrdb_hact))) + warn("Native video resolution of %ux%u is smaller than the max preferred progressive resolution %ux%u.\n", + native_nvrdb_hact, native_nvrdb_vact, + max_pref_prog_hact, max_pref_prog_vact); + else if (!native_nvrdb_vact && !native_prog_mixed_resolutions && native_prog_vact && (max_pref_prog_vact > native_prog_vact || (max_pref_prog_vact == native_prog_vact && max_pref_prog_hact > native_prog_hact))) warn("Native progressive resolution of %ux%u is smaller than the max preferred progressive resolution %ux%u.\n", _______________________________________________ linuxtv-commits mailing list linuxtv-commits@linuxtv.org https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits