之前在某项目上做屏幕自适应分辨率时,按照vesa标准解析edid得出的分辨率不全导致自适应功能概率性失效,换为CTA 861标准解析后功能正常。此功能的代码对数据结构知识的要求不高,但是对C语言能力要求较高,特别是数位移、临界值的判断以及接口构建等操作。正好锻炼逻辑能力与熟悉基础语法。
花了一下午写了VSDB与VDB解析的接口,除了vic数组其余全部手码,代码如下:
#include <stdio.h>
//static int edid[] = {
//0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x22,0x0e,0xd5,0x36,0x01,0x01,0x01,0x01,
//0x1b,0x1f,0x01,0x03,0x80,0x3c,0x22,0x78,0x2e,0xee,0x95,0xa3,0x54,0x4c,0x99,0x26,
//0x0f,0x50,0x54,0xa1,0x08,0x00,0xd1,0xc0,0xa9,0xc0,0xa9,0x40,0xd1,0x00,0xb3,0x00,
//0x95,0x00,0x81,0x00,0x81,0x80,0x4d,0xd0,0x00,0xa0,0xf0,0x70,0x3e,0x80,0x30,0x20,
//0x35,0x00,0x55,0x50,0x21,0x00,0x00,0x1a,0x00,0x00,0x00,0xfd,0x00,0x1d,0x3c,0x1c,
//0x87,0x3c,0x00,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xfc,0x00,0x48,
//0x50,0x20,0x5a,0x32,0x37,0x6b,0x20,0x47,0x33,0x0a,0x20,0x20,0x00,0x00,0x00,0xff,
//0x00,0x43,0x4e,0x34,0x31,0x32,0x37,0x34,0x32,0x46,0x30,0x0a,0x20,0x20,0x01,0x1c,
//
//0x02,0x03,0x30,0xb1,0x51,0x61,0x10,0x04,0x03,0x02,0x1f,0x13,0x12,0x11,0x5f,0x05,
//0x14,0x07,0x06,0x16,0x15,0x01,0x6b,0x03,0x0c,0x00,0x10,0x00,0x38,0x3c,0x20,0x00,
//0x20,0x01,0x67,0xd8,0x5d,0xc4,0x01,0x78,0x80,0x03,0xe2,0x0f,0x01,0xe2,0x00,0x6b,
//0xa3,0x66,0x00,0xa0,0xf0,0x70,0x1f,0x80,0x30,0x20,0x35,0x00,0x55,0x50,0x21,0x00,
//0x00,0x1a,0x02,0x3a,0x80,0x18,0x71,0x38,0x2d,0x40,0x58,0x2c,0x45,0x00,0x55,0x50,
//0x21,0x00,0x00,0x1e,0x28,0x3c,0x80,0xa0,0x70,0xb0,0x23,0x40,0x30,0x20,0x36,0x00,
//0x55,0x50,0x21,0x00,0x00,0x1a,0x56,0x5e,0x00,0xa0,0xa0,0xa0,0x29,0x50,0x30,0x20,
//0x35,0x00,0x55,0x50,0x21,0x00,0x00,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xec
//};
struct timings {
unsigned hact, vact;
unsigned hratio, vratio;
unsigned pixclk_khz;
unsigned rb;
bool interlaced;
int hfp;
unsigned hsync;
int hbp;
bool pos_pol_hsync;
unsigned vfp, vsync;
int vbp;
bool pos_pol_vsync;
unsigned hborder, vborder;
bool even_vtotal;
bool no_pol_vsync;
unsigned hsize_mm, vsize_mm;
bool ycbcr420;
};
typedef struct panel_info {
int vic;
int hact, vact;
double refresh;
int hratio, vratio;
double freq_khz;
double pixclk;
}panel_info;
typedef struct vsdb_info {
int vic_len;
int vic_add;
}vsdb_info;
typedef struct vdb_info {
int vic_len;
int vic_add;
}vdb_info;
static int edid_hdmi_mode_map[] = { 95, 94, 93, 98 };
static const struct timings edid_cta_modes[] = {
/* VIC 1 */
{ 640, 480, 4, 3, 25175, 0, false, 16, 96, 48, false, 10, 2, 33, false },
{ 720, 480, 4, 3, 27000, 0, false, 16, 62, 60, false, 9, 6, 30, false },
{ 720, 480, 16, 9, 27000, 0, false, 16, 62, 60, false, 9, 6, 30, false },
{ 1280, 720, 16, 9, 74250, 0, false, 110, 40, 220, true, 5, 5, 20, true },
{ 1920, 1080, 16, 9, 74250, 0, true, 88, 44, 148, true, 2, 5, 15, true },
{ 1440, 480, 4, 3, 27000, 0, true, 38, 124, 114, false, 4, 3, 15, false },
{ 1440, 480, 16, 9, 27000, 0, true, 38, 124, 114, false, 4, 3, 15, false },
{ 1440, 240, 4, 3, 27000, 0, false, 38, 124, 114, false, 4, 3, 15, false },
{ 1440, 240, 16, 9, 27000, 0, false, 38, 124, 114, false, 4, 3, 15, false },
{ 2880, 480, 4, 3, 54000, 0, true, 76, 248, 228, false, 4, 3, 15, false },
/* VIC 11 */
{ 2880, 480, 16, 9, 54000, 0, true, 76, 248, 228, false, 4, 3, 15, false },
{ 2880, 240, 4, 3, 54000, 0, false, 76, 248, 228, false, 4, 3, 15, false },
{ 2880, 240, 16, 9, 54000, 0, false, 76, 248, 228, false, 4, 3, 15, false },
{ 1440, 480, 4, 3, 54000, 0, false, 32, 124, 120, false, 9, 6, 30, false },
{ 1440, 480, 16, 9, 54000, 0, false, 32, 124, 120, false, 9, 6, 30, false },
{ 1920, 1080, 16, 9, 148500, 0, false, 88, 44, 148, true, 4, 5, 36, true },
{ 720, 576, 4, 3, 27000, 0, false, 12, 64, 68, false, 5, 5, 39, false },
{ 720, 576, 16, 9, 27000, 0, false, 12, 64, 68, false, 5, 5, 39, false },
{ 1280, 720, 16, 9, 74250, 0, false, 440, 40, 220, true, 5, 5, 20, true },
{ 1920, 1080, 16, 9, 74250, 0, true, 528, 44, 148, true, 2, 5, 15, true },
/* VIC 21 */
{ 1440, 576, 4, 3, 27000, 0, true, 24, 126, 138, false, 2, 3, 19, false },
{ 1440, 576, 16, 9, 27000, 0, true, 24, 126, 138, false, 2, 3, 19, false },
{ 1440, 288, 4, 3, 27000, 0, false, 24, 126, 138, false, 2, 3, 19, false },
{ 1440, 288, 16, 9, 27000, 0, false, 24, 126, 138, false, 2, 3, 19, false },
{ 2880, 576, 4, 3, 54000, 0, true, 48, 252, 276, false, 2, 3, 19, false },
{ 2880, 576, 16, 9, 54000, 0, true, 48, 252, 276, false, 2, 3, 19, false },
{ 2880, 288, 4, 3, 54000, 0, false, 48, 252, 276, false, 2, 3, 19, false },
{ 2880, 288, 16, 9, 54000, 0, false, 48, 252, 276, false, 2, 3, 19, false },
{ 1440, 576, 4, 3, 54000, 0, false, 24, 128, 136, false, 5, 5, 39, false },
{ 1440, 576, 16, 9, 54000, 0, false, 24, 128, 136, false, 5, 5, 39, false },
/* VIC 31 */
{ 1920, 1080, 16, 9, 148500, 0, false, 528, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 16, 9, 74250, 0, false, 638, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 16, 9, 74250, 0, false, 528, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 16, 9, 74250, 0, false, 88, 44, 148, true, 4, 5, 36, true },
{ 2880, 480, 4, 3, 108000, 0, false, 64, 248, 240, false, 9, 6, 30, false },
{ 2880, 480, 16, 9, 108000, 0, false, 64, 248, 240, false, 9, 6, 30, false },
{ 2880, 576, 4, 3, 108000, 0, false, 48, 256, 272, false, 5, 5, 39, false },
{ 2880, 576, 16, 9, 108000, 0, false, 48, 256, 272, false, 5, 5, 39, false },
{ 1920, 1080, 16, 9, 72000, 0, true, 32, 168, 184, true, 23, 5, 57, false, 0, 0, true },
{ 1920, 1080, 16, 9, 148500, 0, true, 528, 44, 148, true, 2, 5, 15, true },
/* VIC 41 */
{ 1280, 720, 16, 9, 148500, 0, false, 440, 40, 220, true, 5, 5, 20, true },
{ 720, 576, 4, 3, 54000, 0, false, 12, 64, 68, false, 5, 5, 39, false },
{ 720, 576, 16, 9, 54000, 0, false, 12, 64, 68, false, 5, 5, 39, false },
{ 1440, 576, 4, 3, 54000, 0, true, 24, 126, 138, false, 2, 3, 19, false },
{ 1440, 576, 16, 9, 54000, 0, true, 24, 126, 138, false, 2, 3, 19, false },
{ 1920, 1080, 16, 9, 148500, 0, true, 88, 44, 148, true, 2, 5, 15, true },
{ 1280, 720, 16, 9, 148500, 0, false, 110, 40, 220, true, 5, 5, 20, true },
{ 720, 480, 4, 3, 54000, 0, false, 16, 62, 60, false, 9, 6, 30, false },
{ 720, 480, 16, 9, 54000, 0, false, 16, 62, 60, false, 9, 6, 30, false },
{ 1440, 480, 4, 3, 54000, 0, true, 38, 124, 114, false, 4, 3, 15, false },
/* VIC 51 */
{ 1440, 480, 16, 9, 54000, 0, true, 38, 124, 114, false, 4, 3, 15, false },
{ 720, 576, 4, 3, 108000, 0, false, 12, 64, 68, false, 5, 5, 39, false },
{ 720, 576, 16, 9, 108000, 0, false, 12, 64, 68, false, 5, 5, 39, false },
{ 1440, 576, 4, 3, 108000, 0, true, 24, 126, 138, false, 2, 3, 19, false },
{ 1440, 576, 16, 9, 108000, 0, true, 24, 126, 138, false, 2, 3, 19, false },
{ 720, 480, 4, 3, 108000, 0, false, 16, 62, 60, false, 9, 6, 30, false },
{ 720, 480, 16, 9, 108000, 0, false, 16, 62, 60, false, 9, 6, 30, false },
{ 1440, 480, 4, 3, 108000, 0, true, 38, 124, 114, false, 4, 3, 15, false },
{ 1440, 480, 16, 9, 108000, 0, true, 38, 124, 114, false, 4, 3, 15, false },
{ 1280, 720, 16, 9, 59400, 0, false, 1760, 40, 220, true, 5, 5, 20, true },
/* VIC 61 */
{ 1280, 720, 16, 9, 74250, 0, false, 2420, 40, 220, true, 5, 5, 20, true },
{ 1280, 720, 16, 9, 74250, 0, false, 1760, 40, 220, true, 5, 5, 20, true },
{ 1920, 1080, 16, 9, 297000, 0, false, 88, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 16, 9, 297000, 0, false, 528, 44, 148, true, 4, 5, 36, true },
{ 1280, 720, 64, 27, 59400, 0, false, 1760, 40, 220, true, 5, 5, 20, true },
{ 1280, 720, 64, 27, 74250, 0, false, 2420, 40, 220, true, 5, 5, 20, true },
{ 1280, 720, 64, 27, 74250, 0, false, 1760, 40, 220, true, 5, 5, 20, true },
{ 1280, 720, 64, 27, 74250, 0, false, 440, 40, 220, true, 5, 5, 20, true },
{ 1280, 720, 64, 27, 74250, 0, false, 110, 40, 220, true, 5, 5, 20, true },
{ 1280, 720, 64, 27, 148500, 0, false, 440, 40, 220, true, 5, 5, 20, true },
/* VIC 71 */
{ 1280, 720, 64, 27, 148500, 0, false, 110, 40, 220, true, 5, 5, 20, true },
{ 1920, 1080, 64, 27, 74250, 0, false, 638, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 64, 27, 74250, 0, false, 528, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 64, 27, 74250, 0, false, 88, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 64, 27, 148500, 0, false, 528, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 64, 27, 148500, 0, false, 88, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 64, 27, 297000, 0, false, 528, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 64, 27, 297000, 0, false, 88, 44, 148, true, 4, 5, 36, true },
{ 1680, 720, 64, 27, 59400, 0, false, 1360, 40, 220, true, 5, 5, 20, true },
{ 1680, 720, 64, 27, 59400, 0, false, 1228, 40, 220, true, 5, 5, 20, true },
/* VIC 81 */
{ 1680, 720, 64, 27, 59400, 0, false, 700, 40, 220, true, 5, 5, 20, true },
{ 1680, 720, 64, 27, 82500, 0, false, 260, 40, 220, true, 5, 5, 20, true },
{ 1680, 720, 64, 27, 99000, 0, false, 260, 40, 220, true, 5, 5, 20, true },
{ 1680, 720, 64, 27, 165000, 0, false, 60, 40, 220, true, 5, 5, 95, true },
{ 1680, 720, 64, 27, 198000, 0, false, 60, 40, 220, true, 5, 5, 95, true },
{ 2560, 1080, 64, 27, 99000, 0, false, 998, 44, 148, true, 4, 5, 11, true },
{ 2560, 1080, 64, 27, 90000, 0, false, 448, 44, 148, true, 4, 5, 36, true },
{ 2560, 1080, 64, 27, 118800, 0, false, 768, 44, 148, true, 4, 5, 36, true },
{ 2560, 1080, 64, 27, 185625, 0, false, 548, 44, 148, true, 4, 5, 36, true },
{ 2560, 1080, 64, 27, 198000, 0, false, 248, 44, 148, true, 4, 5, 11, true },
/* VIC 91 */
{ 2560, 1080, 64, 27, 371250, 0, false, 218, 44, 148, true, 4, 5, 161, true },
{ 2560, 1080, 64, 27, 495000, 0, false, 548, 44, 148, true, 4, 5, 161, true },
{ 3840, 2160, 16, 9, 297000, 0, false, 1276, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 16, 9, 297000, 0, false, 1056, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 16, 9, 297000, 0, false, 176, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 16, 9, 594000, 0, false, 1056, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 16, 9, 594000, 0, false, 176, 88, 296, true, 8, 10, 72, true },
{ 4096, 2160, 256, 135, 297000, 0, false, 1020, 88, 296, true, 8, 10, 72, true },
{ 4096, 2160, 256, 135, 297000, 0, false, 968, 88, 128, true, 8, 10, 72, true },
{ 4096, 2160, 256, 135, 297000, 0, false, 88, 88, 128, true, 8, 10, 72, true },
/* VIC 101 */
{ 4096, 2160, 256, 135, 594000, 0, false, 968, 88, 128, true, 8, 10, 72, true },
{ 4096, 2160, 256, 135, 594000, 0, false, 88, 88, 128, true, 8, 10, 72, true },
{ 3840, 2160, 64, 27, 297000, 0, false, 1276, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 64, 27, 297000, 0, false, 1056, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 64, 27, 297000, 0, false, 176, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 64, 27, 594000, 0, false, 1056, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 64, 27, 594000, 0, false, 176, 88, 296, true, 8, 10, 72, true },
{ 1280, 720, 16, 9, 90000, 0, false, 960, 40, 220, true, 5, 5, 20, true },
{ 1280, 720, 64, 27, 90000, 0, false, 960, 40, 220, true, 5, 5, 20, true },
{ 1680, 720, 64, 27, 99000, 0, false, 810, 40, 220, true, 5, 5, 20, true },
/* VIC 111 */
{ 1920, 1080, 16, 9, 148500, 0, false, 638, 44, 148, true, 4, 5, 36, true },
{ 1920, 1080, 64, 27, 148500, 0, false, 638, 44, 148, true, 4, 5, 36, true },
{ 2560, 1080, 64, 27, 198000, 0, false, 998, 44, 148, true, 4, 5, 11, true },
{ 3840, 2160, 16, 9, 594000, 0, false, 1276, 88, 296, true, 8, 10, 72, true },
{ 4096, 2160, 256, 135, 594000, 0, false, 1020, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 64, 27, 594000, 0, false, 1276, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 16, 9, 1188000, 0, false, 1056, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 16, 9, 1188000, 0, false, 176, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 64, 27, 1188000, 0, false, 1056, 88, 296, true, 8, 10, 72, true },
{ 3840, 2160, 64, 27, 1188000, 0, false, 176, 88, 296, true, 8, 10, 72, true },
/* VIC 121 */
{ 5120, 2160, 64, 27, 396000, 0, false, 1996, 88, 296, true, 8, 10, 22, true },
{ 5120, 2160, 64, 27, 396000, 0, false, 1696, 88, 296, true, 8, 10, 22, true },
{ 5120, 2160, 64, 27, 396000, 0, false, 664, 88, 128, true, 8, 10, 22, true },
{ 5120, 2160, 64, 27, 742500, 0, false, 746, 88, 296, true, 8, 10, 297, true },
{ 5120, 2160, 64, 27, 742500, 0, false, 1096, 88, 296, true, 8, 10, 72, true },
{ 5120, 2160, 64, 27, 742500, 0, false, 164, 88, 128, true, 8, 10, 72, true },
{ 5120, 2160, 64, 27, 1485000, 0, false, 1096, 88, 296, true, 8, 10, 72, true },
};
static int edid[] = {
0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x50,0x6c,0x62,0x09,0x01,0x00,0x00,0x00,
0x11,0x1c,0x01,0x03,0x80,0x73,0x41,0x78,0x0a,0xcf,0x74,0xa3,0x57,0x4c,0xb0,0x23,
0x09,0x48,0x4c,0x21,0x08,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x3a,0x80,0x18,0x71,0x38,0x2d,0x40,0x58,0x2c,
0x45,0x00,0x20,0xc2,0x31,0x00,0x00,0x1e,0x01,0x1d,0x00,0x72,0x51,0xd0,0x1e,0x20,
0x6e,0x28,0x55,0x00,0x20,0xc2,0x31,0x00,0x00,0x1e,0x00,0x00,0x00,0xfc,0x00,0x54,
0x43,0x4c,0x20,0x53,0x4d,0x41,0x52,0x54,0x20,0x54,0x56,0x0a,0x00,0x00,0x00,0xfd,
0x00,0x3b,0x46,0x1f,0x8c,0x3c,0x00,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x01,0x4c,
0x02,0x03,0x35,0xf0,0x53,0x10,0x1f,0x14,0x05,0x13,0x04,0x20,0x22,0x3c,0x3e,0x12,
0x16,0x03,0x07,0x11,0x15,0x02,0x06,0x01,0x26,0x09,0x07,0x03,0x15,0x07,0x50,0x83,
0x01,0x00,0x00,0x6e,0x03,0x0c,0x00,0x20,0x00,0xb8,0x3c,0x20,0x00,0x80,0x01,0x02,
0x03,0x04,0xe2,0x00,0xfb,0x02,0x3a,0x80,0xd0,0x72,0x38,0x2d,0x40,0x10,0x2c,0x45,
0x80,0x30,0xeb,0x52,0x00,0x00,0x1f,0x01,0x1d,0x00,0xbc,0x52,0xd0,0x1e,0x20,0xb8,
0x28,0x55,0x40,0x30,0xeb,0x52,0x00,0x00,0x1f,0x8c,0x0a,0xd0,0x8a,0x20,0xe0,0x2d,
0x10,0x10,0x3e,0x96,0x00,0x13,0x8e,0x21,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70
};
void block_name(unsigned char block) {
switch (block) {
case 0x00: printf("Base EDID\n\n"); break;
case 0x02: printf("CTA-861 Extension Block\n\n"); break;
case 0x10: printf("Video Timing Extension Block\n\n"); break;
case 0x20: printf("EDID 2.0 Extension Block\n\n"); break;
case 0x40: printf("Display Information Extension Block\n\n"); break;
case 0x50: printf("Localized String Extension Block\n\n"); break;
case 0x60: printf("Microdisplay Interface Extension Block\n\n"); break;
case 0x70: printf("DisplayID Extension Block\n\n"); break;
case 0xf0: printf("Block Map Extension Block\n\n"); break;
case 0xff: printf("Manufacturer-Specific Extension Block\n\n"); break;
default:
printf("Unknown EDID Extension Block\n\n");
}
}
void block_info() {
printf("Get block1 information start!\n");
if (edid[0x80] == 0x02) {
unsigned version = edid[0x81];
unsigned offset = edid[0x82];
printf("Revision: %u\n", edid[0x81]);
if (version >= 1) {
if (version == 1 && edid[0x83] != 0)
printf("Non-zero byte 3.\n");
if (offset < 4) {
return;
}
if (version < 3 && ((offset - 4) / 8)) {
printf(" 8-byte timing descriptors: %u\n", (offset - 4) / 8);
printf("8-byte descriptors were never used.\n");
}
if (version >= 2) {
if (edid[0x83] & 0x80)
printf(" Underscans IT Video Formats by default\n");
else
printf("IT Video Formats are overscanned by default, but normally this should be underscanned.\n");
if (edid[0x83] & 0x40)
printf(" Basic audio support\n");
if (edid[0x83] & 0x20)
printf(" Supports YCbCr 4:4:4\n");
if (edid[0x83] & 0x10)
printf(" Supports YCbCr 4:2:2\n");
printf(" Native detailed modes: %u\n\n", edid[0x83] & 0x0f);
}
}
}
}
panel_info get_panel_info(struct timings info,int x) {
panel_info panel;
panel.vic = x;
panel.vact = info.vact;
panel.hact = info.hact;
panel.vratio = info.vratio;
panel.hratio = info.hratio;
unsigned hbl = info.hfp + info.hsync + info.hbp + 2 * info.hborder;
unsigned vbl = info.vfp + info.vsync + info.vbp + 2 * info.vborder;
unsigned htotal = info.hact + hbl;
double hor_freq_khz = htotal ? (double)info.pixclk_khz / htotal : 0;
if (info.interlaced)
panel.vact /= 2;
panel.freq_khz = hor_freq_khz;
if (info.ycbcr420)
hor_freq_khz /= 2;
long vtotal = panel.vact + vbl;
if (info.even_vtotal)
vtotal = panel.vact + info.vfp + info.vsync + info.vbp;
else if (info.interlaced)
vtotal = panel.vact + info.vfp + info.vsync + info.vbp + 0.5;
panel.refresh = info.pixclk_khz * 1000.0 / (htotal * vtotal);
panel.pixclk = info.pixclk_khz * 1000.0;
panel.pixclk /= 1000000;
return panel;
}
vsdb_info get_VSDB_vic(vsdb_info vsdb) {
int start = 0x83;
int i;
int length = 0, flag = 0;
int len_vic, h_active, v_active, len_3d;
int num = sizeof(edid) / sizeof(int);
while ((flag != 3) & (num > start)) {
start += (length + 1);
length = edid[start] & 0x1F;
flag = edid[start] >> 5;
}
printf(" Source physical address: %x.%x.%x.%x\n", edid[start + 4] >> 4, edid[start + 4] & 0x0f,
edid[start + 5] >> 4, edid[start + 5] & 0x0f);
if (length < 3)
return vsdb;
if (edid[start + 6] & 0x80)
printf(" Supports_AI\n");
if (edid[start + 6] & 0x40)
printf(" DC_48bit\n");
if (edid[start + 6] & 0x20)
printf(" DC_36bit\n");
if (edid[start + 6] & 0x10)
printf(" DC_30bit\n");
if (edid[start + 6] & 0x08)
printf(" DC_Y444\n");
/* two reserved bits */
if (edid[start + 6] & 0x01)
printf(" DVI_Dual\n");
if (length < 4)
return vsdb;
printf(" Maximum TMDS clock: %u MHz\n", edid[start + 7] * 5);
if (edid[start + 8] & 0x0f) {
printf(" Supported Content Types:\n");
if (edid[start + 8] & 0x01)
printf(" Graphics\n");
if (edid[start + 8] & 0x02)
printf(" Photo\n");
if (edid[start + 8] & 0x04)
printf(" Cinema\n");
if (edid[start + 8] & 0x08)
printf(" Game\n");
}
int b = 9;
if (edid[start + 8] & 0x80) {
if (edid[start + 8] & 0x40) {
if (edid[b] == edid[b + 2] &&
edid[b + 1] == edid[b + 3])
printf("Progressive and Interlaced latency values are identical, no need for both.\n");
b += 2;
}
b += 2;
}
if ((!edid[start + 8]) & 0x20)
return vsdb;
bool mask = false;
bool formats = false;
printf(" Extended HDMI video details:\n");
if (edid[b] & 0x80)
printf(" 3D present\n");
if ((edid[b] & 0x60) == 0x20) {
printf(" All advertised VICs are 3D-capable\n");
formats = true;
}
if ((edid[b] & 0x60) == 0x40) {
printf(" 3D-capable-VIC mask present\n");
formats = true;
mask = true;
}
switch (edid[b] & 0x18) {
case 0x00: break;
case 0x08:
printf(" Base EDID image size is aspect ratio\n");
break;
case 0x10:
printf(" Base EDID image size is in units of 1 cm\n");
break;
case 0x18:
printf(" Base EDID image size is in units of 5 cm\n");
break;
}
b++;
len_vic = (edid[start + b] & 0xe0) >> 5;
len_3d = (edid[start + b] & 0x1f) >> 0;
b++;
vsdb.vic_add = b + start;
vsdb.vic_len = len_vic;
return vsdb;
}
vdb_info get_VDB_vic(vdb_info vdb) {
int start = 0x83;
int i;
int length = 0, flag = 0;
vsdb_info vsdb_inf;
vdb_info vdb_inf;
int len_vic, h_active, v_active, len_3d;
int num = sizeof(edid) / sizeof(int);
while ((flag != 2) & (num > start)) {
start += (length + 1);
length = edid[start] & 0x1F;
flag = edid[start] >> 5;
}
vdb.vic_add = start + 1;
vdb.vic_len = length;
return vdb;
}
void print_vdb_timings() {
int i;
vdb_info vdb_inf;
vdb_inf.vic_add = vdb_inf.vic_len = 0;
vdb_inf = get_VDB_vic(vdb_inf);
for (i = 0; i < vdb_inf.vic_len; i++) {
int p = edid[vdb_inf.vic_add + i] - 1;
panel_info panel;
panel = get_panel_info(edid_cta_modes[p], edid[vdb_inf.vic_add + i]);
printf("VIC %d %dx%d %d:%d %10.6ffps %8.3f %13.6f MHz\n", panel.vic, panel.hact, panel.vact, panel.hratio, panel.vratio, panel.refresh, panel.freq_khz, panel.pixclk);
}
}
void print_vsdb_timings() {
int i;
vsdb_info vsdb_inf;
vsdb_inf.vic_add = vsdb_inf.vic_len = 0;
vsdb_inf = get_VSDB_vic(vsdb_inf);
for (i = 0; i < vsdb_inf.vic_len; i++) {
int vic = edid[vsdb_inf.vic_add + i];
int p = edid_hdmi_mode_map[vic - 1] - 1;
panel_info panel;
if (vic && (vic <= 127)) {
panel = get_panel_info(edid_cta_modes[p], vic);
printf("VIC %d %dx%d %d:%d %10.6ffps %8.3f %13.6f MHz\n", panel.vic, panel.hact, panel.vact, panel.hratio, panel.vratio, panel.refresh, panel.freq_khz, panel.pixclk);
}
}
}
int main() {
block_name(edid[0x80]);
block_info();
printf("Parse cta block start!\n");
print_vdb_timings();
print_vsdb_timings();
return 0;
}
代码提供了两种不同的edid,其中一个解析出来为:
首先是edid的版本信息。然后是vdb支持的分辨率,一共19组,最后是vsdb支持的分辨率,一共四组。