Fixed a lot of bugs in TS, updated to std-string implementation
This commit is contained in:
parent
c43fba4275
commit
611d4db3d7
2 changed files with 122 additions and 195 deletions
|
@ -5,7 +5,10 @@
|
||||||
|
|
||||||
/// This constructor creates an empty TS::Packet, ready for use for either reading or writing.
|
/// This constructor creates an empty TS::Packet, ready for use for either reading or writing.
|
||||||
/// All this constructor does is call TS::Packet::Clear().
|
/// All this constructor does is call TS::Packet::Clear().
|
||||||
TS::Packet::Packet() { Clear( ); }
|
TS::Packet::Packet() {
|
||||||
|
strBuf.reserve( 188 );
|
||||||
|
Clear( );
|
||||||
|
}
|
||||||
|
|
||||||
/// This function fills a TS::Packet from provided Data.
|
/// This function fills a TS::Packet from provided Data.
|
||||||
/// It fills the content with the first 188 bytes of Data.
|
/// It fills the content with the first 188 bytes of Data.
|
||||||
|
@ -15,9 +18,8 @@ bool TS::Packet::FromString( std::string & Data ) {
|
||||||
if( Data.size() < 188 ) {
|
if( Data.size() < 188 ) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
for( int i = 0; i < 188; i++ ) { Buffer[i] = Data[i]; }
|
strBuf = Data.substr(0,188);
|
||||||
Data.erase(0,188);
|
Data.erase(0,188);
|
||||||
Free = 0;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -28,42 +30,41 @@ TS::Packet::~Packet() { }
|
||||||
/// Sets the PID of a single TS::Packet.
|
/// Sets the PID of a single TS::Packet.
|
||||||
/// \param NewPID The new PID of the packet.
|
/// \param NewPID The new PID of the packet.
|
||||||
void TS::Packet::PID( int NewPID ) {
|
void TS::Packet::PID( int NewPID ) {
|
||||||
Buffer[1] = (Buffer[1] & 0xE0) + ((NewPID & 0x1F00) >> 8 );
|
strBuf[1] = (strBuf[1] & 0xE0) + ((NewPID & 0x1F00) >> 8 );
|
||||||
Buffer[2] = (NewPID & 0x00FF);
|
strBuf[2] = (NewPID & 0x00FF);
|
||||||
Free = std::min( Free, 184 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the PID of a single TS::Packet.
|
/// Gets the PID of a single TS::Packet.
|
||||||
/// \return The value of the PID.
|
/// \return The value of the PID.
|
||||||
int TS::Packet::PID() {
|
int TS::Packet::PID() {
|
||||||
return (( Buffer[1] & 0x1F ) << 8 ) + Buffer[2];
|
return (( strBuf[1] & 0x1F ) << 8 ) + strBuf[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the Continuity Counter of a single TS::Packet.
|
/// Sets the Continuity Counter of a single TS::Packet.
|
||||||
/// \param NewContinuity The new Continuity Counter of the packet.
|
/// \param NewContinuity The new Continuity Counter of the packet.
|
||||||
void TS::Packet::ContinuityCounter( int NewContinuity ) {
|
void TS::Packet::ContinuityCounter( int NewContinuity ) {
|
||||||
Buffer[3] = ( Buffer[3] & 0xF0 ) + ( NewContinuity & 0x0F );
|
strBuf[3] = ( strBuf[3] & 0xF0 ) + ( NewContinuity & 0x0F );
|
||||||
Free = std::min( Free, 184 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the Continuity Counter of a single TS::Packet.
|
/// Gets the Continuity Counter of a single TS::Packet.
|
||||||
/// \return The value of the Continuity Counter.
|
/// \return The value of the Continuity Counter.
|
||||||
int TS::Packet::ContinuityCounter() {
|
int TS::Packet::ContinuityCounter() {
|
||||||
return ( Buffer[3] & 0x0F );
|
return ( strBuf[3] & 0x0F );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the amount of bytes that are not written yet in a TS::Packet.
|
/// Gets the amount of bytes that are not written yet in a TS::Packet.
|
||||||
/// \return The amount of bytes that can still be written to this packet.
|
/// \return The amount of bytes that can still be written to this packet.
|
||||||
int TS::Packet::BytesFree( ) {
|
int TS::Packet::BytesFree( ) {
|
||||||
return Free;
|
return 188 - strBuf.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears a TS::Packet.
|
/// Clears a TS::Packet.
|
||||||
void TS::Packet::Clear( ) {
|
void TS::Packet::Clear( ) {
|
||||||
Free = 184;
|
strBuf.resize(4);
|
||||||
Buffer[0] = 0x47;
|
strBuf[0] = 0x47;
|
||||||
for( int i = 1; i < 188; i++ ) { Buffer[i] = 0x00; }
|
strBuf[1] = 0x00;
|
||||||
AdaptationField( 1 );
|
strBuf[2] = 0x00;
|
||||||
|
strBuf[3] = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the selection value for an adaptationfield of a TS::Packet.
|
/// Sets the selection value for an adaptationfield of a TS::Packet.
|
||||||
|
@ -72,9 +73,12 @@ void TS::Packet::Clear( ) {
|
||||||
/// - 2: AdaptationField Only.
|
/// - 2: AdaptationField Only.
|
||||||
/// - 3: AdaptationField followed by Data.
|
/// - 3: AdaptationField followed by Data.
|
||||||
void TS::Packet::AdaptationField( int NewSelector ) {
|
void TS::Packet::AdaptationField( int NewSelector ) {
|
||||||
Buffer[3] = ( Buffer[3] & 0xCF ) + ((NewSelector & 0x03) << 4);
|
strBuf[3] = ( strBuf[3] & 0xCF ) + ((NewSelector & 0x03) << 4);
|
||||||
Buffer[4] = 0;
|
if( NewSelector & 0x02 ) {
|
||||||
Free = std::min( Free, 184 );
|
strBuf[4] = 0x00;
|
||||||
|
} else {
|
||||||
|
strBuf.resize(4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets whether a TS::Packet contains an adaptationfield.
|
/// Gets whether a TS::Packet contains an adaptationfield.
|
||||||
|
@ -82,26 +86,28 @@ void TS::Packet::AdaptationField( int NewSelector ) {
|
||||||
/// - 0: No adaptationfield present.
|
/// - 0: No adaptationfield present.
|
||||||
/// - 1: Adaptationfield is present.
|
/// - 1: Adaptationfield is present.
|
||||||
int TS::Packet::AdaptationField( ) {
|
int TS::Packet::AdaptationField( ) {
|
||||||
return ((Buffer[3] & 0x30) >> 4 );
|
return ((strBuf[3] & 0x30) >> 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the PCR (Program Clock Reference) of a TS::Packet.
|
/// Sets the PCR (Program Clock Reference) of a TS::Packet.
|
||||||
/// \param NewVal The new PCR Value.
|
/// \param NewVal The new PCR Value.
|
||||||
void TS::Packet::PCR( int64_t NewVal ) {
|
void TS::Packet::PCR( int64_t NewVal ) {
|
||||||
|
if( strBuf.size() < 12 ) {
|
||||||
|
strBuf.resize( 12 );
|
||||||
|
}
|
||||||
AdaptationField( 3 );
|
AdaptationField( 3 );
|
||||||
Buffer[4] = 7;
|
strBuf[4] = 0x07;
|
||||||
Buffer[5] = (Buffer[5] | 0x10 );
|
strBuf[5] = (strBuf[5] | 0x10 );
|
||||||
int64_t TmpVal = NewVal / 300;
|
int64_t TmpVal = NewVal / 300;
|
||||||
fprintf( stderr, "\tSetting PCR_Base: %d\n", TmpVal );
|
fprintf( stderr, "\tSetting PCR_Base: %d\n", TmpVal );
|
||||||
Buffer[6] = (((TmpVal>>1)>>24) & 0xFF);
|
strBuf[6] = (((TmpVal>>1)>>24) & 0xFF);
|
||||||
Buffer[7] = (((TmpVal>>1)>>16) & 0xFF);
|
strBuf[7] = (((TmpVal>>1)>>16) & 0xFF);
|
||||||
Buffer[8] = (((TmpVal>>1)>>8) & 0xFF);
|
strBuf[8] = (((TmpVal>>1)>>8) & 0xFF);
|
||||||
Buffer[9] = ((TmpVal>>1) & 0xFF);
|
strBuf[9] = ((TmpVal>>1) & 0xFF);
|
||||||
int Remainder = NewVal % 300;
|
int Remainder = NewVal % 300;
|
||||||
Buffer[10] = 0x7E + ((TmpVal & 0x01)<<7) + ((Remainder & 0x0100) >> 8 );
|
strBuf[10] = 0x7E + ((TmpVal & 0x01)<<7) + ((Remainder & 0x0100) >> 8 );
|
||||||
Buffer[11] = (Remainder & 0x00FF);
|
strBuf[11] = (Remainder & 0x00FF);
|
||||||
Free = std::min( Free, 176 );
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/// Gets the PCR (Program Clock Reference) of a TS::Packet.
|
/// Gets the PCR (Program Clock Reference) of a TS::Packet.
|
||||||
/// \return The value of the PCR.
|
/// \return The value of the PCR.
|
||||||
|
@ -109,13 +115,13 @@ int64_t TS::Packet::PCR( ) {
|
||||||
if( !AdaptationField() ) {
|
if( !AdaptationField() ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if( !(Buffer[5] & 0x10 ) ) {
|
if( !(strBuf[5] & 0x10 ) ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int64_t Result = 0;
|
int64_t Result = 0;
|
||||||
Result = (((((((Buffer[6] << 8) + Buffer[7]) << 8) + Buffer[8]) << 8) + Buffer[9]) << 1) + ( Buffer[10] & 0x80 );
|
Result = (((strBuf[6] << 24) + (strBuf[7] << 16) + (strBuf[8] << 8) + strBuf[9]) << 1) + ( strBuf[10] & 0x80 >> 7 );
|
||||||
Result = Result * 300;
|
Result = Result * 300;
|
||||||
Result += ((Buffer[10] & 0x01) << 8 + Buffer[11]);
|
Result += ((strBuf[10] & 0x01) << 8 + strBuf[11]);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,12 +131,12 @@ int TS::Packet::AdaptationFieldLen( ) {
|
||||||
if( !AdaptationField() ) {
|
if( !AdaptationField() ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (int)Buffer[4];
|
return (int)strBuf[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a packet to stdout, for analyser purposes.
|
/// Prints a packet to stdout, for analyser purposes.
|
||||||
void TS::Packet::Print( ) {
|
void TS::Packet::Print( ) {
|
||||||
std::cout << "TS Packet: " << (Buffer[0] == 0x47)
|
std::cout << "TS Packet: " << (strBuf[0] == 0x47)
|
||||||
<< "\n\tNewUnit: " << UnitStart()
|
<< "\n\tNewUnit: " << UnitStart()
|
||||||
<< "\n\tPID: " << PID()
|
<< "\n\tPID: " << PID()
|
||||||
<< "\n\tContinuity Counter: " << ContinuityCounter()
|
<< "\n\tContinuity Counter: " << ContinuityCounter()
|
||||||
|
@ -149,16 +155,16 @@ void TS::Packet::Print( ) {
|
||||||
/// Gets whether a new unit starts in this TS::Packet.
|
/// Gets whether a new unit starts in this TS::Packet.
|
||||||
/// \return The start of a new unit.
|
/// \return The start of a new unit.
|
||||||
int TS::Packet::UnitStart( ) {
|
int TS::Packet::UnitStart( ) {
|
||||||
return ( Buffer[1] & 0x40) >> 6;
|
return ( strBuf[1] & 0x40) >> 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the start of a new unit in this TS::Packet.
|
/// Sets the start of a new unit in this TS::Packet.
|
||||||
/// \param NewVal The new value for the start of a unit.
|
/// \param NewVal The new value for the start of a unit.
|
||||||
void TS::Packet::UnitStart( int NewVal ) {
|
void TS::Packet::UnitStart( int NewVal ) {
|
||||||
if( NewVal ) {
|
if( NewVal ) {
|
||||||
Buffer[1] = (Buffer[1] | 0x40);
|
strBuf[1] |= 0x40;
|
||||||
} else {
|
} else {
|
||||||
Buffer[1] = (Buffer[1] & 0xBF);
|
strBuf[1] &= 0xBF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,96 +174,95 @@ int TS::Packet::RandomAccess( ) {
|
||||||
if( AdaptationField() < 2 ) {
|
if( AdaptationField() < 2 ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return ( Buffer[5] & 0x40) >> 6;
|
return ( strBuf[5] & 0x40) >> 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets whether this TS::Packet contains a keyframe
|
/// Sets whether this TS::Packet contains a keyframe
|
||||||
/// \param NewVal Whether or not this TS::Packet contains a keyframe.
|
/// \param NewVal Whether or not this TS::Packet contains a keyframe.
|
||||||
void TS::Packet::RandomAccess( int NewVal ) {
|
void TS::Packet::RandomAccess( int NewVal ) {
|
||||||
if( AdaptationField() ) {
|
if( AdaptationField() == 3 ) {
|
||||||
if( Buffer[4] == 0 ) {
|
if( strBuf.size() < 6 ) {
|
||||||
Buffer[4] = 1;
|
strBuf.resize(6);
|
||||||
}
|
}
|
||||||
|
if( !strBuf[4] ) {
|
||||||
|
strBuf[4] = 1;
|
||||||
|
}
|
||||||
if( NewVal ) {
|
if( NewVal ) {
|
||||||
Buffer[5] = (Buffer[5] | 0x40);
|
strBuf[5] |= 0x40;
|
||||||
} else {
|
} else {
|
||||||
Buffer[5] = (Buffer[5] & 0xBF);
|
strBuf[5] &= 0xBF;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AdaptationField( 3 );
|
if( strBuf.size() < 6 ) {
|
||||||
Buffer[4] = 1;
|
strBuf.resize(6);
|
||||||
if( NewVal ) {
|
}
|
||||||
Buffer[5] = 0x40;
|
AdaptationField( 3 );
|
||||||
} else {
|
strBuf[4] = 1;
|
||||||
Buffer[5] = 0x00;
|
if( NewVal ) {
|
||||||
|
strBuf[5] = 0x40;
|
||||||
|
} else {
|
||||||
|
strBuf[5] = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Free = std::min( Free, 182 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms the TS::Packet into a standard Program Association Table
|
/// Transforms the TS::Packet into a standard Program Association Table
|
||||||
void TS::Packet::DefaultPAT( ) {
|
void TS::Packet::DefaultPAT( ) {
|
||||||
static int MyCntr = 0;
|
static int MyCntr = 0;
|
||||||
std::copy( TS::PAT, TS::PAT + 188, Buffer );
|
strBuf = std::string( TS::PAT, 188 );
|
||||||
ContinuityCounter( MyCntr );
|
ContinuityCounter( MyCntr );
|
||||||
Free = 0;
|
|
||||||
MyCntr = ( (MyCntr + 1) % 0x10);
|
MyCntr = ( (MyCntr + 1) % 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms the TS::Packet into a standard Program Mapping Table
|
/// Transforms the TS::Packet into a standard Program Mapping Table
|
||||||
void TS::Packet::DefaultPMT( ) {
|
void TS::Packet::DefaultPMT( ) {
|
||||||
static int MyCntr = 0;
|
static int MyCntr = 0;
|
||||||
std::copy( TS::PMT, TS::PMT + 188, Buffer );
|
strBuf = std::string( TS::PMT, 188 );
|
||||||
ContinuityCounter( MyCntr );
|
ContinuityCounter( MyCntr );
|
||||||
Free = 0;
|
|
||||||
MyCntr = ( (MyCntr + 1) % 0x10);
|
MyCntr = ( (MyCntr + 1) % 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a string from the contents of the TS::Packet
|
/// Generates a string from the contents of the TS::Packet
|
||||||
/// \return A string representation of the packet.
|
/// \return A string representation of the packet.
|
||||||
char* TS::Packet::ToString( ) {
|
const char* TS::Packet::ToString( ) {
|
||||||
return Buffer;
|
if( strBuf.size() != 188 ) {
|
||||||
|
std::cerr << "Error: Size invalid (" << strBuf.size() << ") Invalid data from this point on." << std::endl;
|
||||||
|
}
|
||||||
|
return strBuf.c_str( );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a PES Lead-in for a video frame.
|
/// Generates a PES Lead-in for a video frame.
|
||||||
/// Starts at the first Free byte.
|
/// Starts at the first Free byte.
|
||||||
/// \param NewLen The length of this video frame.
|
/// \param NewLen The length of this video frame.
|
||||||
void TS::Packet::PESVideoLeadIn( int NewLen, long long unsigned int PTS ) {
|
void TS::Packet::PESVideoLeadIn( int NewLen, long long unsigned int PTS ) {
|
||||||
//static long long unsigned int PTS = 0;
|
NewLen += ( PTS == 1 ? 9 : 14 );
|
||||||
NewLen += 14;
|
strBuf += (char)0x00;//PacketStartCodePrefix
|
||||||
int Offset = ( 188 - Free );
|
strBuf += (char)0x00;//PacketStartCodePrefix (Cont)
|
||||||
Buffer[Offset] = 0x00;//PacketStartCodePrefix
|
strBuf += (char)0x01;//PacketStartCodePrefix (Cont)
|
||||||
Buffer[Offset+1] = 0x00;//PacketStartCodePrefix (Cont)
|
strBuf += (char)0xe0;//StreamType Video
|
||||||
Buffer[Offset+2] = 0x01;//PacketStartCodePrefix (Cont)
|
strBuf += (char)((NewLen & 0xFF00) >> 8);//PES PacketLength
|
||||||
Buffer[Offset+3] = 0xe0;//StreamType Video
|
strBuf += (char)(NewLen & 0x00FF);//PES PacketLength (Cont)
|
||||||
Buffer[Offset+4] = (NewLen & 0xFF00) >> 8;//PES PacketLength
|
strBuf += (char)0x80;//Reserved + Flags
|
||||||
Buffer[Offset+5] = (NewLen & 0x00FF);//PES PacketLength (Cont)
|
|
||||||
Buffer[Offset+6] = 0x80;//Reserved + Flags
|
|
||||||
if( PTS != 1 ) {
|
if( PTS != 1 ) {
|
||||||
Buffer[Offset+7] = 0x80;//PTSOnlyFlag + Flags
|
strBuf += (char)0x80;//PTSOnlyFlag + Flags
|
||||||
Buffer[Offset+8] = 0x05;//PESHeaderDataLength
|
strBuf += (char)0x05;//PESHeaderDataLength
|
||||||
Buffer[Offset+9] = 0x20 + ((PTS & 0x1C0000000) >> 29 ) + 1;//PTS
|
strBuf += (char)(0x20 + ((PTS & 0x1C0000000) >> 29 ) + 1);//PTS
|
||||||
Buffer[Offset+10] = 0x00 + ((PTS & 0x03FC00000) >> 22 );//PTS (Cont)
|
strBuf += (char)((PTS & 0x03FC00000) >> 22 );//PTS (Cont)
|
||||||
Buffer[Offset+11] = 0x00 + ((PTS & 0x0003F8000) >> 14 ) + 1;//PTS (Cont)
|
strBuf += (char)(((PTS & 0x0003F8000) >> 14 ) + 1);//PTS (Cont)
|
||||||
Buffer[Offset+12] = 0x00 + ((PTS & 0x000007F80) >> 7 );//PTS (Cont)
|
strBuf += (char)((PTS & 0x000007F80) >> 7 );//PTS (Cont)
|
||||||
Buffer[Offset+13] = 0x00 + ((PTS & 0x00000007F) << 1) + 1;//PTS (Cont)
|
strBuf += (char)(((PTS & 0x00000007F) << 1) + 1);//PTS (Cont)
|
||||||
Offset += 14;
|
|
||||||
} else {
|
} else {
|
||||||
Buffer[Offset+7] = 0x00;//PTSOnlyFlag + Flags
|
strBuf += (char)0x00;//PTSOnlyFlag + Flags
|
||||||
Buffer[Offset+8] = 0x00;//PESHeaderDataLength
|
strBuf += (char)0x00;//PESHeaderDataLength
|
||||||
Offset += 9;
|
|
||||||
}
|
}
|
||||||
//PesPacket-Wise Prepended Data
|
//PesPacket-Wise Prepended Data
|
||||||
|
|
||||||
Buffer[Offset] = 0x00;//NALU StartCode
|
strBuf += (char)0x00;//NALU StartCode
|
||||||
Buffer[Offset+1] = 0x00;//NALU StartCode (Cont)
|
strBuf += (char)0x00;//NALU StartCode (Cont)
|
||||||
Buffer[Offset+2] = 0x00;//NALU StartCode (Cont)
|
strBuf += (char)0x00;//NALU StartCode (Cont)
|
||||||
Buffer[Offset+3] = 0x01;//NALU StartCode (Cont)
|
strBuf += (char)0x01;//NALU StartCode (Cont)
|
||||||
Buffer[Offset+4] = 0x09;//NALU EndOfPacket (Einde Vorige Packet)
|
strBuf += (char)0x09;//NALU EndOfPacket (Einde Vorige Packet)
|
||||||
Buffer[Offset+5] = 0xF0;//NALU EndOfPacket (Cont)
|
strBuf += (char)0xF0;//NALU EndOfPacket (Cont)
|
||||||
Free = Free - (Offset+6);
|
|
||||||
//PTS += 3003;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a PES Lead-in for an audio frame.
|
/// Generates a PES Lead-in for an audio frame.
|
||||||
|
@ -266,33 +271,30 @@ void TS::Packet::PESVideoLeadIn( int NewLen, long long unsigned int PTS ) {
|
||||||
/// \param PTS The timestamp of the audio frame.
|
/// \param PTS The timestamp of the audio frame.
|
||||||
void TS::Packet::PESAudioLeadIn( int NewLen, uint64_t PTS ) {
|
void TS::Packet::PESAudioLeadIn( int NewLen, uint64_t PTS ) {
|
||||||
NewLen += 8;
|
NewLen += 8;
|
||||||
int Offset = ( 188 - Free ) - 2;
|
strBuf += (char)0x00;//PacketStartCodePrefix
|
||||||
Buffer[Offset] = 0x00;//PacketStartCodePrefix
|
strBuf += (char)0x00;//PacketStartCodePrefix (Cont)
|
||||||
Buffer[Offset+1] = 0x00;//PacketStartCodePrefix (Cont)
|
strBuf += (char)0x01;//PacketStartCodePrefix (Cont)
|
||||||
Buffer[Offset+2] = 0x01;//PacketStartCodePrefix (Cont)
|
strBuf += (char)0xc0;//StreamType Audio
|
||||||
Buffer[Offset+3] = 0xc0;//StreamType Video
|
|
||||||
|
|
||||||
Buffer[Offset+4] = (NewLen & 0xFF00) >> 8;//PES PacketLength
|
strBuf += (char)((NewLen & 0xFF00) >> 8);//PES PacketLength
|
||||||
Buffer[Offset+5] = (NewLen & 0x00FF);//PES PacketLength (Cont)
|
strBuf += (char)(NewLen & 0x00FF);//PES PacketLength (Cont)
|
||||||
Buffer[Offset+6] = 0x80;//Reserved + Flags
|
strBuf += (char)0x80;//Reserved + Flags
|
||||||
Buffer[Offset+7] = 0x80;//PTSOnlyFlag + Flags
|
strBuf += (char)0x80;//PTSOnlyFlag + Flags
|
||||||
Buffer[Offset+8] = 0x05;//PESHeaderDataLength
|
strBuf += (char)0x05;//PESHeaderDataLength
|
||||||
Buffer[Offset+9] = 0x20 + ((PTS & 0x1C0000000) >> 29 ) + 1;//PTS
|
strBuf += (char)(0x20 + ((PTS & 0x1C0000000) >> 29 ) + 1);//PTS
|
||||||
Buffer[Offset+10] = 0x00 + ((PTS & 0x03FC00000) >> 22 );//PTS (Cont)
|
strBuf += (char)((PTS & 0x03FC00000) >> 22 );//PTS (Cont)
|
||||||
Buffer[Offset+11] = 0x00 + ((PTS & 0x0003F8000) >> 14 ) + 1;//PTS (Cont)
|
strBuf += (char)(((PTS & 0x0003F8000) >> 14 ) + 1);//PTS (Cont)
|
||||||
Buffer[Offset+12] = 0x00 + ((PTS & 0x000007F80) >> 7 );//PTS (Cont)
|
strBuf += (char)((PTS & 0x000007F80) >> 7 );//PTS (Cont)
|
||||||
Buffer[Offset+13] = 0x00 + ((PTS & 0x00000007F) << 1) + 1;//PTS (Cont)
|
strBuf += (char)(((PTS & 0x00000007F) << 1) + 1);//PTS (Cont)
|
||||||
Free = Free - 12;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fills the free bytes of the TS::Packet.
|
/// Fills the free bytes of the TS::Packet.
|
||||||
/// Stores as many bytes from NewVal as possible in the packet.
|
/// Stores as many bytes from NewVal as possible in the packet.
|
||||||
/// \param NewVal The data to store in the packet.
|
/// \param NewVal The data to store in the packet.
|
||||||
void TS::Packet::FillFree( std::string & NewVal ) {
|
void TS::Packet::FillFree( std::string & NewVal ) {
|
||||||
int Offset = 188 - Free;
|
int toWrite = 188-strBuf.size();
|
||||||
std::copy( NewVal.begin(), NewVal.begin() + Free, Buffer + Offset );
|
strBuf += NewVal.substr(0,toWrite);
|
||||||
NewVal.erase(0,Free);
|
NewVal.erase(0,toWrite);
|
||||||
Free = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds NumBytes of stuffing to the TS::Packet.
|
/// Adds NumBytes of stuffing to the TS::Packet.
|
||||||
|
@ -300,56 +302,19 @@ void TS::Packet::FillFree( std::string & NewVal ) {
|
||||||
void TS::Packet::AddStuffing( int NumBytes ) {
|
void TS::Packet::AddStuffing( int NumBytes ) {
|
||||||
if( NumBytes <= 0 ) { return; }
|
if( NumBytes <= 0 ) { return; }
|
||||||
if( AdaptationField( ) == 3 ) {
|
if( AdaptationField( ) == 3 ) {
|
||||||
int Offset = Buffer[4];
|
int Offset = strBuf[4];
|
||||||
Buffer[4] = Offset + NumBytes - 1;
|
strBuf[4] = Offset + NumBytes - 1;
|
||||||
|
strBuf.resize(7+Offset+NumBytes-2);
|
||||||
for( int i = 0; i < ( NumBytes -2 ); i ++ ) {
|
for( int i = 0; i < ( NumBytes -2 ); i ++ ) {
|
||||||
Buffer[6+Offset+i] = 0xFF;
|
strBuf[6+Offset+i] = 0xFF;
|
||||||
}
|
}
|
||||||
Free -= NumBytes;
|
|
||||||
} else {
|
} else {
|
||||||
AdaptationField( 3 );
|
AdaptationField( 3 );
|
||||||
Buffer[4] = NumBytes - 1;
|
strBuf.resize(6);
|
||||||
Buffer[5] = 0x00;
|
strBuf[4] = (char)(NumBytes - 1);
|
||||||
for( int i = 0; i < ( NumBytes -2 ); i ++ ) {
|
strBuf[5] = (char)0x00;
|
||||||
Buffer[6+i] = 0xFF;
|
for( int i = 0; i < ( NumBytes - 2 ); i ++ ) {
|
||||||
|
strBuf += (char)0xFF;
|
||||||
}
|
}
|
||||||
Free -= NumBytes;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Transforms this TS::Packet into a standard Service Description Table
|
|
||||||
void TS::Packet::FFMpegHeader( ) {
|
|
||||||
static int MyCntr = 0;
|
|
||||||
std::copy( TS::SDT, TS::SDT + 188, Buffer );
|
|
||||||
ContinuityCounter( MyCntr );
|
|
||||||
Free = 0;
|
|
||||||
MyCntr = ( (MyCntr + 1) % 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TS::Packet::PESTimeStamp( ) {
|
|
||||||
if( !UnitStart( ) ) { return -1; }
|
|
||||||
int PesOffset = 4;
|
|
||||||
if( AdaptationField( ) >= 2 ) { PesOffset += 1 + AdaptationFieldLen( ); }
|
|
||||||
fprintf( stderr, "PES Offset: %d\n", PesOffset );
|
|
||||||
fprintf( stderr, "PES StartCode: %0.2X %0.2X %0.2X\n", Buffer[PesOffset], Buffer[PesOffset+1], Buffer[PesOffset+2] );
|
|
||||||
int MyTimestamp = (Buffer[PesOffset+9] & 0x0F) >> 1;
|
|
||||||
MyTimestamp = (MyTimestamp << 8) + Buffer[PesOffset+10];
|
|
||||||
MyTimestamp = (MyTimestamp << 7) + ((Buffer[PesOffset+11]) >> 1);
|
|
||||||
MyTimestamp = (MyTimestamp << 8) + Buffer[PesOffset+12];
|
|
||||||
MyTimestamp = (MyTimestamp << 7) + ((Buffer[PesOffset+13]) >> 1);
|
|
||||||
fprintf( stderr, "PES Timestamp: %d\n", MyTimestamp );
|
|
||||||
return MyTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TS::Packet::GetDataOffset( ) {
|
|
||||||
int Offset = 4;
|
|
||||||
if( AdaptationField( ) >= 2 ) {
|
|
||||||
Offset += 1 + AdaptationFieldLen( );
|
|
||||||
}
|
|
||||||
if( UnitStart() ) {
|
|
||||||
Offset += 8;//Default Header + Flag Bytes
|
|
||||||
Offset += 1 + Buffer[Offset];//HeaderLengthByte + HeaderLength
|
|
||||||
}
|
|
||||||
return Offset;
|
|
||||||
}
|
|
||||||
|
|
|
@ -39,18 +39,15 @@ namespace TS {
|
||||||
int BytesFree();
|
int BytesFree();
|
||||||
|
|
||||||
void Print();
|
void Print();
|
||||||
char* ToString();
|
const char* ToString();
|
||||||
void PESVideoLeadIn( int NewLen, long long unsigned int PTS = 1 );
|
void PESVideoLeadIn( int NewLen, long long unsigned int PTS = 1 );
|
||||||
void PESAudioLeadIn( int NewLen, uint64_t PTS = 0 );
|
void PESAudioLeadIn( int NewLen, uint64_t PTS = 0 );
|
||||||
void FillFree( std::string & PackageData );
|
void FillFree( std::string & PackageData );
|
||||||
void AddStuffing( int NumBytes );
|
void AddStuffing( int NumBytes );
|
||||||
void FFMpegHeader( );
|
|
||||||
|
|
||||||
int PESTimeStamp( );
|
|
||||||
int GetDataOffset( );
|
|
||||||
private:
|
private:
|
||||||
int Free;
|
//int Free;
|
||||||
char Buffer[188];///< The actual data
|
std::string strBuf;
|
||||||
|
//char Buffer[188];///< The actual data
|
||||||
};//TS::Packet class
|
};//TS::Packet class
|
||||||
|
|
||||||
/// Constructs an audio header to be used on each audio frame.
|
/// Constructs an audio header to be used on each audio frame.
|
||||||
|
@ -100,41 +97,6 @@ namespace TS {
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF
|
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A standard Sevice Description Table, as generated by FFMPEG.
|
|
||||||
/// Not used in our connector, provided for compatibility means
|
|
||||||
static char SDT[188] = {
|
|
||||||
0x47,0x40,0x11,0x10, 0x00,0x42,0xF0,0x25, 0x00,0x01,0xC1,0x00, 0x00,0x00,0x01,0xFF,
|
|
||||||
0x00,0x01,0xFC,0x80, 0x14,0x48,0x12,0x01, 0x06,0x46,0x46,0x6D, 0x70,0x65,0x67,0x09,
|
|
||||||
0x53,0x65,0x72,0x76, 0x69,0x63,0x65,0x30, 0x31,0xA7,0x79,0xA0, 0x03,0xFF,0xFF,0xFF,
|
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
|
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
|
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
|
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
|
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
|
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
|
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
|
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
|
|
||||||
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A standard Picture Parameter Set, as generated by FFMPEG.
|
|
||||||
/// Seems to be stream-independent.
|
|
||||||
static char PPS[24] = {
|
|
||||||
0x00,0x00,0x00,0x01,
|
|
||||||
0x27,0x4D,0x40,0x1F,
|
|
||||||
0xA9,0x18,0x0A,0x00,
|
|
||||||
0xB7,0x60,0x0D,0x40,
|
|
||||||
0x40,0x40,0x4C,0x2B,
|
|
||||||
0x5E,0xF7,0xC0,0x40
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A standard Sequence Parameter Set, as generated by FFMPEG.
|
|
||||||
/// Seems to be stream-independent.
|
|
||||||
static char SPS[8] = {
|
|
||||||
0x00,0x00,0x00,0x01,
|
|
||||||
0x28,0xCE,0x09,0xC8
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The full Bytesteam Nal-Header.
|
/// The full Bytesteam Nal-Header.
|
||||||
static char NalHeader[4] = {
|
static char NalHeader[4] = {
|
||||||
0x00,0x00,0x00,0x01
|
0x00,0x00,0x00,0x01
|
||||||
|
|
Loading…
Add table
Reference in a new issue