Updated the ogg2dtsc converter, now updates valid data without header.
This commit is contained in:
parent
4364199f50
commit
d72b1ebbbf
1 changed files with 39 additions and 82 deletions
|
@ -3,7 +3,6 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
//#include <string.h>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mist/dtsc.h>
|
#include <mist/dtsc.h>
|
||||||
#include <mist/ogg.h>
|
#include <mist/ogg.h>
|
||||||
|
@ -14,17 +13,15 @@
|
||||||
namespace Converters{
|
namespace Converters{
|
||||||
enum codecType {THEORA, VORBIS};
|
enum codecType {THEORA, VORBIS};
|
||||||
|
|
||||||
struct oggTrack{
|
class oggTrack{
|
||||||
//long unsigned int serialNumber; //serial number in read OGG file
|
public:
|
||||||
long unsigned int lastSequenceNumber;//error checking for lost pages in OGG
|
oggTrack() : lastTime() { }
|
||||||
codecType codec;
|
codecType codec;
|
||||||
|
std::string name;
|
||||||
long long unsigned int dtscID;
|
long long unsigned int dtscID;
|
||||||
long long signed int fpks; //frames per kilo second
|
long long unsigned int lastTime;
|
||||||
char KFGShift;
|
//Codec specific elements
|
||||||
int width;
|
theora::header idHeader;
|
||||||
int height;
|
|
||||||
int bps;
|
|
||||||
DTSC::datatype type; //type of stream in DTSC
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int OGG2DTSC(){
|
int OGG2DTSC(){
|
||||||
|
@ -44,123 +41,85 @@ namespace Converters{
|
||||||
for (unsigned int i = 0; (i < 1024) && (std::cin.good()); i++){//buffering
|
for (unsigned int i = 0; (i < 1024) && (std::cin.good()); i++){//buffering
|
||||||
oggBuffer += std::cin.get();
|
oggBuffer += std::cin.get();
|
||||||
}
|
}
|
||||||
//while OGG::page check functie{ read
|
|
||||||
while (oggPage.read(oggBuffer)){//reading ogg to ogg::page
|
while (oggPage.read(oggBuffer)){//reading ogg to ogg::page
|
||||||
//on succes, we handle one page
|
//on succes, we handle one page
|
||||||
long unsigned int sNum = oggPage.getBitstreamSerialNumber();
|
long unsigned int sNum = oggPage.getBitstreamSerialNumber();
|
||||||
if (oggPage.typeBOS()){//defines a new track
|
if (oggPage.typeBOS()){//defines a new track
|
||||||
std::cerr << "Begin "<< sNum << std::endl;
|
std::cerr << "Begin "<< sNum << std::endl;
|
||||||
trackData[sNum].lastSequenceNumber = oggPage.getPageSequenceNumber();
|
|
||||||
trackData[sNum].dtscID = lastTrackID++;
|
|
||||||
if (memcmp(oggPage.getFullPayload()+1, "theora", 6) == 0){
|
if (memcmp(oggPage.getFullPayload()+1, "theora", 6) == 0){
|
||||||
trackData[sNum].type = DTSC::VIDEO;
|
|
||||||
trackData[sNum].codec = THEORA;
|
trackData[sNum].codec = THEORA;
|
||||||
std::cerr << "Snr " << sNum << "=theora" << std::endl;
|
std::cerr << "Snr " << sNum << "=theora" << std::endl;
|
||||||
}else if(memcmp(oggPage.getFullPayload()+1, "vorbis", 6) == 0){
|
}else if(memcmp(oggPage.getFullPayload()+1, "vorbis", 6) == 0){
|
||||||
std::cerr << "Snr " << sNum << "=vorbis" << std::endl;
|
std::cerr << "Snr " << sNum << "=vorbis" << std::endl;
|
||||||
trackData[sNum].codec = VORBIS;
|
trackData[sNum].codec = VORBIS;
|
||||||
trackData[sNum].type = DTSC::AUDIO;
|
|
||||||
}else{
|
}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 Serial number is available in mapping
|
||||||
if(trackData.find(sNum)!=trackData.end()){
|
if(trackData.find(sNum)!=trackData.end()){
|
||||||
//switch on codec
|
//switch on codec
|
||||||
//oggTrack curTrack = trackData[oggPage.getBitstreamSerialNumber()];
|
|
||||||
switch(trackData[sNum].codec){
|
switch(trackData[sNum].codec){
|
||||||
case THEORA:{
|
case THEORA:{
|
||||||
//std::cerr << "Theora" << std::endl;
|
int offset = 0;
|
||||||
char* curSeg;//current segment
|
|
||||||
curSeg = oggPage.getFullPayload();//setting pointer to first segment
|
|
||||||
std::deque<unsigned int> segTable;//
|
|
||||||
//oggPage.getSegmentTableDeque().swap(segTable);
|
|
||||||
segTable = oggPage.getSegmentTableDeque();
|
|
||||||
unsigned int curPlace = 0;
|
|
||||||
unsigned int curLength;
|
|
||||||
theora::header tHead;
|
theora::header tHead;
|
||||||
while (!segTable.empty()) {
|
fprintf(stderr, "Parsing %d elements\n", oggPage.getSegmentTableDeque().size());
|
||||||
curLength = segTable.front();
|
for (std::deque<unsigned int>::iterator it = oggPage.getSegmentTableDeque().begin(); it != oggPage.getSegmentTableDeque().end(); it++){
|
||||||
segTable.pop_front();
|
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 << curLength << ", " << std::hex << curSeg << std::dec;
|
|
||||||
if(tHead.read(curSeg+curPlace, curLength)){//if the current segment is a header part
|
|
||||||
std::cerr << "Theora Header Segment " << tHead.getHeaderType() << std::endl;
|
std::cerr << "Theora Header Segment " << tHead.getHeaderType() << std::endl;
|
||||||
//fillDTSC header
|
//fillDTSC header
|
||||||
switch(tHead.getHeaderType()){
|
switch(tHead.getHeaderType()){
|
||||||
case 0:{ //identification header
|
case 0:{ //identification header
|
||||||
std::stringstream tID;
|
trackData[sNum].idHeader = tHead;
|
||||||
tID << "track" << trackData[sNum].dtscID;
|
break;
|
||||||
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;}
|
|
||||||
case 1: //comment header
|
case 1: //comment header
|
||||||
break;
|
break;
|
||||||
case 2:{ //setup header, also the point to start writing the header
|
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();
|
std::cout << DTSCHeader.toNetPacked();
|
||||||
break;}
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}else{//if the current segment is a movie part
|
}else{//if the current segment is a movie part
|
||||||
//std::cerr << "Theora Movie" << std::endl;
|
|
||||||
//output DTSC packet
|
//output DTSC packet
|
||||||
DTSCOut.null();//clearing DTSC buffer
|
DTSCOut.null();//clearing DTSC buffer
|
||||||
DTSCOut["trackid"] = (long long)trackData[sNum].dtscID;
|
DTSCOut["trackid"] = (long long)trackData[sNum].dtscID;
|
||||||
long long unsigned int temp = oggPage.getGranulePosition();
|
long long unsigned int temp = oggPage.getGranulePosition();
|
||||||
//std::cerr << std::hex << temp << std::dec << " " << (temp >> trackData[sNum].KFGShift) << " " << (temp & (trackData[sNum].KFGShift * 2 -1));
|
DTSCOut["time"] = (long long)trackData[sNum].lastTime ++;
|
||||||
//std::cerr << " " << (unsigned int)trackData[sNum].KFGShift << std::endl;
|
DTSCOut["data"] = std::string(oggPage.getFullPayload()+offset, (*it)); //segment content put in JSON
|
||||||
DTSCOut["time"] = (long long)(((temp >> trackData[sNum].KFGShift) + (temp & (trackData[sNum].KFGShift * 2 -1))) * 1000000 / trackData[sNum].fpks);
|
if (trackData[sNum].idHeader.parseGranuleLower(temp) == 0){ //granule mask equals zero when on keyframe
|
||||||
//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["keyframe"] = 1;
|
DTSCOut["keyframe"] = 1;
|
||||||
}else{
|
}else{
|
||||||
DTSCOut["interframe"] = 1;
|
DTSCOut["interframe"] = 1;
|
||||||
}
|
}
|
||||||
|
fprintf(stderr,"Outputting a packet of %d bytes\n", (*it));
|
||||||
std::cout << DTSCOut.toNetPacked();
|
std::cout << DTSCOut.toNetPacked();
|
||||||
}
|
}
|
||||||
curPlace += curLength;
|
offset += (*it);
|
||||||
|
}
|
||||||
|
if (trackData[sNum].lastTime != (trackData[sNum].idHeader.parseGranuleUpper(oggPage.getGranulePosition()) + trackData[sNum].idHeader.parseGranuleLower(oggPage.getGranulePosition()))){
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VORBIS:
|
case VORBIS:
|
||||||
//std::cerr << oggPage.getFullPayload() << " ";
|
|
||||||
//std::cerr << "Vorbis Page" << std::endl;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "Can not handle this codec" << std::endl;
|
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{
|
}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
|
if (oggPage.typeEOS()){//ending page
|
||||||
std::cerr << oggPage.getBitstreamSerialNumber() << " ending" << std::endl;
|
std::cerr << oggPage.getBitstreamSerialNumber() << " ending" << std::endl;
|
||||||
|
trackData.erase(sNum);
|
||||||
//remove from trackdata
|
//remove from trackdata
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,7 +129,5 @@ namespace Converters{
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv){
|
int main(int argc, char ** argv){
|
||||||
//Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION);
|
|
||||||
//conf.parseArgs(argc, argv);
|
|
||||||
return Converters::OGG2DTSC();
|
return Converters::OGG2DTSC();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue