From d72b1ebbbf7858cde69dd9a8c00f8626fc1bf01d Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Tue, 25 Jun 2013 16:04:33 +0200 Subject: [PATCH] Updated the ogg2dtsc converter, now updates valid data without header. --- src/converters/ogg2dtsc.cpp | 121 ++++++++++++------------------------ 1 file changed, 39 insertions(+), 82 deletions(-) diff --git a/src/converters/ogg2dtsc.cpp b/src/converters/ogg2dtsc.cpp index 4b0b0fda..64cc3f8a 100644 --- a/src/converters/ogg2dtsc.cpp +++ b/src/converters/ogg2dtsc.cpp @@ -3,7 +3,6 @@ #include #include #include -//#include #include #include #include @@ -14,17 +13,15 @@ namespace Converters{ enum codecType {THEORA, VORBIS}; - struct oggTrack{ - //long unsigned int serialNumber; //serial number in read OGG file - long unsigned int lastSequenceNumber;//error checking for lost pages in OGG - codecType codec; - long long unsigned int dtscID; - long long signed int fpks; //frames per kilo second - char KFGShift; - int width; - int height; - int bps; - DTSC::datatype type; //type of stream in DTSC + class oggTrack{ + public: + oggTrack() : lastTime() { } + codecType codec; + std::string name; + long long unsigned int dtscID; + long long unsigned int lastTime; + //Codec specific elements + theora::header idHeader; }; int OGG2DTSC(){ @@ -44,123 +41,85 @@ namespace Converters{ for (unsigned int i = 0; (i < 1024) && (std::cin.good()); i++){//buffering oggBuffer += std::cin.get(); } - //while OGG::page check functie{ read while (oggPage.read(oggBuffer)){//reading ogg to ogg::page //on succes, we handle one page long unsigned int sNum = oggPage.getBitstreamSerialNumber(); if (oggPage.typeBOS()){//defines a new track std::cerr << "Begin "<< sNum << std::endl; - trackData[sNum].lastSequenceNumber = oggPage.getPageSequenceNumber(); - trackData[sNum].dtscID = lastTrackID++; if (memcmp(oggPage.getFullPayload()+1, "theora", 6) == 0){ - trackData[sNum].type = DTSC::VIDEO; trackData[sNum].codec = THEORA; std::cerr << "Snr " << sNum << "=theora" << std::endl; }else if(memcmp(oggPage.getFullPayload()+1, "vorbis", 6) == 0){ std::cerr << "Snr " << sNum << "=vorbis" << std::endl; trackData[sNum].codec = VORBIS; - trackData[sNum].type = DTSC::AUDIO; }else{ - std::cerr << "Unknown Codec!" << std::endl; + std::cerr << "Unknown Codec, skipping" << std::endl; + continue; } + std::stringstream tID; + tID << "track" << trackData[sNum].dtscID; + trackData[sNum].name = tID.str(); + trackData[sNum].dtscID = lastTrackID++; } //if Serial number is available in mapping if(trackData.find(sNum)!=trackData.end()){ //switch on codec - //oggTrack curTrack = trackData[oggPage.getBitstreamSerialNumber()]; switch(trackData[sNum].codec){ case THEORA:{ - //std::cerr << "Theora" << std::endl; - char* curSeg;//current segment - curSeg = oggPage.getFullPayload();//setting pointer to first segment - std::deque segTable;// - //oggPage.getSegmentTableDeque().swap(segTable); - segTable = oggPage.getSegmentTableDeque(); - unsigned int curPlace = 0; - unsigned int curLength; + int offset = 0; theora::header tHead; - while (!segTable.empty()) { - curLength = segTable.front(); - segTable.pop_front(); - - //std::cerr << curLength << ", " << std::hex << curSeg << std::dec; - if(tHead.read(curSeg+curPlace, curLength)){//if the current segment is a header part + fprintf(stderr, "Parsing %d elements\n", oggPage.getSegmentTableDeque().size()); + for (std::deque::iterator it = oggPage.getSegmentTableDeque().begin(); it != oggPage.getSegmentTableDeque().end(); it++){ + fprintf(stderr, "Parsing Snr %u: element of length %d\n", sNum, (*it)); + if(tHead.read(oggPage.getFullPayload()+offset, (*it))){//if the current segment is a header part std::cerr << "Theora Header Segment " << tHead.getHeaderType() << std::endl; //fillDTSC header switch(tHead.getHeaderType()){ case 0:{ //identification header - std::stringstream tID; - tID << "track" << trackData[sNum].dtscID; - trackData[sNum].fpks = ((long long int)tHead.getFRN() * 1000) / tHead.getFRD(); - DTSCHeader["tracks"][tID.str()]["fpks"] = trackData[sNum].fpks; - DTSCHeader["identification"] = std::string(curSeg+curPlace, curLength); - DTSCHeader["tracks"][tID.str()]["height"] = (long long)tHead.getPICH(); - DTSCHeader["tracks"][tID.str()]["width"] = (long long)tHead.getPICW(); - trackData[sNum].KFGShift = tHead.getKFGShift(); - //std::cerr << trackData[sNum].fpks << std::endl; - break;} + trackData[sNum].idHeader = tHead; + break; + } case 1: //comment header - break; + break; case 2:{ //setup header, also the point to start writing the header - std::stringstream tID; - tID << "track" << trackData[sNum].dtscID; - DTSCHeader["tracks"][tID.str()]["codec"] = "THEORA"; - DTSCHeader["tracks"][tID.str()]["type"] = "video"; - //DTSCHeader["tracks"][tID.str()]["fpks"] = (long long)trackData[sNum].fpks; - DTSCHeader["tracks"][tID.str()]["trackid"] = (long long)trackData[sNum].dtscID; std::cout << DTSCHeader.toNetPacked(); - break;} + break; + } } - }else{//if the current segment is a movie part - //std::cerr << "Theora Movie" << std::endl; //output DTSC packet DTSCOut.null();//clearing DTSC buffer DTSCOut["trackid"] = (long long)trackData[sNum].dtscID; long long unsigned int temp = oggPage.getGranulePosition(); - //std::cerr << std::hex << temp << std::dec << " " << (temp >> trackData[sNum].KFGShift) << " " << (temp & (trackData[sNum].KFGShift * 2 -1)); - //std::cerr << " " << (unsigned int)trackData[sNum].KFGShift << std::endl; - DTSCOut["time"] = (long long)(((temp >> trackData[sNum].KFGShift) + (temp & (trackData[sNum].KFGShift * 2 -1))) * 1000000 / trackData[sNum].fpks); - //std::cerr << DTSCOut["time"].asInt() << std::endl; - //timestamp calculated by frames * FPS. Amount of frames is calculated by: - // granule position using keyframe (bitshift) and distance from keyframe (mask) - DTSCOut["data"] = std::string(curSeg + curPlace, curLength); //segment content put in JSON - if ((temp & (trackData[sNum].KFGShift * 2 -1)) == 0){ //granule mask equals zero when on keyframe + DTSCOut["time"] = (long long)trackData[sNum].lastTime ++; + DTSCOut["data"] = std::string(oggPage.getFullPayload()+offset, (*it)); //segment content put in JSON + if (trackData[sNum].idHeader.parseGranuleLower(temp) == 0){ //granule mask equals zero when on keyframe DTSCOut["keyframe"] = 1; }else{ DTSCOut["interframe"] = 1; } + fprintf(stderr,"Outputting a packet of %d bytes\n", (*it)); std::cout << DTSCOut.toNetPacked(); } - curPlace += curLength; + offset += (*it); } - break; + if (trackData[sNum].lastTime != (trackData[sNum].idHeader.parseGranuleUpper(oggPage.getGranulePosition()) + trackData[sNum].idHeader.parseGranuleLower(oggPage.getGranulePosition()))){ + + } + break; } case VORBIS: - //std::cerr << oggPage.getFullPayload() << " "; - //std::cerr << "Vorbis Page" << std::endl; - break; + break; default: std::cerr << "Can not handle this codec" << std::endl; - break; + break; } - /* - //ogg page 2 DTSC packet - //for every segment - DTSCOut.null();//clearing DTSC buffer - DTSCOut["trackid"] = 1; //video - DTSCOut["trackid"] = 2; //audio - DTSCOut["time"] = 0; //timestamp - DTSCOut["data"] = 0; //segment inhoud - DTSCOut["keyframe"] = "x"; //Aanmaken als eerste segment = keyframe - else DTSCOut["interframe"] = "x"; - //std::cout << "inner" << std::endl; - */ }else{ - std::cerr <<"Error! " << oggPage.getBitstreamSerialNumber() << "unknown bitstream serial number" << std::endl; + std::cerr <<"Error! Unknown bitstream number " << oggPage.getBitstreamSerialNumber() << std::endl; } if (oggPage.typeEOS()){//ending page std::cerr << oggPage.getBitstreamSerialNumber() << " ending" << std::endl; + trackData.erase(sNum); //remove from trackdata } } @@ -170,7 +129,5 @@ namespace Converters{ } int main(int argc, char ** argv){ - //Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); - //conf.parseArgs(argc, argv); return Converters::OGG2DTSC(); }