diff --git a/src/conn_ts.cpp b/src/conn_ts.cpp index 2c320db5..0fab5610 100644 --- a/src/conn_ts.cpp +++ b/src/conn_ts.cpp @@ -20,11 +20,10 @@ #include //TS support #include //DTSC support #include //For initdata conversion - /// 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 ) { +int TS_Handler(Socket::Connection conn, std::string streamname){ std::string ToPack; TS::Packet PackData; std::string DTMIData; @@ -39,173 +38,175 @@ int TS_Handler( Socket::Connection conn, std::string streamname ) { bool FirstIDRInKeyFrame; MP4::AVCC avccbox; bool haveAvcc = false; - + DTSC::Stream Strm; bool inited = false; Socket::Connection ss; - - while(conn.connected()) { - if( !inited ) { + + while (conn.connected()){ + if ( !inited){ ss = Util::Stream::getStream(streamname); - if (!ss.connected()){ - #if DEBUG >= 1 + if ( !ss.connected()){ +#if DEBUG >= 1 fprintf(stderr, "Could not connect to server!\n"); - #endif +#endif conn.close(); break; } - ss.SendNow( "p\n" ); - #if DEBUG >= 3 + ss.SendNow("p\n"); +#if DEBUG >= 3 fprintf(stderr, "Everything connected, starting to send video data...\n"); - #endif +#endif inited = true; } if (ss.spool()){ while (Strm.parsePacket(ss.Received())){ - if( !haveAvcc ) { - avccbox.setPayload( Strm.metadata["video"]["init"].asString() ); + if ( !haveAvcc){ + avccbox.setPayload(Strm.metadata["video"]["init"].asString()); haveAvcc = true; } - if( Strm.lastType() == DTSC::VIDEO ) { + if (Strm.lastType() == DTSC::VIDEO){ DTMIData = Strm.lastData(); - if( Strm.getPacket(0).isMember("keyframe") ) { + if (Strm.getPacket(0).isMember("keyframe")){ IsKeyFrame = true; FirstIDRInKeyFrame = true; - } else { + }else{ IsKeyFrame = false; FirstKeyFrame = false; } - if( IsKeyFrame ) { - TimeStamp = ( Strm.getPacket(0)["time"].asInt() * 27000 ); + if (IsKeyFrame){ + TimeStamp = (Strm.getPacket(0)["time"].asInt() * 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; + 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] & 0x1F; - if( TSType == 0x05 ) { - if( FirstPic ) { - ToPack += avccbox.asAnnexB( ); + if (TSType == 0x05){ + if (FirstPic){ + ToPack += avccbox.asAnnexB(); FirstPic = false; - } - if( IsKeyFrame ) { - if( !FirstKeyFrame && FirstIDRInKeyFrame ) { - ToPack.append(TS::NalHeader,4); + } + if (IsKeyFrame){ + if ( !FirstKeyFrame && FirstIDRInKeyFrame){ + ToPack.append(TS::NalHeader, 4); FirstIDRInKeyFrame = false; - } else { - ToPack.append(TS::ShortNalHeader,3); + }else{ + ToPack.append(TS::ShortNalHeader, 3); } } - } else if ( TSType == 0x01 ) { - if( FirstPic ) { - ToPack.append(TS::NalHeader,4); + }else if (TSType == 0x01){ + if (FirstPic){ + ToPack.append(TS::NalHeader, 4); FirstPic = false; - } else { - ToPack.append(TS::ShortNalHeader,3); + }else{ + ToPack.append(TS::ShortNalHeader, 3); } - } else { - ToPack.append(TS::NalHeader,4); + }else{ + ToPack.append(TS::NalHeader, 4); } - ToPack.append(DTMIData,0,ThisNaluSize); - DTMIData.erase(0,ThisNaluSize); + ToPack.append(DTMIData, 0, ThisNaluSize); + DTMIData.erase(0, ThisNaluSize); } WritePesHeader = true; - while( ToPack.size() ) { - if ( ( PacketNumber % 42 ) == 0 ) { + while (ToPack.size()){ + if ((PacketNumber % 42) == 0){ PackData.DefaultPAT(); - conn.SendNow( PackData.ToString(), 188 ); + conn.SendNow(PackData.ToString(), 188); PackData.DefaultPMT(); - conn.SendNow( PackData.ToString(), 188 ); + conn.SendNow(PackData.ToString(), 188); PacketNumber += 2; } 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( 1 ); + PackData.PID(0x100); + PackData.ContinuityCounter(VideoCounter); + VideoCounter++; + if (WritePesHeader){ + PackData.UnitStart(1); + if (IsKeyFrame){ + PackData.RandomAccess(1); + PackData.PCR(TimeStamp); + }else{ + PackData.AdaptationField(1); } - PackData.AddStuffing( 184 - (20+ToPack.size()) ); - PackData.PESVideoLeadIn( ToPack.size(), Strm.getPacket(0)["time"].asInt() * 90 ); + PackData.AddStuffing(184 - (20 + ToPack.size())); + PackData.PESVideoLeadIn(ToPack.size(), Strm.getPacket(0)["time"].asInt() * 90); WritePesHeader = false; - } else { - PackData.AdaptationField( 1 ); - PackData.AddStuffing( 184 - (ToPack.size()) ); + }else{ + PackData.AdaptationField(1); + PackData.AddStuffing(184 - (ToPack.size())); } - PackData.FillFree( ToPack ); - conn.SendNow( PackData.ToString(), 188 ); - PacketNumber ++; + PackData.FillFree(ToPack); + conn.SendNow(PackData.ToString(), 188); + PacketNumber++; } - } else if( Strm.lastType() == DTSC::AUDIO ) { + }else if (Strm.lastType() == DTSC::AUDIO){ WritePesHeader = true; DTMIData = Strm.lastData(); - ToPack = TS::GetAudioHeader( DTMIData.size(), Strm.metadata["audio"]["init"].asString() ); + ToPack = TS::GetAudioHeader(DTMIData.size(), Strm.metadata["audio"]["init"].asString()); ToPack += DTMIData; TimeStamp = Strm.getPacket(0)["time"].asInt() * 81000; - while( ToPack.size() ) { - if ( ( PacketNumber % 42 ) == 0 ) { + while (ToPack.size()){ + if ((PacketNumber % 42) == 0){ PackData.DefaultPAT(); - conn.SendNow( PackData.ToString(), 188 ); + conn.SendNow(PackData.ToString(), 188); PackData.DefaultPMT(); - conn.SendNow( PackData.ToString(), 188 ); + conn.SendNow(PackData.ToString(), 188); PacketNumber += 2; } PackData.Clear(); - PackData.PID( 0x101 ); - PackData.ContinuityCounter( AudioCounter ); - AudioCounter ++; - if( WritePesHeader ) { - PackData.UnitStart( 1 ); - PackData.RandomAccess( 1 ); - PackData.AddStuffing( 184 - (14 + ToPack.size()) ); - PackData.PESAudioLeadIn( ToPack.size(), TimeStamp ); + PackData.PID(0x101); + PackData.ContinuityCounter(AudioCounter); + AudioCounter++; + if (WritePesHeader){ + PackData.UnitStart(1); + PackData.RandomAccess(1); + PackData.AddStuffing(184 - (14 + ToPack.size())); + PackData.PESAudioLeadIn(ToPack.size(), TimeStamp); WritePesHeader = false; - } else { - PackData.AdaptationField( 1 ); - PackData.AddStuffing( 184 - (ToPack.size()) ); + }else{ + PackData.AdaptationField(1); + PackData.AddStuffing(184 - (ToPack.size())); } - PackData.FillFree( ToPack ); - conn.SendNow( PackData.ToString(), 188 ); - PacketNumber ++; + PackData.FillFree(ToPack); + conn.SendNow(PackData.ToString(), 188); + PacketNumber++; } } } } } - fprintf( stderr, "Exiting\n" ); + fprintf(stderr, "Exiting\n"); return 0; } int main(int argc, char ** argv){ Util::Config conf(argv[0], PACKAGE_VERSION); - conf.addOption("streamname",JSON::fromString("{\"arg\":\"string\",\"arg_num\":1,\"help\":\"The name of the stream that this connector will transmit.\"}")); + conf.addOption("streamname", + JSON::fromString("{\"arg\":\"string\",\"arg_num\":1,\"help\":\"The name of the stream that this connector will transmit.\"}")); conf.addConnectorOptions(8888); conf.parseArgs(argc, argv); Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface")); - if (!server_socket.connected()){return 1;} + if ( !server_socket.connected()){ + return 1; + } conf.activate(); - + while (server_socket.connected() && conf.is_active){ Socket::Connection S = server_socket.accept(); - if (S.connected()){//check if the new connection is valid -fprintf(stderr,"Incoming connection\n"); + if (S.connected()){ //check if the new connection is valid + fprintf(stderr, "Incoming connection\n"); pid_t myid = fork(); - if (myid == 0){//if new child, start MAINHANDLER - return TS_Handler(S,conf.getString("streamname")); - }else{//otherwise, do nothing or output debugging text - #if DEBUG >= 3 + if (myid == 0){ //if new child, start MAINHANDLER + return TS_Handler(S, conf.getString("streamname")); + }else{ //otherwise, do nothing or output debugging text +#if DEBUG >= 3 fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket()); - #endif +#endif } } - }//while connected + } //while connected server_socket.close(); return 0; -}//main +} //main diff --git a/src/controller_capabilities.cpp b/src/controller_capabilities.cpp index c51fb5e7..ae214097 100644 --- a/src/controller_capabilities.cpp +++ b/src/controller_capabilities.cpp @@ -159,9 +159,25 @@ namespace Controller { capa["connectors"]["RTMP"]["optional"]["interface"]["help"] = "Address of the interface to listen on - default if unprovided is all interfaces"; capa["connectors"]["RTMP"]["optional"]["interface"]["type"] = "str"; capa["connectors"]["RTMP"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["RTMP"]["optional"]["username"]["help"] = "Username to drop privileges to - default if unprovided means do not drop privileges"; + capa["connectors"]["RTMP"]["optional"]["username"]["help"] = + "Username to drop privileges to - default if unprovided means do not drop privileges"; capa["connectors"]["RTMP"]["optional"]["username"]["type"] = "str"; - capa["connectors"]["HTTP"]["desc"] = "Enables the generic HTTP listener, required by all other HTTP protocols. Needs other HTTP protocols enabled to do much of anything."; + capa["connectors"]["TS"]["desc"] = "Enables the raw MPEG Transport Stream protocol over TCP."; + capa["connectors"]["TS"]["deps"] = ""; + capa["connectors"]["TS"]["required"]["port"]["name"] = "TCP port"; + capa["connectors"]["TS"]["required"]["port"]["help"] = "TCP port to listen on"; + capa["connectors"]["TS"]["required"]["port"]["type"] = "uint"; + capa["connectors"]["TS"]["required"]["args"]["name"] = "Stream"; + capa["connectors"]["TS"]["required"]["args"]["help"] = "What streamname to serve - for multiple streams, add this protocol multiple times."; + capa["connectors"]["TS"]["required"]["args"]["type"] = "str"; + capa["connectors"]["TS"]["optional"]["interface"]["name"] = "Interface"; + capa["connectors"]["TS"]["optional"]["interface"]["help"] = "Address of the interface to listen on - default if unprovided is all interfaces"; + capa["connectors"]["TS"]["optional"]["interface"]["type"] = "str"; + capa["connectors"]["TS"]["optional"]["username"]["name"] = "Username"; + capa["connectors"]["TS"]["optional"]["username"]["help"] = "Username to drop privileges to - default if unprovided means do not drop privileges"; + capa["connectors"]["TS"]["optional"]["username"]["type"] = "str"; + capa["connectors"]["HTTP"]["desc"] = + "Enables the generic HTTP listener, required by all other HTTP protocols. Needs other HTTP protocols enabled to do much of anything."; capa["connectors"]["HTTP"]["deps"] = ""; capa["connectors"]["HTTP"]["optional"]["port"]["name"] = "TCP port"; capa["connectors"]["HTTP"]["optional"]["port"]["help"] = "TCP port to listen on - default if unprovided is 8080"; @@ -170,22 +186,26 @@ namespace Controller { capa["connectors"]["HTTP"]["optional"]["interface"]["help"] = "Address of the interface to listen on - default if unprovided is all interfaces"; capa["connectors"]["HTTP"]["optional"]["interface"]["type"] = "str"; capa["connectors"]["HTTP"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["HTTP"]["optional"]["username"]["help"] = "Username to drop privileges to - default if unprovided means do not drop privileges"; + capa["connectors"]["HTTP"]["optional"]["username"]["help"] = + "Username to drop privileges to - default if unprovided means do not drop privileges"; capa["connectors"]["HTTP"]["optional"]["username"]["type"] = "str"; capa["connectors"]["HTTPProgressive"]["desc"] = "Enables HTTP protocol progressive streaming."; capa["connectors"]["HTTPProgressive"]["deps"] = "HTTP"; capa["connectors"]["HTTPProgressive"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["HTTPProgressive"]["optional"]["username"]["help"] = "Username to drop privileges to - default if unprovided means do not drop privileges"; + capa["connectors"]["HTTPProgressive"]["optional"]["username"]["help"] = + "Username to drop privileges to - default if unprovided means do not drop privileges"; capa["connectors"]["HTTPProgressive"]["optional"]["username"]["type"] = "str"; capa["connectors"]["HTTPDynamic"]["desc"] = "Enables HTTP protocol Adobe-specific dynamic streaming (aka HDS)."; capa["connectors"]["HTTPDynamic"]["deps"] = "HTTP"; capa["connectors"]["HTTPDynamic"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["HTTPDynamic"]["optional"]["username"]["help"] = "Username to drop privileges to - default if unprovided means do not drop privileges"; + capa["connectors"]["HTTPDynamic"]["optional"]["username"]["help"] = + "Username to drop privileges to - default if unprovided means do not drop privileges"; capa["connectors"]["HTTPDynamic"]["optional"]["username"]["type"] = "str"; capa["connectors"]["HTTPSmooth"]["desc"] = "Enables HTTP protocol MicroSoft-specific smooth streaming through silverlight."; capa["connectors"]["HTTPSmooth"]["deps"] = "HTTP"; capa["connectors"]["HTTPSmooth"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["HTTPSmooth"]["optional"]["username"]["help"] = "Username to drop privileges to - default if unprovided means do not drop privileges"; + capa["connectors"]["HTTPSmooth"]["optional"]["username"]["help"] = + "Username to drop privileges to - default if unprovided means do not drop privileges"; capa["connectors"]["HTTPSmooth"]["optional"]["username"]["type"] = "str"; } diff --git a/src/converters/dtsc2ts.cpp b/src/converters/dtsc2ts.cpp index 3f0f9a9f..f70820f3 100644 --- a/src/converters/dtsc2ts.cpp +++ b/src/converters/dtsc2ts.cpp @@ -10,9 +10,8 @@ #include //TS support #include //DTSC support #include //For initdata conversion - -int main( ) { - char charBuffer[1024*10]; +int main(){ + char charBuffer[1024 * 10]; unsigned int charCount; std::string StrData; std::string ToPack; @@ -30,126 +29,124 @@ int main( ) { bool FirstIDRInKeyFrame; MP4::AVCC avccbox; bool haveAvcc = false; - - - while( std::cin.good() ) { - if ( DTSCStream.parsePacket( StrData ) ) { - if( !haveAvcc ) { - avccbox.setPayload( DTSCStream.metadata["video"]["init"].asString() ); + + while (std::cin.good()){ + if (DTSCStream.parsePacket(StrData)){ + if ( !haveAvcc){ + avccbox.setPayload(DTSCStream.metadata["video"]["init"].asString()); haveAvcc = true; } - if( DTSCStream.lastType() == DTSC::VIDEO ) { + if (DTSCStream.lastType() == DTSC::VIDEO){ DTMIData = DTSCStream.lastData(); - if( DTSCStream.getPacket(0).isMember("keyframe") ) { + if (DTSCStream.getPacket(0).isMember("keyframe")){ IsKeyFrame = true; FirstIDRInKeyFrame = true; - } else { + }else{ IsKeyFrame = false; FirstKeyFrame = false; } - if( IsKeyFrame ) { - TimeStamp = ( DTSCStream.getPacket(0)["time"].asInt() * 27000 ); + if (IsKeyFrame){ + TimeStamp = (DTSCStream.getPacket(0)["time"].asInt() * 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; + 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] & 0x1F; - if( TSType == 0x05 ) { - if( FirstPic ) { - ToPack += avccbox.asAnnexB( ); + if (TSType == 0x05){ + if (FirstPic){ + ToPack += avccbox.asAnnexB(); FirstPic = false; - } - if( IsKeyFrame ) { - if( !FirstKeyFrame && FirstIDRInKeyFrame ) { - ToPack.append(TS::NalHeader,4); + } + if (IsKeyFrame){ + if ( !FirstKeyFrame && FirstIDRInKeyFrame){ + ToPack.append(TS::NalHeader, 4); FirstIDRInKeyFrame = false; - } else { - ToPack.append(TS::ShortNalHeader,3); + }else{ + ToPack.append(TS::ShortNalHeader, 3); } } - } else if ( TSType == 0x01 ) { - if( FirstPic ) { - ToPack.append(TS::NalHeader,4); + }else if (TSType == 0x01){ + if (FirstPic){ + ToPack.append(TS::NalHeader, 4); FirstPic = false; - } else { - ToPack.append(TS::ShortNalHeader,3); + }else{ + ToPack.append(TS::ShortNalHeader, 3); } - } else { - ToPack.append(TS::NalHeader,4); + }else{ + ToPack.append(TS::NalHeader, 4); } - ToPack.append(DTMIData,0,ThisNaluSize); - DTMIData.erase(0,ThisNaluSize); + ToPack.append(DTMIData, 0, ThisNaluSize); + DTMIData.erase(0, ThisNaluSize); } WritePesHeader = true; - while( ToPack.size() ) { - if ( ( PacketNumber % 42 ) == 0 ) { + while (ToPack.size()){ + if ((PacketNumber % 42) == 0){ PackData.DefaultPAT(); - std::cout.write( PackData.ToString(), 188 ); + std::cout.write(PackData.ToString(), 188); PackData.DefaultPMT(); - std::cout.write( PackData.ToString(), 188 ); + std::cout.write(PackData.ToString(), 188); PacketNumber += 2; } 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( 1 ); + PackData.PID(0x100); + PackData.ContinuityCounter(VideoCounter); + VideoCounter++; + if (WritePesHeader){ + PackData.UnitStart(1); + if (IsKeyFrame){ + PackData.RandomAccess(1); + PackData.PCR(TimeStamp); + }else{ + PackData.AdaptationField(1); } - PackData.AddStuffing( 184 - (20+ToPack.size()) ); - PackData.PESVideoLeadIn( ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90 ); + PackData.AddStuffing(184 - (20 + ToPack.size())); + PackData.PESVideoLeadIn(ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90); WritePesHeader = false; - } else { - PackData.AdaptationField( 1 ); - PackData.AddStuffing( 184 - (ToPack.size()) ); + }else{ + PackData.AdaptationField(1); + PackData.AddStuffing(184 - (ToPack.size())); } - PackData.FillFree( ToPack ); - std::cout.write( PackData.ToString(), 188 ); - PacketNumber ++; + PackData.FillFree(ToPack); + std::cout.write(PackData.ToString(), 188); + PacketNumber++; } - } else if( DTSCStream.lastType() == DTSC::AUDIO ) { + }else if (DTSCStream.lastType() == DTSC::AUDIO){ WritePesHeader = true; DTMIData = DTSCStream.lastData(); - ToPack = TS::GetAudioHeader( DTMIData.size(), DTSCStream.metadata["audio"]["init"].asString() ); + ToPack = TS::GetAudioHeader(DTMIData.size(), DTSCStream.metadata["audio"]["init"].asString()); ToPack += DTMIData; TimeStamp = DTSCStream.getPacket(0)["time"].asInt() * 81000; - while( ToPack.size() ) { - if ( ( PacketNumber % 42 ) == 0 ) { + while (ToPack.size()){ + if ((PacketNumber % 42) == 0){ PackData.DefaultPAT(); - std::cout.write( PackData.ToString(), 188 ); + std::cout.write(PackData.ToString(), 188); PackData.DefaultPMT(); - std::cout.write( PackData.ToString(), 188 ); + std::cout.write(PackData.ToString(), 188); PacketNumber += 2; } PackData.Clear(); - PackData.PID( 0x101 ); - PackData.ContinuityCounter( AudioCounter ); - AudioCounter ++; - if( WritePesHeader ) { - PackData.UnitStart( 1 ); - PackData.RandomAccess( 1 ); - PackData.AddStuffing( 184 - (14 + ToPack.size()) ); - PackData.PESAudioLeadIn( ToPack.size(), TimeStamp ); + PackData.PID(0x101); + PackData.ContinuityCounter(AudioCounter); + AudioCounter++; + if (WritePesHeader){ + PackData.UnitStart(1); + PackData.RandomAccess(1); + PackData.AddStuffing(184 - (14 + ToPack.size())); + PackData.PESAudioLeadIn(ToPack.size(), TimeStamp); WritePesHeader = false; - } else { - PackData.AdaptationField( 1 ); - PackData.AddStuffing( 184 - (ToPack.size()) ); + }else{ + PackData.AdaptationField(1); + PackData.AddStuffing(184 - (ToPack.size())); } - PackData.FillFree( ToPack ); - std::cout.write( PackData.ToString(), 188 ); - PacketNumber ++; + PackData.FillFree(ToPack); + std::cout.write(PackData.ToString(), 188); + PacketNumber++; } } - } else { - std::cin.read(charBuffer, 1024*10); + }else{ + std::cin.read(charBuffer, 1024 * 10); charCount = std::cin.gcount(); StrData.append(charBuffer, charCount); }