summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2017-09-09 12:08:22 +0200
committerAdam Jackson <ajax@redhat.com>2017-09-18 10:16:47 -0400
commit83101c4598d820a26122b8ccfe47cd299daacbcb (patch)
tree7b66bd58b983f9e80a9892e1ce6cae7a168b7a17
parent307e9c2ea986ee928dbb4e2b2fb0eb4cdd63fb48 (diff)
edid-decode: add support for Room/Speaker data blocks
Support the Room Configuration Data Block and the Speaker Location Data Block. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
-rw-r--r--edid-decode.c112
1 files changed, 109 insertions, 3 deletions
diff --git a/edid-decode.c b/edid-decode.c
index 8d47a5f..4534d58 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -1614,7 +1614,7 @@ static struct field *vcdb_fields[] = {
&CE_scan,
};
-static const char *sadb_map[] = {
+static const char *speaker_map[] = {
"FL/FR - Front Left/Right",
"LFE - Low Frequency Effects",
"FC - Front Center",
@@ -1648,13 +1648,111 @@ cea_sadb(unsigned char *x)
printf(" Speaker map:\n");
- for (i = 0; i < ARRAY_SIZE(sadb_map); i++) {
+ for (i = 0; i < ARRAY_SIZE(speaker_map); i++) {
if ((sad >> i) & 1)
- printf(" %s\n", sadb_map[i]);
+ printf(" %s\n", speaker_map[i]);
}
}
}
+static float
+decode_uchar_as_float(unsigned char x)
+{
+ signed char s = (signed char)x;
+
+ return s / 64.0;
+}
+
+static void
+cea_rcdb(unsigned char *x)
+{
+ int length = x[0] & 0x1f;
+ uint32_t spm = ((x[5] << 16) | (x[4] << 8) | x[3]);
+ int i;
+
+ if (length < 4)
+ return;
+
+ if (x[2] & 0x40)
+ printf(" Speaker count: %d\n", (x[2] & 0x1f) + 1);
+
+ printf(" Speaker Presence Mask:\n");
+ for (i = 0; i < ARRAY_SIZE(speaker_map); i++) {
+ if ((spm >> i) & 1)
+ printf(" %s\n", speaker_map[i]);
+ }
+ if ((x[2] & 0x20) && length >= 7) {
+ printf(" Xmax: %d dm\n", x[6]);
+ printf(" Ymax: %d dm\n", x[7]);
+ printf(" Zmax: %d dm\n", x[8]);
+ }
+ if ((x[2] & 0x80) && length >= 10) {
+ printf(" DisplayX: %.3f * Xmax\n", decode_uchar_as_float(x[9]));
+ printf(" DisplayY: %.3f * Ymax\n", decode_uchar_as_float(x[10]));
+ printf(" DisplayZ: %.3f * Zmax\n", decode_uchar_as_float(x[11]));
+ }
+}
+
+static const char *speaker_location[] = {
+ "FL - Front Left",
+ "FR - Front Right",
+ "FC - Front Center",
+ "LFE1 - Low Frequency Effects 1",
+ "BL - Back Left",
+ "BR - Back Right",
+ "FLC - Front Left of Center",
+ "FRC - Front Right of Center",
+ "BC - Back Center",
+ "LFE2 - Low Frequency Effects 2",
+ "SiL - Side Left",
+ "SiR - Side Right",
+ "TpFL - Top Front Left",
+ "TpFH - Top Front Right",
+ "TpFC - Top Front Center",
+ "TpC - Top Center",
+ "TpBL - Top Back Left",
+ "TpBR - Top Back Right",
+ "TpSiL - Top Side Left",
+ "TpSiR - Top Side Right",
+ "TpBC - Top Back Center",
+ "BtFC - Bottom Front Center",
+ "BtFL - Bottom Front Left",
+ "BtBR - Bottom Front Right",
+ "FLW - Front Left Wide",
+ "FRW - Front Right Wide",
+ "LS - Left Surround",
+ "RS - Right Surround",
+};
+
+static void
+cea_sldb(unsigned char *x)
+{
+ int length = x[0] & 0x1f;
+
+ if (!length)
+ return;
+
+ x += 2;
+ length--;
+
+ while (length >= 2) {
+ printf(" Channel: %d (%sactive)\n", x[0] & 0x1f,
+ (x[0] & 0x20) ? "" : "not ");
+ if ((x[1] & 0x1f) < ARRAY_SIZE(speaker_location))
+ printf(" Speaker: %s\n", speaker_location[x[1] & 0x1f]);
+ if (length >= 5 && (x[0] & 0x40)) {
+ printf(" X: %.3f * Xmax\n", decode_uchar_as_float(x[2]));
+ printf(" Y: %.3f * Ymax\n", decode_uchar_as_float(x[3]));
+ printf(" Z: %.3f * Zmax\n", decode_uchar_as_float(x[4]));
+ length -= 3;
+ x += 3;
+ }
+
+ length -= 2;
+ x += 2;
+ }
+}
+
static void
cea_vcdb(unsigned char *x)
{
@@ -1812,6 +1910,14 @@ cea_block(unsigned char *x)
case 0x12:
printf("HDMI audio data block\n");
break;
+ case 0x13:
+ printf("Room configuration data block\n");
+ cea_rcdb(x);
+ break;
+ case 0x14:
+ printf("Speaker location data block\n");
+ cea_sldb(x);
+ break;
case 0x20:
printf("InfoFrame data block\n");
break;