From afef126295344be16893fefee5bc8b7e4e5dcd7d Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Tue, 2 Dec 2014 12:41:48 +0100 Subject: [PATCH] Fix for not having to read through the entire file on startup of input. --- lib/dtsc.h | 10 +- lib/dtscmeta.cpp | 172 ++++++++++------- lib/ogg.cpp | 479 ----------------------------------------------- lib/ogg.h | 72 ------- 4 files changed, 114 insertions(+), 619 deletions(-) delete mode 100644 lib/ogg.cpp delete mode 100644 lib/ogg.h diff --git a/lib/dtsc.h b/lib/dtsc.h index a764d44c..383f6a8c 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -250,6 +250,9 @@ namespace DTSC { public: readOnlyTrack(); readOnlyTrack(JSON::Value & trackRef); + inline operator bool() const { + return (partLen && keySizes.size() && (keySizes.size() == keyLen)); + } int getSendLen(); void send(Socket::Connection & conn); void writeTo(char *& p); @@ -260,6 +263,7 @@ namespace DTSC { Fragment * fragments; long long unsigned int keyLen; Key * keys; + std::vector keySizes; long long unsigned int partLen; Part * parts; int trackID; @@ -278,9 +282,6 @@ namespace DTSC { int width; int height; int fpks; - //vorbis and theora only - std::string idHeader; - std::string commentHeader; void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0); }; @@ -292,7 +293,7 @@ namespace DTSC { Track(JSON::Value & trackRef); Track(Scan & trackRef); inline operator bool() const { - return parts.size(); + return (parts.size() && keySizes.size() && (keySizes.size() == keys.size())); } void update(DTSC::Packet & pack); void update(JSON::Value & pack); @@ -302,6 +303,7 @@ namespace DTSC { JSON::Value toJSON(); std::deque fragments; std::deque keys; + std::deque keySizes; std::deque parts; Key & getKey(unsigned int keyNum); void reset(); diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index c6caaa82..da3de762 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -985,9 +985,11 @@ namespace DTSC { height = trackRef["height"].asInt(); fpks = trackRef["fpks"].asInt(); } - if (codec == "vorbis" || codec == "theora") { - idHeader = trackRef["idheader"].asStringRef(); - commentHeader = trackRef["commentheader"].asStringRef(); + if (trackRef.isMember("keysizes") && trackRef["keysizes"].isString()) { + std::string tmp = trackRef["keysizes"].asStringRef(); + for (int i = 0; i < tmp.size(); i += 4){ + keySizes.push_back((((long unsigned)tmp[i]) << 24) | (((long unsigned)tmp[i+1]) << 16) | (((long unsigned int)tmp[i+2]) << 8) | tmp[i+3]); + } } } @@ -1022,8 +1024,6 @@ namespace DTSC { width = rhs.width; height = rhs.height; fpks = rhs.fpks; - idHeader = rhs.idHeader; - commentHeader = rhs.commentHeader; if (rhs.fragments && rhs.fragLen) { fragments = std::deque(rhs.fragments, rhs.fragments + rhs.fragLen); } @@ -1033,6 +1033,9 @@ namespace DTSC { if (rhs.parts && rhs.partLen) { parts = std::deque(rhs.parts, rhs.parts + rhs.partLen); } + for(std::vector::const_iterator it = rhs.keySizes.begin(); it != rhs.keySizes.end(); it++){ + keySizes.push_back(*it); + } } ///\brief Constructs a track from a JSON::Value @@ -1067,9 +1070,11 @@ namespace DTSC { height = trackRef["height"].asInt(); fpks = trackRef["fpks"].asInt(); } - if (codec == "vorbis" || codec == "theora") { - idHeader = trackRef["idheader"].asStringRef(); - commentHeader = trackRef["commentheader"].asStringRef(); + if (trackRef.isMember("keysizes") && trackRef["keysizes"].isString()) { + std::string tmp = trackRef["keysizes"].asStringRef(); + for (int i = 0; i < tmp.size(); i += 4){ + keySizes.push_back((((long unsigned)tmp[i]) << 24) | (((long unsigned)tmp[i+1]) << 16) | (((long unsigned int)tmp[i+2]) << 8) | tmp[i+3]); + } } } @@ -1111,6 +1116,14 @@ namespace DTSC { height = trackRef.getMember("height").asInt(); fpks = trackRef.getMember("fpks").asInt(); } + if (trackRef.getMember("keysizes").getType() == DTSC_STR) { + char * tmp = 0; + unsigned int tmplen = 0; + trackRef.getMember("keysizes").getString(tmp, tmplen); + for (int i = 0; i < tmplen; i += 4){ + keySizes.push_back((((long unsigned)tmp[i]) << 24) | (((long unsigned)tmp[i+1]) << 16) | (((long unsigned int)tmp[i+2]) << 8) | tmp[i+3]); + } + } } ///\brief Updates a track and its metadata given a DTSC::Packet. @@ -1152,6 +1165,7 @@ namespace DTSC { newKey.setBpos(0); } keys.push_back(newKey); + keySizes.push_back(0); firstms = keys[0].getTime(); if (!fragments.size() || (pack.getTime() > 5000 && pack.getTime() - 5000 >= (unsigned long long)getKey(fragments.rbegin()->getNumber()).getTime())) { //new fragment @@ -1174,6 +1188,7 @@ namespace DTSC { } } keys.rbegin()->setParts(keys.rbegin()->getParts() + 1); + (*keySizes.rbegin()) += pack.getDataLen(); fragments.rbegin()->setSize(fragments.rbegin()->getSize() + dataLen); } @@ -1213,6 +1228,7 @@ namespace DTSC { newKey.setBpos(0); } keys.push_back(newKey); + keySizes.push_back(0); firstms = keys[0].getTime(); if (!fragments.size() || (pack["time"].asInt() > 5000 && pack["time"].asInt() - 5000 >= getKey(fragments.rbegin()->getNumber()).getTime())) { //new fragment @@ -1235,6 +1251,8 @@ namespace DTSC { } } keys.rbegin()->setParts(keys.rbegin()->getParts() + 1); + std::string tmp = pack.toNetPacked(); + keySizes[keySizes.size() - 1] += tmp.size(); fragments.rbegin()->setSize(fragments.rbegin()->getSize() + pack["data"].asStringRef().size()); } @@ -1346,10 +1364,6 @@ namespace DTSC { str << std::string(indent + 2, ' ') << "Height: " << height << std::endl; str << std::string(indent + 2, ' ') << "Fpks: " << fpks << std::endl; } - if (codec == "vorbis" || codec == "theora") { - str << std::string(indent + 2, ' ') << "IdHeader: " << idHeader << std::endl; - str << std::string(indent + 2, ' ') << "CommentHeader: " << commentHeader << std::endl; - } str << std::string(indent + 2, ' ') << "Fragments: " << fragLen << std::endl; if (fragments && verbosity & 0x01) { for (unsigned int i = 0; i < fragLen; i++) { @@ -1362,6 +1376,12 @@ namespace DTSC { keys[i].toPrettyString(str, indent + 4); } } + str << std::string(indent + 2, ' ') << "KeySizes: " << keySizes.size() << std::endl; + if (keySizes.size() && verbosity & 0x02){ + for (unsigned int i = 0; i < keySizes.size(); i++){ + str << std::string(indent + 4, ' ') << "[" << i << "] " << keySizes[i] << std::endl; + } + } str << std::string(indent + 2, ' ') << "Parts: " << partLen << std::endl; if (parts && verbosity & 0x04) { for (unsigned int i = 0; i < partLen; i++) { @@ -1485,10 +1505,6 @@ namespace DTSC { str << std::string(indent + 2, ' ') << "Height: " << height << std::endl; str << std::string(indent + 2, ' ') << "Fpks: " << fpks << std::endl; } - if (codec == "vorbis" || codec == "theora") { - str << std::string(indent + 2, ' ') << "IdHeader: " << idHeader << std::endl; - str << std::string(indent + 2, ' ') << "CommentHeader: " << commentHeader << std::endl; - } str << std::string(indent + 2, ' ') << "Fragments: " << fragments.size() << std::endl; if (verbosity & 0x01) { for (unsigned int i = 0; i < fragments.size(); i++) { @@ -1501,6 +1517,12 @@ namespace DTSC { keys[i].toPrettyString(str, indent + 4); } } + str << std::string(indent + 2, ' ') << "KeySizes: " << keySizes.size() << std::endl; + if (keySizes.size() && verbosity & 0x02){ + for (unsigned int i = 0; i < keySizes.size(); i++){ + str << std::string(indent + 4, ' ') << "[" << i << "] " << keySizes[i] << std::endl; + } + } str << std::string(indent + 2, ' ') << "Parts: " << parts.size() << std::endl; if (verbosity & 0x04) { for (unsigned int i = 0; i < parts.size(); i++) { @@ -1546,16 +1568,15 @@ namespace DTSC { int result = 146 + init.size() + codec.size() + type.size() + getWritableIdentifier().size(); result += fragLen * 11; result += keyLen * 16; + if (keySizes.size()){ + result += 11 + (keySizes.size() * 4) + 4; + } result += partLen * 9; if (type == "audio") { result += 49; } else if (type == "video") { result += 48; } - if (codec == "vorbis" || codec == "theora") { - result += 15 + idHeader.size();//idheader - result += 20 + commentHeader.size();//commentheader - } if (missedFrags) { result += 23; } @@ -1567,16 +1588,15 @@ namespace DTSC { int result = 146 + init.size() + codec.size() + type.size() + getWritableIdentifier().size(); result += fragments.size() * 11; result += keys.size() * 16; + if (keySizes.size()){ + result += 11 + (keySizes.size() * 4) + 4; + } result += parts.size() * 9; if (type == "audio") { result += 49; } else if (type == "video") { result += 48; } - if (codec == "vorbis" || codec == "theora") { - result += 15 + idHeader.size();//idheader - result += 20 + commentHeader.size();//commentheader - } if (missedFrags) { result += 23; } @@ -1610,6 +1630,17 @@ namespace DTSC { writePointer(p, "\000\004keys\002", 7); writePointer(p, convertInt(keyLen * 16), 4); writePointer(p, (char *)keys, keyLen * 16); + writePointer(p, "\000\010keysizes\002,", 11); + writePointer(p, convertInt(keySizes.size() * 4), 4); + std::string tmp; + tmp.reserve(keySizes.size() * 4); + for (int i = 0; i < keySizes.size(); i++){ + tmp += ((char)keySizes[i] >> 24); + tmp += ((char)keySizes[i] >> 16); + tmp += ((char)keySizes[i] >> 8); + tmp += ((char)keySizes[i]); + } + writePointer(p, tmp.data(), tmp.size()); writePointer(p, "\000\005parts\002", 8); writePointer(p, convertInt(partLen * 9), 4); writePointer(p, (char *)parts, partLen * 9); @@ -1649,14 +1680,6 @@ namespace DTSC { writePointer(p, "\000\004fpks\001", 7); writePointer(p, convertLongLong(fpks), 8); } - if (codec == "vorbis" || codec == "theora") { - writePointer(p, "\000\010idheader\002", 11); - writePointer(p, convertInt(idHeader.size()), 4); - writePointer(p, idHeader); - writePointer(p, "\000\015commentheader\002", 16); - writePointer(p, convertInt(commentHeader.size()), 4); - writePointer(p, commentHeader); - } writePointer(p, "\000\000\356", 3);//End this track Object } @@ -1671,6 +1694,17 @@ namespace DTSC { conn.SendNow("\000\004keys\002", 7); conn.SendNow(convertInt(keyLen * 16), 4); conn.SendNow((char *)keys, keyLen * 16); + conn.SendNow("\000\010keysizes\002,", 11); + conn.SendNow(convertInt(keySizes.size() * 4), 4); + std::string tmp; + tmp.reserve(keySizes.size() * 4); + for (int i = 0; i < keySizes.size(); i++){ + tmp += ((char)keySizes[i] >> 24); + tmp += ((char)keySizes[i] >> 16); + tmp += ((char)keySizes[i] >> 8); + tmp += ((char)keySizes[i]); + } + conn.SendNow(tmp.data(), tmp.size()); conn.SendNow("\000\005parts\002", 8); conn.SendNow(convertInt(partLen * 9), 4); conn.SendNow((char *)parts, partLen * 9); @@ -1710,14 +1744,6 @@ namespace DTSC { conn.SendNow("\000\004fpks\001", 7); conn.SendNow(convertLongLong(fpks), 8); } - if (codec == "vorbis" || codec == "theora") { - conn.SendNow("\000\010idheader\002", 11); - conn.SendNow(convertInt(idHeader.size()), 4); - conn.SendNow(idHeader); - conn.SendNow("\000\015commentheader\002", 16); - conn.SendNow(convertInt(commentHeader.size()), 4); - conn.SendNow(commentHeader); - } conn.SendNow("\000\000\356", 3);//End this track Object } @@ -1736,6 +1762,17 @@ namespace DTSC { for (std::deque::iterator it = keys.begin(); it != keys.end(); it++) { writePointer(p, it->getData(), 16); } + writePointer(p, "\000\010keysizes\002,", 11); + writePointer(p, convertInt(keySizes.size() * 4), 4); + std::string tmp; + tmp.reserve(keySizes.size() * 4); + for (int i = 0; i < keySizes.size(); i++){ + tmp += ((char)keySizes[i] >> 24); + tmp += ((char)keySizes[i] >> 16); + tmp += ((char)keySizes[i] >> 8); + tmp += ((char)keySizes[i]); + } + writePointer(p, tmp.data(), tmp.size()); writePointer(p, "\000\005parts\002", 8); writePointer(p, convertInt(parts.size() * 9), 4); for (std::deque::iterator it = parts.begin(); it != parts.end(); it++) { @@ -1777,14 +1814,6 @@ namespace DTSC { writePointer(p, "\000\004fpks\001", 7); writePointer(p, convertLongLong(fpks), 8); } - if (codec == "vorbis" || codec == "theora") { - writePointer(p, "\000\010idheader\002", 11); - writePointer(p, convertInt(idHeader.size()), 4); - writePointer(p, idHeader); - writePointer(p, "\000\015commentheader\002", 16); - writePointer(p, convertInt(commentHeader.size()), 4); - writePointer(p, commentHeader); - } writePointer(p, "\000\000\356", 3);//End this track Object } @@ -1803,6 +1832,17 @@ namespace DTSC { for (std::deque::iterator it = keys.begin(); it != keys.end(); it++) { conn.SendNow(it->getData(), 16); } + conn.SendNow("\000\010keysizes\002,", 11); + conn.SendNow(convertInt(keySizes.size() * 4), 4); + std::string tmp; + tmp.reserve(keySizes.size() * 4); + for (int i = 0; i < keySizes.size(); i++){ + tmp += ((char)keySizes[i] >> 24); + tmp += ((char)keySizes[i] >> 16); + tmp += ((char)keySizes[i] >> 8); + tmp += ((char)keySizes[i]); + } + conn.SendNow(tmp.data(), tmp.size()); conn.SendNow("\000\005parts\002", 8); conn.SendNow(convertInt(parts.size() * 9), 4); for (std::deque::iterator it = parts.begin(); it != parts.end(); it++) { @@ -1844,14 +1884,6 @@ namespace DTSC { conn.SendNow("\000\004fpks\001", 7); conn.SendNow(convertLongLong(fpks), 8); } - if (codec == "vorbis" || codec == "theora") { - conn.SendNow("\000\010idheader\002", 11); - conn.SendNow(convertInt(idHeader.size()), 4); - conn.SendNow(idHeader); - conn.SendNow("\000\015commentheader\002", 16); - conn.SendNow(convertInt(commentHeader.size()), 4); - conn.SendNow(commentHeader); - } conn.SendNow("\000\000\356", 3);//End this track Object } @@ -2006,6 +2038,17 @@ namespace DTSC { if (keys) { result["keys"] = std::string((char *)keys, keyLen * 16); } + if (keySizes.size()){ + std::string tmp; + tmp.reserve(keySizes.size() * 4); + for (int i = 0; i < keySizes.size(); i++){ + tmp += ((char)(keySizes[i] >> 24)); + tmp += ((char)(keySizes[i] >> 16)); + tmp += ((char)(keySizes[i] >> 8)); + tmp += ((char)keySizes[i]); + } + result["keysizes"] = tmp; + } if (parts) { result["parts"] = std::string((char *)parts, partLen * 9); } @@ -2028,10 +2071,6 @@ namespace DTSC { result["height"] = height; result["fpks"] = fpks; } - if (codec == "vorbis" || codec == "theora") { - result["idheader"] = idHeader; - result["commentheader"] = commentHeader; - } return result; } @@ -2051,6 +2090,15 @@ namespace DTSC { } result["keys"] = tmp; tmp = ""; + tmp.reserve(keySizes.size() * 4); + for (int i = 0; i < keySizes.size(); i++){ + tmp += ((char)(keySizes[i] >> 24)); + tmp += ((char)(keySizes[i] >> 16)); + tmp += ((char)(keySizes[i] >> 8)); + tmp += ((char)keySizes[i]); + } + result["keysizes"] = tmp; + tmp = ""; tmp.reserve(parts.size() * 9); for (std::deque::iterator it = parts.begin(); it != parts.end(); it++) { tmp.append(it->getData(), 9); @@ -2075,10 +2123,6 @@ namespace DTSC { result["height"] = height; result["fpks"] = fpks; } - if (codec == "vorbis" || codec == "theora") { - result["idheader"] = idHeader; - result["commentheader"] = commentHeader; - } return result; } diff --git a/lib/ogg.cpp b/lib/ogg.cpp deleted file mode 100644 index 30e7c3b6..00000000 --- a/lib/ogg.cpp +++ /dev/null @@ -1,479 +0,0 @@ -#include "ogg.h" -#include "defines.h" -#include -#include -#include -#include - -namespace OGG { - inline long long unsigned int get_64(char * data) { - long long unsigned int temp = 0; - for (int i = 7; i >= 0; --i) { - temp <<= 8; - temp += data[i]; - } - return temp; - } - - inline long unsigned int get_32(char * data) { - long unsigned int temp = 0; - for (int i = 3; i >= 0; --i) { - temp <<= 8; - temp += data[i]; - } - return temp; - } - - inline void set_64(char * data, long unsigned int val) { - for (int i = 0; i < 8; ++i) { - data[i] = val & 0xFF; - val >>= 8; - } - } - - - inline void set_32(char * data, long unsigned int val) { - for (int i = 0; i < 4; ++i) { - data[i] = val & 0xFF; - val >>= 8; - } - } - - - Page::Page() { - data = NULL; - datasize = 0; - dataSum = 0; - } - - Page::~Page() { - if (data) { - free(data); - } - } - - bool Page::read(std::string & newData) { - segmentTableDeque.clear(); - //datasize = 0; - if (newData.size() < 27) { - return false; - } - if (newData.substr(0, 4) != "OggS") { - DEBUG_MSG(DLVL_FAIL, "Invalid Ogg page encountered - cannot continue"); - return false; - } - dataSum = 0; - if (!checkDataSize(27)) { - return false; - } - memcpy(data, newData.c_str(), 27);//copying the header, always 27 bytes - - if (newData.size() < 27u + getPageSegments()) { //check input size - return false; - } - if (!checkDataSize(27 + getPageSegments())) { //check if size available in memory - return false; - } - memcpy(data + 27, newData.c_str() + 27, getPageSegments()); - //copying the first part of the page into data, which tells the size of the page - - for (unsigned int i = 0; i < getPageSegments(); i++) { - dataSum += getSegmentTable()[i]; - } - - if (newData.size() < 27 + getPageSegments() + dataSum) { //check input size - dataSum = 0; - return false; - } - if (!checkDataSize(27 + getPageSegments() + dataSum)) { - dataSum = 0; - return false; - } - memcpy(data + 27 + getPageSegments(), newData.c_str() + 27 + getPageSegments(), dataSum); - newData.erase(0, getPageSize()); - return true; - } - - - bool Page::read(FILE * inFile) { - segmentTableDeque.clear(); - int oriPos = ftell(inFile); - dataSum = 0; - if (!checkDataSize(27)) { - DEBUG_MSG(DLVL_WARN, "Unable to read a page: memory allocation"); - return false; - } - if (!fread(data, 27, 1, inFile)) { - DEBUG_MSG(DLVL_WARN, "Unable to read a page: fread"); - fseek(inFile, oriPos, SEEK_SET); - return false; - } - if (!checkDataSize(27 + getPageSegments())) { - DEBUG_MSG(DLVL_WARN, "Unable to read a page: memory allocation1"); - return false; - } - if (!fread(data + 27, getPageSegments(), 1, inFile)) { - DEBUG_MSG(DLVL_WARN, "Unable to read a page: fread1"); - fseek(inFile, oriPos, SEEK_SET); - return false; - } - for (unsigned int i = 0; i < getPageSegments(); i++) { - dataSum += data[27 + i]; - } - if (!checkDataSize(27 + getPageSegments() + dataSum)) { - DEBUG_MSG(DLVL_WARN, "Unable to read a page: memory allocation2"); - dataSum = 0; - return false; - } - if (!fread(data + 27 + getPageSegments(), dataSum, 1, inFile)) { - DEBUG_MSG(DLVL_WARN, "Unable to read a page: fread2"); - fseek(inFile, oriPos, SEEK_SET); - dataSum = 0; - return false; - } - return true; - } - - bool Page::getSegment(unsigned int index, char * ret, unsigned int & len) { - if (index > segmentTableDeque.size()) { - ret = NULL; - len = 0; - return false; - } - ret = getFullPayload(); - for (unsigned int i = 0; i < index; i++) { - ret += segmentTableDeque[i]; - } - len = segmentTableDeque[index]; - return true; - } - - void Page::setMagicNumber() { - if (checkDataSize(4)) { - memcpy(data, "OggS", 4); - } - } - - char Page::getVersion() { - return data[4]; - } - - void Page::setVersion(char newVal) { - if (checkDataSize(5)) { - data[4] = newVal; - } - } - - char Page::getHeaderType() { - return data[5]; - } - - void Page::setHeaderType(char newVal) { - if (checkDataSize(6)) { - data[5] = newVal; - } - } - - long long unsigned int Page::getGranulePosition() { - if (checkDataSize(14)) { - //switching bit order upon return - //return ntohl(((long unsigned*)(data+6))[1]) & ((long long unsigned)((long long unsigned)ntohl(((long unsigned*)(data+6))[0]) << 32)); - //long long unsigned int temp; - //temp = ((long unsigned int)(data+6)[0]); - //temp = temp << 32 + ((long unsigned int)(data+6)[1]); - return get_64(data + 6); - } - return 0; - } - - void Page::setGranulePosition(long long unsigned int newVal) { - if (checkDataSize(14)) { - set_64(data + 6, newVal); - } - } - - long unsigned int Page::getBitstreamSerialNumber() { - //return ntohl(((long unsigned int*)(data+14))[0]); - return get_32(data + 14); - } - - void Page::setBitstreamSerialNumber(long unsigned int newVal) { - if (checkDataSize(18)) { - //((long unsigned *)(data+14))[0] = htonl(newVal); - set_32(data + 14, newVal); - } - } - - long unsigned int Page::getPageSequenceNumber() { - return get_32(data + 18); - } - - void Page::setPageSequenceNumber(long unsigned int newVal) { - if (checkDataSize(22)) { - //((long unsigned *)(data+18))[0] = htonl(newVal); - set_32(data + 18, newVal); - } - } - - long unsigned int Page::getCRCChecksum() { - //return ntohl(((long unsigned int*)(data+22))[0]); - return get_32(data + 22); - } - - void Page::setCRCChecksum(long unsigned int newVal) { - if (checkDataSize(26)) { - set_32(data + 22, newVal); - } - } - - char Page::getPageSegments() { - return data[26]; - } - - inline void Page::setPageSegments(char newVal) { - if (checkDataSize(26)) { - data[26] = newVal; - } - } - - char * Page::getSegmentTable() { - return data + 27; - } - - std::deque & Page::getSegmentTableDeque() { - if (!segmentTableDeque.size()) { - unsigned int temp = 0; - for (unsigned int i = 0; i < getPageSegments(); i++) { - temp += getSegmentTable()[i]; - if (getSegmentTable()[i] < 255) { - segmentTableDeque.push_back(temp); - temp = 0; - } - } - if (temp != 0) { - segmentTableDeque.push_back(temp); - } - } - return segmentTableDeque; - } - - static void STerrMSG() { - DEBUG_MSG(DLVL_ERROR, "Segment too big, create a continue page"); - } - - bool Page::setSegmentTable(std::vector layout) { - dataSum = 0; - for (unsigned int i = 0; i < layout.size(); i++) { - dataSum += layout[i]; - } - unsigned int place = 0; - char table[256]; - for (unsigned int i = 0; i < layout.size(); i++) { - int amount = (layout[i] / 255) + 1; - if (i == layout.size() - 1 && place + amount > (255 + (layout[i] % 255 == 0))) { - STerrMSG(); - return false; - } - memset(table + place, 255, amount - 1); - table[place + amount - 1] = layout[i] % 255; - place += amount; - } - //Don't send element 256, even if it was filled. - if (place > 255) { - place = 255; - } - setPageSegments(place); - setSegmentTable(table, place); - return true; - } - - void Page::setSegmentTable(char * newVal, unsigned int length) { - if (checkDataSize(27 + length)) { - memcpy(data + 27, newVal, length); - } - } - - unsigned long int Page::getPageSize() { - return 27 + getPageSegments() + dataSum; - } - - char * Page::getPage() { - return data; - } - - char * Page::getFullPayload() { - return data + 27 + getPageSegments(); - } - - void Page::setInternalCodec(std::string myCodec) { - codec = myCodec; - } - - std::string Page::toPrettyString(size_t indent) { - std::stringstream r; - r << std::string(indent, ' ') << "Ogg page (" << getPageSize() << ")" << std::endl; - r << std::string(indent + 2, ' ') << "Version: " << (int)getVersion() << std::endl; - r << std::string(indent + 2, ' ') << "Header type:"; - if (!getHeaderType()) { - r << " Normal"; - } else { - if (getHeaderType() & Continued) { - r << " Continued"; - } - if (getHeaderType() & BeginOfStream) { - r << " BeginOfStream"; - } - if (getHeaderType() & EndOfStream) { - r << " EndOfStream"; - } - } - r << " (" << (int)getHeaderType() << ")" << std::endl; - r << std::string(indent + 2, ' ') << "Granule position: " << getGranulePosition() << std::endl; - r << std::string(indent + 2, ' ') << "Bitstream number: " << getBitstreamSerialNumber() << std::endl; - r << std::string(indent + 2, ' ') << "Sequence number: " << getPageSequenceNumber() << std::endl; - r << std::string(indent + 2, ' ') << "Checksum: " << std::hex << getCRCChecksum() << std::dec << std::endl; - //r << " Calced Checksum: " << std::hex << calcChecksum() << std::dec << std::endl; - r << std::string(indent + 2, ' ') << "Payloadsize: " << dataSum << std::endl; - r << std::string(indent + 2, ' ') << (int)getPageSegments() << " segments:" << std::endl; - r << std::string(indent + 3, ' '); - std::deque temp = getSegmentTableDeque(); - for (std::deque::iterator i = temp.begin(); i != temp.end(); i++) { - r << " " << (*i); - } - r << std::endl; - return r.str(); - } - - - long unsigned int Page::calcChecksum() { - long unsigned int retVal = 0; - long unsigned int oldChecksum = getCRCChecksum(); - setCRCChecksum(0); - retVal = checksum::crc32c(0, data, getPageSize()); - setCRCChecksum(oldChecksum); - return retVal; - } - - inline bool Page::checkDataSize(unsigned int size) { - if (size > datasize) { - void * tmp = realloc(data, size); - if (tmp) { - data = (char *)tmp; - datasize = size; - return true; - } else { - return false; - } - } else { - return true; - } - } - - int Page::getPayloadSize() { - return dataSum; - } - - bool Page::clear() { - if (!checkDataSize(27)) { //check if size available in memory - return false; - } - memset(data, 0, 27); - dataSum = 0; - codec = ""; - setMagicNumber(); - segmentTableDeque.clear(); - return true; - } - - bool Page::setPayload(char * newData, unsigned int length) { - if (!checkDataSize(27 + getPageSegments() + length)) { //check if size available in memory - return false; - } - memcpy(data + 27 + getPageSegments(), newData, length); - return true; - } - - void Page::readDTSCVector(std::vector DTSCVec, unsigned int serial, unsigned int sequence) { - clear(); - setVersion(); - if (DTSCVec[0]["OggCont"]) {//if it is a continue page, also for granule=0xFFFFFFFF - setHeaderType(1);//headertype 1 = Continue Page - } else if (DTSCVec[0]["OggEOS"]) { - setHeaderType(4);//headertype 4 = end of stream - } else { - setHeaderType(0);//headertype 0 = normal - } - setGranulePosition(DTSCVec[0]["granule"].asInt()); - for (unsigned int i = 1; i < DTSCVec.size(); i++) { - if (DTSCVec[0]["granule"].asInt() != DTSCVec[i]["granule"].asInt()) { - DEBUG_MSG(DLVL_WARN, "Granule inconcistency!! %u != %u", (unsigned int)DTSCVec[0]["granule"].asInt(), (unsigned int)DTSCVec[i]["granule"].asInt()); - } - if (DTSCVec[0]["trackid"].asInt() != DTSCVec[i]["trackid"].asInt()) { - DEBUG_MSG(DLVL_WARN, "Track ID inconcistency!! %u != %u", (unsigned int)DTSCVec[0]["trackid"].asInt(), (unsigned int)DTSCVec[i]["trackid"].asInt()); - } - } - setBitstreamSerialNumber(serial); - setPageSequenceNumber(sequence); - - std::vector curSegTable; - std::string pageBuffer; - - for (unsigned int i = 0; i < DTSCVec.size(); i++) { - curSegTable.push_back(DTSCVec[i]["data"].asString().size()); - pageBuffer += DTSCVec[i]["data"].asString(); - } - setSegmentTable(curSegTable); - setPayload((char *)pageBuffer.c_str(), pageBuffer.size()); - setCRCChecksum(calcChecksum()); - } - - void headerPages::readDTSCHeader(DTSC::Meta & meta) { - //pages.clear(); - parsedPages = ""; - Page curOggPage; - srand(Util::getMS()); //randomising with milliseconds from boot - std::vector curSegTable; - DTSCID2OGGSerial.clear(); - DTSCID2seqNum.clear(); - //Creating ID headers for theora and vorbis - for (std::map::iterator it = meta.tracks.begin(); it != meta.tracks.end(); it ++) { - curOggPage.clear(); - curOggPage.setVersion(); - curOggPage.setHeaderType(2);//headertype 2 = Begin of Stream - curOggPage.setGranulePosition(0); - DTSCID2OGGSerial[it->second.trackID] = rand() % 0xFFFFFFFE + 1; //initialising on a random not 0 number - curOggPage.setBitstreamSerialNumber(DTSCID2OGGSerial[it->second.trackID]); - DTSCID2seqNum[it->second.trackID] = 0; - curOggPage.setPageSequenceNumber(DTSCID2seqNum[it->second.trackID]++); - curSegTable.clear(); - curSegTable.push_back(it->second.idHeader.size()); - curOggPage.setSegmentTable(curSegTable); - curOggPage.setPayload((char *)it->second.idHeader.c_str(), it->second.idHeader.size()); - curOggPage.setCRCChecksum(curOggPage.calcChecksum()); - //std::cout << std::string(curOggPage.getPage(), curOggPage.getPageSize()); - //pages.push_back(curOggPage); - parsedPages += std::string(curOggPage.getPage(), curOggPage.getPageSize()); - } - //Creating remaining headers for theora and vorbis - //for tracks in header - //create standard page with comment (empty) en setup header(init) - for (std::map::iterator it = meta.tracks.begin(); it != meta.tracks.end(); it ++) { - curOggPage.clear(); - curOggPage.setVersion(); - curOggPage.setHeaderType(0);//headertype 0 = normal - curOggPage.setGranulePosition(0); - curOggPage.setBitstreamSerialNumber(DTSCID2OGGSerial[it->second.trackID]); - curOggPage.setPageSequenceNumber(DTSCID2seqNum[it->second.trackID]++); - curSegTable.clear(); - curSegTable.push_back(it->second.commentHeader.size()); - curSegTable.push_back(it->second.init.size()); - curOggPage.setSegmentTable(curSegTable); - std::string fullHeader = it->second.commentHeader + it->second.init; - curOggPage.setPayload((char *)fullHeader.c_str(), fullHeader.size()); - curOggPage.setCRCChecksum(curOggPage.calcChecksum()); - //std::cout << std::string(curOggPage.getPage(), curOggPage.getPageSize()); - //pages.push_back(curOggPage); - parsedPages += std::string(curOggPage.getPage(), curOggPage.getPageSize()); - } - } -} diff --git a/lib/ogg.h b/lib/ogg.h deleted file mode 100644 index 5447f148..00000000 --- a/lib/ogg.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include "dtsc.h" -#include "theora.h" -#include "vorbis.h" -#include "json.h" -#include "checksum.h" - -namespace OGG { - - enum HeaderType { - Continued = 1, - BeginOfStream = 2, - EndOfStream = 4 - }; - - class Page { - public: - Page(); - ~Page(); - bool read(std::string & newData); - bool read(FILE * inFile); - bool getSegment(unsigned int index, char * data, unsigned int & len); - void setMagicNumber(); - char getVersion(); - void setVersion(char newVal = 0); - char getHeaderType(); - void setHeaderType(char newVal); - long long unsigned int getGranulePosition(); - void setGranulePosition(long long unsigned int newVal); - long unsigned int getBitstreamSerialNumber(); - void setBitstreamSerialNumber(long unsigned int newVal); - long unsigned int getPageSequenceNumber(); - void setPageSequenceNumber(long unsigned int newVal); - long unsigned int getCRCChecksum(); - void setCRCChecksum(long unsigned int newVal); - char getPageSegments(); - inline void setPageSegments(char newVal); - char * getSegmentTable(); - std::deque & getSegmentTableDeque(); - bool setSegmentTable(std::vector layout); - void setSegmentTable(char * newVal, unsigned int length); - char * getPage(); //returns complete page with header - unsigned long int getPageSize(); - char * getFullPayload(); //returns all segments in the page - int getPayloadSize(); - std::string toPrettyString(size_t indent = 0); - void setInternalCodec(std::string myCodec); - long unsigned int calcChecksum(); - bool clear(); - bool setPayload(char * newData, unsigned int length); - void readDTSCVector(std::vector DTSCVec, unsigned int serial, unsigned int sequence); - private: - std::deque segmentTableDeque; - char * data; //pointer to the beginning of the Page data - unsigned int datasize;//size of the allocated memory - unsigned int dataSum;//size of the total segments - bool checkDataSize(unsigned int size); - std::string codec;//codec in the page - }; - - class headerPages { - public: - void readDTSCHeader(DTSC::Meta & meta); - std::map DTSCID2OGGSerial; - std::map DTSCID2seqNum; - std::string parsedPages; - }; -}