1、PCR概念与解析
PCR(program clock reference),即节目时钟基准。每一个节目都有一个独立的PCR字段。
PCR有PCR-base和PCR-extension两部分,由42位码字组成。一部分以系统参考时钟(27MHz)的1/300(90kHz)为单位,称为PCR_base,共33bit;另一部分以系统参考时钟(27MHz)为单位,称为PCR_ext,共9bit。
通过PCR值不但可以获得正确的解码时间,还可以计算TS速率等与时间有关的信息。这里的I’-I’’意思是连个包含PCR的数据包之间的字节差值。
读取pcr的代码如下:
// buf为ts packet加4字节偏移量,比较时需要保证同一个节目的,因此最好是同一个pid的。
uint64 ts_get_pcr(uint8* buf, int *flag)
{
int offset = 0;
uint8 pcr_flag = 0;
uint64 pcrbase=0;
uint16 pcrext=0;
uint64 pcr = 0; //TS: program clock reference [parsed in adaption field]
if(!buf) return 0;
pcr_flag = (buf[1] & 0x10) >>4;
offset = 2;
if(1==pcr_flag)
{
pcrbase = (buf[offset]<<25) | (buf[offset+1]<<17) | (buf[offset+2]<<9) | (buf[offset+3]<<1) | ((buf[offset+4]&0x80)>>7 );
pcrext = ((buf[offset+4]&0x01)<<8) | buf[offset+5];
pcr = pcrbase*300 + pcrext;
*flag = 1;
offset +=6;
}
return pcr;
}
2、根据PCR计算码率
A、在文件前面查一个含PCR字段的TS包,取出PCR值和PID。
pcr = pcrbase*300 + pcrext;
B、在文件尾查找这个PID的TS包,取出PCR值。
C、将这两个包的位置之间的BYTE大小除PCR的差值再乘27000000再乘8,即得TS文件的码率。
3、应用范例
某个
198M字节,播放时长95秒
,总码率17395kbps
的ts文件中的pid=256的流参数:
begin pcr=18900000, pcr_offset=752,
end pcr=2337816600, pcr_offset=187060752,
如果程序每次读取字节数为:
496*188。则为了ts流播放稳定,设置定时读取的时间间隔timer_val 应该是多少?
码率=(187,060,752-752)*27,000,000*8/(2,337,816,600-18,900,000)=
17,424,067 bps
timer_val =
496*188*8*1,000,000/17,424,067=42813