CTA-861标准解析EDID的VSDB与VDB

之前在某项目上做屏幕自适应分辨率时,按照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支持的分辨率,一共四组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值