summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorBurt P <pburt0@gmail.com>2019-08-19 01:27:30 -0500
committerLeandro A. F. Pereira <leandro@hardinfo.org>2019-08-22 23:10:17 +0200
commit64b19e4986f1f2233fd16d1252dc19a2014a1116 (patch)
tree312cf383f1f128ed7552769253ffe6845abf0aa3 /deps
parent4a33434d40bb9b3d4d36fb65c80f36dfa492daf6 (diff)
monitors: speakers and SADs
Signed-off-by: Burt P <pburt0@gmail.com>
Diffstat (limited to 'deps')
-rw-r--r--deps/sysobj_early/include/util_edid.h34
-rw-r--r--deps/sysobj_early/src/util_edid.c185
2 files changed, 127 insertions, 92 deletions
diff --git a/deps/sysobj_early/include/util_edid.h b/deps/sysobj_early/include/util_edid.h
index 4efee6b3..b50dcb33 100644
--- a/deps/sysobj_early/include/util_edid.h
+++ b/deps/sysobj_early/include/util_edid.h
@@ -54,30 +54,21 @@ struct edid_svd {
edid_output out;
};
-struct edid_cea_header {
- uint8_t *ptr;
- int type, len;
-};
-
-struct edid_cea_block {
- struct edid_cea_header header;
- int reserved[8];
-};
-
-struct edid_cea_audio {
- struct edid_cea_header header;
+struct edid_sad {
+ uint8_t v[3];
int format, channels, freq_bits;
int depth_bits; /* format 1 */
int max_kbps; /* formats 2-8 */
};
-struct edid_cea_vendor_spec {
- struct edid_cea_header header;
+struct edid_cea_header {
+ uint8_t *ptr;
+ int type, len;
};
-struct edid_cea_speaker {
+struct edid_cea_block {
struct edid_cea_header header;
- int alloc_bits;
+ int reserved[8];
};
typedef struct {
@@ -109,11 +100,14 @@ typedef struct {
int dtd_count;
struct edid_dtd *dtds;
+ int cea_block_count;
+ struct edid_cea_block *cea_blocks;
+
int svd_count;
struct edid_svd *svds;
- int cea_block_count;
- struct edid_cea_block *cea_blocks;
+ int sad_count;
+ struct edid_sad *sads;
char ven[4];
int d_type[4];
@@ -132,6 +126,8 @@ typedef struct {
int week, year;
edid_output img;
edid_output img_max;
+ int speaker_alloc_bits;
+
} edid;
edid *edid_new(const char *data, unsigned int len);
edid *edid_new_from_hex(const char *hex_string);
@@ -149,6 +145,8 @@ const char *edid_cea_audio_type(int type);
char *edid_output_describe(edid_output *out);
char *edid_dtd_describe(struct edid_dtd *dtd, int dump_bytes);
char *edid_cea_block_describe(struct edid_cea_block *blk);
+char *edid_cea_audio_describe(struct edid_sad *sad);
+char *edid_cea_speaker_allocation_describe(int bitfield, int short_version);
char *edid_dump2(edid *e);
diff --git a/deps/sysobj_early/src/util_edid.c b/deps/sysobj_early/src/util_edid.c
index 936744e0..7c9f9a05 100644
--- a/deps/sysobj_early/src/util_edid.c
+++ b/deps/sysobj_early/src/util_edid.c
@@ -53,28 +53,37 @@ char *hex_bytes(uint8_t *bytes, int count) {
return buffer;
}
-static void cea_block_decode(struct edid_cea_block *blk) {
- struct edid_cea_audio *blk_audio = (void*)blk;
- struct edid_cea_speaker *blk_speaker = (void*)blk;
- //struct edid_cea_vendor_spec *blk_vendor_spec = (void*)blk;
+static void cea_block_decode(struct edid_cea_block *blk, edid *e) {
+ int i;
if (blk) {
switch(blk->header.type) {
- case 0x1:
- blk_audio->format = (blk->header.ptr[1] & 0x78) >> 3;
- blk_audio->channels = 1 + blk->header.ptr[1] & 0x7;
- blk_audio->freq_bits = blk->header.ptr[2];
- if (blk_audio->format == 1) {
- blk_audio->depth_bits = blk->header.ptr[3];
- } else if (blk_audio->format >= 2
- && blk_audio->format <= 8) {
- blk_audio->max_kbps = blk->header.ptr[3] * 8;
+ case 0x1: /* SADS */
+ for(i = 1; i <= blk->header.len; i+=3) {
+ struct edid_sad *sad = &e->sads[e->sad_count];
+ sad->v[0] = blk->header.ptr[i];
+ sad->v[1] = blk->header.ptr[i+1];
+ sad->v[2] = blk->header.ptr[i+2];
+ sad->format = (sad->v[0] & 0x78) >> 3;
+ sad->channels = 1 + sad->v[0] & 0x7;
+ sad->freq_bits = sad->v[1];
+ if (sad->format == 1) {
+ sad->depth_bits = sad->v[2];
+ } else if (sad->format >= 2
+ && sad->format <= 8) {
+ sad->max_kbps = 8 * sad->v[2];
+ }
+ e->sad_count++;
}
break;
- case 0x4:
- blk_speaker->alloc_bits = blk->header.ptr[1];
+ case 0x4: /* Speaker allocation */
+ e->speaker_alloc_bits = blk->header.ptr[1];
+ break;
+ case 0x2: /* SVDs */
+ for(i = 1; i <= blk->header.len; i++)
+ e->svds[e->svd_count++].v = blk->header.ptr[i];
break;
- case 0x3:
- case 0x2: /* SVD list is handled elsewhere */
+ case 0x3: /* Vendor-specific */
+ // TODO:
default:
break;
}
@@ -154,9 +163,11 @@ edid *edid_new(const char *data, unsigned int len) {
e->dtds = malloc(sizeof(struct edid_dtd) * 1000);
e->cea_blocks = malloc(sizeof(struct edid_cea_block) * 1000);
e->svds = malloc(sizeof(struct edid_svd) * 1000);
+ e->sads = malloc(sizeof(struct edid_sad) * 1000);
memset(e->dtds, 0, sizeof(struct edid_dtd) * 1000);
memset(e->cea_blocks, 0, sizeof(struct edid_cea_block) * 1000);
memset(e->svds, 0, sizeof(struct edid_svd) * 1000);
+ memset(e->sads, 0, sizeof(struct edid_sad) * 1000);
uint16_t vid = be16toh(e->u16[4]); /* bytes 8-9 */
e->ven[2] = 64 + (vid & 0x1f);
@@ -305,11 +316,7 @@ edid *edid_new(const char *data, unsigned int len) {
e->cea_blocks[e->cea_block_count].header.ptr = &u8[b];
e->cea_blocks[e->cea_block_count].header.type = db_type;
e->cea_blocks[e->cea_block_count].header.len = db_size;
- if (db_type == 0x2) {
- for(i = 1; i <= db_size; i++)
- e->svds[e->svd_count++].v = u8[b+i];
- } else
- cea_block_decode(&e->cea_blocks[e->cea_block_count]);
+ cea_block_decode(&e->cea_blocks[e->cea_block_count], e);
e->cea_block_count++;
b += db_size + 1;
}
@@ -442,6 +449,13 @@ edid *edid_new(const char *data, unsigned int len) {
} else {
e->svds = realloc(e->svds, sizeof(struct edid_svd) * e->svd_count);
}
+ if (!e->sad_count) {
+ if (e->sads)
+ free(e->sads);
+ e->sads = NULL;
+ } else {
+ e->sads = realloc(e->sads, sizeof(struct edid_sad) * e->sad_count);
+ }
return e;
}
@@ -635,72 +649,81 @@ const char *edid_descriptor_type(int type) {
return N_("detailed timing descriptor");
}
+char *edid_cea_audio_describe(struct edid_sad *sad) {
+ if (!sad) return NULL;
+
+ if (!sad->format)
+ return g_strdup_printf("format:([%x] %s)",
+ sad->format, _(edid_cea_audio_type(sad->format)) );
+
+ gchar *ret = NULL;
+ gchar *tmp[3] = {};
+#define appfreq(b, f) if (sad->freq_bits & (1 << b)) tmp[0] = appf(tmp[0], ", ", "%d", f);
+#define appdepth(b, d) if (sad->depth_bits & (1 << b)) tmp[1] = appf(tmp[1], ", ", "%d%s", d, _("-bit"));
+ appfreq(0, 32);
+ appfreq(1, 44);
+ appfreq(2, 48);
+ appfreq(3, 88);
+ appfreq(4, 96);
+ appfreq(5, 176);
+ appfreq(6, 192);
+
+ if (sad->format == 1) {
+ appdepth(0, 16);
+ appdepth(1, 20);
+ appdepth(2, 24);
+ tmp[2] = g_strdup_printf("depths: %s", tmp[1]);
+ } else if (sad->format >= 2
+ && sad->format <= 8 ) {
+ tmp[2] = g_strdup_printf("max_bitrate: %d %s", sad->max_kbps, _("kbps"));
+ } else
+ tmp[2] = g_strdup("");
+
+ ret = g_strdup_printf("format:([%x] %s) channels:%d rates:%s %s %s",
+ sad->format, _(edid_cea_audio_type(sad->format)),
+ sad->channels, tmp[0], _("kHz"),
+ tmp[2]);
+ g_free(tmp[0]);
+ g_free(tmp[1]);
+ g_free(tmp[2]);
+ return ret;
+}
+
+char *edid_cea_speaker_allocation_describe(int bitfield, int short_version) {
+ gchar *spk_list = NULL;
+#define appspk(b, sv, fv) if (bitfield & (1 << b)) \
+ spk_list = appf(spk_list, short_version ? ", " : "\n", "%s", short_version ? sv : fv);
+
+ appspk(0, "FL+FR", _("Front left and right"));
+ appspk(1, "LFE", _("Low-frequency effects"));
+ appspk(2, "FC", _("Front center"));
+ appspk(3, "RL+RR", _("Rear left and right"));
+ appspk(4, "RC", _("Rear center"));
+ appspk(5, "???", _(""));
+ appspk(6, "???", _(""));
+
+ return spk_list;
+}
+
char *edid_cea_block_describe(struct edid_cea_block *blk) {
gchar *ret = NULL;
gchar *tmp[3] = {};
- struct edid_cea_audio *blk_audio = (void*)blk;
- struct edid_cea_speaker *blk_speaker = (void*)blk;
- //struct edid_cea_vendor_spec *blk_vendor_spec = (void*)blk;
if (blk) {
char *hb = hex_bytes(blk->header.ptr, blk->header.len+1);
switch(blk->header.type) {
- case 0x1:
-
-#define appfreq(b, f) if (blk_audio->freq_bits & (1 << b)) tmp[0] = appf(tmp[0], ", ", "%d", f);
-#define appdepth(b, d) if (blk_audio->depth_bits & (1 << b)) tmp[1] = appf(tmp[1], ", ", "%d%s", d, _("-bit"));
- appfreq(0, 32);
- appfreq(1, 44);
- appfreq(2, 48);
- appfreq(3, 88);
- appfreq(4, 96);
- appfreq(5, 176);
- appfreq(6, 192);
-
- if (blk_audio->format == 1) {
- appdepth(0, 16);
- appdepth(1, 20);
- appdepth(2, 24);
- tmp[2] = g_strdup_printf("depths: %s", tmp[1]);
- } else if (blk_audio->format >= 2
- && blk_audio->format <= 8 ) {
- tmp[2] = g_strdup_printf("max_bitrate: %d %s", blk_audio->max_kbps, _("kbps"));
- } else
- tmp[2] = g_strdup("");
-
- ret = g_strdup_printf("([%x] %s) len:%d format:([%x] %s) channels:%d rates:%s %s %s -- %s",
- blk->header.type, _(edid_cea_block_type(blk->header.type)),
- blk->header.len,
- blk_audio->format, _(edid_cea_audio_type(blk_audio->format)),
- blk_audio->channels, tmp[0], _("kHz"),
- tmp[2],
- hb);
- g_free(tmp[0]);
- g_free(tmp[1]);
- g_free(tmp[2]);
- break;
- case 0x4:
-#define appspk(b, s) if (blk_speaker->alloc_bits & (1 << b)) tmp[0] = appf(tmp[0], ", ", "%s", s);
- appspk(0, _("LF+LR: Front left and right"));
- appspk(1, _("LFE: Low-frequency effects"));
- appspk(2, _("FC: Front center"));
- appspk(3, _("LR+LR: Rear left and right"));
- appspk(4, _("RC: Rear center"));
- appspk(5, _("???"));
- appspk(6, _("???"));
- ret = g_strdup_printf("([%x] %s) len:%d %s -- %s",
+ case 0x1: /* SAD list */
+ ret = g_strdup_printf("([%x] %s) sads:%d",
blk->header.type, _(edid_cea_block_type(blk->header.type)),
- blk->header.len,
- tmp[0],
- hb);
- g_free(tmp[0]);
+ blk->header.len/3);
break;
- case 0x2:
+ case 0x2: /* SVD list */
ret = g_strdup_printf("([%x] %s) svds:%d",
blk->header.type, _(edid_cea_block_type(blk->header.type)),
blk->header.len);
break;
case 0x3: //TODO
+ case 0x4:
default:
ret = g_strdup_printf("([%x] %s) len:%d -- %s",
blk->header.type, _(edid_cea_block_type(blk->header.type)),
@@ -772,6 +795,12 @@ char *edid_dump2(edid *e) {
g_free(desc);
g_free(desc_max);
+ if (e->speaker_alloc_bits) {
+ char *desc = edid_cea_speaker_allocation_describe(e->speaker_alloc_bits, 1);
+ ret = appfnl(ret, "speakers: %s", desc);
+ g_free(desc);
+ }
+
for(i = 0; i < e->etb_count; i++) {
char *desc = edid_output_describe(&e->etbs[i]);
ret = appfnl(ret, "etb[%d]: %s", i, desc);
@@ -817,6 +846,14 @@ char *edid_dump2(edid *e) {
free(desc);
}
+ for(i = 0; i < e->sad_count; i++) {
+ char *desc = edid_cea_audio_describe(&e->sads[i]);
+ ret = appfnl(ret, "sad[%d] [%02x%02x%02x] %s", i,
+ e->sads[i].v[0], e->sads[i].v[1], e->sads[i].v[2],
+ desc);
+ free(desc);
+ }
+
return ret;
}