diff --git a/lib/bitfields.h b/lib/bitfields.h index 186a064c..96b7605f 100644 --- a/lib/bitfields.h +++ b/lib/bitfields.h @@ -51,6 +51,51 @@ namespace Bit{ p[2] = val & 0xFF; } + /// Retrieves a 40-bit uint in network order from the pointer p. + inline uint64_t btoh40(const char * p) { + return ((uint64_t)p[0] << 32) | ((uint64_t)p[1] << 24) | ((uint64_t)p[2] << 16) | ((uint64_t)p[3] << 8) | p[4]; + } + + /// Stores a 40-bit uint value of val in network order to the pointer p. + inline void htob40(char * p, uint64_t val) { + p[0] = (val >> 32) & 0xFF; + p[1] = (val >> 24) & 0xFF; + p[2] = (val >> 16) & 0xFF; + p[3] = (val >> 8) & 0xFF; + p[4] = val & 0xFF; + } + + /// Retrieves a 48-bit uint in network order from the pointer p. + inline uint64_t btoh48(const char * p) { + return ((uint64_t)p[0] << 40) | ((uint64_t)p[1] << 32) | ((uint64_t)p[2] << 24) | ((uint64_t)p[3] << 16) | ((uint64_t)p[4] << 8) | p[5]; + } + + /// Stores a 48-bit uint value of val in network order to the pointer p. + inline void htob48(char * p, uint64_t val) { + p[0] = (val >> 40) & 0xFF; + p[1] = (val >> 32) & 0xFF; + p[2] = (val >> 24) & 0xFF; + p[3] = (val >> 16) & 0xFF; + p[4] = (val >> 8) & 0xFF; + p[5] = val & 0xFF; + } + + /// Retrieves a 56-bit uint in network order from the pointer p. + inline uint64_t btoh56(const char * p) { + return ((uint64_t)p[0] << 48) | ((uint64_t)p[1] << 40) | ((uint64_t)p[2] << 32) | ((uint64_t)p[3] << 24) | ((uint64_t)p[4] << 16) | ((uint64_t)p[5] << 8) | p[6]; + } + + /// Stores a 56-bit uint value of val in network order to the pointer p. + inline void htob56(char * p, uint64_t val) { + p[0] = (val >> 48) & 0xFF; + p[1] = (val >> 40) & 0xFF; + p[2] = (val >> 32) & 0xFF; + p[3] = (val >> 24) & 0xFF; + p[4] = (val >> 16) & 0xFF; + p[5] = (val >> 8) & 0xFF; + p[6] = val & 0xFF; + } + /// Retrieves a long long in network order from the pointer p. inline unsigned long long btohll(const char * p) { return ((unsigned long long)p[0] << 56) | ((unsigned long long)p[1] << 48) | ((unsigned long long)p[2] << 40) | ((unsigned long long)p[3] << 32) | ((unsigned long)p[4] << 24) | ((unsigned long)p[5] << 16) | ((unsigned long)p[6] << 8) | p[7]; @@ -68,6 +113,24 @@ namespace Bit{ p[7] = val & 0xFF; } + inline float btohf(const char * p){ + uint32_t tmp = btohl(p); + return *reinterpret_cast(&tmp); + } + + inline float htobf(char * p, float val){ + htobl(p, *reinterpret_cast(&val)); + } + + inline double btohd(const char * p){ + uint64_t tmp = btohll(p); + return *reinterpret_cast(&tmp); + } + + inline float htobd(char * p, double val){ + htobll(p, *reinterpret_cast(&val)); + } + /// Retrieves a short in little endian from the pointer p. inline unsigned short btohs_le(const char * p) { return ((unsigned short)p[1] << 8) | p[0]; diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index fa14827b..47302ae5 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -1406,6 +1406,20 @@ namespace DTSC { return keys[keyNum - keys[0].getNumber()]; } + ///\brief Returns a fragment given its number, or an empty fragment if the number is out of bounds + Fragment & Track::getFrag(unsigned int fragNum) { + static Fragment empty; + if (!fragments.size() || fragNum < fragments[0].getNumber() || fragNum > fragments.rbegin()->getNumber()) { + return empty; + } + for (std::deque::iterator it = fragments.begin(); it != fragments.end(); ++it){ + if (fragNum >= it->getNumber() && fragNum <= it->getNumber() + it->getLength()){ + return *it; + } + } + return empty; + } + /// Returns the number of the key containing timestamp, or last key if nowhere. unsigned int Track::timeToKeynum(unsigned int timestamp){ unsigned int result = 0; diff --git a/lib/socket.cpp b/lib/socket.cpp index 2607c47d..c2e2e395 100644 --- a/lib/socket.cpp +++ b/lib/socket.cpp @@ -341,6 +341,7 @@ Socket::Connection::Connection(int sockNo){ conntime = Util::epoch(); Error = false; Blocking = false; + skipCount = 0; }// Socket::Connection basic constructor /// Simulate a socket using two file descriptors. @@ -355,6 +356,7 @@ Socket::Connection::Connection(int write, int read){ conntime = Util::epoch(); Error = false; Blocking = false; + skipCount = 0; }// Socket::Connection basic constructor /// Create a new disconnected base socket. This is a basic constructor for placeholder purposes. @@ -368,6 +370,7 @@ Socket::Connection::Connection(){ conntime = Util::epoch(); Error = false; Blocking = false; + skipCount = 0; }// Socket::Connection basic constructor void Socket::Connection::resetCounter(){ @@ -629,6 +632,11 @@ void Socket::Connection::SendNow(const std::string &data){ SendNow(data.data(), data.size()); } +void Socket::Connection::skipBytes(uint32_t byteCount){ + INFO_MSG("Skipping first %lu bytes going to socket", byteCount); + skipCount = byteCount; +} + /// Incremental write call. This function tries to write len bytes to the socket from the buffer, /// returning the amount of bytes it actually wrote. /// \param buffer Location of the buffer to write from. @@ -636,6 +644,18 @@ void Socket::Connection::SendNow(const std::string &data){ /// \returns The amount of bytes actually written. unsigned int Socket::Connection::iwrite(const void *buffer, int len){ if (!connected() || len < 1){return 0;} + if (skipCount){ + //We have bytes to skip writing. + //Pretend we write them, but don't really. + if (len <= skipCount){ + skipCount -= len; + return len; + }else{ + unsigned int retCode = iwrite((((char*)buffer)+skipCount), len-skipCount); + skipCount = 0; + return retCode; + } + } int r; if (sock >= 0){ r = send(sock, buffer, len, 0); diff --git a/lib/socket.h b/lib/socket.h index 73c391c3..cf8a4749 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -106,6 +106,8 @@ namespace Socket{ void SendNow(const std::string &data); ///< Will not buffer anything but always send right away. Blocks. void SendNow(const char *data); ///< Will not buffer anything but always send right away. Blocks. void SendNow(const char *data, size_t len); ///< Will not buffer anything but always send right away. Blocks. + void skipBytes(uint32_t byteCount); + uint32_t skipCount; // stats related methods unsigned int connTime(); ///< Returns the time this socket has been connected. uint64_t dataUp(); ///< Returns total amount of bytes sent. diff --git a/lib/util.h b/lib/util.h index 9d0c560e..d721885f 100644 --- a/lib/util.h +++ b/lib/util.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include diff --git a/src/input/input.cpp b/src/input/input.cpp index 5dfd6195..353d1521 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -611,6 +611,20 @@ namespace Mist { } } } + + void Input::trackSelect(std::string trackSpec){ + selectedTracks.clear(); + size_t index; + while (trackSpec != "") { + index = trackSpec.find(' '); + selectedTracks.insert(atoi(trackSpec.substr(0, index).c_str())); + if (index != std::string::npos) { + trackSpec.erase(0, index + 1); + } else { + trackSpec = ""; + } + } + } void Input::parseHeader() { if (hasSrt){ diff --git a/src/input/input.h b/src/input/input.h index fe6ee55c..0f2b53b0 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -46,7 +46,7 @@ namespace Mist { void quitPlay(); void checkHeaderTimes(std::string streamFile); virtual void removeUnused(); - virtual void trackSelect(std::string trackSpec){}; + virtual void trackSelect(std::string trackSpec); virtual void userCallback(char * data, size_t len, unsigned int id); virtual void convert(); virtual void serve(); diff --git a/src/io.cpp b/src/io.cpp index f53f01a6..30773c83 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -29,6 +29,20 @@ namespace Mist { } + /// Returns the ID of the main selected track, or 0 if no tracks are selected. + /// The main track is the first video track, if any, and otherwise the first other track. + long unsigned int InOutBase::getMainSelectedTrack(){ + if (!selectedTracks.size()){ + return 0; + } + for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ + if (myMeta.tracks.count(*it) && myMeta.tracks[*it].type == "video"){ + return *it; + } + } + return *(selectedTracks.begin()); + } + void negotiationProxy::clear(){ pagesByTrack.clear(); trackOffset.clear(); diff --git a/src/io.h b/src/io.h index 77523fa8..10d36e1e 100644 --- a/src/io.h +++ b/src/io.h @@ -77,6 +77,7 @@ namespace Mist { void bufferFinalize(unsigned long tid); void bufferRemove(unsigned long tid, unsigned long pageNumber); virtual void bufferLivePacket(const DTSC::Packet & packet); + long unsigned int getMainSelectedTrack(); protected: void continueNegotiate(unsigned long tid, bool quickNegotiate = false); void continueNegotiate(); diff --git a/src/output/output.cpp b/src/output/output.cpp index 7b0dc291..e8595bd1 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -1246,20 +1246,6 @@ namespace Mist{ return 0; } - /// Returns the ID of the main selected track, or 0 if no tracks are selected. - /// The main track is the first video track, if any, and otherwise the first other track. - long unsigned int Output::getMainSelectedTrack(){ - if (!selectedTracks.size()){ - return 0; - } - for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ - if (myMeta.tracks.count(*it) && myMeta.tracks[*it].type == "video"){ - return *it; - } - } - return *(selectedTracks.begin()); - } - void Output::dropTrack(uint32_t trackId, std::string reason, bool probablyBad){ //depending on whether this is probably bad and the current debug level, print a message unsigned int printLevel = DLVL_INFO; diff --git a/src/output/output.h b/src/output/output.h index aed5318b..ae2ec56b 100644 --- a/src/output/output.h +++ b/src/output/output.h @@ -54,7 +54,6 @@ namespace Mist { uint64_t endTime(); uint64_t liveTime(); void setBlocking(bool blocking); - long unsigned int getMainSelectedTrack(); void updateMeta(); void selectTrack(const std::string &trackType, const std::string &trackVal); /*LTS*/ void selectDefaultTracks();