从 PTS 生成 PCR

发布于 2024-11-11 14:49:45 字数 549 浏览 3 评论 0原文

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

I am trying to create PCR from PTS as follows.

        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; 

But the problem is VLC is playing only first frame and not playing any other frames.
and I am getting the warning "early picture skipped".

Could any one help me in converting from PTS to PCR..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一指流沙 2024-11-18 14:49:45

首先,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;

First, the PCR has 33+9 bits, the PTS 33 bits. The 33 bit-portion (called PCR_base) runs at 90kHz, as does the PTS. The remaining 9 bits are called PCR_ext and run at 27MHz.

Thus, this is how you could calculate the PCR:

S64 nPcr = (S64)nPts << 9;

Note that there should be a time-offset between the PTSs of the multiplexed streams and the PCR, it's usually in the range of a few hundred ms, depending on the stream.

The respective decoder needs some time to decode the data and get it ready for presentation at the time given by the respective PTS, that's why the PTSs are always "ahead" of the PCR. ISO-13818 and some DVB specs give specifics about buffering and (de)multiplexing.

About your bitshifting I'm not sure, this is a code snippet of mine. The comment may help in shifting the bits to the right place, R stands for reserved.

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;
萌梦深 2024-11-18 14:49:45

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

有时,B 帧在(谁的 PTS 小于)P 帧之后到达。所以如果每张图片都打上PTS值,PTS就可以是非线性的。然而,PCR 必须是增量线性的。

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

The answer of @schieferstapel is correct. I am only adding one more note here which refers to an exception.

There are times when B frames arrives after (who's PTS is less than) P frames. so PTS can be non-linear if every picture is stamped with PTS value. Whereas, PCR must be incrementally linear.

So in the above situation, you must try to either omit B frames or make relevant calculation when putting PCR values. Also, if this is hardware playouts, it is advisable that PCR should be slightly ahead (lesser by 400 ms or so) than PTS of corresponding I frames.

甜妞爱困 2024-11-18 14:49:45

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];

the PCR contains 33(PCR_Base)+6(PCR_const)+9(PCR_Ext) number of bits and also it states that the first 33 bits are based on a 90 kHz clock while the last 9 are based on a 27 MHz clock.PCR_const = 0x3F PCR_Ext=0 PCR_Base=pts/dts

Below code is easy understand.

    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];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文