From 45022f36c905e6293d1258eecc417c7ba914c83c Mon Sep 17 00:00:00 2001 From: Ramoe Date: Fri, 31 Mar 2017 17:32:35 +0200 Subject: [PATCH 1/4] Added several DTSC packet convenience functions --- lib/dtsc.h | 5 ++++ lib/dtscmeta.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/lib/dtsc.h b/lib/dtsc.h index 89524610..c74bda4d 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -118,6 +118,7 @@ namespace DTSC { void reInit(Socket::Connection & src); void reInit(const char * data_, unsigned int len, bool noCopy = false); void genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, uint64_t packBytePos, bool isKeyframe); + void appendData(const char * appendData, uint32_t appendLen); void getString(const char * identifier, char *& result, unsigned int & len) const; void getString(const char * identifier, std::string & result) const; void getInt(const char * identifier, int & result) const; @@ -125,11 +126,15 @@ namespace DTSC { void getFlag(const char * identifier, bool & result) const; bool getFlag(const char * identifier) const; bool hasMember(const char * identifier) const; + void appendNal(const char * appendData, uint32_t appendLen, uint32_t totalLen); + void clearKeyFrame(); long long unsigned int getTime() const; long int getTrackId() const; char * getData() const; int getDataLen() const; int getPayloadLen() const; + uint32_t getDataStringLen(); + uint32_t getDataStringLenOffset(); JSON::Value toJSON() const; std::string toSummary() const; Scan getScan() const; diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index 67bc499d..aaa2f6ea 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -270,6 +270,71 @@ namespace DTSC { memcpy(data+offset+11+packDataSize, "\000\000\356", 3); } + ///clear the keyframe byte. + void Packet::clearKeyFrame(){ + uint32_t offset = 23; + while (data[offset] != 'd' && data[offset] != 'k'){ + switch (data[offset]){ + case 'o': offset += 17; break; + case 'b': offset += 15; break; + default: + FAIL_MSG("Errrrrrr"); + } + } + + if(data[offset] == 'k'){ + data[offset] = 'K'; + data[offset+16] = 0; + } + } + + void Packet::appendData(const char * appendData, uint32_t appendLen){ + resize(dataLen + appendLen); + memcpy(data + dataLen-3, appendData, appendLen); + memcpy(data + dataLen-3 + appendLen, "\000\000\356", 3); //end container + dataLen += appendLen; + Bit::htobl(data+4, Bit::btohl(data +4)+appendLen); + uint32_t offset = getDataStringLenOffset(); + Bit::htobl(data+offset, Bit::btohl(data+offset)+appendLen); + } + + void Packet::appendNal(const char * appendData, uint32_t appendLen, uint32_t totalLen){ + if(totalLen ==0){ + return; + } + +// INFO_MSG("totallen: %d, appendLen: %d",totalLen,appendLen); + resize(dataLen + appendLen +4); + Bit::htobl(data+dataLen -3, totalLen); + memcpy(data + dataLen-3+4, appendData, appendLen); + memcpy(data + dataLen-3+4 + appendLen, "\000\000\356", 3); //end container + dataLen += appendLen +4; + Bit::htobl(data+4, Bit::btohl(data +4)+appendLen+4); + uint32_t offset = getDataStringLenOffset(); + Bit::htobl(data+offset, Bit::btohl(data+offset)+appendLen+4); + } + + uint32_t Packet::getDataStringLen(){ + return Bit::btohl(data+getDataStringLenOffset()); + } + + ///Method can only be used when using internal functions to build the data. + uint32_t Packet::getDataStringLenOffset(){ + uint32_t offset = 23; + while (data[offset] != 'd'){ + switch (data[offset]){ + case 'o': offset += 17; break; + case 'b': offset += 15; break; + case 'k': offset += 19; break; + default: + FAIL_MSG("Errrrrrr"); + return -1; + } + } + return offset +5; + } + + /// Helper function for skipping over whole DTSC parts static char * skipDTSC(char * p, char * max) { if (p + 1 >= max || p[0] == 0x00) { From ae448d6e8abf07da641ff0e588594dcf5bc232d4 Mon Sep 17 00:00:00 2001 From: Ramoe Date: Fri, 12 May 2017 12:02:27 +0200 Subject: [PATCH 2/4] Added several TS and NAL convenience functions --- lib/nal.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++ lib/nal.h | 2 ++ lib/ts_packet.cpp | 20 +++++++++++++++++++ lib/ts_packet.h | 2 ++ 4 files changed, 74 insertions(+) diff --git a/lib/nal.cpp b/lib/nal.cpp index 25ae8d7f..f4d75d0d 100644 --- a/lib/nal.cpp +++ b/lib/nal.cpp @@ -69,6 +69,56 @@ namespace nalu { return dataSize; } + const char* nalEndPosition(const char * data, uint32_t dataSize){ + while(dataSize > 0 && memcmp(data+dataSize-1, "\000",1) == 0 ){ + dataSize--; + } + + return data+dataSize; + } + + ///scan data stream for startcode. return pointer to location when found, NULL otherwise + void scanAnnexB(const char * data, uint32_t dataSize, const char *& packetPointer){ + int offset = 0; + + while(offset+2 < dataSize){ + const char * begin = data + offset; +// int t = ((((int*)begin)[0]) >> 8) & 0x00FFFFFF; + int t = (int)((begin[0] << 8)|((begin[1]) << 8)|(begin[2])); + //int t = (int)((begin[0]|begin[1]) << 1)|(begin[2]); + //search for startcode + + //if(memcmp(begin, "\000\000\001",3) != 0){ + if(t != 1){ + + //if((t & 0x0000FF != 0 )) + if((int)begin[2] != 0 ) //XX1 + { + offset +=3; + }else if(((int)begin[1] == 1) && ((int)begin[2] ==0)){ //X10 + offset +=2; + }else{ + offset++; //[X00]? incr with 1 because the startcode could be one at 1byte offset. + } +/* + if(t != 0 ) + { + offset += 3; + }else{ + offset++; + } +*/ + +// offset++; + }else{ + packetPointer = begin; + return; + } + } + + packetPointer = NULL; + } + unsigned long fromAnnexB(const char * data, unsigned long dataSize, char *& result){ const char * lastCheck = data + dataSize - 3; if (!result){ diff --git a/lib/nal.h b/lib/nal.h index e1ad63ff..28a3e246 100644 --- a/lib/nal.h +++ b/lib/nal.h @@ -16,4 +16,6 @@ namespace nalu { unsigned long toAnnexB(const char * data, unsigned long dataSize, char *& result); unsigned long fromAnnexB(const char * data, unsigned long dataSize, char *& result); + void scanAnnexB(const char * data, uint32_t dataSize, const char *& packetPointer); + const char* nalEndPosition(const char * data, uint32_t dataSize); } diff --git a/lib/ts_packet.cpp b/lib/ts_packet.cpp index bd77c471..5d528348 100644 --- a/lib/ts_packet.cpp +++ b/lib/ts_packet.cpp @@ -48,6 +48,26 @@ namespace TS { return true; } + bool Packet::FromStream(std::istream & data) + { + long long int bPos = data.tellg(); + if(!data.read (strBuf,188)) + { + HIGH_MSG("failed to read 188 bytes"); + return false; + } + + if(strBuf[0] != 0x47) + { + HIGH_MSG("Failed to read a good packet on pos %lld", bPos); + return false; + } + + pos = 188; + return true; + } + + ///This funtion fills a Packet from ///a char array. It fills the content with ///the first 188 characters of a char array diff --git a/lib/ts_packet.h b/lib/ts_packet.h index 633afe92..fad0f231 100644 --- a/lib/ts_packet.h +++ b/lib/ts_packet.h @@ -12,6 +12,7 @@ #include #include "dtsc.h" #include "checksum.h" +#include /// Holds all TS processing related code. namespace TS { @@ -26,6 +27,7 @@ namespace TS { ~Packet(); bool FromPointer(const char * data); bool FromFile(FILE * data); + bool FromStream(std::istream & data); //Base properties void setPID(int NewPID); From c56b72dbcab55025415ab0a9f0c0493454e0c42c Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Mon, 8 May 2017 10:59:46 +0200 Subject: [PATCH 3/4] Added a couple of IO convenience functions --- src/io.cpp | 12 ++++++++++++ src/io.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/io.cpp b/src/io.cpp index 195060c2..684a757b 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -520,10 +520,22 @@ namespace Mist { nProxy.continueNegotiate(tid, myMeta, quickNegotiate); } + void InOutBase::continueNegotiate() { + nProxy.continueNegotiate(myMeta); + } + negotiationProxy::negotiationProxy(){ negTimer = 0; } + void negotiationProxy::continueNegotiate(DTSC::Meta & myMeta) { + for (std::map::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){ + if (!trackState.count(it->first) || (trackState[it->first] != FILL_ACC && trackState[it->first] != FILL_DEC)){ + continueNegotiate(it->first, myMeta); + } + } + } + void negotiationProxy::continueNegotiate(unsigned long tid, DTSC::Meta & myMeta, bool quickNegotiate) { if (!tid) { return; diff --git a/src/io.h b/src/io.h index 0ab55171..3e85b902 100644 --- a/src/io.h +++ b/src/io.h @@ -56,6 +56,8 @@ namespace Mist { std::string streamName;///< Name of the stream to connect to void continueNegotiate(unsigned long tid, DTSC::Meta & myMeta, bool quickNegotiate = false); + void continueNegotiate(DTSC::Meta & myMeta); + uint32_t negTimer; ///< How long we've been negotiating, in packets. }; @@ -70,6 +72,7 @@ namespace Mist { virtual void bufferLivePacket(DTSC::Packet & packet); protected: void continueNegotiate(unsigned long tid, bool quickNegotiate = false); + void continueNegotiate(); From 260894468e159dc18c28213e35acea6663c876b7 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Fri, 12 May 2017 12:47:15 +0200 Subject: [PATCH 4/4] Changed input boot sequence to allow for finer control --- src/input/input.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/input/input.cpp b/src/input/input.cpp index 1b7378cb..53aca0cb 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -93,7 +93,17 @@ namespace Mist { /// Starts checks the SEM_INPUT lock, starts an angel process and then int Input::boot(int argc, char * argv[]){ if (!(config->parseArgs(argc, argv))){return 1;} - streamName = config->getString("streamname"); + streamName = nProxy.streamName = config->getString("streamname"); + + if (config->getBool("json")) { + std::cout << capa.toString() << std::endl; + return 0; + } + + if (!setup()) { + FAIL_MSG("Setup failed - exiting"); + return 0; + } IPC::semaphore playerLock; if (needsLock() && streamName.size()){ @@ -152,18 +162,6 @@ namespace Mist { } int Input::run() { - if (config->getBool("json")) { - std::cout << capa.toString() << std::endl; - return 0; - } - - nProxy.streamName = streamName; - - if (!setup()){ - std::cerr << config->getString("cmd") << " setup failed." << std::endl; - return 0; - } - checkHeaderTimes(config->getString("input")); if (!readHeader()){ std::cerr << "Reading header for " << config->getString("input") << " failed." << std::endl; @@ -291,16 +289,19 @@ namespace Mist { pullLock.close(); return; } + if (Util::streamAlive(streamName)){ pullLock.post(); pullLock.close(); pullLock.unlink(); + WARN_MSG("Stream already online, cancelling"); return; } if (!Util::startInput(streamName, "push://INTERNAL_ONLY:"+config->getString("input"))) {//manually override stream url to start the buffer pullLock.post(); pullLock.close(); pullLock.unlink(); + WARN_MSG("Could not start buffer, cancelling"); return; } @@ -324,6 +325,7 @@ namespace Mist { pullLock.post(); pullLock.close(); pullLock.unlink(); + WARN_MSG("No tracks found, cancelling"); return; } nProxy.userClient.countAsViewer = false; @@ -561,7 +563,7 @@ namespace Mist { if ((int)myMeta.tracks[track].keys.size() > keyNum - 1 + nProxy.pagesByTrack[track][keyNum].keyNum) { stopTime = myMeta.tracks[track].keys[keyNum - 1 + nProxy.pagesByTrack[track][keyNum].keyNum].getTime(); } - DEBUG_MSG(DLVL_HIGH, "Playing from %llu to %llu", myMeta.tracks[track].keys[keyNum - 1].getTime(), stopTime); + HIGH_MSG("Playing from %llu to %llu", myMeta.tracks[track].keys[keyNum - 1].getTime(), stopTime); getNext(); //in case earlier seeking was inprecise, seek to the exact point while (thisPacket && thisPacket.getTime() < (unsigned long long)myMeta.tracks[track].keys[keyNum - 1].getTime()){