[vdr] cReceiver vs cFilter and PTS questions

Reinhard Nissl rnissl at gmx.de
Mon Nov 7 23:11:16 CET 2005


Hi,

Patrick Fischer wrote:

>>> From standard, I miss the following checks:
>>
>> - Is there payload in this TS packet?
>> - Does a new PES packet start with this TS packet?
>>  (payload_unit_start_indicator)
>> - Does the payload start with 00 00 01 PES header prefix?
>> - Does the stream_id refer to an A/V stream with full headers?
>>  (well, if VideoPid is valid, this should be expected)
>> - Is the PTS field present in the PES header?
>>
>> With these assumptions, Data+4+off points to the PES header, and
>> PESheader+9 points to the PTS.
>>
>> Cheers,
>>
>> Udo
>>  
>>
> Hello at the WE I have rewritten my  PTSReceiver. It works with more 
> then 3 PID.
> 
> #define TS_SIZE       188
> #define PAY_START     0x40 // 0100 0000
> #define ADAPT_FIELD   0x20 // 0010 0000
> #define PAYLOAD       0x10 // 0001 0000
> #define PTS_DTS_FLAGS 0xC0 // 1100 0000
> 
> //See spec. at ISO/IEC 12818-1
> // TS Page 42
> // PES Header Page 142
> void cPTSReceiver::Receive(uchar *Data, int Length)
> {
>    char spts[20];
> 
>    // TS packet length: TS_SIZE
>    if (Length == TS_SIZE)
>    {
>        int pid = ((Data[1] & 0x1f) << 8) | (Data[2]);
>              if (!(Data[3] & PAYLOAD))
>        {
>            return;//no payload avalible
>        }
>        uint8_t off = 0;
>        if (Data[3] & ADAPT_FIELD)        {
>            off = Data[4] + 1;//Skip adaptrer_field()
>        }
> 
>        if (Data[1] & PAY_START)//if payload_unit_start_indicator is 1, 
> then a new PES Packet start
>        {
>                  uint8_t *sb = Data + 4 + off; //pointer to data_byte 
> (payload)
>                      if ((sb[0] << 16 | sb[1] << 8 | sb[2] )!= 
> 0x000001){//packet_start_code_prefix                        return;
>            }
>                      if (sb[7] & PTS_DTS_FLAGS) //the 8 byte of the PES 
> packet are 7 Flags
>            {
>                uint64_t frame_pts = (uint64_t)floor( 
> (trans_pts_dts(sb+9)/90000.)+0.5 );

^^^^^^^ looks like frame_pts contains complete seconds (90000 pts = 1 s)

Try this to get frames (90000 pts = 25 frames):

	uint64_t frame_pts = trans_pts_dts(sb+9) / 3600;

>                frameToTime(frame_pts,spts);
>                printf("pid:%d vpts : %s\t %d \n",pid,spts,frame_pts);
>            }
>        }
>    }
> }
> 
> uint64_t cPTSReceiver::trans_pts_dts(uint8_t *pts)
> {
>    uint64_t wts;
> 
>    wts = ((uint64_t)((pts[0] & 0x0E) << 5) |
>           ((pts[1] & 0xFC) >> 2)) << 24;
>    wts |= (((pts[1] & 0x03) << 6) |
>            ((pts[2] & 0xFC) >> 2)) << 16;
>    wts |= (((pts[2] & 0x02) << 6) |
>            ((pts[3] & 0xFE) >> 1)) << 8;
>    wts |= (((pts[3] & 0x01) << 7) |
>            ((pts[4] & 0xFE) >> 1));
>    return wts;
> }
> 
> 
> void cPTSReceiver::frameToTime(uint64_t frame_pts,char* timecode)
> {
>    int h,min, sec, res;
>    h=min=sec=res=0;
>    if (frame_pts != 0)
>    {
>        h   = frame_pts/(25 * 60 * 60);
>        min = frame_pts/(25 * 60) - h * 60;
>        sec = frame_pts/25 - min*60  -h*3600 ;
>        res = frame_pts - h*3600 *25 -min * 60 *25 - sec *25;
>    }
>    sprintf(timecode,"%d:%d:%d.%d\n",h,min,sec,res);
>    return;
> }
> 
> It seems to work but I have a problem.
> .......
> pid:545 vpts : 0:40:3.3    60078
> pid:561 vpts : 0:29:36.0  44400
> pid:545 vpts : 0:40:3.3    60078
> pid:561 vpts : 0:29:36.0  44400
> pid:561 vpts : 0:29:36.0  44400
> pid:545 vpts : 0:40:3.3    60078
> pid:545 vpts : 0:40:3.3    60078
> .....
> I get double entries for each PID.
> If I understand, "payload_unit_start_indicator" should be 1 for every 
> new Packet.
> Should this prevent that I get doubel PTS?

See above.

But keep in mind, that video frames and associated PTS values appear in 
decoding order while the PTS values are used to order the decoded frames 
  chronologically for sending them on screen.

An example:
The video sequence (frame type + pts value)

	B0 B1 I2 B3 B4 P5 B6 B7 P8

with rising pts values (= display order) will be broadcast like that 
(decoding order):

	I2 B0 B1 P5 B3 B4 P8 B6 B7

So you'll see the PTS values jump back and forth.

Bye.
-- 
Dipl.-Inform. (FH) Reinhard Nissl
mailto:rnissl at gmx.de



More information about the vdr mailing list