diff --git a/lib/defines.h b/lib/defines.h index c491018b..38e0e858 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -37,12 +37,30 @@ static const char * DBG_LVL_LIST[] = {"NONE", "FAIL", "ERROR", "WARN", "INFO", " #endif #endif +#include +static inline void show_stackframe() { + void *trace[16]; + char **messages = 0; + int i, trace_size = 0; + trace_size = backtrace(trace, 16); + messages = backtrace_symbols(trace, trace_size); + for (i=1; i analysePackets(const char * data, unsigned long len){ std::deque res; diff --git a/lib/h264.h b/lib/h264.h index 922c4c2c..d54748c9 100644 --- a/lib/h264.h +++ b/lib/h264.h @@ -72,6 +72,8 @@ namespace h264 { size_t dataLen; }; + bool isKeyframe(const char * data, uint32_t len); + class nalUnit { public: nalUnit(const char * data, size_t len) : payload(data, len) {} diff --git a/lib/socket.cpp b/lib/socket.cpp index 41883955..55c378a0 100644 --- a/lib/socket.cpp +++ b/lib/socket.cpp @@ -65,6 +65,10 @@ std::string uint2string(unsigned int i){ return st.str(); } +Socket::Buffer::Buffer(){ + splitter = "\n"; +} + /// Returns the amount of elements in the internal std::deque of std::string objects. /// The back is popped as long as it is empty, first - this way this function is /// guaranteed to return 0 if the buffer is empty. @@ -83,26 +87,58 @@ unsigned int Socket::Buffer::bytes(unsigned int max){ return i; } +/// Returns how many bytes to read until the next splitter, or 0 if none found. +unsigned int Socket::Buffer::bytesToSplit(){ + unsigned int i = 0; + for (std::deque::reverse_iterator it = data.rbegin(); it != data.rend(); ++it){ + i += (*it).size(); + if ((*it).size() >= splitter.size() && (*it).substr((*it).size()-splitter.size()) == splitter){ + return i; + } + } + return 0; +} + /// Appends this string to the internal std::deque of std::string objects. -/// It is automatically split every BUFFER_BLOCKSIZE bytes. +/// It is automatically split every BUFFER_BLOCKSIZE bytes and when the splitter string is encountered. void Socket::Buffer::append(const std::string &newdata){ - append(newdata.c_str(), newdata.size()); + append(newdata.data(), newdata.size()); +} + +///Helper function that does a short-circuiting string compare +inline bool string_compare(const char *a, const char *b, const size_t len){ + for (size_t i = 0; i < len; ++i){ + if (a[i] != b[i]){return false;} + } + return true; } /// Appends this data block to the internal std::deque of std::string objects. -/// It is automatically split every BUFFER_BLOCKSIZE bytes. +/// It is automatically split every BUFFER_BLOCKSIZE bytes and when the splitter string is encountered. void Socket::Buffer::append(const char *newdata, const unsigned int newdatasize){ - unsigned int i = 0, j = 0; + uint32_t i = 0; while (i < newdatasize){ - j = i; - while (j < newdatasize && j - i <= BUFFER_BLOCKSIZE){ - j++; - if (newdata[j - 1] == '\n'){break;} - } - if (i != j){ - data.push_front(std::string(newdata + i, (size_t)(j - i))); - i = j; + uint32_t j = 0; + if (!splitter.size()){ + if (newdatasize - i > BUFFER_BLOCKSIZE){ + j = BUFFER_BLOCKSIZE; + }else{ + j = newdatasize - i; + } }else{ + while (j+i < newdatasize && j < BUFFER_BLOCKSIZE){ + j++; + if (j >= splitter.size()){ + if (string_compare(newdata+i+j-splitter.size(), splitter.data(), splitter.size())){break;} + } + } + } + if (j){ + data.push_front(""); + data.front().assign(newdata + i, (size_t)j); + i += j; + }else{ + FAIL_MSG("Appended an empty string to buffer: aborting!"); break; } } diff --git a/lib/socket.h b/lib/socket.h index 7704143d..0975c283 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -32,8 +32,11 @@ namespace Socket{ std::deque data; public: + std::string splitter;///