# MKV格式的PTS解析代码

2016-12-23

MKV格式的PTS解析代码：在文章视频解码研究之PTS(2)Mp4格式，AVI格式和MKV格式中，提到mkv格式的PTS，并编写程序对某MKV文件进行解析计算，得到各个block绝对时间码。

MKV格式的PTS解析代码：在文章视频解码研究之PTS(2)Mp4格式，AVI格式和MKV格式中，提到mkv格式的PTS，并编写程序对某MKV文件进行解析计算，得到各个block绝对时间码。程序十分简单，代码如下，帮助大家理解mkv文件的格式。

#include
#define ID_CLUSTER 0x1F43B675
#define ID_TC 0xE7
#define ID_BL 0xA1
#define ID_SBL 0xA3
#define R4(a) ((a<<24)| \
( (a<<8) & 0xFF0000 ) | \
( (a>>8) & 0xFF00 )   | \
( a>>24 ))

#define R3(a) (((a<<16) & 0xFF0000) | (a>>16) |(a & 0xFF00))
#define R2(a)  ((a<<8)&(0xFF00))|(a>>8)
unsigned int re(int l,int w) // l should be 2~4
{
if(l == 1)
return w;
else if(l == 2)
return R2(w);
else if(l == 3)
return R3(w);
else if(l == 4)
return R4(w);
}

unsigned int readEBML(FILE *fpE,unsigned char id)
{
unsigned char ucTemp;
unsigned int eLength = 0;
unsigned int ulEle,ulRest=0;
for(;eLength < 8;eLength++)
{
if(((ucTemp<=0x80)
break;
}
if(id == 0)
ucTemp = ucTemp - (0x1<<(8-eLength-1));
if(eLength!=0)
{
ulEle = (ucTemp<<(eLength*8))|(re(eLength,ulRest));
}
else
ulEle = ucTemp;
return ulEle;
}
void main(void)
{
FILE *fpMkv ;
unsigned int  ulTempID;
unsigned int  eLength;
unsigned int  clSize = 0,clTCSize = 0,blSize = 0;
unsigned int  clTC = 0;
int           blTC=0,aTC = 0; //aTC = blTC + clTC
unsigned char trackID;
char          tcCnt = 0;
fpMkv = fopen("D://xx.mkv","rb"); //open mkv file
ulTempID = readEBML(fpMkv,1); //test, should be "1a45dfa3"
while(1)
{
ulTempID = R4(ulTempID);
if(ulTempID == ID_CLUSTER) //find cluster
{
printf("cluster found!\n");
break;
}
else
{
fseek(fpMkv,-3,SEEK_CUR);
}
}

if(ulTempID == ID_TC)       //timecode id
{
clTC = R2(clTC);
}
while(tcCnt < 30) // first 30 time code
{
if(ulTempID == ID_BL||ulTempID == ID_SBL) // or simple block id
{
if(trackID == 1) // video, not necessary to 1
{
blTC = R2(blTC);
aTC = blTC + clTC;
printf("block %d, timecode = %ld\n",tcCnt,aTC);
tcCnt++;
fseek(fpMkv,blSize - 3,SEEK_CUR);
}
else
{
fseek(fpMkv,blSize - 1,SEEK_CUR);
}
}
}
getchar();
}