Re-fixed indenting (post-merge)

This commit is contained in:
Erik Zandvliet 2013-01-08 14:39:09 +01:00
parent f9876c7548
commit 48bbb8afdb
3 changed files with 278 additions and 282 deletions

View file

@ -27,9 +27,9 @@
/// Holds everything unique to HTTP Connectors. /// Holds everything unique to HTTP Connectors.
namespace Connector_HTTP { namespace Connector_HTTP {
/// Parses the list of keyframes into 10 second fragments /// Parses the list of keyframes into 10 second fragments
std::vector<int> keyframesToFragments( JSON::Value & metadata ) { std::vector<int> keyframesToFragments(JSON::Value & metadata){
std::vector<int> result; std::vector<int> result;
if( metadata.isNull() ) { if (metadata.isNull()){
return result; return result;
} }
result.push_back(0); result.push_back(0);
@ -46,37 +46,36 @@ namespace Connector_HTTP {
/// Returns a m3u or m3u8 index file /// Returns a m3u or m3u8 index file
std::string BuildIndex(std::string & MovieId, JSON::Value & metadata){ std::string BuildIndex(std::string & MovieId, JSON::Value & metadata){
std::stringstream Result; std::stringstream Result;
std::vector<int> fragIndices = keyframesToFragments( metadata ); std::vector<int> fragIndices = keyframesToFragments(metadata);
int longestFragment = 0; int longestFragment = 0;
for (int i = 1; i < fragIndices.size(); i++){ for (int i = 1; i < fragIndices.size(); i++){
int fragDuration = metadata["keytime"][fragIndices[i]].asInt() - metadata["keytime"][fragIndices[i-1]].asInt(); int fragDuration = metadata["keytime"][fragIndices[i]].asInt() - metadata["keytime"][fragIndices[i - 1]].asInt();
if (fragDuration > longestFragment){ if (fragDuration > longestFragment){
longestFragment = fragDuration; longestFragment = fragDuration;
} }
} }
if (metadata.isMember("length") && metadata["length"].asInt() > 0){ if (metadata.isMember("length") && metadata["length"].asInt() > 0){
Result << Result << "#EXTM3U\r\n"
"#EXTM3U\r\n" //"#EXT-X-VERSION:1\r\n"
//"#EXT-X-VERSION:1\r\n"
"#EXT-X-MEDIA-SEQUENCE:1\r\n" "#EXT-X-MEDIA-SEQUENCE:1\r\n"
//"#EXT-X-ALLOW-CACHE:YES\r\n" //"#EXT-X-ALLOW-CACHE:YES\r\n"
"#EXT-X-TARGETDURATION:" << (longestFragment / 1000) + 1 << "\r\n"; "#EXT-X-TARGETDURATION:" << (longestFragment / 1000) + 1 << "\r\n";
//"#EXT-X-PLAYLIST-TYPE:VOD\r\n"; //"#EXT-X-PLAYLIST-TYPE:VOD\r\n";
int lastDuration = 0; int lastDuration = 0;
bool writeOffset = true; bool writeOffset = true;
fragIndices.push_back( metadata["keytime"][metadata["keytime"].size()-1].asInt() + 1 ); fragIndices.push_back(metadata["keytime"][metadata["keytime"].size() - 1].asInt() + 1);
for (int i = 0; i < fragIndices.size() - 1; i++) { for (int i = 0; i < fragIndices.size() - 1; i++){
Result << "#EXTINF:" << (metadata["keytime"][fragIndices[i]].asInt() - lastDuration) / 1000 << "." << std::setw(3) << std::setfill('0') << ((metadata["keytime"][fragIndices[i]].asInt() - lastDuration) % 1000) << ",\r\n" Result << "#EXTINF:" << (metadata["keytime"][fragIndices[i]].asInt() - lastDuration) / 1000 << "." << std::setw(3) << std::setfill('0')
<< fragIndices[i] << "_" << fragIndices[i+1] - fragIndices[i] << ".ts\r\n"; << ((metadata["keytime"][fragIndices[i]].asInt() - lastDuration) % 1000) << ",\r\n" << fragIndices[i] << "_"
<< fragIndices[i + 1] - fragIndices[i] << ".ts\r\n";
lastDuration = metadata["keytime"][fragIndices[i]].asInt(); lastDuration = metadata["keytime"][fragIndices[i]].asInt();
} }
Result << "#EXT-X-ENDLIST"; Result << "#EXT-X-ENDLIST";
}else{ }else{
Result << Result << "#EXTM3U\r\n"
"#EXTM3U\r\n" "#EXT-X-VERSION:4\r\n"
"#EXT-X-VERSION:4\r\n" "#EXT-X-MEDIA-SEQUENCE:1\r\n"
"#EXT-X-MEDIA-SEQUENCE:1\r\n" "#EXT-X-TARGETDURATION:" << ((metadata["video"]["keyms"].asInt() + metadata["video"]["keyvar"].asInt()) / 1000) + 1 << "\r\n";
"#EXT-X-TARGETDURATION:" << ((metadata["video"]["keyms"].asInt() + metadata["video"]["keyvar"].asInt()) / 1000) + 1 << "\r\n";
} }
#if DEBUG >= 8 #if DEBUG >= 8
std::cerr << "Sending this index:" << std::endl << Result.str() << std::endl; std::cerr << "Sending this index:" << std::endl << Result.str() << std::endl;
@ -162,11 +161,11 @@ namespace Connector_HTTP {
temp = HTTP_R.url.find("_", temp) + 1; temp = HTTP_R.url.find("_", temp) + 1;
int frameCount = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find(".ts", temp) - temp).c_str()); int frameCount = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find(".ts", temp) - temp).c_str());
//if( !fragIndices.size() ) { //if( !fragIndices.size() ) {
//fragIndices = keyframesToFragments( Strm.metadata ); //fragIndices = keyframesToFragments( Strm.metadata );
//} //}
#if DEBUG >= 4 #if DEBUG >= 4
fprintf( stderr, "Fragment number %d\n", Segment); fprintf(stderr, "Fragment number %d\n", Segment);
//fprintf( stderr, "Fragment indices %d\n", fragIndices.size() ); //fprintf( stderr, "Fragment indices %d\n", fragIndices.size() );
//fprintf( stderr, "Seeking to fragment %d\n", fragIndices[Segment-1] + 1 ); //fprintf( stderr, "Seeking to fragment %d\n", fragIndices[Segment-1] + 1 );
#endif #endif
@ -176,7 +175,7 @@ namespace Connector_HTTP {
sstream << "f " << Segment + 1 << "\n"; sstream << "f " << Segment + 1 << "\n";
#if DEBUG >= 4 #if DEBUG >= 4
fprintf( stderr, "Frame count %d\n", frameCount); fprintf(stderr, "Frame count %d\n", frameCount);
#endif #endif
for (int i = 0; i < frameCount; i++){ for (int i = 0; i < frameCount; i++){
sstream << "o \n"; sstream << "o \n";
@ -187,10 +186,10 @@ namespace Connector_HTTP {
streamname = HTTP_R.url.substr(5, HTTP_R.url.find("/", 5) - 5); streamname = HTTP_R.url.substr(5, HTTP_R.url.find("/", 5) - 5);
if ( !Strm.metadata.isNull()){ if ( !Strm.metadata.isNull()){
HTTP_S.Clean(); HTTP_S.Clean();
if (HTTP_R.url.find(".m3u8") != std::string::npos) { if (HTTP_R.url.find(".m3u8") != std::string::npos){
HTTP_S.SetHeader("Content-Type", "application/vnd.apple.mpegurl");//m3u8 HTTP_S.SetHeader("Content-Type", "application/vnd.apple.mpegurl"); //m3u8
}else{ }else{
HTTP_S.SetHeader("Content-Type", "audio/mpegurl");//m3u HTTP_S.SetHeader("Content-Type", "audio/mpegurl"); //m3u
} }
HTTP_S.SetHeader("Cache-Control", "no-cache"); HTTP_S.SetHeader("Cache-Control", "no-cache");
if (Strm.metadata.isMember("length")){ if (Strm.metadata.isMember("length")){
@ -262,10 +261,10 @@ namespace Connector_HTTP {
receive_marks = true; receive_marks = true;
} }
std::string manifest = BuildIndex(streamname, Strm.metadata); std::string manifest = BuildIndex(streamname, Strm.metadata);
if (HTTP_R.url.find(".m3u8") != std::string::npos) { if (HTTP_R.url.find(".m3u8") != std::string::npos){
HTTP_S.SetHeader("Content-Type", "application/vnd.apple.mpegurl");//m3u8 HTTP_S.SetHeader("Content-Type", "application/vnd.apple.mpegurl"); //m3u8
}else{ }else{
HTTP_S.SetHeader("Content-Type", "audio/mpegurl");//m3u HTTP_S.SetHeader("Content-Type", "audio/mpegurl"); //m3u
} }
HTTP_S.SetBody(manifest); HTTP_S.SetBody(manifest);
conn.SendNow(HTTP_S.BuildResponse("200", "OK")); conn.SendNow(HTTP_S.BuildResponse("200", "OK"));
@ -291,10 +290,10 @@ namespace Connector_HTTP {
HTTP_S.SetBody(""); HTTP_S.SetBody("");
HTTP_S.SetHeader("Content-Length", TSBuf.str().size()); HTTP_S.SetHeader("Content-Length", TSBuf.str().size());
conn.SendNow(HTTP_S.BuildResponse("200", "OK")); conn.SendNow(HTTP_S.BuildResponse("200", "OK"));
conn.SendNow(TSBuf.str().c_str(),TSBuf.str().size()); conn.SendNow(TSBuf.str().c_str(), TSBuf.str().size());
TSBuf.str(""); TSBuf.str("");
Flash_RequestPending--; Flash_RequestPending--;
fprintf( stderr, "Sent %d packets\n", PacketNumber ); fprintf(stderr, "Sent %d packets\n", PacketNumber);
PacketNumber = 0; PacketNumber = 0;
#if DEBUG >= 3 #if DEBUG >= 3
fprintf(stderr, "Done\n"); fprintf(stderr, "Done\n");
@ -302,93 +301,56 @@ fprintf( stderr, "Sent %d packets\n", PacketNumber );
} }
TSBuf.str(""); TSBuf.str("");
} }
if( !haveAvcc ) { if ( !haveAvcc){
avccbox.setPayload( Strm.metadata["video"]["init"].asString() ); avccbox.setPayload(Strm.metadata["video"]["init"].asString());
haveAvcc = true; haveAvcc = true;
} }
if (Strm.lastType() == DTSC::VIDEO || Strm.lastType() == DTSC::AUDIO){ if (Strm.lastType() == DTSC::VIDEO || Strm.lastType() == DTSC::AUDIO){
if( Strm.lastType() == DTSC::VIDEO ) { if (Strm.lastType() == DTSC::VIDEO){
DTMIData = Strm.lastData(); DTMIData = Strm.lastData();
if( Strm.getPacket(0).isMember("keyframe") ) { if (Strm.getPacket(0).isMember("keyframe")){
fprintf( stderr, " Received Keyframe of size %d\n", Strm.lastData().size() ); fprintf(stderr, " Received Keyframe of size %d\n", Strm.lastData().size());
IsKeyFrame = true; IsKeyFrame = true;
FirstIDRInKeyFrame = true; FirstIDRInKeyFrame = true;
} else { }else{
IsKeyFrame = false; IsKeyFrame = false;
FirstKeyFrame = false; FirstKeyFrame = false;
} }
if( IsKeyFrame ) { if (IsKeyFrame){
TimeStamp = ( Strm.getPacket(0)["time"].asInt() * 27000 ); TimeStamp = (Strm.getPacket(0)["time"].asInt() * 27000);
} }
int TSType; int TSType;
bool FirstPic = true; bool FirstPic = true;
while( DTMIData.size() ) { while (DTMIData.size()){
ThisNaluSize = (DTMIData[0] << 24) + (DTMIData[1] << 16) + ThisNaluSize = (DTMIData[0] << 24) + (DTMIData[1] << 16) + (DTMIData[2] << 8) + DTMIData[3];
(DTMIData[2] << 8) + DTMIData[3]; DTMIData.erase(0, 4); //Erase the first four characters;
DTMIData.erase(0,4);//Erase the first four characters;
TSType = (int)DTMIData[0] & 0x1F; TSType = (int)DTMIData[0] & 0x1F;
if( TSType == 0x05 ) { if (TSType == 0x05){
if( FirstPic ) { if (FirstPic){
ToPack += avccbox.asAnnexB( ); ToPack += avccbox.asAnnexB();
FirstPic = false; FirstPic = false;
} }
if( IsKeyFrame ) { if (IsKeyFrame){
//if( !FirstKeyFrame && FirstIDRInKeyFrame ) { //if( !FirstKeyFrame && FirstIDRInKeyFrame ) {
// ToPack += (char)0x00; // ToPack += (char)0x00;
// FirstIDRInKeyFrame = false; // FirstIDRInKeyFrame = false;
//} //}
ToPack.append(TS::NalHeader,4); ToPack.append(TS::NalHeader, 4);
} }
} else if ( TSType == 0x01 ) { }else if (TSType == 0x01){
if( FirstPic ) { if (FirstPic){
//ToPack += (char)0x00; //ToPack += (char)0x00;
FirstPic = false; FirstPic = false;
} }
ToPack.append(TS::NalHeader,4); ToPack.append(TS::NalHeader, 4);
} else { }else{
ToPack.append(TS::NalHeader,4); ToPack.append(TS::NalHeader, 4);
} }
ToPack.append(DTMIData,0,ThisNaluSize); ToPack.append(DTMIData, 0, ThisNaluSize);
DTMIData.erase(0,ThisNaluSize); DTMIData.erase(0, ThisNaluSize);
} }
WritePesHeader = true; WritePesHeader = true;
while( ToPack.size() ) { while (ToPack.size()){
if ((PacketNumber % 42) == 0) {
PackData.DefaultPAT();
TSBuf.write(PackData.ToString(), 188);
PackData.DefaultPMT();
TSBuf.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.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()) );
}
PackData.FillFree( ToPack );
TSBuf.write(PackData.ToString(), 188);
PacketNumber ++;
}
} else if( Strm.lastType() == DTSC::AUDIO ) {
WritePesHeader = true;
DTMIData = Strm.lastData();
ToPack = TS::GetAudioHeader( DTMIData.size(), Strm.metadata["audio"]["init"].asString() );
ToPack += DTMIData;
while( ToPack.size() ) {
if ((PacketNumber % 42) == 0){ if ((PacketNumber % 42) == 0){
PackData.DefaultPAT(); PackData.DefaultPAT();
TSBuf.write(PackData.ToString(), 188); TSBuf.write(PackData.ToString(), 188);
@ -397,21 +359,57 @@ fprintf( stderr, " Received Keyframe of size %d\n", Strm.lastData().size() );
PacketNumber += 2; PacketNumber += 2;
} }
PackData.Clear(); PackData.Clear();
PackData.PID( 0x101 ); PackData.PID(0x100);
PackData.ContinuityCounter( AudioCounter ); PackData.ContinuityCounter(VideoCounter);
AudioCounter ++; VideoCounter++;
if( WritePesHeader ) { if (WritePesHeader){
PackData.UnitStart( 1 ); PackData.UnitStart(1);
PackData.AddStuffing( 184 - (14 + ToPack.size()) ); if (IsKeyFrame){
PackData.PESAudioLeadIn( ToPack.size(), Strm.getPacket(0)["time"].asInt() * 90 ); 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);
WritePesHeader = false; WritePesHeader = false;
} else { }else{
PackData.AdaptationField( 1 ); PackData.AdaptationField(1);
PackData.AddStuffing( 184 - ToPack.size() ); PackData.AddStuffing(184 - (ToPack.size()));
} }
PackData.FillFree( ToPack ); PackData.FillFree(ToPack);
TSBuf.write(PackData.ToString(), 188); TSBuf.write(PackData.ToString(), 188);
PacketNumber ++; PacketNumber++;
}
}else if (Strm.lastType() == DTSC::AUDIO){
WritePesHeader = true;
DTMIData = Strm.lastData();
ToPack = TS::GetAudioHeader(DTMIData.size(), Strm.metadata["audio"]["init"].asString());
ToPack += DTMIData;
while (ToPack.size()){
if ((PacketNumber % 42) == 0){
PackData.DefaultPAT();
TSBuf.write(PackData.ToString(), 188);
PackData.DefaultPMT();
TSBuf.write(PackData.ToString(), 188);
PacketNumber += 2;
}
PackData.Clear();
PackData.PID(0x101);
PackData.ContinuityCounter(AudioCounter);
AudioCounter++;
if (WritePesHeader){
PackData.UnitStart(1);
PackData.AddStuffing(184 - (14 + ToPack.size()));
PackData.PESAudioLeadIn(ToPack.size(), Strm.getPacket(0)["time"].asInt() * 90);
WritePesHeader = false;
}else{
PackData.AdaptationField(1);
PackData.AddStuffing(184 - ToPack.size());
}
PackData.FillFree(ToPack);
TSBuf.write(PackData.ToString(), 188);
PacketNumber++;
} }
} }
} }
@ -422,10 +420,10 @@ fprintf( stderr, " Received Keyframe of size %d\n", Strm.lastData().size() );
if (Strm.metadata.isMember("length")){ if (Strm.metadata.isMember("length")){
receive_marks = true; receive_marks = true;
} }
if (HTTP_R.url.find(".m3u8") != std::string::npos) { if (HTTP_R.url.find(".m3u8") != std::string::npos){
HTTP_S.SetHeader("Content-Type", "application/vnd.apple.mpegurl");//m3u8 HTTP_S.SetHeader("Content-Type", "application/vnd.apple.mpegurl"); //m3u8
}else{ }else{
HTTP_S.SetHeader("Content-Type", "audio/mpegurl");//m3u HTTP_S.SetHeader("Content-Type", "audio/mpegurl"); //m3u
} }
std::string manifest = BuildIndex(streamname, Strm.metadata); std::string manifest = BuildIndex(streamname, Strm.metadata);
HTTP_S.SetBody(manifest); HTTP_S.SetBody(manifest);

View file

@ -20,11 +20,10 @@
#include <mist/ts_packet.h> //TS support #include <mist/ts_packet.h> //TS support
#include <mist/dtsc.h> //DTSC support #include <mist/dtsc.h> //DTSC support
#include <mist/mp4.h> //For initdata conversion #include <mist/mp4.h> //For initdata conversion
/// The main function of the connector /// The main function of the connector
/// \param conn A connection with the client /// \param conn A connection with the client
/// \param streamname The name of the stream /// \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; std::string ToPack;
TS::Packet PackData; TS::Packet PackData;
std::string DTMIData; std::string DTMIData;
@ -44,166 +43,168 @@ int TS_Handler( Socket::Connection conn, std::string streamname ) {
bool inited = false; bool inited = false;
Socket::Connection ss; Socket::Connection ss;
while(conn.connected()) { while (conn.connected()){
if( !inited ) { if ( !inited){
ss = Util::Stream::getStream(streamname); ss = Util::Stream::getStream(streamname);
if (!ss.connected()){ if ( !ss.connected()){
#if DEBUG >= 1 #if DEBUG >= 1
fprintf(stderr, "Could not connect to server!\n"); fprintf(stderr, "Could not connect to server!\n");
#endif #endif
conn.close(); conn.close();
break; break;
} }
ss.SendNow( "p\n" ); ss.SendNow("p\n");
#if DEBUG >= 3 #if DEBUG >= 3
fprintf(stderr, "Everything connected, starting to send video data...\n"); fprintf(stderr, "Everything connected, starting to send video data...\n");
#endif #endif
inited = true; inited = true;
} }
if (ss.spool()){ if (ss.spool()){
while (Strm.parsePacket(ss.Received())){ while (Strm.parsePacket(ss.Received())){
if( !haveAvcc ) { if ( !haveAvcc){
avccbox.setPayload( Strm.metadata["video"]["init"].asString() ); avccbox.setPayload(Strm.metadata["video"]["init"].asString());
haveAvcc = true; haveAvcc = true;
} }
if( Strm.lastType() == DTSC::VIDEO ) { if (Strm.lastType() == DTSC::VIDEO){
DTMIData = Strm.lastData(); DTMIData = Strm.lastData();
if( Strm.getPacket(0).isMember("keyframe") ) { if (Strm.getPacket(0).isMember("keyframe")){
IsKeyFrame = true; IsKeyFrame = true;
FirstIDRInKeyFrame = true; FirstIDRInKeyFrame = true;
} else { }else{
IsKeyFrame = false; IsKeyFrame = false;
FirstKeyFrame = false; FirstKeyFrame = false;
} }
if( IsKeyFrame ) { if (IsKeyFrame){
TimeStamp = ( Strm.getPacket(0)["time"].asInt() * 27000 ); TimeStamp = (Strm.getPacket(0)["time"].asInt() * 27000);
} }
int TSType; int TSType;
bool FirstPic = true; bool FirstPic = true;
while( DTMIData.size() ) { while (DTMIData.size()){
ThisNaluSize = (DTMIData[0] << 24) + (DTMIData[1] << 16) + ThisNaluSize = (DTMIData[0] << 24) + (DTMIData[1] << 16) + (DTMIData[2] << 8) + DTMIData[3];
(DTMIData[2] << 8) + DTMIData[3]; DTMIData.erase(0, 4); //Erase the first four characters;
DTMIData.erase(0,4);//Erase the first four characters;
TSType = (int)DTMIData[0] & 0x1F; TSType = (int)DTMIData[0] & 0x1F;
if( TSType == 0x05 ) { if (TSType == 0x05){
if( FirstPic ) { if (FirstPic){
ToPack += avccbox.asAnnexB( ); ToPack += avccbox.asAnnexB();
FirstPic = false; FirstPic = false;
} }
if( IsKeyFrame ) { if (IsKeyFrame){
if( !FirstKeyFrame && FirstIDRInKeyFrame ) { if ( !FirstKeyFrame && FirstIDRInKeyFrame){
ToPack.append(TS::NalHeader,4); ToPack.append(TS::NalHeader, 4);
FirstIDRInKeyFrame = false; FirstIDRInKeyFrame = false;
} else { }else{
ToPack.append(TS::ShortNalHeader,3); ToPack.append(TS::ShortNalHeader, 3);
} }
} }
} else if ( TSType == 0x01 ) { }else if (TSType == 0x01){
if( FirstPic ) { if (FirstPic){
ToPack.append(TS::NalHeader,4); ToPack.append(TS::NalHeader, 4);
FirstPic = false; FirstPic = false;
} else { }else{
ToPack.append(TS::ShortNalHeader,3); ToPack.append(TS::ShortNalHeader, 3);
} }
} else { }else{
ToPack.append(TS::NalHeader,4); ToPack.append(TS::NalHeader, 4);
} }
ToPack.append(DTMIData,0,ThisNaluSize); ToPack.append(DTMIData, 0, ThisNaluSize);
DTMIData.erase(0,ThisNaluSize); DTMIData.erase(0, ThisNaluSize);
} }
WritePesHeader = true; WritePesHeader = true;
while( ToPack.size() ) { while (ToPack.size()){
if ( ( PacketNumber % 42 ) == 0 ) { if ((PacketNumber % 42) == 0){
PackData.DefaultPAT(); PackData.DefaultPAT();
conn.SendNow( PackData.ToString(), 188 ); conn.SendNow(PackData.ToString(), 188);
PackData.DefaultPMT(); PackData.DefaultPMT();
conn.SendNow( PackData.ToString(), 188 ); conn.SendNow(PackData.ToString(), 188);
PacketNumber += 2; PacketNumber += 2;
} }
PackData.Clear(); PackData.Clear();
PackData.PID( 0x100 ); PackData.PID(0x100);
PackData.ContinuityCounter( VideoCounter ); PackData.ContinuityCounter(VideoCounter);
VideoCounter ++; VideoCounter++;
if( WritePesHeader ) { if (WritePesHeader){
PackData.UnitStart( 1 ); PackData.UnitStart(1);
if( IsKeyFrame ) { if (IsKeyFrame){
PackData.RandomAccess( 1 ); PackData.RandomAccess(1);
PackData.PCR( TimeStamp ); PackData.PCR(TimeStamp);
} else { }else{
PackData.AdaptationField( 1 ); PackData.AdaptationField(1);
} }
PackData.AddStuffing( 184 - (20+ToPack.size()) ); PackData.AddStuffing(184 - (20 + ToPack.size()));
PackData.PESVideoLeadIn( ToPack.size(), Strm.getPacket(0)["time"].asInt() * 90 ); PackData.PESVideoLeadIn(ToPack.size(), Strm.getPacket(0)["time"].asInt() * 90);
WritePesHeader = false; WritePesHeader = false;
} else { }else{
PackData.AdaptationField( 1 ); PackData.AdaptationField(1);
PackData.AddStuffing( 184 - (ToPack.size()) ); PackData.AddStuffing(184 - (ToPack.size()));
} }
PackData.FillFree( ToPack ); PackData.FillFree(ToPack);
conn.SendNow( PackData.ToString(), 188 ); conn.SendNow(PackData.ToString(), 188);
PacketNumber ++; PacketNumber++;
} }
} else if( Strm.lastType() == DTSC::AUDIO ) { }else if (Strm.lastType() == DTSC::AUDIO){
WritePesHeader = true; WritePesHeader = true;
DTMIData = Strm.lastData(); 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; ToPack += DTMIData;
while( ToPack.size() ) { while (ToPack.size()){
if ( ( PacketNumber % 42 ) == 0 ) { if ((PacketNumber % 42) == 0){
PackData.DefaultPAT(); PackData.DefaultPAT();
conn.SendNow( PackData.ToString(), 188 ); conn.SendNow(PackData.ToString(), 188);
PackData.DefaultPMT(); PackData.DefaultPMT();
conn.SendNow( PackData.ToString(), 188 ); conn.SendNow(PackData.ToString(), 188);
PacketNumber += 2; PacketNumber += 2;
} }
PackData.Clear(); PackData.Clear();
PackData.PID( 0x101 ); PackData.PID(0x101);
PackData.ContinuityCounter( AudioCounter ); PackData.ContinuityCounter(AudioCounter);
AudioCounter ++; AudioCounter++;
if( WritePesHeader ) { if (WritePesHeader){
PackData.UnitStart( 1 ); PackData.UnitStart(1);
PackData.AddStuffing( 184 - (14 + ToPack.size()) ); PackData.AddStuffing(184 - (14 + ToPack.size()));
PackData.PESAudioLeadIn( ToPack.size(), Strm.getPacket(0)["time"].asInt() * 90 ); PackData.PESAudioLeadIn(ToPack.size(), Strm.getPacket(0)["time"].asInt() * 90);
WritePesHeader = false; WritePesHeader = false;
} else { }else{
PackData.AdaptationField( 1 ); PackData.AdaptationField(1);
PackData.AddStuffing( 184 - (ToPack.size()) ); PackData.AddStuffing(184 - (ToPack.size()));
} }
PackData.FillFree( ToPack ); PackData.FillFree(ToPack);
conn.SendNow( PackData.ToString(), 188 ); conn.SendNow(PackData.ToString(), 188);
PacketNumber ++; PacketNumber++;
} }
} }
} }
} }
} }
fprintf( stderr, "Exiting\n" ); fprintf(stderr, "Exiting\n");
return 0; return 0;
} }
int main(int argc, char ** argv){ int main(int argc, char ** argv){
Util::Config conf(argv[0], PACKAGE_VERSION); 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.addConnectorOptions(8888);
conf.parseArgs(argc, argv); conf.parseArgs(argc, argv);
Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface")); 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(); conf.activate();
while (server_socket.connected() && conf.is_active){ while (server_socket.connected() && conf.is_active){
Socket::Connection S = server_socket.accept(); Socket::Connection S = server_socket.accept();
if (S.connected()){//check if the new connection is valid if (S.connected()){ //check if the new connection is valid
fprintf(stderr,"Incoming connection\n"); fprintf(stderr, "Incoming connection\n");
pid_t myid = fork(); pid_t myid = fork();
if (myid == 0){//if new child, start MAINHANDLER if (myid == 0){ //if new child, start MAINHANDLER
return TS_Handler(S,conf.getString("streamname")); return TS_Handler(S, conf.getString("streamname"));
}else{//otherwise, do nothing or output debugging text }else{ //otherwise, do nothing or output debugging text
#if DEBUG >= 3 #if DEBUG >= 3
fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket()); fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket());
#endif #endif
} }
} }
}//while connected } //while connected
server_socket.close(); server_socket.close();
return 0; return 0;
}//main } //main

View file

@ -10,12 +10,11 @@
#include <mist/ts_packet.h> //TS support #include <mist/ts_packet.h> //TS support
#include <mist/dtsc.h> //DTSC support #include <mist/dtsc.h> //DTSC support
#include <mist/mp4.h> //For initdata conversion #include <mist/mp4.h> //For initdata conversion
#define VIDEO_SCALING ( 27000000.0 / (double)DTSCStream.metadata["video"]["fpks"].asInt()) #define VIDEO_SCALING ( 27000000.0 / (double)DTSCStream.metadata["video"]["fpks"].asInt())
#define AUDIO_SCALING ( 27000000.0 / (double)DTSCStream.metadata["audio"]["rate"].asInt()) #define AUDIO_SCALING ( 27000000.0 / (double)DTSCStream.metadata["audio"]["rate"].asInt())
int main( ) { int main(){
char charBuffer[1024*10]; char charBuffer[1024 * 10];
unsigned int charCount; unsigned int charCount;
std::string StrData; std::string StrData;
std::string ToPack; std::string ToPack;
@ -34,125 +33,123 @@ int main( ) {
MP4::AVCC avccbox; MP4::AVCC avccbox;
bool haveAvcc = false; bool haveAvcc = false;
while (std::cin.good()){
while( std::cin.good() ) { if (DTSCStream.parsePacket(StrData)){
if ( DTSCStream.parsePacket( StrData ) ) { if ( !haveAvcc){
if( !haveAvcc ) { avccbox.setPayload(DTSCStream.metadata["video"]["init"].asString());
avccbox.setPayload( DTSCStream.metadata["video"]["init"].asString() );
haveAvcc = true; haveAvcc = true;
} }
if( DTSCStream.lastType() == DTSC::VIDEO ) { if (DTSCStream.lastType() == DTSC::VIDEO){
DTMIData = DTSCStream.lastData(); DTMIData = DTSCStream.lastData();
if( DTSCStream.getPacket(0).isMember("keyframe") ) { if (DTSCStream.getPacket(0).isMember("keyframe")){
IsKeyFrame = true; IsKeyFrame = true;
FirstIDRInKeyFrame = true; FirstIDRInKeyFrame = true;
} else { }else{
IsKeyFrame = false; IsKeyFrame = false;
FirstKeyFrame = false; FirstKeyFrame = false;
} }
if( IsKeyFrame ) { if (IsKeyFrame){
TimeStamp = ( DTSCStream.getPacket(0)["time"].asInt() * 27000 ); TimeStamp = (DTSCStream.getPacket(0)["time"].asInt() * 27000);
} }
int TSType; int TSType;
bool FirstPic = true; bool FirstPic = true;
while( DTMIData.size() ) { while (DTMIData.size()){
ThisNaluSize = (DTMIData[0] << 24) + (DTMIData[1] << 16) + ThisNaluSize = (DTMIData[0] << 24) + (DTMIData[1] << 16) + (DTMIData[2] << 8) + DTMIData[3];
(DTMIData[2] << 8) + DTMIData[3]; DTMIData.erase(0, 4); //Erase the first four characters;
DTMIData.erase(0,4);//Erase the first four characters;
TSType = (int)DTMIData[0] & 0x1F; TSType = (int)DTMIData[0] & 0x1F;
if( !( TSType == 0x09 ) ) { if ( !(TSType == 0x09)){
if( TSType == 0x05 ) { if (TSType == 0x05){
if( FirstPic ) { if (FirstPic){
ToPack += avccbox.asAnnexB( ); ToPack += avccbox.asAnnexB();
FirstPic = false; FirstPic = false;
} }
if( IsKeyFrame ) { if (IsKeyFrame){
if( !FirstKeyFrame && FirstIDRInKeyFrame ) { if ( !FirstKeyFrame && FirstIDRInKeyFrame){
ToPack.append(TS::NalHeader,4); ToPack.append(TS::NalHeader, 4);
FirstIDRInKeyFrame = false; FirstIDRInKeyFrame = false;
} else { }else{
ToPack.append(TS::ShortNalHeader,3); ToPack.append(TS::ShortNalHeader, 3);
} }
} }
} else if ( TSType == 0x01 ) { }else if (TSType == 0x01){
if( FirstPic ) { if (FirstPic){
ToPack.append(TS::NalHeader,4); ToPack.append(TS::NalHeader, 4);
FirstPic = false; FirstPic = false;
} else { }else{
ToPack.append(TS::ShortNalHeader,3); ToPack.append(TS::ShortNalHeader, 3);
} }
} else { }else{
ToPack.append(TS::NalHeader,4); ToPack.append(TS::NalHeader, 4);
} }
ToPack.append(DTMIData,0,ThisNaluSize); ToPack.append(DTMIData, 0, ThisNaluSize);
} }
DTMIData.erase(0,ThisNaluSize); DTMIData.erase(0, ThisNaluSize);
} }
WritePesHeader = true; WritePesHeader = true;
while( ToPack.size() ) { while (ToPack.size()){
if ( ( PacketNumber % 42 ) == 0 ) { if ((PacketNumber % 42) == 0){
PackData.DefaultPAT(); PackData.DefaultPAT();
std::cout.write( PackData.ToString(), 188 ); std::cout.write(PackData.ToString(), 188);
PackData.DefaultPMT(); PackData.DefaultPMT();
std::cout.write( PackData.ToString(), 188 ); std::cout.write(PackData.ToString(), 188);
PacketNumber += 2; PacketNumber += 2;
} }
PackData.Clear(); PackData.Clear();
PackData.PID( 0x100 ); PackData.PID(0x100);
PackData.ContinuityCounter( VideoCounter ); PackData.ContinuityCounter(VideoCounter);
VideoCounter ++; VideoCounter++;
if( WritePesHeader ) { if (WritePesHeader){
PackData.UnitStart( 1 ); PackData.UnitStart(1);
if( IsKeyFrame ) { if (IsKeyFrame){
PackData.RandomAccess( 1 ); PackData.RandomAccess(1);
PackData.PCR( TimeStamp ); PackData.PCR(TimeStamp);
} else { }else{
PackData.AdaptationField( 1 ); PackData.AdaptationField(1);
} }
PackData.AddStuffing( 184 - (20+ToPack.size()) ); PackData.AddStuffing(184 - (20 + ToPack.size()));
PackData.PESVideoLeadIn( ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90 ); PackData.PESVideoLeadIn(ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90);
WritePesHeader = false; WritePesHeader = false;
} else { }else{
PackData.AdaptationField( 1 ); PackData.AdaptationField(1);
PackData.AddStuffing( 184 - (ToPack.size()) ); PackData.AddStuffing(184 - (ToPack.size()));
} }
PackData.FillFree( ToPack ); PackData.FillFree(ToPack);
std::cout.write( PackData.ToString(), 188 ); std::cout.write(PackData.ToString(), 188);
PacketNumber ++; PacketNumber++;
} }
} else if( DTSCStream.lastType() == DTSC::AUDIO ) { }else if (DTSCStream.lastType() == DTSC::AUDIO){
WritePesHeader = true; WritePesHeader = true;
DTMIData = DTSCStream.lastData(); 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; ToPack += DTMIData;
while( ToPack.size() ) { while (ToPack.size()){
if ( ( PacketNumber % 42 ) == 0 ) { if ((PacketNumber % 42) == 0){
PackData.DefaultPAT(); PackData.DefaultPAT();
std::cout.write( PackData.ToString(), 188 ); std::cout.write(PackData.ToString(), 188);
PackData.DefaultPMT(); PackData.DefaultPMT();
std::cout.write( PackData.ToString(), 188 ); std::cout.write(PackData.ToString(), 188);
PacketNumber += 2; PacketNumber += 2;
} }
PackData.Clear(); PackData.Clear();
PackData.PID( 0x101 ); PackData.PID(0x101);
PackData.ContinuityCounter( AudioCounter ); PackData.ContinuityCounter(AudioCounter);
AudioCounter ++; AudioCounter++;
if( WritePesHeader ) { if (WritePesHeader){
PackData.UnitStart( 1 ); PackData.UnitStart(1);
PackData.AddStuffing( 184 - (14 + ToPack.size()) ); PackData.AddStuffing(184 - (14 + ToPack.size()));
PackData.PESAudioLeadIn( ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90 ); PackData.PESAudioLeadIn(ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90);
WritePesHeader = false; WritePesHeader = false;
} else { }else{
PackData.AdaptationField( 1 ); PackData.AdaptationField(1);
PackData.AddStuffing( 184 - ToPack.size() ); PackData.AddStuffing(184 - ToPack.size());
} }
PackData.FillFree( ToPack ); PackData.FillFree(ToPack);
std::cout.write( PackData.ToString(), 188 ); std::cout.write(PackData.ToString(), 188);
PacketNumber ++; PacketNumber++;
} }
} }
} else { }else{
std::cin.read(charBuffer, 1024*10); std::cin.read(charBuffer, 1024 * 10);
charCount = std::cin.gcount(); charCount = std::cin.gcount();
StrData.append(charBuffer, charCount); StrData.append(charBuffer, charCount);
} }