從手上現有的HDMI EDID(256 bytes)發現,block1(CEA EDID Timing Extension data format)的video data block會存放擴展用的resolution list。
因此寫一支小程式特別讀取resolution id並轉換成寬x高 (pixel)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BLOCK0_SIZE 128
int getResolutionWidth(int index)
{
switch(index)
{
case 1: return 640;
case 2: case 3: case 6: case 17: case 18: return 720;
case 4: case 19: case 60: case 61: case 62: case 65: case 66: case 67: case 68: case 69: return 1280;
case 5: case 16: case 20: case 31: case 32: case 33: case 34: case 39: case 72: case 73: case 74: case 75: case 76: return 1920;
case 86: case 87: case 88: case 89: case 90: case 91: case 92: case 113: return 2560;
case 93: case 94: case 95: case 96: case 97: case 114: case 116: case 117: case 118: case 119: case 120: return 3840;
case 98: case 99: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: case 115: return 4096;
case 121: case 122: case 123: case 124: case 125: case 126: case 127: return 5120;
}
return 0;
}
int getResolutionHeight(int index)
{
switch(index)
{
case 1: case 2: case 3: case 6: return 480;
case 17: case 18: return 720;
case 4: case 19: case 60: case 61: case 62: case 65: case 66: case 67: case 68: case 69: return 720;
case 5: case 16: case 20: case 31: case 32: case 33: case 34: case 39: case 72: case 73: case 74: case 75: case 76: case 86: case 87: case 88: case 89: case 90: case 91: case 92: case 113: return 1080;
case 93: case 94: case 95: case 96: case 97: case 114: case 116: case 117: case 118: case 119: case 120: case 98: case 99: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: case 115: case 121: case 122: case 123: case 124: case 125: case 126: case 127: return 2160;
}
return 0;
}
int main(int argc, char *argv[])
{
int fd = -1;
int ret = 0;
int size = 0;
char *edidBuf = NULL;
if(argc <= 1) {
printf("invalid argument, please set input parameter.\n");
return -1;
}
fd = open(argv[1],O_RDONLY);
if(fd == -1)
return -1;
size = lseek(fd,0,SEEK_END);
lseek(fd,0,SEEK_SET);
printf("edid size:%d \n",size);
edidBuf = (char*)malloc(sizeof(char)*size);
if(edidBuf == NULL)
{
printf("malloc failed\n");
ret = -1;
goto parse_exit;
}
if((size != read(fd,edidBuf,sizeof(char)*size)) && size < BLOCK0_SIZE)
{
printf("Get edid size not match, size should be %d \n",size);
ret = -1;
goto parse_exit;
}
int index = 0;
int width = 0, height = 0;
int block_num = 0, block_end_offset;
//CEA EDID
if(size > BLOCK0_SIZE && edidBuf[0x80] == 0x02)
{
if(edidBuf[0x82] == 0x04) //No data block, jump out
{
printf("No data block, exit!\n");
goto parse_exit;
}
else if(edidBuf[0x82] == 0)
{
block_end_offset=size;
}
else
{
block_end_offset = edidBuf[0x82] + 0x80;
}
printf("block_end_offset:%d \n",block_end_offset);
index = 0;
width = 0;
height = 0;
while((0x84 + index) < block_end_offset) //Start to parse from data block
{
printf("edid data:0x%02x \n",edidBuf[0x84+index]);
if((edidBuf[0x84+index]&0xE0) == 0x40) //Video data block
{
block_num = edidBuf[0x84+index]&0x1F;
printf("video block number:%d \n",block_num);
int i=0,max=0;
for(i=0;i<block_num;i++)
{
if(getResolutionHeight((int)edidBuf[0x84+index+1+i])>height)
{
width = getResolutionWidth((int)edidBuf[0x84+index+1+i]);
height = getResolutionHeight((int)edidBuf[0x84+index+1+i]);
}
printf("id:%d width:%d height:%d\n",edidBuf[0x84+index+1+i],getResolutionWidth((int)edidBuf[0x84+index+1+i]),getResolutionHeight((int)edidBuf[0x84+index+1+i]));
}
break;
}
else //other data block(we ignore it)
{
block_num = edidBuf[0x84+index]&0x1F;
index+=block_num;
}
index++;
}
printf("max resolution is (%d,%d)\n",width,height);
}
parse_exit:
if(edidBuf != NULL)
free(edidBuf);
close(fd);
return ret;
}
簡單來說就是檢查block1是否是CEA block,非CEA就不做下一步。
檢查offset 0x02是否有DTD,如果值是0x04也代表不用檢查Data block,因為resolution會是由DTD block決定(不過暫時不支援DTD parser)
然後從offset 0x04開始過濾Data Block Collection ,因為只要過濾video data block,所以其它部分均跳過,Data Block Collection的類型可以參考EDID Wiki有說明。
最後根據VIC數值轉換到相應的寬x高並找出即可(我們先判斷高度然後再判斷寬度)。
運行結果如下:
1. https://en.wikipedia.org/wiki/Extended_Display_Identification_Data
2.. http://www.edidreader.com/
沒有留言:
張貼留言