/*******************************************************}
{
}
{ File : transport_packet_class.h }
{ Created by Tsviatko Jongov }
{ http://tsviatko.jongov.com }
{
}
{ Transport packet class. }
{
}
{*******************************************************/
#ifndef
__TRANSPORT_PACKET_CLASS_H__
#define
__TRANSPORT_PACKET_CLASS_H__
#include "mpegtsutils.h"
class
Ctransport_packet_class
{
public:
unsigned long m_TSPacketLen;
//188, 192, 196, 204 or 212
unsigned char m_Data[212];
transport_packet m_transport_packet;
unsigned long m_PayloadOffset;
protected:
bool
ParsePacket()
{
unsigned
char * p;
unsigned
char * paf; //Points
the start of the adaptation field
unsigned
char * pe;
//Points the start of the adaptation field
extension
unsigned
int i = 0;
p = &m_Data[0];
m_transport_packet.sync_byte = *p;
if
(m_transport_packet.sync_byte != 0x47)
{
OutputDebugString(TEXT("tsv: Error in Ctransport_packet_class.ParsePacket -
invalid packet."));
return
false;
}
p++;
m_transport_packet.transport_error_indicator = (*p >> 7) &
0x01;
m_transport_packet.payload_unit_start_indicator = (*p >> 6) &
0x01;
m_transport_packet.transport_priority =
(*p >> 5) & 0x01;
m_transport_packet.PID = (*p &
0x1F) << 8;
p++;
m_transport_packet.PID =
m_transport_packet.PID | *p;
p++;
m_transport_packet.transport_scrambling_control = (*p >> 6) &
0x03;
m_transport_packet.adaptation_field_control = (*p >> 4) &
0x03;
m_transport_packet.continuity_counter =
(*p & 0x0F);
p++;
if
(m_transport_packet.adaptation_field_control & 0x02) //Has adaptation field
{
paf = p;
m_transport_packet.adaptation_fld.adaptation_field_length = *p;
p++;
if
(m_transport_packet.adaptation_fld.adaptation_field_length > 0)
{
m_transport_packet.adaptation_fld.discontinuity_indicator = (*p >>
7) & 0x01;
m_transport_packet.adaptation_fld.random_access_indicator = (*p >>
6) & 0x01;
m_transport_packet.adaptation_fld.elementary_stream_priority_indicator =
(*p >> 5) & 0x01;
m_transport_packet.adaptation_fld.PCR_flag = (*p >> 4) & 0x01;
m_transport_packet.adaptation_fld.OPCR_flag = (*p >> 3) &
0x01;
m_transport_packet.adaptation_fld.splicing_point_flag = (*p >> 2)
& 0x01;
m_transport_packet.adaptation_fld.transport_private_data_flag = (*p
>> 1) & 0x01;
m_transport_packet.adaptation_fld.adaptation_field_extension_flag
= *p & 0x01;
p++;
if
(m_transport_packet.adaptation_fld.PCR_flag & 0x01)
{
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->HighPart
= (*p >> 7) & 0x01;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->LowPart
= (*p & 0x7F) << 25;
p++;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->LowPart
=
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->LowPart
| (*p << 17);
p++;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->LowPart
=
((LARGE_INTEGER *)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->LowPart
| (*p << 9);
p++;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->LowPart
=
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->LowPart
| (*p << 1);
p++;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->LowPart
=
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.program_clock_reference_base))->LowPart
| ((*p >> 7) & 0x01);
m_transport_packet.adaptation_fld.reserved0 = (*p & 0x7E) >>
1;
m_transport_packet.adaptation_fld.program_clock_reference_extension =
(*p & 0x01) << 8;
p++;
m_transport_packet.adaptation_fld.program_clock_reference_extension =
m_transport_packet.adaptation_fld.program_clock_reference_extension |
*p;
p++;
}
}
if
(m_transport_packet.adaptation_fld.OPCR_flag & 0x01)
{
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->HighPart
= (*p >> 7) & 0x01;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->LowPart
= (*p & 0x7F) << 25;
p++;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->LowPart
=
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->LowPart
| (*p << 17);
p++;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->LowPart
=
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->LowPart
| (*p << 9);
p++;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->LowPart
=
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->LowPart
| (*p << 1);
p++;
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->LowPart
=
((LARGE_INTEGER
*)(&m_transport_packet.adaptation_fld.original_program_clock_reference_base))->LowPart
| ((*p >> 7) & 0x01);
m_transport_packet.adaptation_fld.reserved1 = (*p & 0x7E) >>
1;
m_transport_packet.adaptation_fld.original_program_clock_reference_extension
= (*p & 0x01) << 8;
p++;
m_transport_packet.adaptation_fld.original_program_clock_reference_extension
=
m_transport_packet.adaptation_fld.original_program_clock_reference_extension
| *p;
p++;
}
if
(m_transport_packet.adaptation_fld.splicing_point_flag & 0x01)
{
m_transport_packet.adaptation_fld.splice_countdown = *p;
p++;
}
if
(m_transport_packet.adaptation_fld.transport_private_data_flag & 0x01)
{
m_transport_packet.adaptation_fld.transport_private_data_length = *p;
p++;
for
(i = 0; i < m_transport_packet.adaptation_fld.transport_private_data_length;
i++)
{
m_transport_packet.adaptation_fld.private_data_byte[i] = *p;
p++;
}
}
if
(m_transport_packet.adaptation_fld.adaptation_field_extension_flag & 0x01)
{
pe = p;
m_transport_packet.adaptation_fld.adaptation_field_extension_length =
*p;
p++;
m_transport_packet.adaptation_fld.ltw_flag = (*p >> 7) & 0x01;
m_transport_packet.adaptation_fld.piecewise_rate_flag = (*p >> 6)
& 0x01;
m_transport_packet.adaptation_fld.seamless_splice_flag = (*p >> 5)
& 0x01;
m_transport_packet.adaptation_fld.reserved2 = (*p & 0x1F);
p++;
if
(m_transport_packet.adaptation_fld.ltw_flag & 0x01)
{
m_transport_packet.adaptation_fld.ltw_valid_flag
= (*p >> 7) & 0x01;
m_transport_packet.adaptation_fld.ltw_offset = (*p & 0x7F) <<
8;
p++;
m_transport_packet.adaptation_fld.ltw_offset =
m_transport_packet.adaptation_fld.ltw_offset | *p;
p++;
}
if
(m_transport_packet.adaptation_fld.piecewise_rate_flag & 0x01)
{
m_transport_packet.adaptation_fld.reserved3 = (*p >> 6) &
0x03;
m_transport_packet.adaptation_fld.piecewise_rate = (*p & 0x3F)
<< 16;
p++;
m_transport_packet.adaptation_fld.piecewise_rate
= m_transport_packet.adaptation_fld.piecewise_rate | (*p << 8);
p++;
m_transport_packet.adaptation_fld.piecewise_rate = m_transport_packet.adaptation_fld.piecewise_rate
| *p;
p++;
}
if
(m_transport_packet.adaptation_fld.seamless_splice_flag & 0x01)
{
m_transport_packet.adaptation_fld.splice_type = (*p >> 4) &
0x0F;
m_transport_packet.adaptation_fld.DTS_next_AU_32_30 = (*p >> 1)
& 0x07;
m_transport_packet.adaptation_fld.marker_bit0 = *p & 0x01;
p++;
m_transport_packet.adaptation_fld.DTS_next_AU_29_15
= *p << 7;
p++;
m_transport_packet.adaptation_fld.DTS_next_AU_29_15 =
m_transport_packet.adaptation_fld.DTS_next_AU_29_15 | ((*p >> 1)
& 0x7F);
m_transport_packet.adaptation_fld.marker_bit1 = *p & 0x01;
p++;
m_transport_packet.adaptation_fld.DTS_next_AU_14_0
= *p << 7;
p++;
m_transport_packet.adaptation_fld.DTS_next_AU_14_0 =
m_transport_packet.adaptation_fld.DTS_next_AU_14_0 | ((*p >> 1)
& 0x7F);
m_transport_packet.adaptation_fld.marker_bit2 = *p & 0x01;
p++;
}
//Reserved...
int
reserved_length =
m_transport_packet.adaptation_fld.adaptation_field_extension_length - (p - pe -
1);
for
(i = 0; i < reserved_length; i++)
{
m_transport_packet.adaptation_fld.reserved4[i] = *p;
p++;
}
}
//Stuffing...
int
stuffing_length = m_transport_packet.adaptation_fld.adaptation_field_length -
(p - paf - 1);
for
(i = 0; i < stuffing_length; i++)
{
m_transport_packet.adaptation_fld.stuffing_byte[i] = *p;
p++;
}
}
m_PayloadOffset = (unsigned long)(p -
&m_Data[0]);
return true;
}
public:
Ctransport_packet_class()
{
}
virtual bool SetData(void *
Data, unsigned long
Size)
{
if (
(!Data) || (Size == 0) )
{
OutputDebugString(TEXT("tsv: Error in Ctransport_packet_class.SetData -
invalid parameters."));
return false;
}
memcpy(&m_Data[0], Data, Size);
return
ParsePacket();
}
HRESULT GetPCRPosition(unsigned long *
Position)
{
*Position = 4;
if
(m_transport_packet.adaptation_field_control & 0x02) //Has adaptation field
{
*Position++;
if
(m_transport_packet.adaptation_fld.adaptation_field_length > 0)
{
*Position++;
if
(m_transport_packet.adaptation_fld.PCR_flag & 0x01)
{
*Position += 6;
return
S_OK;
}
}
}
*Position = 0;
return
S_FALSE;
}
};
#endif // __TRANSPORT_PACKET_CLASS_H__