计算视频文件(包含PCR)播放带宽的方法 PCR计算码率

来源:互联网 发布:卓依婷 知乎 编辑:程序博客网 时间:2024/04/29 03:56

 

关于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

通过对码流播放卡的分析,以及对公式的对照,对实际计算播放视频文件所用带宽的方法进行了分析(附件中,带有c语言的实现)
 
分析如下:
关键是最后计算带宽的公式:
PCRdelta = (uint64_t) ((uint64_t)PCR1 - (uint64_t)PCR0);
bitRate = (double) ( ((double)(40608000000ULL)*((double)mpegPackets))/(double)(PCRdelta));
 
PCRdelta : 是相邻N个PCR的PCR差值
mpegPackets : 是相邻N个PCR,所包含的packet的数量(MPEG packet)
 
我们可以理解为: mpegPackets*188表示实际的数据
                而PCRdelta表示播放这段实际数据,总需要播放的总数据量.
 
则: (mpegPackets*188)/PCRdelta : 单位实际播放的数据中所包含的有效(MPEG packet)数据量
而我们目前所使用的VP播放卡,要求了,DVB-ASI输出带宽必须是216Mb/s
所以就有 bitRate/216000000 =  (mpegPackets*188)/PCRdelta  
 
因此得到   bitRate = (double) ( ((double)(40608000000ULL)*((double)mpegPackets))/(double)(PCRdelta));
 
所以,按照目前这样分析,播放同一个包含pcr的视频文件,如果播放的DVB-ASI输出总带宽不同,则播放视频文件所分配的带宽也应该不同.
////////////////////////////////////////////////////////////////////////
//
//    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);
}
0 0
原创粉丝点击