Merge branch 'development' into LTS_development
This commit is contained in:
commit
3cba6f011f
5 changed files with 78 additions and 18 deletions
|
@ -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;
|
||||
}
|
||||
|
|
35
lib/opus.cpp
35
lib/opus.cpp
|
@ -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{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <string>
|
||||
|
||||
namespace Opus{
|
||||
unsigned int Opus_getDuration(const char *part);
|
||||
std::string Opus_prettyPacket(const char *part, int len);
|
||||
}
|
||||
|
||||
|
|
|
@ -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: {
|
||||
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue