Created a NAL_Unit class to aid in translation between 'Regular' and 'Annex B' h264 streams
This commit is contained in:
parent
663a504891
commit
01dc2a1a00
6 changed files with 142 additions and 6 deletions
|
@ -1,4 +1,4 @@
|
|||
noinst_LTLIBRARIES=libamf.la libauth.la libbase64.la libconfig.la libcrypto.la libdtsc.la libflv_tag.la libhttp_parser.la libjson.la libprocs.la librtmpchunks.la libsocket.la libtinythread.la libmp4.la libts_packet.la
|
||||
noinst_LTLIBRARIES=libamf.la libauth.la libbase64.la libconfig.la libcrypto.la libdtsc.la libflv_tag.la libhttp_parser.la libjson.la libprocs.la librtmpchunks.la libsocket.la libtinythread.la libmp4.la libts_packet.la libnal_unit.la
|
||||
libamf_la_SOURCES=amf.h amf.cpp
|
||||
libauth_la_SOURCES=auth.h auth.cpp
|
||||
libauth_la_LIBADD=-lssl -lcrypto
|
||||
|
@ -20,3 +20,4 @@ libtinythread_la_LIBADD=-lpthread
|
|||
libmp4_la_SOURCES=mp4.h mp4.cpp
|
||||
libts_packet_la_SOURCES=ts_packet.h ts_packet.cpp
|
||||
libts_packet_la_LIBADD=./libdtsc.la
|
||||
libnal_unit_la_SOURCES=nal.h nal.cpp
|
||||
|
|
77
lib/nal.cpp
Normal file
77
lib/nal.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "nal.h"
|
||||
|
||||
NAL_Unit::NAL_Unit( ) {
|
||||
|
||||
}
|
||||
|
||||
NAL_Unit::NAL_Unit( std::string & InputData ) {
|
||||
ReadData( InputData );
|
||||
}
|
||||
|
||||
bool NAL_Unit::ReadData( std::string & InputData ) {
|
||||
bool AnnexB = false;
|
||||
if( InputData[0] == 0x00 && InputData[1] == 0x00 ) {
|
||||
if( InputData[2] == 0x01 ) {
|
||||
AnnexB = true;
|
||||
}
|
||||
if( InputData[2] == 0x00 && InputData[3] == 0x01 ) {
|
||||
InputData.erase(0,1);
|
||||
AnnexB = true;
|
||||
}
|
||||
}
|
||||
if( AnnexB ) {
|
||||
MyData = "";
|
||||
InputData.erase(0,3);//Intro Bytes
|
||||
bool FinalByteRead = false;
|
||||
while( !FinalByteRead ) {
|
||||
MyData += InputData[0];
|
||||
InputData.erase(0,1);
|
||||
if( InputData[0] == 0x00 && InputData[1] == 0x00 ) {
|
||||
if( InputData[2] == 0x01 ) {
|
||||
FinalByteRead = true;
|
||||
}
|
||||
if( InputData[2] == 0x00 && InputData[3] == 0x01 ) {
|
||||
InputData.erase(0,1);
|
||||
FinalByteRead= true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if( InputData.size() < 4 ) { return false; }
|
||||
int UnitLen = (InputData[0] << 24) + (InputData[1] << 16) + (InputData[2] << 8) + InputData[3];
|
||||
if( InputData.size() < 4+UnitLen ) { return false; }
|
||||
InputData.erase(0,4);//Remove Length
|
||||
MyData = InputData.substr(0,UnitLen);
|
||||
InputData.erase(0,UnitLen);//Remove this unit from the string
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string NAL_Unit::AnnexB( bool LongIntro ) {
|
||||
std::string Result;
|
||||
if( MyData.size() ) {
|
||||
if( LongIntro ) { Result += (char)0x00; }
|
||||
Result += (char)0x00;
|
||||
Result += (char)0x00;
|
||||
Result += (char)0x01;//Annex B Lead-In
|
||||
Result += MyData;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::string NAL_Unit::SizePrepended( ) {
|
||||
std::string Result;
|
||||
if( MyData.size() ) {
|
||||
int DataSize = MyData.size();
|
||||
Result += (char)( ( DataSize & 0xFF000000 ) >> 24 );
|
||||
Result += (char)( ( DataSize & 0x00FF0000 ) >> 16 );
|
||||
Result += (char)( ( DataSize & 0x0000FF00 ) >> 8 );
|
||||
Result += (char)( DataSize & 0x000000FF );//Size Lead-In
|
||||
Result += MyData;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
int NAL_Unit::Type( ) {
|
||||
return ( MyData[0] & 0x1F );
|
||||
}
|
13
lib/nal.h
Normal file
13
lib/nal.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <string>
|
||||
|
||||
class NAL_Unit {
|
||||
public:
|
||||
NAL_Unit( );
|
||||
NAL_Unit( std::string & InputData );
|
||||
bool ReadData( std::string & InputData );
|
||||
std::string AnnexB( bool LongIntro = false );
|
||||
std::string SizePrepended( );
|
||||
int Type( );
|
||||
private:
|
||||
std::string MyData;
|
||||
};//NAL_Unit class
|
|
@ -368,11 +368,55 @@ int TS::Packet::PESTimeStamp( ) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int TS::Packet::GetDataOffset( ) {
|
||||
int Offset = 4;
|
||||
fprintf( stderr,"\tBefore Adapt: %d\n", Offset );
|
||||
if( AdaptationField( ) >= 2 ) {
|
||||
Offset += 1 + AdaptationFieldLen( );
|
||||
}
|
||||
fprintf( stderr,"\tBefore UnitStart: %d\n", Offset );
|
||||
if( UnitStart() ) {
|
||||
fprintf( stderr, "\t\tPES Header Len: %d\n", Buffer[Offset+8] );
|
||||
Offset += 8;//Default Header + Flag Bytes
|
||||
Offset += 1 + Buffer[Offset];//HeaderLengthByte + HeaderLength
|
||||
}
|
||||
fprintf( stderr,"\tBefore Return: %d\n", Offset );
|
||||
return Offset;
|
||||
}
|
||||
|
||||
/*
|
||||
DTSC::DTMI TS::Packet::toDTSC(DTSC::DTMI & metadata, std::string Type) {
|
||||
DTSC::DTMI outPack = DTSC::DTMI(Type, DTSC::DTMI_ROOT);
|
||||
outPack.addContent(DTSC::DTMI("datatype", Type));
|
||||
if( UnitStart() ) {
|
||||
outPack.addContent(DTSC::DTMI("time", PESTimeStamp( )));
|
||||
}
|
||||
if( UnitStart() ){ outPack.addContent(DTSC::DTMI("time", PESTimeStamp( ))); }
|
||||
if( Type == "video" && (RandomAccess() > 0) ){ outPack.addContent(DTSC::DTMI("keyframe", 1)); }
|
||||
int DataOffset = GetDataOffset();
|
||||
fprintf( stderr, "Data Offset: %d\n", DataOffset );
|
||||
outPack.addContent(DTSC::DTMI("data", std::string((char*)Buffer+DataOffset, (size_t)188-DataOffset)));
|
||||
return outPack;
|
||||
}
|
||||
*/
|
||||
|
||||
void TS::Packet::toDTSC( std::string Type, DTSC::DTMI & CurrentDTSC ) {
|
||||
if( !CurrentDTSC.getContentP( "datatype" ) ) {
|
||||
CurrentDTSC.addContent( DTSC::DTMI("datatype", Type ) );
|
||||
}
|
||||
if( UnitStart() ) {
|
||||
if( !CurrentDTSC.getContentP( "time" ) ) {
|
||||
CurrentDTSC.addContent( DTSC::DTMI( "time", PESTimeStamp( ) ) );
|
||||
}
|
||||
}
|
||||
if( Type == "video" && (RandomAccess() > 0) ){
|
||||
if( !CurrentDTSC.getContentP( "keyframe" ) ) {
|
||||
CurrentDTSC.addContent(DTSC::DTMI("keyframe", 1));
|
||||
}
|
||||
}
|
||||
int DataOffset = GetDataOffset();
|
||||
fprintf( stderr, "Data Offset: %d\n", DataOffset );
|
||||
std::string ToAppend = std::string((char*)Buffer+DataOffset, (size_t)188-DataOffset);
|
||||
std::string CurrentData;
|
||||
if( CurrentDTSC.getContentP( "data" ) ) {
|
||||
CurrentData = CurrentDTSC.getContent( "data" ).StrValue( );
|
||||
}
|
||||
CurrentDTSC.addContent(DTSC::DTMI("data", CurrentData + ToAppend ));
|
||||
}
|
||||
|
|
|
@ -47,11 +47,13 @@ namespace TS {
|
|||
void FFMpegHeader( );
|
||||
|
||||
int PESTimeStamp( );
|
||||
int GetDataOffset( );
|
||||
|
||||
//For output to DTSC
|
||||
int ProgramMapPID( );
|
||||
void UpdateStreamPID( int & VideoPid, int & AudioPid );
|
||||
DTSC::DTMI toDTSC(DTSC::DTMI & metadata, std::string Type);
|
||||
//DTSC::DTMI toDTSC(DTSC::DTMI & metadata, std::string Type);
|
||||
void toDTSC( std::string Type, DTSC::DTMI & CurrentDTSC );
|
||||
private:
|
||||
int Free;
|
||||
char Buffer[188];///< The actual data
|
||||
|
|
|
@ -6,4 +6,3 @@ MistFLV2DTSC_SOURCES=flv2dtsc.cpp
|
|||
MistDTSCFix_SOURCES=dtscfix.cpp
|
||||
MistDTSC2TS_SOURCES=dtsc2ts.cpp
|
||||
MistTS2DTSC_SOURCES=ts2dtsc.cpp
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue