diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2017-09-09 12:08:22 +0200 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2017-09-18 10:16:47 -0400 |
commit | 83101c4598d820a26122b8ccfe47cd299daacbcb (patch) | |
tree | 7b66bd58b983f9e80a9892e1ce6cae7a168b7a17 | |
parent | 307e9c2ea986ee928dbb4e2b2fb0eb4cdd63fb48 (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.c | 112 |
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; |