Merge branch 'development' into LTS_development

This commit is contained in:
Thulinma 2017-05-13 23:43:06 +02:00
commit 3cba6f011f
5 changed files with 78 additions and 18 deletions

View file

@ -504,6 +504,8 @@ namespace OGG {
tempGranule = (currentSegment.lastKeyFrameSeen << split) | currentSegment.framesSinceKeyFrame;
} else if (codec == OGG::VORBIS){
tempGranule = currentSegment.lastKeyFrameSeen;
} else if (codec == OGG::OPUS){
tempGranule = currentSegment.timeStamp*48;
}
return tempGranule;
}

View file

@ -2,11 +2,42 @@
#include <sstream>
namespace Opus{
unsigned int Opus_getDuration(const char *part){
const char config = part[0] >> 3;
const char code = part[0] & 3;
double dur = 0;
if (config < 14){
switch (config % 4){
case 0: dur = 10; break;
case 1: dur = 20; break;
case 2: dur = 40; break;
case 3: dur = 60; break;
}
} else if (config < 16){
if (config % 2 == 0){
dur = 10;
}else{
dur = 20;
}
} else {
switch (config % 4){
case 0: dur = 2.5; break;
case 1: dur = 5; break;
case 2: dur = 10; break;
case 3: dur = 20; break;
}
}
if (code == 0){return (unsigned int)dur;}
if (code < 3){return (unsigned int)(dur*2);}
return (unsigned int)(dur*(part[1] & 63));
}
std::string Opus_prettyPacket(const char *part, int len){
if (len < 1){return "Invalid packet (0 byte length)";}
std::stringstream r;
char config = part[0] >> 3;
char code = part[0] & 3;
const char config = part[0] >> 3;
const char code = part[0] & 3;
if ((part[0] & 4) == 4){
r << "Stereo, ";
}else{

View file

@ -1,6 +1,7 @@
#include <string>
namespace Opus{
unsigned int Opus_getDuration(const char *part);
std::string Opus_prettyPacket(const char *part, int len);
}

View file

@ -9,6 +9,7 @@
#include <mist/ogg.h>
#include <mist/defines.h>
#include <mist/bitstream.h>
#include <mist/opus.h>
#include "input_ogg.h"
///\todo Whar be Opus support?
@ -49,6 +50,7 @@ namespace Mist {
capa["source_match"] = "/*.ogg";
capa["codecs"][0u][0u].append("theora");
capa["codecs"][0u][1u].append("vorbis");
capa["codecs"][0u][1u].append("opus");
}
bool inputOGG::setup(){
@ -73,10 +75,7 @@ namespace Mist {
theora::header tmpHead((char*)bosPage.getSegment(0), bosPage.getSegmentLen(0));
oggTracks[tid].codec = OGG::THEORA;
oggTracks[tid].msPerFrame = (double)(tmpHead.getFRD() * 1000) / (double)tmpHead.getFRN(); //this should be: 1000/( tmpHead.getFRN()/ tmpHead.getFRD() )
DEBUG_MSG(DLVL_DEVEL, "theora trackID: %u msperFrame %f ", tid, oggTracks[tid].msPerFrame);
oggTracks[tid].KFGShift = tmpHead.getKFGShift(); //store KFGShift for granule calculations
DEVEL_MSG("read theora header size: %d, tid: %u", tmpHead.datasize, tid);
myMeta.tracks[tid].type = "video";
myMeta.tracks[tid].codec = "theora";
myMeta.tracks[tid].trackID = tid;
@ -88,6 +87,7 @@ namespace Mist {
myMeta.tracks[tid].init += (char)(bosPage.getPayloadSize() & 0xFF);
myMeta.tracks[tid].init.append(bosPage.getSegment(0), bosPage.getSegmentLen(0));
}
INFO_MSG("Track %lu is %s", tid, myMeta.tracks[tid].codec.c_str());
}
if (memcmp(bosPage.getSegment(0) + 1, "vorbis", 6) == 0){
vorbis::header tmpHead((char*)bosPage.getSegment(0), bosPage.getSegmentLen(0));
@ -106,6 +106,17 @@ namespace Mist {
myMeta.tracks[tid].rate = tmpHead.getAudioSampleRate();
myMeta.tracks[tid].trackID = tid;
myMeta.tracks[tid].channels = tmpHead.getAudioChannels();
INFO_MSG("Track %lu is %s", tid, myMeta.tracks[tid].codec.c_str());
}
if (memcmp(bosPage.getSegment(0), "OpusHead", 8) == 0){
oggTracks[tid].codec = OGG::OPUS;
myMeta.tracks[tid].type = "audio";
myMeta.tracks[tid].codec = "opus";
myMeta.tracks[tid].rate = 48000;
myMeta.tracks[tid].trackID = tid;
myMeta.tracks[tid].init.assign(bosPage.getSegment(0), bosPage.getSegmentLen(0));
myMeta.tracks[tid].channels = myMeta.tracks[tid].init[9];
INFO_MSG("Track %lu is %s", tid, myMeta.tracks[tid].codec.c_str());
}
}
@ -134,19 +145,14 @@ namespace Mist {
// INFO_MSG("tid: %d",tid);
//Parsing headers
// INFO_MSG("parsing headers for tid: %d",tid);
///\todo make sure the header is ffmpeg compatible
if (myMeta.tracks[tid].codec == "theora"){
// INFO_MSG("theora");
for (unsigned int i = 0; i < myPage.getAllSegments().size(); i++){
unsigned long len = myPage.getSegmentLen(i);
INFO_MSG("Length for segment %d: %lu", i, len);
theora::header tmpHead((char*)myPage.getSegment(i),len);
if (!tmpHead.isHeader()){ //not copying the header anymore, should this check isHeader?
DEBUG_MSG(DLVL_FAIL, "Theora Header read failed!");
return false;
}
DEBUG_MSG(DLVL_WARN, "Theora header, type %d", tmpHead.getHeaderType());
switch (tmpHead.getHeaderType()){
//Case 0 is being handled by parseBeginOfStream
case 1: {
@ -167,7 +173,7 @@ namespace Mist {
}
}
if (myMeta.tracks[tid].codec == "vorbis"){
if (myMeta.tracks[tid].codec == "vorbis"){
for (unsigned int i = 0; i < myPage.getAllSegments().size(); i++){
unsigned long len = myPage.getSegmentLen(i);
vorbis::header tmpHead((char*)myPage.getSegment(i), len);
@ -175,7 +181,6 @@ namespace Mist {
DEBUG_MSG(DLVL_FAIL, "Header read failed!");
return false;
}
DEBUG_MSG(DLVL_WARN, "Vorbis header, type %d", tmpHead.getHeaderType());
switch (tmpHead.getHeaderType()){
//Case 1 is being handled by parseBeginOfStream
case 3: {
@ -205,10 +210,14 @@ namespace Mist {
}
}
}
if (myMeta.tracks[tid].codec == "opus"){
oggTracks[tid].parsedHeaders = true;
}
}
for (std::map<long unsigned int, OGG::oggTrack>::iterator it = oggTracks.begin(); it != oggTracks.end(); it++){
fseek(inFile, 0, SEEK_SET);
INFO_MSG("Finding first data for track %lu", it->first);
position tmp = seekFirstData(it->first);
if (tmp.trackID){
currentPositions.insert(tmp);
@ -250,6 +259,11 @@ namespace Mist {
quitloop = false;
continue;
}
if (oggTracks[tid].codec == OGG::OPUS){
if (std::string(oggTracks[tid].myPage.getSegment(0), 2) == "Op"){
quitloop = false;
}
}
if (oggTracks[tid].codec == OGG::VORBIS){
vorbis::header tmpHead((char*)oggTracks[tid].myPage.getSegment(0), oggTracks[tid].myPage.getSegmentLen(0));
if (tmpHead.isHeader()){
@ -351,6 +365,10 @@ namespace Mist {
// INFO_MSG("thisTime: %d", thisPacket.getTime());
}
curPos.time += oggTracks[thisSegment.tid].msPerFrame;
} else if (oggTracks[thisSegment.tid].codec == OGG::OPUS){
if (thisSegment.parts.size()){
curPos.time += Opus::Opus_getDuration(thisSegment.parts.front().data());
}
}
if (readFullPacket){
currentPositions.insert(curPos);
@ -362,6 +380,9 @@ namespace Mist {
case OGG::VORBIS:
return granule * oggTracks[tid].msPerFrame ; //= samples * samples per second
break;
case OGG::OPUS:
return granule / 48; //always 48kHz
break;
case OGG::THEORA:{
long long unsigned int parseGranuleUpper = granule >> oggTracks[tid].KFGShift ;
long long unsigned int parseGranuleLower = (granule & ((1 << oggTracks[tid].KFGShift) - 1));

View file

@ -133,8 +133,8 @@ namespace Mist {
OGG::oggSegment newSegment;
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
parseInit(myMeta.tracks[*it].init, initData[*it]);
if (myMeta.tracks[*it].codec == "theora"){ //get size and position of init data for this page.
parseInit(myMeta.tracks[*it].init, initData[*it]);
pageBuffer[*it].codec = OGG::THEORA;
pageBuffer[*it].totalFrames = 1; //starts at frame number 1, according to weird offDetectMeta function.
std::string tempStr = initData[*it][0];
@ -142,6 +142,7 @@ namespace Mist {
pageBuffer[*it].split = tempHead.getKFGShift();
INFO_MSG("got theora KFG shift: %d", pageBuffer[*it].split); //looks OK.
} else if (myMeta.tracks[*it].codec == "vorbis"){
parseInit(myMeta.tracks[*it].init, initData[*it]);
pageBuffer[*it].codec = OGG::VORBIS;
pageBuffer[*it].totalFrames = 0;
pageBuffer[*it].sampleRate = myMeta.tracks[*it].rate;
@ -155,17 +156,21 @@ namespace Mist {
} else if (myMeta.tracks[*it].codec == "opus"){
pageBuffer[*it].totalFrames = 0; //?
pageBuffer[*it].codec = OGG::OPUS;
initData[*it].push_back(myMeta.tracks[*it].init);
initData[*it].push_back(std::string("OpusTags\000\000\000\012MistServer\000\000\000\000", 26));
}
pageBuffer[*it].clear(OGG::BeginOfStream, 0, *it, 0); //CREATES a (map)pageBuffer object, *it = id, pagetype=BOS
newSegment.dataString = initData[*it][0];
newSegment.dataString = initData[*it].front();
initData[*it].pop_front();
pageBuffer[*it].oggSegments.push_back(newSegment);
pageBuffer[*it].sendTo(myConn, 0); //granule position of 0
}
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
newSegment.dataString = initData[*it][1];
pageBuffer[*it].oggSegments.push_back(newSegment);
newSegment.dataString = initData[*it][2];
pageBuffer[*it].oggSegments.push_back(newSegment);
while (initData[*it].size()){
newSegment.dataString = initData[*it].front();
initData[*it].pop_front();
pageBuffer[*it].oggSegments.push_back(newSegment);
}
while (pageBuffer[*it].oggSegments.size()){
pageBuffer[*it].sendTo(myConn, 0); //granule position of 0
}