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支持的分辨率,一共四组。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CTA-861-G是《电子消费设备——视频系统的解析能力以及互连操作标准》的一个版本。其目的是更新和扩展视频和音频设备的标准,以便消费者能够享受更好的音视频体验。在这一标准中,CSN指向一个重要的补充规范,该规范主要解决了视频信号完整性和兼容性问题。 CTA-861-G标准规定了各种信号格式的参数、最大分辨率、刷新率、输入格式等,这些是连接更高端的电视显示器和其他设备所必需的。其覆盖范围和要求更高于之前的版本,包括HDR、4K分辨率、更宽的色域和色深,以及增加的音频和视频容量等。 此外,CSN编写了一系列附加规范,这些规范为设备间的互操作性提供了更多的细节和要求。例如,规范对于HDMI连接的电缆长度、欧洲广播联盟电视标准、高效视频编码等均给出了明确的说明。这些标准的制定有利于产品的互通性和兼容性,消费者可以更加方便、稳定地连接和使用各种设备。 总之,CTA-861-G CSN是一种定义了电子消费设备互联操作标准的规范,它可以确保设备兼容性和可互操作性的良好表现,并为消费者提供更好的音视频体验。 ### 回答2: CTA-861-G是一项显示技术标准,该标准由消费技术协会(Consumer Technology Association,简称CTA)制定。它定义了高清视频和音频设备之间的连接规范和协议,确保视频和音频信号的正确传输和兼容性。 CTA-861-G标准主要应用于HDMI接口,旨在实现不同厂家生产的高清显示设备的互操作性。标准规定了视频信号的分辨率、帧率、色彩空间、音频格式等参数,并定义了支持这些参数的设备之间的通信和交互方式。通过遵循CTA-861-G标准,用户可以将各种设备(如电视机、投影仪、音箱、DVD播放器等)连接起来,享受高质量的音视频体验。 在实际应用中,CTA-861-G标准广泛被采用于家庭娱乐系统、影院系统、游戏主机、电视机等设备。它确保了设备之间的兼容性,提供了高清画面的展示和高品质音频的播放效果。此外,该标准还支持HDCP(High-bandwidth Digital Content Protection)内容保护技术,防止未经授权的内容复制和传播。 总之,CTA-861-G是一项用于高清视频和音频设备间连接的技术标准,它确保了设备之间的互操作性和信号传输的正确性,为用户提供了优质的音视频体验。 ### 回答3: cta-861-g是一种视频显示标准,由消费电子协会(Consumer Technology Association, CTA)制定。该标准规定了视频显示设备的互连性、分辨率、频率、音频格式等方面的要求。 在视频显示技术发展迅猛的今天,标准化的互连接口对设备之间的兼容性和互操作性至关重要。cta-861-g标准定义了视频设备之间的连接方式,确保了设备的互联互通。例如,标准规定了HDMI(高清晰度多媒体接口)的信号格式,使得不同品牌的HDMI设备可以无缝连接并进行高质量视频传输。 另外,cta-861-g还规定了视频显示的分辨率和频率要求。通过统一规范显示器的分辨率和刷新率,可以保证视频信号在不同设备之间的兼容性和一致性。这对于视频内容创作者和用户来说,意味着他们可以在各种不同的设备上获得相同的视觉效果,提升了视听体验。 此外,cta-861-g还关注音频格式的兼容性。它规定了支持哪些音频格式以及它们的传输方式,确保音频信号在设备之间的传输和解码一致。这对于音频制作和消费者来说,保证了音频效果的一致性和高质量。 总的来说,cta-861-g是一个重要的视频显示标准,它在设备互联性、分辨率、频率和音频方面提供了统一的规范和指导。它的出现,促进了视频设备的互操作性和用户体验的统一,对于视频行业的发展具有重要的意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值