7

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..

Ven
  • 247
  • 1
  • 5
  • 17

3 Answers3

16

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;
schieferstapel
  • 915
  • 8
  • 14
  • Giving it a closer look I noticed that my bitshifting for data[10] wasn't quite right either, I've fixed it here :) I've never noticed that before, probably due to decoders not paying much attention to the less significant bits... – schieferstapel Jun 01 '11 at 18:12
  • Hi Schieferstapel,Thank you :) – Ven Jun 02 '11 at 07:44
  • It is important to note that a simple bitshift (as shown in the first part of the answer) will give incorrect results, as the PCR is given as (PCR_base * 300) + PCR_ext – paintcan Jul 30 '13 at 14:46
  • 1
    paintcan: I would agree that it's not possible to convert from a 27 MHz reference to a 90 kHz reference with a bitshift, but in this case there's no 27 MHz clock, only the 90 kHz PTS value. – pc3e Feb 07 '14 at 23:03
  • Actually the PCR value could be obtained by multiplying the PTS (and DTS if used) by 300. Normally they share the same clock source. – rkachach Feb 22 '16 at 18:20
3

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.

Dipan Mehta
  • 2,080
  • 1
  • 16
  • 31
  • Normally the frames carry their corresponding DTS timestamp (decoding time-stamp) that should be used to decode/prepare them before presenting them at PTS. This is critical specially for video since the decoding operation is time consuming. – rkachach Feb 22 '16 at 18:22
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];
daozhao
  • 267
  • 2
  • 8