关于PCR的重要性在网络上到处都是,但是关于PCR的计算的帖子网上写的却不多
,分析来,发现并不是一个很复杂的过程
在此 我简单描述一下关于通过PCR计算码率的过程。首先。我们要在TS流中找到
PSI信息表,这里我就不多说了。顺序是PAT-->PMT--->PCR_PID.
当得到PCR_PID后,我们就可以根据它找对应具有PCR信息的包,有时候这个包的
指向会在VIDEO数据包内,不要奇怪。是否具有PCR信息关键看
Adaptation_Filed_Control,关于Adaptation_Filed_Control的描述在协议里说
的很清楚,大家可以看协议:)
当Adaptation_Filed_Control 描述此包具有调整字段时,注意了,在这里我们
就可以找到PCR的值了。分析得出PCR_Base 和 PCR_ext。把PCR_Base*300+
PCR_ext。就可以得到一个PCR的值。那么再找紧跟其后的一个PCR的值,方法同
上。
当得到2个PCR的值 姑且定义为 PCR_ONE,PCR_TWO.
根据协议中的公式 I-2-5计算出rate;
rate = (2个PCR相隔的包的个数*188*8 *27000000)/(PCR_TWO - PCR_ONE)
PCR包个数*188*8 得到2个PCR之间相差的位数
from : http://blog.csdn.net/charlie0895/archive/2007/08/23/1755683.aspx
//
// This routine extracts the bitrate from the content file.
// The content file must contain PCRs
//
double getBitRate(FILE *fp)
{
// variables used to get bit rate from content file
uint64_t PCR0 = 0, PCR1 = 0;
uint64_t PCRdelta;
double bitRate = 0;
uint32_t mpegPackets = 0;
uint32_t gotPCR = 0;
unsigned char m2tTmp[256];
int length;
unsigned int PID = 0;
//used to control "." output
int sync = 0;
printf(" Scanning content file for bit rate ");
for (;;) {
length = fread(m2tTmp, sizeof(uint8_t), 188, fp);
if(length != 188) break;
mpegPackets++;
if (sync % 1200 == 0 ) {
//show user something while we loop
printf(".");
//force it out-may not otherwise appear in real time
fflush(stdout);
}
sync++;
// look for the sync byte
if(m2tTmp[0] != 0x47) {
printf("vpSendspts: data corruption in content file ");
fclose(fp);
exit(2);
}
// we are going to scan through the first 10 PCRs in this content.
// According to the specifications that will be on the order of
// every 40 milliseconds. We don't have to scan the whole file
// to get a good sense of its validity and bit rate.
// First see if the TS header indicates the presence of an
// adaptation field.
if(GET_DVBASI_ADAPT(m2tTmp) & 0x02) {
// Get the adaptation field and look for the presence of
// a PCR in the adaptation field
if(GET_DVBASI_ADAPTLENGTH(m2tTmp) == 0) {
printf("Zero length AF ");
continue;
}
if(GET_DVBASI_ADAPTFIELD(m2tTmp) & 0x10) {
// Get the initial PCR and reset the counter
if(gotPCR == 10) { // skip the first few, some times they are bad!
PID = GET_DVBASI_PID(m2tTmp);
GET_DVBASI_PCR(m2tTmp, PCR0);
mpegPackets = 0;
}
// Look for the 10th PCR in this content and
if((gotPCR > 20) && PID == GET_DVBASI_PID(m2tTmp)) {
GET_DVBASI_PCR(m2tTmp, PCR1);
PCRdelta = (uint64_t) ((uint64_t)PCR1 - (uint64_t)PCR0);
bitRate = (double) ( ((double)(40608000000ULL)*((double)mpegPackets))/(double)(PCRdelta));
break;
}
gotPCR++;
} // GET_DVBASI_ADAPTFIELD
} //GET_DVBASI_ADAPT
} // while read
//rewind file
rewind(fp);
fflush(fp);
return(bitRate);
}