aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--edid-decode.h15
-rw-r--r--parse-cta-block.cpp34
-rw-r--r--parse-displayid-block.cpp27
3 files changed, 32 insertions, 44 deletions
diff --git a/edid-decode.h b/edid-decode.h
index 9f73e9c..6a40092 100644
--- a/edid-decode.h
+++ b/edid-decode.h
@@ -153,7 +153,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 = false;
- cta.last_block_was_hdmi_vsdb = cta.have_hf_vsdb = cta.have_hf_scdb = false;
+ cta.previous_cta_tag = 0xfff;
+ cta.have_hf_vsdb = cta.have_hf_scdb = false;
cta.block_number = 0;
cta.first_svd = true;
cta.supported_hdmi_vic_codes = cta.supported_hdmi_vic_vsb_codes = 0;
@@ -244,8 +245,8 @@ struct edid_state {
vec_timings_ext preferred_timings;
bool preparsed_has_t8vtdb;
// Keep track of the found Tag/Extended Tag pairs.
- // The unsigned value is equal to: (tag << 8) | ext_tag
- std::set<unsigned> found_tags;
+ // 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;
bool has_vic_1;
@@ -259,7 +260,7 @@ struct edid_state {
bool preparsed_sld;
bool has_sldb;
unsigned short preparsed_phys_addr;
- bool last_block_was_hdmi_vsdb;
+ unsigned previous_cta_tag;
bool have_hf_vsdb, have_hf_scdb;
unsigned block_number;
bool first_svd;
@@ -286,8 +287,8 @@ struct edid_state {
unsigned native_width, native_height;
unsigned block_number;
// Keep track of the found CTA-861 Tag/Extended Tag pairs.
- // The unsigned value is equal to: (tag << 8) | ext_tag
- std::set<unsigned> found_tags;
+ // The unsigned value is equal to: (tag) | (OUI enum << 12) or (extended tag) | (tag << 8) | (OUI enum << 12)
+ std::vector<unsigned> found_tags;
} dispid;
// Block Map block state
@@ -350,7 +351,7 @@ struct edid_state {
void cta_displayid_type_7(const unsigned char *x, unsigned length);
void cta_displayid_type_8(const unsigned char *x, unsigned length);
void cta_displayid_type_10(const unsigned char *x, unsigned length);
- void cta_block(const unsigned char *x, bool duplicate);
+ 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);
diff --git a/parse-cta-block.cpp b/parse-cta-block.cpp
index 61712a7..b9f4312 100644
--- a/parse-cta-block.cpp
+++ b/parse-cta-block.cpp
@@ -7,6 +7,7 @@
* Maintainer: Hans Verkuil <hverkuil-cisco@xs4all.nl>
*/
+#include <algorithm>
#include <stdio.h>
#include <math.h>
@@ -2029,13 +2030,15 @@ static void cta_hdmi_audio_block(const unsigned char *x, unsigned length)
#define data_block_o(n) \
do { \
+ unsigned ouinum; \
data_block_oui(n, x, length, &ouinum); \
x += (length < 3) ? length : 3; \
length -= (length < 3) ? length : 3; \
dooutputname = false; \
+ tag |= ouinum; \
} while(0)
-void edid_state::cta_block(const unsigned char *x, bool duplicate)
+void edid_state::cta_block(const unsigned char *x, std::vector<unsigned> &found_tags)
{
unsigned length = x[0] & 0x1f;
unsigned tag=(x[0] & 0xe0) >> 5;
@@ -2048,7 +2051,6 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
x++;
}
- unsigned ouinum = 0;
bool dooutputname = true;
bool audio_block = false;
data_block.clear();
@@ -2118,7 +2120,7 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
case 0x713:
case 0x778:
case 0x779:
- if (duplicate)
+ if (std::find(found_tags.begin(), found_tags.end(), tag) != found_tags.end())
fail("Only one instance of this Data Block is allowed.\n");
break;
}
@@ -2127,28 +2129,25 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
if (audio_block && !(cta.byte3 & 0x40))
fail("Audio information is present, but bit 6 of Byte 3 of the CTA-861 Extension header indicates no Basic Audio support.\n");
- tag |= ouinum;
switch (tag) {
case 0x01: cta_audio_block(x, length); break;
case 0x02: cta_svd(x, length, false); break;
case 0x03|kOUI_HDMI:
cta_hdmi_block(x, length);
- cta.last_block_was_hdmi_vsdb = 1;
- cta.block_number++;
// The HDMI OUI is present, so this EDID represents an HDMI
// interface. And HDMI interfaces must use EDID version 1.3
// according to the HDMI Specification, so check for this.
if (base.edid_minor != 3)
fail("The HDMI Specification requires EDID 1.3 instead of 1.%u.\n",
base.edid_minor);
- return;
+ break;
case 0x03|kOUI_HDMIForum:
- if (!cta.last_block_was_hdmi_vsdb)
+ if (cta.previous_cta_tag != (0x03|kOUI_HDMI))
fail("HDMI Forum VSDB did not immediately follow the HDMI VSDB.\n");
if (cta.have_hf_scdb || cta.have_hf_vsdb)
fail("Duplicate HDMI Forum VSDB/SCDB.\n");
cta_hf_scdb(x, length);
- cta.have_hf_vsdb = 1;
+ cta.have_hf_vsdb = true;
break;
case 0x03|kOUI_AMD: cta_amd(x, length); break;
case 0x03|kOUI_Microsoft: if (length != 0x12) goto dodefault; cta_microsoft(x, length); break;
@@ -2180,7 +2179,7 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
fail("Block starts at a wrong offset.\n");
break;
case 0x779:
- if (!cta.last_block_was_hdmi_vsdb)
+ if (cta.previous_cta_tag != (0x03|kOUI_HDMI))
fail("HDMI Forum SCDB did not immediately follow the HDMI VSDB.\n");
if (cta.have_hf_scdb || cta.have_hf_vsdb)
fail("Duplicate HDMI Forum VSDB/SCDB.\n");
@@ -2192,7 +2191,7 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
if (x[0] || x[1])
printf(" Non-zero SCDB reserved fields!\n");
cta_hf_scdb(x + 2, length - 2);
- cta.have_hf_scdb = 1;
+ cta.have_hf_scdb = true;
break;
dodefault:
default:
@@ -2201,7 +2200,8 @@ dodefault:
}
cta.block_number++;
- cta.last_block_was_hdmi_vsdb = 0;
+ cta.previous_cta_tag = tag;
+ found_tags.push_back(tag);
}
void edid_state::preparse_cta_block(const unsigned char *x)
@@ -2347,15 +2347,7 @@ void edid_state::parse_cta_block(const unsigned char *x)
unsigned i;
for (i = 4; i < offset; i += (x[i] & 0x1f) + 1) {
- unsigned tag = (x[i] & 0xe0) << 3;
-
- if (tag == 0x700)
- tag |= x[i + 1];
- bool duplicate = cta.found_tags.find(tag) != cta.found_tags.end();
-
- cta_block(x + i, duplicate);
- if (!duplicate)
- cta.found_tags.insert(tag);
+ cta_block(x + i, cta.found_tags);
}
data_block.clear();
diff --git a/parse-displayid-block.cpp b/parse-displayid-block.cpp
index 597005e..a38c90e 100644
--- a/parse-displayid-block.cpp
+++ b/parse-displayid-block.cpp
@@ -1556,15 +1556,7 @@ void edid_state::parse_displayid_cta_data_block(const unsigned char *x)
x += 3;
for (i = 0; i < len; i += (x[i] & 0x1f) + 1) {
- unsigned tag = (x[i] & 0xe0) << 3;
-
- if (tag == 0x700)
- tag |= x[i + 1];
- bool duplicate = dispid.found_tags.find(tag) != dispid.found_tags.end();
-
- cta_block(x + i, duplicate);
- if (!duplicate)
- dispid.found_tags.insert(tag);
+ cta_block(x + i, dispid.found_tags);
}
if (i != len)
@@ -1653,21 +1645,25 @@ void edid_state::preparse_displayid_block(const unsigned char *x)
#define data_block_o(n, a, b) \
do { \
+ unsigned ouinum; \
data_block_oui(n, x + 3, len, &ouinum, tag == 0, a, b); \
dooutputname = false; \
+ if (tag != 0x00 && tag != 0x20) tag |= ouinum; \
+ hasoui = true; \
} while (0)
unsigned edid_state::displayid_block(const unsigned version, const unsigned char *x, unsigned length)
{
unsigned i;
unsigned tag = x[0];
- unsigned ouinum = 0;
+ unsigned tag_version = (tag < 0x20) ? 1 : (tag < 0x7f) ? 2 : (tag < 0x80) ? 1 : 0;
bool dooutputname = true;
unsigned len = (length < 3) ? 0 : x[2];
+ bool hasoui = false;
switch (tag) {
// DisplayID 1.3:
- case 0x00: data_block_o("Product Identification Data Block (" + utohex(tag) + ")", true, false); ouinum = 0; break;
+ case 0x00: data_block_o("Product Identification Data Block (" + utohex(tag) + ")", true, false); break;
case 0x01: data_block = "Display Parameters Data Block (" + utohex(tag) + ")"; break;
case 0x02: data_block = "Color Characteristics Data Block"; break;
case 0x03: data_block = "Video Timing Modes Type 1 - Detailed Timings Data Block"; break;
@@ -1689,7 +1685,7 @@ unsigned edid_state::displayid_block(const unsigned version, const unsigned char
case 0x13: data_block = "Video Timing Modes Type 6 - Detailed Timings Data Block"; break;
// 0x14 .. 0x7e RESERVED for Additional VESA-defined Data Blocks
// DisplayID 2.0
- case 0x20: data_block_o("Product Identification Data Block (" + utohex(tag) + ")", false, false); ouinum = 0; break;
+ case 0x20: data_block_o("Product Identification Data Block (" + utohex(tag) + ")", false, false); break;
case 0x21: data_block = "Display Parameters Data Block (" + utohex(tag) + ")"; break;
case 0x22: data_block = "Video Timing Modes Type 7 - Detailed Timings Data Block"; break;
case 0x23: data_block = "Video Timing Modes Type 8 - Enumerated Timing Codes Data Block"; break;
@@ -1743,16 +1739,15 @@ unsigned edid_state::displayid_block(const unsigned version, const unsigned char
if (dooutputname && data_block.length())
printf(" %s:\n", data_block.c_str());
- if (version >= 0x20 && (tag < 0x20 || tag == 0x7f))
+ if (version >= 0x20 && tag_version == 1)
fail("Use of DisplayID v1.x tag for DisplayID v%u.%u.\n",
version >> 4, version & 0xf);
- if (version < 0x20 && tag >= 0x20 && tag <= 0x7e)
+ if (version < 0x20 && tag_version == 2)
fail("Use of DisplayID v2.0 tag for DisplayID v%u.%u.\n",
version >> 4, version & 0xf);
unsigned block_rev = x[1] & 0x07;
- tag |= ouinum;
switch (tag) {
case 0x00: parse_displayid_product_id(x); break;
case 0x01: parse_displayid_parameters(x); break;
@@ -1875,7 +1870,7 @@ unsigned edid_state::displayid_block(const unsigned version, const unsigned char
}
case 0x7e|kOUI_VESA: parse_displayid_vesa(x); break;
case 0x81: parse_displayid_cta_data_block(x); break;
- default: hex_block(" ", x + 3 + (ouinum ? 3 : 0), len - (ouinum ? 3 : 0)); break;
+ default: hex_block(" ", x + 3 + (hasoui ? 3 : 0), (len > (hasoui ? 3 : 0)) ? len - (hasoui ? 3 : 0) : 0); break;
}
if ((tag == 0x00 || tag == 0x20) &&

Privacy Policy