[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