[vdr] cReceiver vs cFilter and PTS questions

Patrick Fischer patrick_fischer at gmx.de
Mon Nov 7 14:45:35 CET 2005


Hello

>>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 );
                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?

Yours sincerely
Patrick



More information about the vdr mailing list