我正在尝试从PTS创建PCR,如下所示。
S64 nPcr = nPts * 9 / 100;
pTsBuf[4] = 7 + nStuffyingBytes;
pTsBuf[5] = 0x10; /* flags */
pTsBuf[6] = ( nPcr >> 25 )&0xff;
pTsBuf[7] = ( nPcr >> 17 )&0xff;
pTsBuf[8] = ( nPcr >> 9 )&0xff;
pTsBuf[9] = ( nPcr >> 1 )&0xff;
pTsBuf[10]= ( nPcr << 7 )&0x80;
pTsBuf[11]= 0;
但问题是VLC只播放第一帧而不播放任何其他帧。 我收到警告“早期图片被跳过”。
任何人都可以帮助我从PTS转换为PCR ..
答案 0 :(得分:16)
首先,PCR具有33 + 9位,PTS 33位。与PTS一样,33位部分(称为PCR_base)以90kHz运行。其余9位称为PCR_ext,运行频率为27MHz。
因此,这是您计算PCR的方法:
S64 nPcr = (S64)nPts << 9;
请注意,多路复用流的PTS和PCR之间应该有一个时间偏移,它通常在几百毫秒的范围内,具体取决于流。
各个解码器需要一些时间来解码数据并使其准备好在相应PTS给出的时间进行呈现,这就是PTS始终“超前”PCR的原因。 ISO-13818和一些DVB规范给出了有关缓冲和(反)多路复用的细节。
关于你的bithifting我不确定,这是我的代码片段。注释可能有助于将位移位到正确的位置,R代表保留。
data[4] = 7;
data[5] = 1 << 4; // PCR_flag
// pcr has 33+9=42 bits
// 4 3 2 1 0
// 76543210 98765432 10987654 32109876 54321098 76543210
// xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xRRRRRRx xxxxxxxx
// 10987654 32109876 54321098 76543210 9 8 76543210
// 4 3 2 1 0
// b6 b7 b8 b9 b10 b11
data[ 6] = (pcr >> 34) & 0xff;
data[ 7] = (pcr >> 26) & 0xff;
data[ 8] = (pcr >> 18) & 0xff;
data[ 9] = (pcr >> 10) & 0xff;
data[10] = 0x7e | ((pcr & (1 << 9)) >> 2) | ((pcr & (1 << 8)) >> 8);
data[11] = pcr & 0xff;
答案 1 :(得分:3)
@schieferstapel的答案是正确的。我在这里只添加一个注释,指的是异常。
有时候B帧到达之后(谁的PTS小于)P帧。因此,如果每张图片都标有PTS值,则PTS可以是非线性的。然而,PCR必须是递增线性的。
因此,在上述情况下,您必须尝试省略B帧或在放置PCR值时进行相关计算。此外,如果这是硬件播出,建议PCR应该比相应的I帧的PTS略微提前(小于400 ms左右)。
答案 2 :(得分:0)
PCR包含33(PCR_Base)+6(PCR_const)+9(PCR_Ext)位数,并且它还指出前33位基于90 kHz时钟,而后9位基于27 MHz时钟.PCR_const = 0x3F PCR_Ext = 0 PCR_Base = pts / dts
下面的代码很容易理解。
PCR_Ext = 0;
PCR_Const = 0x3F;
int64_t pcrv = PCR_Ext & 0x1ff;
pcrv |= (PCR_Const << 9) & 0x7E00;
pcrv |= (PCR_Base << 15) & 0xFFFFFFFF8000LL;
pp = (char*)&pcrv;
data[ 6] = pp[5];
data[ 7] = pp[4];
data[ 8] = pp[3];
data[ 9] = pp[2];
data[10] = pp[1];
data[11] = pp[0];