首页 > 程序开发 > 综合编程 > 其他综合 >

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;
	fread(&ucTemp,1,sizeof(char),fpE);
	for(;eLength < 8;eLength++)
	{
		if(((ucTemp<=0x80)
			break;
	}
	if(id == 0)
		ucTemp = ucTemp - (0x1<<(8-eLength-1));
	if(eLength!=0)
	{
		fread(&ulRest,1,eLength*sizeof(char),fpE);
		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)
	{
		fread(&ulTempID,1,sizeof(unsigned int),fpMkv);
		ulTempID = R4(ulTempID);
		if(ulTempID == ID_CLUSTER) //find cluster
		{
			printf("cluster found!\n");	
			break;
		}
		else
		{
			fseek(fpMkv,-3,SEEK_CUR);	
		}
	}

	clSize = readEBML(fpMkv,0); //cluster size
	ulTempID = readEBML(fpMkv,1);
	if(ulTempID == ID_TC)       //timecode id
	{
		clTCSize = readEBML(fpMkv,0); //timecode size
		fread(&clTC,sizeof(char),clTCSize,fpMkv); //cluster timecode
		clTC = R2(clTC);
	}
	while(tcCnt < 30) // first 30 time code
	{
		ulTempID = readEBML(fpMkv,1); //block id
		if(ulTempID == ID_BL||ulTempID == ID_SBL) // or simple block id
		{
			blSize = readEBML(fpMkv,0); //block size
			trackID = readEBML(fpMkv,0);
			if(trackID == 1) // video, not necessary to 1 
			{
				fread(&blTC,sizeof(char),2,fpMkv);
				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();
}
相关文章
最新文章
热点推荐