7

我正在尝试从 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 ..

4

3 回答 3

16

首先,PCR 有 33+9 位,PTS 有 33 位。33 位部分(称为 PCR_base)以 90kHz 运行,PTS 也是如此。剩余的 9 位称为 PCR_ext,以 27MHz 运行。

因此,这就是您可以计算 PCR 的方式:

S64 nPcr = (S64)nPts << 9;

请注意,复用流的 PTS 和 PCR 之间应该存在时间偏移,通常在几百毫秒的范围内,具体取决于流。

各个解码器需要一些时间来解码数据并在各个 PTS 给定的时间准备好呈现,这就是 PTS 总是“领先”于 PCR 的原因。ISO-13818 和一些 DVB 规范给出了关于缓冲和(去)复用的细节。

关于您的位移我不确定,这是我的代码片段。该注释可能有助于将位移动到正确的位置,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;
于 2011-06-01T13:28:33.783 回答
3

@schieferstapel 的答案是正确的。我在这里只添加一个注释,它指的是一个例外。

有时B帧在(谁的PTS小于)P帧之后到达。因此,如果每张图片都印有 PTS 值,则 PTS 可能是非线性的。然而,PCR 必须是增量线性的。

所以在上述情况下,放PCR值时必须尽量省略B帧或进行相关计算。此外,如果这是硬件播出,建议 PCR 应该比相应 I 帧的 PTS 稍微提前(少 400 毫秒左右)。

于 2011-11-27T11:37:13.710 回答
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];
于 2016-10-12T07:44:40.657 回答