Ogg 2 DTSC nearly working
This commit is contained in:
parent
d72b1ebbbf
commit
a0a6e957a5
2 changed files with 102 additions and 49 deletions
|
@ -27,6 +27,9 @@ namespace Analysers{
|
||||||
if (memcmp("theora",oggPage.getFullPayload() + 1,6) == 0){
|
if (memcmp("theora",oggPage.getFullPayload() + 1,6) == 0){
|
||||||
sn2Codec[oggPage.getBitstreamSerialNumber()] = "theora";
|
sn2Codec[oggPage.getBitstreamSerialNumber()] = "theora";
|
||||||
}
|
}
|
||||||
|
if (memcmp("vorbis",oggPage.getFullPayload() + 1,6) == 0){
|
||||||
|
sn2Codec[oggPage.getBitstreamSerialNumber()] = "vorbis";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
oggPage.setInternalCodec(sn2Codec[oggPage.getBitstreamSerialNumber()]);
|
oggPage.setInternalCodec(sn2Codec[oggPage.getBitstreamSerialNumber()]);
|
||||||
std::cout << oggPage.toPrettyString() << std::endl;
|
std::cout << oggPage.toPrettyString() << std::endl;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <mist/dtsc.h>
|
#include <mist/dtsc.h>
|
||||||
#include <mist/ogg.h>
|
#include <mist/ogg.h>
|
||||||
#include <mist/theora.h>
|
#include <mist/theora.h>
|
||||||
|
#include <mist/vorbis.h>
|
||||||
#include <mist/config.h>
|
#include <mist/config.h>
|
||||||
#include <mist/json.h>
|
#include <mist/json.h>
|
||||||
|
|
||||||
|
@ -15,13 +16,14 @@ namespace Converters{
|
||||||
|
|
||||||
class oggTrack{
|
class oggTrack{
|
||||||
public:
|
public:
|
||||||
oggTrack() : lastTime() { }
|
oggTrack() : lastTime(), parsedHeaders(false) { }
|
||||||
codecType codec;
|
codecType codec;
|
||||||
std::string name;
|
std::string name;
|
||||||
long long unsigned int dtscID;
|
long long unsigned int dtscID;
|
||||||
long long unsigned int lastTime;
|
long long unsigned int lastTime;
|
||||||
|
bool parsedHeaders;
|
||||||
//Codec specific elements
|
//Codec specific elements
|
||||||
theora::header idHeader;
|
theora::header idHeader;//needed to determine keyframe
|
||||||
};
|
};
|
||||||
|
|
||||||
int OGG2DTSC(){
|
int OGG2DTSC(){
|
||||||
|
@ -30,13 +32,16 @@ namespace Converters{
|
||||||
//netpacked
|
//netpacked
|
||||||
//Read all of std::cin to oggBuffer
|
//Read all of std::cin to oggBuffer
|
||||||
|
|
||||||
//while stream busy
|
|
||||||
JSON::Value DTSCOut;
|
JSON::Value DTSCOut;
|
||||||
JSON::Value DTSCHeader;
|
JSON::Value DTSCHeader;
|
||||||
DTSCHeader.null();
|
DTSCHeader.null();
|
||||||
DTSCHeader["moreheader"] = 0ll;
|
DTSCHeader["moreheader"] = 0ll;
|
||||||
std::map<long unsigned int, oggTrack> trackData;
|
std::map<long unsigned int, oggTrack> trackData;
|
||||||
long long int lastTrackID = 1;
|
long long int lastTrackID = 1;
|
||||||
|
int headerSeen = 0;
|
||||||
|
bool headerWritten = false;//important bool, used for outputting the simple DTSC header.
|
||||||
|
bool allStreamsSeen = false; //other important bool used for error checking the EOS.
|
||||||
|
//while stream busy
|
||||||
while (std::cin.good()){
|
while (std::cin.good()){
|
||||||
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();
|
||||||
|
@ -47,9 +52,13 @@ namespace Converters{
|
||||||
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;
|
||||||
if (memcmp(oggPage.getFullPayload()+1, "theora", 6) == 0){
|
if (memcmp(oggPage.getFullPayload()+1, "theora", 6) == 0){
|
||||||
|
headerSeen += 1;
|
||||||
|
headerWritten = false;
|
||||||
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){
|
||||||
|
headerSeen += 1;
|
||||||
|
headerWritten = false;
|
||||||
std::cerr << "Snr " << sNum << "=vorbis" << std::endl;
|
std::cerr << "Snr " << sNum << "=vorbis" << std::endl;
|
||||||
trackData[sNum].codec = VORBIS;
|
trackData[sNum].codec = VORBIS;
|
||||||
}else{
|
}else{
|
||||||
|
@ -63,60 +72,101 @@ namespace Converters{
|
||||||
}
|
}
|
||||||
//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
|
int offset = 0;
|
||||||
switch(trackData[sNum].codec){
|
for (std::deque<unsigned int>::iterator it = oggPage.getSegmentTableDeque().begin(); it != oggPage.getSegmentTableDeque().end(); it++){
|
||||||
case THEORA:{
|
if (trackData[sNum].parsedHeaders){
|
||||||
int offset = 0;
|
//todo output segment
|
||||||
theora::header tHead;
|
//output DTSC packet
|
||||||
fprintf(stderr, "Parsing %d elements\n", oggPage.getSegmentTableDeque().size());
|
DTSCOut.null();//clearing DTSC buffer
|
||||||
for (std::deque<unsigned int>::iterator it = oggPage.getSegmentTableDeque().begin(); it != oggPage.getSegmentTableDeque().end(); it++){
|
DTSCOut["trackid"] = (long long)trackData[sNum].dtscID;
|
||||||
fprintf(stderr, "Parsing Snr %u: element of length %d\n", sNum, (*it));
|
long long unsigned int temp = oggPage.getGranulePosition();
|
||||||
if(tHead.read(oggPage.getFullPayload()+offset, (*it))){//if the current segment is a header part
|
DTSCOut["time"] = (long long)trackData[sNum].lastTime ++;
|
||||||
std::cerr << "Theora Header Segment " << tHead.getHeaderType() << std::endl;
|
DTSCOut["data"] = std::string(oggPage.getFullPayload()+offset, (*it)); //segment content put in JSON
|
||||||
//fillDTSC header
|
if (trackData[sNum].codec == THEORA){
|
||||||
switch(tHead.getHeaderType()){
|
if (trackData[sNum].idHeader.parseGranuleLower(temp) == 0){ //granule mask equals zero when on keyframe
|
||||||
case 0:{ //identification header
|
DTSCOut["keyframe"] = 1;
|
||||||
trackData[sNum].idHeader = tHead;
|
}else{
|
||||||
break;
|
DTSCOut["interframe"] = 1;
|
||||||
}
|
|
||||||
case 1: //comment header
|
|
||||||
break;
|
|
||||||
case 2:{ //setup header, also the point to start writing the header
|
|
||||||
std::cout << DTSCHeader.toNetPacked();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{//if the current segment is a movie part
|
|
||||||
//output DTSC packet
|
|
||||||
DTSCOut.null();//clearing DTSC buffer
|
|
||||||
DTSCOut["trackid"] = (long long)trackData[sNum].dtscID;
|
|
||||||
long long unsigned int temp = oggPage.getGranulePosition();
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
offset += (*it);
|
|
||||||
}
|
}
|
||||||
if (trackData[sNum].lastTime != (trackData[sNum].idHeader.parseGranuleUpper(oggPage.getGranulePosition()) + trackData[sNum].idHeader.parseGranuleLower(oggPage.getGranulePosition()))){
|
std::cout << DTSCOut.toNetPacked();
|
||||||
|
}else{
|
||||||
|
//switch on codec
|
||||||
|
switch(trackData[sNum].codec){
|
||||||
|
case THEORA:{
|
||||||
|
theora::header tHead;
|
||||||
|
if(tHead.read(oggPage.getFullPayload()+offset, (*it))){//if the current segment is a Theora header part
|
||||||
|
std::cerr << "Theora Header Segment " << tHead.getHeaderType() << std::endl;
|
||||||
|
//fillDTSC header
|
||||||
|
switch(tHead.getHeaderType()){
|
||||||
|
case 0:{ //identification header
|
||||||
|
std::cerr << "Theora ID header found" << std::endl;
|
||||||
|
trackData[sNum].idHeader = tHead;
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["height"] = (long long)tHead.getPICH();
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["width"] = (long long)tHead.getPICW();
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["theoraID"] = std::string(oggPage.getFullPayload()+offset, (*it));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: //comment header
|
||||||
|
std::cerr << "Theora comment header found" << std::endl;
|
||||||
|
break;
|
||||||
|
case 2:{ //setup header, also the point to start writing the header
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["codec"] = "theora";
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["trackid"] = (long long)trackData[sNum].dtscID;
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["type"] = "video";
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["init"] = std::string(oggPage.getFullPayload()+offset, (*it));
|
||||||
|
headerSeen --;
|
||||||
|
trackData[sNum].parsedHeaders = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{//if the current segment is a movie part
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VORBIS:{
|
||||||
|
vorbis::header vHead;
|
||||||
|
if(vHead.read(oggPage.getFullPayload()+offset, (*it))){//if the current segment is a Theora header part
|
||||||
|
switch(vHead.getHeaderType()){
|
||||||
|
case 1:{
|
||||||
|
std::cerr << "Vorbis ID header" << std::endl;
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["channels"] = (long long)vHead.getAudioChannels();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5:{
|
||||||
|
std::cerr << "Vorbis init header" << std::endl;
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["codec"] = "vorbis";
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["trackid"] = (long long)trackData[sNum].dtscID;
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["type"] = "audio";
|
||||||
|
DTSCHeader["tracks"][trackData[sNum].name]["init"] = std::string(oggPage.getFullPayload()+offset, (*it));
|
||||||
|
headerSeen --;
|
||||||
|
trackData[sNum].parsedHeaders = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//buffer vorbis
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
std::cerr << "Can not handle this codec" << std::endl;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case VORBIS:
|
offset += (*it);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
std::cerr << "Can not handle this codec" << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
std::cerr <<"Error! Unknown bitstream number " << oggPage.getBitstreamSerialNumber() << std::endl;
|
std::cerr <<"Error! Unknown bitstream number " << oggPage.getBitstreamSerialNumber() << std::endl;
|
||||||
}
|
}
|
||||||
|
//write header here
|
||||||
|
if (headerSeen == 0 && headerWritten == false){
|
||||||
|
std::cout << DTSCHeader.toNetPacked();
|
||||||
|
headerWritten = true;
|
||||||
|
}
|
||||||
|
//write section buffer
|
||||||
|
//write section
|
||||||
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);
|
trackData.erase(sNum);
|
||||||
|
|
Loading…
Add table
Reference in a new issue