diff --git a/src/analysers/Makefile.am b/src/analysers/Makefile.am index 3447ab61..fb5f0619 100644 --- a/src/analysers/Makefile.am +++ b/src/analysers/Makefile.am @@ -1,10 +1,9 @@ AM_CPPFLAGS = $(global_CFLAGS) $(MIST_CFLAGS) LDADD = $(MIST_LIBS) -bin_PROGRAMS=MistAnalyserRTMP MistAnalyserFLV MistAnalyserDTSC MistAnalyserAMF MistAnalyserMP4 MistAnalyserTS +bin_PROGRAMS=MistAnalyserRTMP MistAnalyserFLV MistAnalyserDTSC MistAnalyserAMF MistAnalyserMP4 MistAnalyserRTMP_SOURCES=rtmp_analyser.cpp MistAnalyserFLV_SOURCES=flv_analyser.cpp MistAnalyserDTSC_SOURCES=dtsc_analyser.cpp MistAnalyserAMF_SOURCES=amf_analyser.cpp MistAnalyserMP4_SOURCES=mp4_analyser.cpp -MistAnalyserTS_SOURCES=ts_analyser.cpp diff --git a/src/conn_ts.cpp b/src/conn_ts.cpp index a3148453..418e1391 100644 --- a/src/conn_ts.cpp +++ b/src/conn_ts.cpp @@ -21,15 +21,15 @@ #include #include #include +#include /// The main function of the connector /// \param conn A connection with the client /// \param streamname The name of the stream int TS_Handler( Socket::Connection conn, std::string streamname ) { std::string ToPack; - std::string DTMIData; TS::Packet PackData; - DTSC::Stream DTSCStream; + DTSC::Stream Strm; int PacketNumber = 0; uint64_t TimeStamp = 0; int ThisNaluSize; @@ -40,12 +40,15 @@ int TS_Handler( Socket::Connection conn, std::string streamname ) { bool FirstKeyFrame = true; bool FirstIDRInKeyFrame; + std::string myPPS; + std::string mySPS; + bool inited = false; Socket::Connection ss; while(conn.connected()) { if( !inited ) { - ss = Socket::Connection("/tmp/mist/stream_" + streamname ); + ss = Util::Stream::getStream(streamname); if (!ss.connected()){ #if DEBUG >= 1 fprintf(stderr, "Could not connect to server!\n"); @@ -53,153 +56,143 @@ int TS_Handler( Socket::Connection conn, std::string streamname ) { conn.close(); break; } + ss.SendNow( "p\n" ); #if DEBUG >= 3 fprintf(stderr, "Everything connected, starting to send video data...\n"); #endif inited = true; } - - switch (ss.ready()){ - case -1: - conn.close(); - #if DEBUG >= 1 - fprintf(stderr, "Source socket is disconnected.\n"); - #endif - break; - case 0: break;//not ready yet - default: - ss.spool(); - if ( DTSCStream.parsePacket( ss.Received() ) ) { - if( DTSCStream.lastType() == DTSC::VIDEO ) { - DTMIData = DTSCStream.lastData(); - if( DTSCStream.getPacket(0).getContent("keyframe").NumValue() ) { - IsKeyFrame = true; - FirstIDRInKeyFrame = true; - } else { - IsKeyFrame = false; - FirstKeyFrame = false; - } - #if DEBUG >= 3 - fprintf(stderr, "Videoframe received -- Keyframe: %d\n", IsKeyFrame ); - #endif - TimeStamp = (DTSCStream.getPacket(0).getContent("time").NumValue() * 27000 ); - int TSType; - bool FirstPic = true; - while( DTMIData.size() ) { - ThisNaluSize = (DTMIData[0] << 24) + (DTMIData[1] << 16) + - (DTMIData[2] << 8) + DTMIData[3]; - DTMIData.erase(0,4);//Erase the first four characters; - TSType = (int)DTMIData[0]; - if( TSType == 0x25 ) { - if( FirstPic ) { - ToPack.append(TS::PPS,24); - ToPack.append(TS::SPS,8); - FirstPic = false; - } - if( IsKeyFrame ) { - if( !FirstKeyFrame && FirstIDRInKeyFrame ) { - ToPack.append(TS::NalHeader,4); - FirstIDRInKeyFrame = false; - } else { - ToPack.append(TS::ShortNalHeader,3); - } - } - } else if ( TSType == 0x21 ) { - if( FirstPic ) { + fprintf( stderr, "Are we inited? %d\n", inited ); + if (ss.spool()){ + while (Strm.parsePacket(ss.Received())){ + if( mySPS == "" && myPPS == "" ) { + int SPSLen = ((Strm.metadata["video"]["init"].asString()[6])<<8) + Strm.metadata["video"]["init"].asString()[7]; + mySPS = Strm.metadata["video"]["init"].asString().substr(8,SPSLen); + fprintf( stderr, "mySPS.size(): %d ( given %d )\n", mySPS.size(), SPSLen ); + int PPSLen = ((Strm.metadata["video"]["init"].asString()[8+SPSLen+1])<<8) + Strm.metadata["video"]["init"].asString()[8+SPSLen+2]; + myPPS = Strm.metadata["video"]["init"].asString().substr(8+SPSLen+3,PPSLen); + fprintf( stderr, "myPPS.size(): %d ( given %d )\n", myPPS.size(), PPSLen ); + } + if( Strm.lastType() == DTSC::VIDEO ) { + fprintf( stderr, "VideoFrame\n" ); + if( Strm.getPacket(0).isMember("keyframe") ) { + IsKeyFrame = true; + FirstIDRInKeyFrame = true; + } else { + IsKeyFrame = false; + FirstKeyFrame = false; + } + TimeStamp = ( Strm.getPacket(0)["time"].asInt() ); + if( IsKeyFrame ) { fprintf( stderr, " Keyframe, timeStamp: %u\n", TimeStamp ); } + int TSType; + bool FirstPic = true; + while( Strm.lastData().size() > 4) { + fprintf( stderr, " Loop-iter\n" ); + ThisNaluSize = (Strm.lastData()[0] << 24) + (Strm.lastData()[1] << 16) + + (Strm.lastData()[2] << 8) + Strm.lastData()[3]; + Strm.lastData().erase(0,4);//Erase the first four characters; + TSType = (int)Strm.lastData()[0]; + if( TSType == 0x05 ) { + if( FirstPic ) { + ToPack.append(myPPS); + ToPack.append(mySPS); + FirstPic = false; + } + if( IsKeyFrame ) { + if( !FirstKeyFrame && FirstIDRInKeyFrame ) { ToPack.append(TS::NalHeader,4); - FirstPic = false; + FirstIDRInKeyFrame = false; } else { ToPack.append(TS::ShortNalHeader,3); } - } else { + } + } else if ( TSType == 0x01 ) { + if( FirstPic ) { ToPack.append(TS::NalHeader,4); - } - ToPack.append(DTMIData,0,ThisNaluSize); - DTMIData.erase(0,ThisNaluSize); - } - WritePesHeader = true; - while( ToPack.size() ) { - if ( ( PacketNumber % 42 ) == 0 ) { - PackData.DefaultPAT(); - #if DEBUG >= 3 - fprintf(stderr, "\tSending PAT\n" ); - #endif - conn.write( PackData.ToString() ); - } else if ( ( PacketNumber % 42 ) == 1 ) { - PackData.DefaultPMT(); - #if DEBUG >= 3 - fprintf(stderr, "\tSending PMT\n" ); - #endif - conn.write( PackData.ToString() ); + FirstPic = false; } else { - PackData.Clear(); - PackData.PID( 0x100 ); - PackData.ContinuityCounter( VideoCounter ); - VideoCounter ++; - if( WritePesHeader ) { - PackData.UnitStart( 1 ); - if( IsKeyFrame ) { - PackData.RandomAccess( 1 ); - PackData.PCR( TimeStamp ); - } else { - PackData.AdaptationField( 0x01 ); - } - PackData.AddStuffing( 184 - (20+ToPack.size()) ); - PackData.PESVideoLeadIn( ToPack.size() ); - WritePesHeader = false; - } else { - PackData.AdaptationField( 0x01 ); - PackData.AddStuffing( 184 - (ToPack.size()) ); - } - PackData.FillFree( ToPack ); - #if DEBUG >= 3 - fprintf(stderr, "\tSending Video Data\n" ); - #endif - conn.write( PackData.ToString() ); + ToPack.append(TS::ShortNalHeader,3); } - PacketNumber ++; - conn.spool(); + } else { + ToPack.append(TS::NalHeader,4); } + ToPack.append(Strm.lastData(),0,ThisNaluSize); + Strm.lastData().erase(0,ThisNaluSize); } - if( DTSCStream.lastType() == DTSC::AUDIO ) { - WritePesHeader = true; - DTMIData = DTSCStream.lastData(); - ToPack = TS::GetAudioHeader( DTMIData.size() ); - ToPack += DTMIData; - TimeStamp = DTSCStream.getPacket(0).getContent("time").NumValue() * 900; - while( ToPack.size() ) { - if ( ( PacketNumber % 42 ) == 0 ) { - PackData.DefaultPAT(); - conn.write( PackData.ToString() ); - } else if ( ( PacketNumber % 42 ) == 1 ) { - PackData.DefaultPMT(); - conn.write( PackData.ToString() ); - } else { - PackData.Clear(); - PackData.PID( 0x101 ); - PackData.ContinuityCounter( AudioCounter ); - AudioCounter ++; - if( WritePesHeader ) { - PackData.UnitStart( 1 ); + WritePesHeader = true; + while( ToPack.size() ) { + if ( ( PacketNumber % 42 ) == 0 ) { + fprintf( stderr, " Sending PAT\n" ); + PackData.DefaultPAT(); + fprintf( stderr, " Constructed PAT\n" ); + conn.SendNow( PackData.ToString(), 188 ); + fprintf( stderr, " Sent PAT\n" ); + } else if ( ( PacketNumber % 42 ) == 1 ) { + PackData.DefaultPMT(); + conn.SendNow( PackData.ToString(), 188 ); + } else { + PackData.Clear(); + PackData.PID( 0x100 ); + PackData.ContinuityCounter( VideoCounter ); + VideoCounter ++; + if( WritePesHeader ) { + PackData.UnitStart( 1 ); + if( IsKeyFrame ) { PackData.RandomAccess( 1 ); - PackData.AddStuffing( 184 - (14 + ToPack.size()) ); - PackData.PESAudioLeadIn( ToPack.size(), TimeStamp ); - WritePesHeader = false; + PackData.PCR( TimeStamp * 27000 ); } else { PackData.AdaptationField( 0x01 ); - PackData.AddStuffing( 184 - (ToPack.size()) ); } - PackData.FillFree( ToPack ); - conn.write( PackData.ToString() ); + PackData.AddStuffing( 184 - (20+ToPack.size()) ); + PackData.PESVideoLeadIn( ToPack.size() ); + WritePesHeader = false; + } else { + PackData.AdaptationField( 0x01 ); + PackData.AddStuffing( 184 - (ToPack.size()) ); } - PacketNumber ++; - conn.spool(); + PackData.FillFree( ToPack ); + conn.SendNow( PackData.ToString(), 188 ); } - } + PacketNumber ++; + } + } else if( Strm.lastType() == DTSC::AUDIO ) { + WritePesHeader = true; + ToPack = TS::GetAudioHeader( Strm.lastData().size() ); + ToPack += Strm.lastData(); + TimeStamp = Strm.getPacket(0)["time"].asInt() * 81000; + while( ToPack.size() ) { + if ( ( PacketNumber % 42 ) == 0 ) { + PackData.DefaultPAT(); + conn.SendNow( PackData.ToString(), 188 ); + } else if ( ( PacketNumber % 42 ) == 1 ) { + PackData.DefaultPMT(); + conn.SendNow( PackData.ToString(), 188 ); + } else { + PackData.Clear(); + PackData.PID( 0x101 ); + PackData.ContinuityCounter( AudioCounter ); + AudioCounter ++; + if( WritePesHeader ) { + PackData.UnitStart( 1 ); + //PackData.RandomAccess( 1 ); + PackData.AddStuffing( 184 - (14 + ToPack.size()) ); + PackData.RandomAccess( 1 ); + PackData.PESAudioLeadIn( ToPack.size(), TimeStamp ); + WritePesHeader = false; + } else { + PackData.AdaptationField( 0x01 ); + PackData.AddStuffing( 184 - (ToPack.size()) ); + } + PackData.FillFree( ToPack ); + conn.SendNow( PackData.ToString(), 188 ); + } + PacketNumber ++; + } } - break; + } } } + fprintf( stderr, "Exiting\n" ); return 0; } diff --git a/src/converters/Makefile.am b/src/converters/Makefile.am index 4865c36a..63f5adf0 100644 --- a/src/converters/Makefile.am +++ b/src/converters/Makefile.am @@ -1,8 +1,7 @@ AM_CPPFLAGS = $(global_CFLAGS) $(MIST_CFLAGS) LDADD = $(MIST_LIBS) -bin_PROGRAMS=MistDTSC2FLV MistFLV2DTSC MistDTSCFix MistDTSC2TS MistTS2DTSC +bin_PROGRAMS=MistDTSC2FLV MistFLV2DTSC MistDTSCFix MistDTSC2TS MistDTSC2FLV_SOURCES=dtsc2flv.cpp MistFLV2DTSC_SOURCES=flv2dtsc.cpp MistDTSCFix_SOURCES=dtscfix.cpp MistDTSC2TS_SOURCES=dtsc2ts.cpp -MistTS2DTSC_SOURCES=ts2dtsc.cpp diff --git a/src/converters/dtsc2ts.cpp b/src/converters/dtsc2ts.cpp index cd78eea9..2f86c5db 100644 --- a/src/converters/dtsc2ts.cpp +++ b/src/converters/dtsc2ts.cpp @@ -34,14 +34,14 @@ int main( ) { if ( DTSCStream.parsePacket( StrData ) ) { if( DTSCStream.lastType() == DTSC::VIDEO ) { DTMIData = DTSCStream.lastData(); - if( DTSCStream.getPacket(0).getContent("keyframe").NumValue() ) { + if( DTSCStream.getPacket(0).isMember("keyframe") ) { IsKeyFrame = true; FirstIDRInKeyFrame = true; } else { IsKeyFrame = false; FirstKeyFrame = false; } - TimeStamp = ((DTSCStream.getPacket(0).getContent("time").NumValue() + 700) * 27000 ); + TimeStamp = ( DTSCStream.getPacket(0)["time"].asInt() * 27000 ); if( IsKeyFrame ) { fprintf( stderr, "Keyframe, timeStamp: %u\n", TimeStamp ); } @@ -117,7 +117,7 @@ int main( ) { DTMIData = DTSCStream.lastData(); ToPack = TS::GetAudioHeader( DTMIData.size() ); ToPack += DTMIData; - TimeStamp = DTSCStream.getPacket(0).getContent("time").NumValue() * 900; + TimeStamp = DTSCStream.getPacket(0)["time"].asInt() * 81000; while( ToPack.size() ) { if ( ( PacketNumber % 42 ) == 0 ) { PackData.DefaultPAT(); diff --git a/src/converters/ts2dtsc.cpp b/src/converters/ts2dtsc.cpp deleted file mode 100644 index 26147534..00000000 --- a/src/converters/ts2dtsc.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include -#include //TS support -#include //DTSC support -#include //NAL Unit operations - -//DTSC::DTMI MetaData -//DTSC::DTMI OutData - //X if( PID() == 0x00 ) --> PAT --> Extract first PMT PID() - //X if( PID() == PMTStream ) --> PMT --> Extract first video PMT() && Extract first audio PMT() - // if( PID() == AudioStream ) --> Audio --> Extract Timestamp IF keyframe --> DTSC - // if( PID() == VideoStream ) --> Video --> AnnexB_to_Regular --> Extract Timestamp IF keyframe --> Remove PPS? --> Remove SPS? --> DTSC - - -//Copied from FLV_TAG -void Meta_Put(DTSC::DTMI & meta, std::string cat, std::string elem, std::string val){ - if (meta.getContentP(cat) == 0){meta.addContent(DTSC::DTMI(cat));} - meta.getContentP(cat)->addContent(DTSC::DTMI(elem, val)); -} - -void Meta_Put(DTSC::DTMI & meta, std::string cat, std::string elem, int val){ - if (meta.getContentP(cat) == 0){meta.addContent(DTSC::DTMI(cat));} - meta.getContentP(cat)->addContent(DTSC::DTMI(elem, val)); -} - - -int main( ) { - char charBuffer[1024*10]; - unsigned int charCount; - std::string StrData; - TS::Packet TSData; - int PMT_PID = -1; - int VideoPID = -1; - int AudioPID = -1; - int VideoTime_Offset = -1; - DTSC::DTMI Meta; - DTSC::DTMI VideoOut; - DTSC::DTMI AudioOut; - //Default MetaData, not NEARLY all options used, because encoded in video rather than parameters - //Combined with Stubdata, for alignment with original DTSC of testcase - Meta_Put(Meta, "video", "codec", "H264"); - Meta_Put(Meta, "video", "width", 1280); - Meta_Put(Meta, "video", "height", 720); - Meta_Put(Meta, "video", "fpks", 2997000); - Meta_Put(Meta, "video", "bps", 832794); - char VideoInit[] = {0x01,0x4D,0x40,0x1F, - 0xFF,0xE1,0x00,0x14, - 0x27,0x4D,0x40,0x1F, - 0xA9,0x18,0x0A,0x00, - 0xB7,0x60,0x0D,0x40, - 0x40,0x40,0x4C,0x2B, - 0x5E,0xF7,0xC0,0x40, - 0x01,0x00,0x04,0x28, - 0xCE,0x09,0xC8}; - Meta_Put(Meta, "video", "init", std::string( VideoInit, 35 ) ); - - Meta_Put(Meta, "audio", "codec", "AAC"); - Meta_Put(Meta, "audio", "bps", 24021); - Meta_Put(Meta, "audio", "rate", 48000); - Meta_Put(Meta, "audio", "size", 16); - Meta_Put(Meta, "audio", "channels", 2); - char AudioInit[] = {0x11,0x90}; - Meta_Put(Meta, "audio", "init", std::string( AudioInit, 2 ) ); - - Meta.Pack(true); - Meta.packed.replace(0, 4, DTSC::Magic_Header); - std::cout << Meta.packed; - std::string PrevType = ""; - while( std::cin.good() ) { - std::cin.read(charBuffer, 1024*10); - charCount = std::cin.gcount(); - StrData.append(charBuffer, charCount); - while( TSData.FromString( StrData ) ) { -// fprintf( stderr, "PID: %d\n", TSData.PID() ); - if( TSData.PID() == 0 ) { - int TmpPMTPid = TSData.ProgramMapPID( ); - if( TmpPMTPid != -1 ) { PMT_PID = TmpPMTPid; } -// fprintf( stderr, "\tPMT PID: %d\n", PMT_PID ); - } - if( TSData.PID() == PMT_PID ) { - TSData.UpdateStreamPID( VideoPID, AudioPID ); -// fprintf( stderr, "\tVideoStream: %d\n\tAudioStream: %d\n", VideoPID, AudioPID ); - } - if( TSData.PID() == VideoPID ) { - if( PrevType == "Audio" ) { - fprintf( stderr, "\tVideopacket, sending audiobuffer\n" ); - std::string AudioData = AudioOut.getContent("data").StrValue(); - AudioData.erase(0,7);//remove the header - AudioOut.addContent( DTSC::DTMI( "data", AudioData ) ); - std::cout << AudioOut.Pack(true); - AudioOut = DTSC::DTMI(); - AudioOut.addContent( DTSC::DTMI( "datatype", "audio" ) ); - } - if( TSData.UnitStart( ) && PrevType == "Video" ) { - fprintf( stderr, "\tNew VideoPacket, Writing old\n" ); - std::string AnnexBData = VideoOut.getContent("data").StrValue(); - std::string NewData; - NAL_Unit Transformer; - int i = 0; - while( Transformer.ReadData( AnnexBData ) ) { - if( Transformer.Type() <= 6 || Transformer.Type() >= 10 ) { //Extract SPS/PPS/Separator Data - NewData += Transformer.SizePrepended( ); - } - } - VideoOut.addContent( DTSC::DTMI( "data", NewData ) ); - if( VideoTime_Offset == -1 ) { - VideoTime_Offset = VideoOut.getContent("time").NumValue(); - } - int VideoTime = VideoOut.getContent("time").NumValue(); - VideoOut.addContent( DTSC::DTMI( "time", VideoTime - VideoTime_Offset ) ); - std::cout << VideoOut.Pack(true); - VideoOut = DTSC::DTMI(); - } - TSData.toDTSC( "video", VideoOut ); - PrevType = "Video"; - } - if( TSData.PID() == AudioPID ) { - if( PrevType == "Video" ) { - fprintf( stderr, "\tAudiopacket, sending videobuffer\n" ); - std::string AnnexBData = VideoOut.getContent("data").StrValue(); - std::string NewData; - NAL_Unit Transformer; - int i = 0; - while( Transformer.ReadData( AnnexBData ) ) { - if( Transformer.Type() < 6 || Transformer.Type() > 9 ) { //Extract SPS/PPS/SEI/Separator Data - NewData += Transformer.SizePrepended( ); - } - } - VideoOut.addContent( DTSC::DTMI( "data", NewData ) ); - if( VideoTime_Offset == -1 ) { - VideoTime_Offset = VideoOut.getContent("time").NumValue(); - } - int VideoTime = VideoOut.getContent("time").NumValue(); - VideoOut.addContent( DTSC::DTMI( "time", VideoTime - VideoTime_Offset ) ); - std::cout << VideoOut.Pack(true); - VideoOut = DTSC::DTMI(); - } - if( TSData.UnitStart( ) && PrevType == "Audio" ) { - - fprintf( stderr, "\tNew AudioPacket, Writing old\n" ); - std::string AudioData = AudioOut.getContent("data").StrValue(); - AudioData.erase(0,7);//remove the header - AudioOut.addContent( DTSC::DTMI( "data", AudioData ) ); - std::cout << AudioOut.Pack(true); - AudioOut = DTSC::DTMI(); - AudioOut.addContent( DTSC::DTMI( "datatype", "audio" ) ); - } - TSData.toDTSC( "audio", AudioOut ); - PrevType = "Audio"; - } - } - } - return 0; -}