From f88bee5baf78fb044e176e894505f94de687f61b Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Tue, 25 Jun 2013 16:03:36 +0200 Subject: [PATCH] Basic Theora support working, added a function to the dtsc lib. --- lib/dtsc.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/dtsc.h | 1 + lib/ogg.cpp | 25 ++++++++++++----------- lib/ogg.h | 3 ++- lib/theora.cpp | 17 ++++++++++++++++ lib/theora.h | 3 +++ 6 files changed, 90 insertions(+), 13 deletions(-) diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index 4875c0b6..f13eff08 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -708,6 +708,60 @@ void DTSC::File::seekNext(){ } } + +void DTSC::File::parseNext(){ + if (fread(buffer, 4, 1, F) != 1){ + if (feof(F)){ +#if DEBUG >= 4 + fprintf(stderr, "End of file reached.\n"); +#endif + }else{ + fprintf(stderr, "Could not read header\n"); + } + strbuffer = ""; + jsonbuffer.null(); + return; + } + if (memcmp(buffer, DTSC::Magic_Header, 4) == 0){ + readHeader(lastreadpos); + jsonbuffer = metadata; + return; + } + long long unsigned int version = 0; + if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0){ + version = 1; + } + if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0){ + version = 2; + } + if (version == 0){ + fprintf(stderr, "Invalid packet header @ %#x - %.4s != %.4s\n", lastreadpos, buffer, DTSC::Magic_Packet2); + strbuffer = ""; + jsonbuffer.null(); + return; + } + if (fread(buffer, 4, 1, F) != 1){ + fprintf(stderr, "Could not read size\n"); + strbuffer = ""; + jsonbuffer.null(); + return; + } + uint32_t * ubuffer = (uint32_t *)buffer; + long packSize = ntohl(ubuffer[0]); + strbuffer.resize(packSize); + if (fread((void*)strbuffer.c_str(), packSize, 1, F) != 1){ + fprintf(stderr, "Could not read packet\n"); + strbuffer = ""; + jsonbuffer.null(); + return; + } + if (version == 2){ + jsonbuffer = JSON::fromDTMI2(strbuffer); + }else{ + jsonbuffer = JSON::fromDTMI(strbuffer); + } +} + /// Returns the byte positon of the start of the last packet that was read. long long int DTSC::File::getLastReadPos(){ return lastreadpos; diff --git a/lib/dtsc.h b/lib/dtsc.h index fc2e5d2a..362f1bc3 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -104,6 +104,7 @@ namespace DTSC { long int getBytePos(); bool reachedEOF(); void seekNext(); + void parseNext(); std::string & getPacket(); JSON::Value & getJSON(); JSON::Value & getTrackById(int trackNo); diff --git a/lib/ogg.cpp b/lib/ogg.cpp index 20a26c26..debba28c 100644 --- a/lib/ogg.cpp +++ b/lib/ogg.cpp @@ -46,6 +46,7 @@ namespace OGG{ } bool Page::read(std::string & newData){ + segmentTableDeque.clear(); //datasize = 0; if (newData.size()<27){ return false; @@ -178,18 +179,18 @@ namespace OGG{ return data+27; } - std::deque Page::getSegmentTableDeque(){ - std::deque retVal; - unsigned int temp = 0; - char* segmentTable = getSegmentTable(); - for (unsigned int i = 0; i < getPageSegments(); i++){ - temp += segmentTable[i]; - if (segmentTable[i] < 255){ - retVal.push_back(temp); - temp = 0; + 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; + } } } - return retVal; + return segmentTableDeque; } bool Page::setSegmentTable(std::vector layout){ @@ -272,10 +273,10 @@ namespace OGG{ r << " eos"; } r << std::endl; - r << std::string(indent + 2,' ') << "Granule Position: " < getSegmentTableDeque(); + std::deque & getSegmentTableDeque(); bool setSegmentTable(std::vector layout); void setSegmentTable(char* newVal, unsigned int length); unsigned long int getPageSize(); @@ -40,6 +40,7 @@ namespace OGG{ std::string toPrettyString(size_t indent = 0); void setInternalCodec(std::string myCodec); private: + std::deque segmentTableDeque; long unsigned int calcChecksum(); char* data; unsigned int datasize; diff --git a/lib/theora.cpp b/lib/theora.cpp index 72160062..45b12f0a 100644 --- a/lib/theora.cpp +++ b/lib/theora.cpp @@ -203,6 +203,13 @@ namespace theora{ return commentLen(offset); } + char header::getLFLIMS(size_t index){ + if (getHeaderType() != 2){return 0;} + if (index >= 64){return 0;} + char NBITS = (data[0] >> 5) & 0x07; + return NBITS; + } + std::string header::getUserComment(size_t index){ if (index >= getNComments()){return "";} int len; @@ -244,6 +251,8 @@ namespace theora{ result << std::string(indent+4,' ') << "[" << i << "] " << getUserComment(i) << std::endl; } break; + case 2: + result << std::string(indent+2,' ') << "NBITS: " << (int)getLFLIMS(0) << std::endl; } return result.str(); } @@ -296,6 +305,14 @@ namespace theora{ return 0; } + long long unsigned int header::parseGranuleUpper(long long unsigned int granPos){ + return granPos >> getKFGShift(); + } + + long long unsigned int header::parseGranuleLower(long long unsigned int granPos){ + return (granPos & ((1 << getKFGShift()) - 1)); + } + std::string frame::toPrettyString(size_t indent){ std::stringstream result; result << std::string(indent,' ') << "Theora Frame" << std::endl; diff --git a/lib/theora.h b/lib/theora.h index 6bfdb64f..e3ab70b4 100644 --- a/lib/theora.h +++ b/lib/theora.h @@ -30,7 +30,10 @@ namespace theora{ std::string getVendor(); long unsigned int getNComments(); std::string getUserComment(size_t index); + char getLFLIMS(size_t index); std::string toPrettyString(size_t indent = 0); + long long unsigned int parseGranuleUpper(long long unsigned int granPos); + long long unsigned int parseGranuleLower(long long unsigned int granPos); protected: uint32_t getInt32(size_t index); uint32_t getInt24(size_t index);