mistserver/lib/ts_packet.cpp
2012-12-31 16:05:17 +01:00

399 lines
11 KiB
C++

#include "ts_packet.h"
TS_Packet::TS_Packet() {
Clear( );
}
TS_Packet::TS_Packet( std::string & Data ) {
if( Data.size() < 188 ) {
Clear( );
} else {
for( int i = 0; i < 188; i++ ) {
Buffer[i] = Data[i];
}
Data.erase(0,188);
Free = 0;
}
}
TS_Packet::~TS_Packet() { }
void TS_Packet::PID( int NewVal ) {
Buffer[1] = (Buffer[1] & 0xE0) + ((NewVal & 0x1F00) >> 8 );
Buffer[2] = (NewVal & 0x00FF);
Free = std::min( Free, 184 );
}
int TS_Packet::PID() {
return (( Buffer[1] & 0x1F ) << 8 ) + Buffer[2];
}
void TS_Packet::ContinuityCounter( int NewVal ) {
Buffer[3] = ( Buffer[3] & 0xF0 ) + ( NewVal & 0x0F );
Free = std::min( Free, 184 );
}
int TS_Packet::ContinuityCounter() {
return ( Buffer[3] & 0x0F );
}
int TS_Packet::BytesFree( ) {
return Free;
}
void TS_Packet::Clear( ) {
Free = 184;
Buffer[0] = 0x47;
for( int i = 1; i < 188; i++ ) {
Buffer[i] = 0x00;
}
AdaptionField( 1 );
}
void TS_Packet::AdaptionField( int NewVal ) {
Buffer[3] = ( Buffer[3] & 0xCF ) + ((NewVal & 0x03) << 4);
Buffer[4] = 0;
Free = std::min( Free, 184 );
}
int TS_Packet::AdaptionField( ) {
return ((Buffer[3] & 0x30) >> 4 );
}
void TS_Packet::PCR( int64_t NewVal ) {
NewVal += (0xF618 * 300);
AdaptionField( 3 );
Buffer[4] = 7;
Buffer[5] = (Buffer[5] | 0x10 );
int64_t TmpVal = NewVal / 300;
Buffer[6] = (((TmpVal>>1)>>24) & 0xFF);
Buffer[7] = (((TmpVal>>1)>>16) & 0xFF);
Buffer[8] = (((TmpVal>>1)>>8) & 0xFF);
Buffer[9] = ((TmpVal>>1) & 0xFF);
int Remainder = NewVal % 300;
Buffer[10] = 0x7E + ((TmpVal & 0x01)<<7) + ((Remainder & 0x0100) >> 8 );
Buffer[11] = (Remainder & 0x00FF);
Free = std::min( Free, 176 );
};
int64_t TS_Packet::PCR( ) {
if( !AdaptionField() ) {
return -1;
}
if( !(Buffer[5] & 0x10 ) ) {
return -1;
}
int64_t Result = 0;
Result = (((((((Buffer[6] << 8) + Buffer[7]) << 8) + Buffer[8]) << 8) + Buffer[9]) << 1) + ( Buffer[10] & 0x80 );
Result = Result * 300;
Result += ((Buffer[10] & 0x01) << 8 + Buffer[11]);
return Result;
}
int TS_Packet::AdaptionFieldLen( ) {
if( !AdaptionField() ) {
return -1;
}
return (int)Buffer[4];
}
void TS_Packet::Print( ) {
std::cout << "TS Packet: " << (Buffer[0] == 0x47)
<< "\n\tNewUnit: " << UnitStart()
<< "\n\tPID: " << PID()
<< "\n\tContinuity Counter: " << ContinuityCounter()
<< "\n\tAdaption Field: " << AdaptionField() << "\n";
if( AdaptionField() ) {
std::cout << "\t\tAdaption Field Length: " << AdaptionFieldLen() << "\n";
if( AdaptionFieldLen() ) {
std::cout << "\t\tRandom Access: " << RandomAccess() << "\n";
}
if( PCR() != -1 ) {
std::cout << "\t\tPCR: " << PCR() << "( " << (double)PCR() / 27000000 << " s )\n";
}
}
}
int TS_Packet::UnitStart( ) {
return ( Buffer[1] & 0x40) >> 6;
}
void TS_Packet::UnitStart( int NewVal ) {
if( NewVal ) {
Buffer[1] = (Buffer[1] | 0x40);
} else {
Buffer[1] = (Buffer[1] & 0xBF);
}
}
int TS_Packet::RandomAccess( ) {
if( !AdaptionField() ) {
return -1;
}
return ( Buffer[5] & 0x40) >> 6;
}
void TS_Packet::RandomAccess( int NewVal ) {
if( AdaptionField() ) {
if( Buffer[4] == 0 ) {
Buffer[4] = 1;
}
if( NewVal ) {
Buffer[5] = (Buffer[5] | 0x40);
} else {
Buffer[5] = (Buffer[5] & 0xBF);
}
} else {
AdaptionField( 3 );
Buffer[4] = 1;
if( NewVal ) {
Buffer[5] = 0x40;
} else {
Buffer[5] = 0x00;
}
}
Free = std::min( Free, 182 );
}
void TS_Packet::DefaultPAT( ) {
static int MyCntr = 0;
UnitStart( 1 );
PID( 0 );
ContinuityCounter( MyCntr );
AdaptionField( 0x01 );
Buffer[ 4] = 0x00;//Pointer Field
Buffer[ 5] = 0x00;//TableID
Buffer[ 6] = 0xB0,//Reserved + SectionLength
Buffer[ 7] = 0x0D;//SectionLength (Cont)
Buffer[ 8] = 0x00;//Transport_Stream_ID
Buffer[ 9] = 0x01;//Transport_Stream_ID (Cont)
Buffer[10] = 0xC1;//Reserved + VersionNumber + Current_Next_Indicator
Buffer[11] = 0x00;//Section_Number
Buffer[12] = 0x00;//Last_Section_Number
Buffer[13] = 0x00; //Program Number
Buffer[14] = 0x01; //Program Number (Cont)
Buffer[15] = 0xF0; //Reserved + Program_Map_PID
Buffer[16] = 0x00; //Program_Map_PID (Cont)
Buffer[17] = 0x2A;//CRC32
Buffer[18] = 0xB1;//CRC32 (Cont)
Buffer[19] = 0x04;//CRC32 (Cont)
Buffer[20] = 0xB2;//CRC32 (Cont)
std::fill( Buffer+21, Buffer+188, 0xFF );
Free = 0;
MyCntr = ( (MyCntr + 1) % 0x10);
}
void TS_Packet::DefaultPMT( ) {
static int MyCntr = 0;
UnitStart( 1 );
PID( 0x1000 );
ContinuityCounter( MyCntr );
AdaptionField( 0x01 );
Buffer[ 4] = 0x00;//Pointer Field
Buffer[ 5] = 0x02;//TableID
Buffer[ 6] = 0xb0;//Reserved + Section_Length
Buffer[ 7] = 0x1D;//Section_Length (Cont)
Buffer[ 8] = 0x00;//Program_Number
Buffer[ 9] = 0x01;//Program_Number (Cont)
Buffer[10] = 0xc1;//Reserved + VersionNumber + Current_Next_Indicator
Buffer[11] = 0x00;//Section_Number
Buffer[12] = 0x00;//Last_Section_Number
Buffer[13] = 0xe1;//Reserved + PCR_PID
Buffer[14] = 0x00;//PCR_PID (Cont)
Buffer[15] = 0xf0;//Reserved + Program_Info_Length
Buffer[16] = 0x00;//Program_Info_Length (Cont)
Buffer[17] = 0x1b; //Stream_Type
Buffer[18] = 0xe1; //Reserved + Elementary_PID
Buffer[19] = 0x00; //Elementary_PID (Cont)
Buffer[20] = 0xf0; //Reserved + ES_Info_Length
Buffer[21] = 0x00; //ES_Info_Length (Cont)
Buffer[22] = 0x0f; //Stream_Type
Buffer[23] = 0xe1;
Buffer[24] = 0x01;
Buffer[25] = 0xf0;
Buffer[26] = 0x06;
Buffer[27] = 0x0a;
Buffer[28] = 0x04;
Buffer[29] = 0x65;
Buffer[30] = 0x6e;
Buffer[31] = 0x67;
Buffer[32] = 0x00;
Buffer[33] = 0x8d;
Buffer[34] = 0x82;
Buffer[35] = 0x9a;
Buffer[36] = 0x07;
std::fill( Buffer+37, Buffer+188, 0xFF );
Free = 0;
MyCntr = ( (MyCntr + 1) % 0x10);
}
std::string TS_Packet::ToString( ) {
fprintf( stderr, "\t\t\tAdaptationFieldBitsInBuffer: %0.2X\n", AdaptionField( ) );
std::string Result( Buffer, 188 );
fprintf( stderr, "\t\t\tAdaptationFieldBitsInString: %0.2X\n", Result[3] );
std::cout.write( Buffer,188 );
if( Buffer[0] != 0x47) {
fprintf( stderr, "Breaking, something terrible has happened\n" );
exit(400);
}
return Result;
}
void TS_Packet::PESVideoLeadIn( int NewLen, uint64_t PTSt ) {
static int PTS = 27000000;
NewLen += 14;
fprintf( stderr, "\t\t\t\t\tMyPTS: %X\n", PTS );
fprintf( stderr, "\t\t\t\t\tMyLen: %d\n", NewLen );
int Offset = ( 188 - Free );
Buffer[Offset] = 0x00;//PacketStartCodePrefix
Buffer[Offset+1] = 0x00;//PacketStartCodePrefix (Cont)
Buffer[Offset+2] = 0x01;//PacketStartCodePrefix (Cont)
Buffer[Offset+3] = 0xe0;//StreamType Video
Buffer[Offset+4] = (NewLen & 0xFF00) >> 8;//PES PacketLength
Buffer[Offset+5] = (NewLen & 0x00FF);//PES PacketLength (Cont)
Buffer[Offset+6] = 0x80;//Reserved + Flags
Buffer[Offset+7] = 0x80;//PTSOnlyFlag + Flags
Buffer[Offset+8] = 0x05;//PESHeaderDataLength
Buffer[Offset+9] = 0x20 + ((PTS & 0x1C0000000) >> 29 ) + 1;//PTS
Buffer[Offset+10] = 0x00 + ((PTS & 0x03FC00000) >> 22 );//PTS (Cont)
Buffer[Offset+11] = 0x00 + ((PTS & 0x0003F8000) >> 14 ) + 1;//PTS (Cont)
Buffer[Offset+12] = 0x00 + ((PTS & 0x000007F80) >> 7 );//PTS (Cont)
Buffer[Offset+13] = 0x00 + ((PTS & 0x00000007F) << 1) + 1;//PTS (Cont)
//PesPacket-Wise Prepended Data
Buffer[Offset+14] = 0x00;//NALU StartCode
Buffer[Offset+15] = 0x00;//NALU StartCode (Cont)
Buffer[Offset+16] = 0x00;//NALU StartCode (Cont)
Buffer[Offset+17] = 0x01;//NALU StartCode (Cont)
Buffer[Offset+18] = 0x09;//NALU EndOfPacket (Einde Vorige Packet)
Buffer[Offset+19] = 0xF0;//NALU EndOfPacket (Cont)
Free = Free - 20;
PTS += 3003;
}
void TS_Packet::PESAudioLeadIn( int NewLen, uint64_t PTS ) {
fprintf( stderr, "Free before PESAudio: %d\n", Free );
PTS = PTS * 90;
fprintf( stderr, "%d\n", PTS );
NewLen += 8;
fprintf( stderr, "\t\t\t\t\tMyPTS: %X\n", PTS );
fprintf( stderr, "\t\t\t\t\tMyLen: %d\n", NewLen );
int Offset = ( 188 - Free ) - 2;
fprintf( stderr, "Audio PES Lead In: Offset = %d\n", Offset );
Buffer[Offset] = 0x00;//PacketStartCodePrefix
Buffer[Offset+1] = 0x00;//PacketStartCodePrefix (Cont)
Buffer[Offset+2] = 0x01;//PacketStartCodePrefix (Cont)
Buffer[Offset+3] = 0xc0;//StreamType Video
Buffer[Offset+4] = (NewLen & 0xFF00) >> 8;//PES PacketLength
Buffer[Offset+5] = (NewLen & 0x00FF);//PES PacketLength (Cont)
Buffer[Offset+6] = 0x80;//Reserved + Flags
Buffer[Offset+7] = 0x80;//PTSOnlyFlag + Flags
Buffer[Offset+8] = 0x05;//PESHeaderDataLength
Buffer[Offset+9] = 0x20 + ((PTS & 0x1C0000000) >> 29 ) + 1;//PTS
Buffer[Offset+10] = 0x00 + ((PTS & 0x03FC00000) >> 22 );//PTS (Cont)
Buffer[Offset+11] = 0x00 + ((PTS & 0x0003F8000) >> 14 ) + 1;//PTS (Cont)
Buffer[Offset+12] = 0x00 + ((PTS & 0x000007F80) >> 7 );//PTS (Cont)
Buffer[Offset+13] = 0x00 + ((PTS & 0x00000007F) << 1) + 1;//PTS (Cont)
Free = Free - 12;
}
void TS_Packet::FillFree( std::string & NewVal ) {
int Offset = (188 - Free);
fprintf( stderr, "Filling Free: Offset = %d\n", Offset );
for( int i = 0; (Offset + i) < 188; i++ ) {
Buffer[Offset+i] = NewVal[i];
}
NewVal.erase(0,Free);
Free = 0;
}
void TS_Packet::AddStuffing( int NumBytes ) {
if( NumBytes <= 0 ) { return; }
if( AdaptionField( ) == 3 ) {
int Offset = Buffer[4];
fprintf( stderr, "AddStuffing: AdaptionField == 3 && Offset = %d\n", Offset );
Buffer[4] = Offset + NumBytes - 1;
for( int i = 0; i < ( NumBytes -2 ); i ++ ) {
Buffer[6+Offset+i] = 0xFF;
}
Free -= NumBytes;
} else {
AdaptionField( 3 );
fprintf( stderr, "AddStuffing: AdaptionField != 3\n" );
Buffer[4] = NumBytes - 1;
Buffer[5] = 0x00;
for( int i = 0; i < ( NumBytes -2 ); i ++ ) {
Buffer[6+i] = 0xFF;
}
Free -= NumBytes;
}
fprintf( stderr, "Free After Stuffing: %d\n", Free );
}
void TS_Packet::FFMpegHeader( ) {
static int MyCntr = 0;
UnitStart( 1 );
PID( 0x0011 );
ContinuityCounter( MyCntr );
AdaptionField( 0x01 );
Buffer[4] = 0x00;
Buffer[5] = 0x42;
Buffer[6] = 0xF0;
Buffer[7] = 0x25;
Buffer[8] = 0x00;
Buffer[9] = 0x01;
Buffer[10] = 0xC1;
Buffer[11] = 0x00;
Buffer[12] = 0x00;
Buffer[13] = 0x00;
Buffer[14] = 0x01;
Buffer[15] = 0xFF;
Buffer[16] = 0x00;
Buffer[17] = 0x01;
Buffer[18] = 0xFC;
Buffer[19] = 0x80;
Buffer[20] = 0x14;
Buffer[21] = 0x48;
Buffer[22] = 0x12;
Buffer[23] = 0x01;
Buffer[24] = 0x06;
Buffer[25] = 0x46;
Buffer[26] = 0x46;
Buffer[27] = 0x6D;
Buffer[28] = 0x70;
Buffer[29] = 0x65;
Buffer[30] = 0x67;
Buffer[31] = 0x09;
Buffer[32] = 0x53;
Buffer[33] = 0x65;
Buffer[34] = 0x72;
Buffer[35] = 0x76;
Buffer[36] = 0x69;
Buffer[37] = 0x63;
Buffer[38] = 0x65;
Buffer[39] = 0x30;
Buffer[40] = 0x31;
Buffer[41] = 0xA7;
Buffer[42] = 0x79;
Buffer[43] = 0xA0;
Buffer[44] = 0x03;
for( int i = 45; i < 188; i++ ) {
Buffer[i] = 0xFF;
}
Free = 0;
MyCntr = ( (MyCntr + 1) % 0x10);
}