Merge branch 'development' into LTS_development

# Conflicts:
#	lib/mp4.cpp
#	lib/mp4_generic.cpp
#	lib/mp4_generic.h
This commit is contained in:
Thulinma 2015-09-03 22:03:24 +02:00
commit f562369db2
9 changed files with 238 additions and 106 deletions

View file

@ -322,6 +322,7 @@ namespace DTSC {
unsigned int timeToFragnum(unsigned int timestamp); unsigned int timeToFragnum(unsigned int timestamp);
void reset(); void reset();
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0); void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
void finalize();
std::string getIdentifier(); std::string getIdentifier();
std::string getWritableIdentifier(); std::string getWritableIdentifier();

View file

@ -1224,6 +1224,10 @@ namespace DTSC {
fragments.rbegin()->setSize(fragments.rbegin()->getSize() + packDataSize); fragments.rbegin()->setSize(fragments.rbegin()->getSize() + packDataSize);
} }
void Track::finalize(){
keys.rbegin()->setLength(lastms - keys.rbegin()->getTime() + parts.rbegin()->getDuration());
}
///\brief Returns a key given its number, or an empty key if the number is out of bounds ///\brief Returns a key given its number, or an empty key if the number is out of bounds
Key & Track::getKey(unsigned int keyNum) { Key & Track::getKey(unsigned int keyNum) {
static Key empty; static Key empty;

View file

@ -409,6 +409,10 @@ namespace MP4 {
case 0x75756964: case 0x75756964:
return ((UUID *)this)->toPrettyString(indent); return ((UUID *)this)->toPrettyString(indent);
break; break;
case 0x70617370:
return ((PASP*)this)->toPrettyString(indent);
break;
/*LTS-START*/
case 0x73696478: case 0x73696478:
return ((SIDX*)this)->toPrettyString(indent); return ((SIDX*)this)->toPrettyString(indent);
break; break;
@ -418,7 +422,6 @@ namespace MP4 {
case 0x696F6473: case 0x696F6473:
return ((IODS*)this)->toPrettyString(indent); return ((IODS*)this)->toPrettyString(indent);
break; break;
/*LTS-START*/
case 0x73696E66: case 0x73696E66:
return ((SINF *)this)->toPrettyString(indent); return ((SINF *)this)->toPrettyString(indent);
break; break;

View file

@ -950,9 +950,10 @@ namespace MP4 {
char * p = getData(); char * p = getData();
char * max_p = p + getDataSize(); char * max_p = p + getDataSize();
r << std::string(indent+1, ' ') << "ES ID: " << (unsigned int)(((unsigned int)p[0] << 8) | (unsigned int)p[1]) << std::endl; r << std::string(indent+1, ' ') << "ES ID: " << (unsigned int)(((unsigned int)p[0] << 8) | (unsigned int)p[1]) << std::endl;
bool dep = (p[2] & 0x80); bool dep = (p[2] & 0x80);//check pagina 28 ISO 1449-1 2001
bool url = (p[2] & 0x40); bool url = (p[2] & 0x40);
bool ocr = (p[2] & 0x20); bool ocr = (p[2] & 0x20);
//6 & 86
r << std::string(indent+1, ' ') << "Priority: " << int(p[2] & 0x1f) << std::endl; r << std::string(indent+1, ' ') << "Priority: " << int(p[2] & 0x1f) << std::endl;
p += 3; p += 3;
if (dep){ if (dep){
@ -1093,7 +1094,7 @@ namespace MP4 {
ESDS::ESDS(std::string init) { ESDS::ESDS(std::string init) {
///\todo Do this better, in a non-hardcoded way. ///\todo Do this better, in a non-hardcoded way.
memcpy(data + 4, "esds", 4); memcpy(data + 4, "esds", 4);
reserve(payloadOffset, 0, init.size() ? init.size()+29 : 26); reserve(payloadOffset, 0, init.size() ? init.size()+28 : 26);
unsigned int i = 12; unsigned int i = 12;
data[i++] = 3;//ES_DescrTag data[i++] = 3;//ES_DescrTag
data[i++] = init.size() ? init.size()+23 : 21;//size data[i++] = init.size() ? init.size()+23 : 21;//size
@ -1127,7 +1128,7 @@ namespace MP4 {
} }
data[i++] = 6;//SLConfigDescriptor data[i++] = 6;//SLConfigDescriptor
data[i++] = 1;//size data[i++] = 1;//size
data[i++] = 2;//predefined, reserverd for use in MP4 files data[i++] = 2;//predefined, reserved for use in MP4 files
} }
bool ESDS::isAAC(){ bool ESDS::isAAC(){
@ -1153,9 +1154,35 @@ namespace MP4 {
return r.str(); return r.str();
} }
DAC3::DAC3(){ DAC3::DAC3(unsigned int rate, unsigned int channels){
memcpy(data + 4, "dac3", 4); memcpy(data + 4, "dac3", 4);
setInt24(0,0); setInt24(0,0);
setBitStreamIdentification(8);///\todo This is right now a default value. check the docs, this is a weird property
setBitStreamMode(0);//main, mixed audio
setAudioConfigMode(2);
switch (rate) {
case 48000:
setSampleRateCode(0);
break;
case 44100:
setSampleRateCode(1);
break;
case 32000:
setSampleRateCode(2);
break;
default:
setSampleRateCode(3);
break;
}
if (channels > 4) {
setLowFrequencyEffectsChannelOn(1);
} else {
setLowFrequencyEffectsChannelOn(0);
}
setFrameSizeCode(20);//should be OK, but test this.
} }
char DAC3::getSampleRateCode(){ char DAC3::getSampleRateCode(){
@ -1222,11 +1249,12 @@ namespace MP4 {
memcpy(data + 4, "ftyp", 4); memcpy(data + 4, "ftyp", 4);
if (fillDefaults){ if (fillDefaults){
setMajorBrand("isom"); setMajorBrand("isom");
setMinorVersion("Mist"); setMinorVersion("\000\000\002\000");
setCompatibleBrands("isom",0); setCompatibleBrands("isom",0);
setCompatibleBrands("iso2",1); setCompatibleBrands("iso2",1);
setCompatibleBrands("avc1",2); setCompatibleBrands("avc1",2);
setCompatibleBrands("mp41",2); setCompatibleBrands("mp41",3);
setCompatibleBrands("Mist",4);
} }
} }
@ -1317,9 +1345,9 @@ namespace MP4 {
memcpy(data + 4, "mvex", 4); memcpy(data + 4, "mvex", 4);
} }
TREX::TREX() { TREX::TREX(unsigned int trackId){
memcpy(data + 4, "trex", 4); memcpy(data + 4, "trex", 4);
setTrackID(0); setTrackID(trackId);
setDefaultSampleDescriptionIndex(1); setDefaultSampleDescriptionIndex(1);
setDefaultSampleDuration(0); setDefaultSampleDuration(0);
setDefaultSampleSize(0); setDefaultSampleSize(0);
@ -1727,7 +1755,7 @@ namespace MP4 {
memcpy(data + 4, "mvhd", 4); memcpy(data + 4, "mvhd", 4);
//reserve an entire version 0 box //reserve an entire version 0 box
if (!reserve(0, 8, 108)) { if (!reserve(0, 9, 108)) {
return;//on fail, cancel all the things return;//on fail, cancel all the things
} }
memset(data + payloadOffset, 0, 100); //set all bytes (108 - 8) to zeroes memset(data + payloadOffset, 0, 100); //set all bytes (108 - 8) to zeroes
@ -2108,26 +2136,41 @@ namespace MP4 {
return r.str(); return r.str();
} }
TKHD::TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height) { TKHD::TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height) {
initialize();
setTrackID(trackId);
setDuration(duration);
setWidth(width << 16);
setHeight(height << 16);
}
TKHD::TKHD(DTSC::Track & track, bool fragmented) {
initialize();
setTrackID(track.trackID);
setDuration(-1);
if (!fragmented) {
setDuration(track.lastms - track.firstms);
}
if (track.type == "video") {
setWidth(track.width << 16);
setHeight(track.height << 16);
}
}
void TKHD::initialize(){
memcpy(data + 4, "tkhd", 4); memcpy(data + 4, "tkhd", 4);
//reserve an entire version 0 box //reserve an entire version 0 box
if (!reserve(0, 8, 92)) { if (!reserve(0, 9, 92)) {
return;//on fail, cancel all the things return;//on fail, cancel all the things
} }
memset(data + payloadOffset, 0, 84); //set all bytes (92 - 8) to zeroes memset(data + payloadOffset, 0, 84); //set all bytes (92 - 8) to zeroes
setFlags(3);//ENABLED | IN_MOVIE
setFlags(15);//ENABLED | IN_MOVIE | IN_PREVIEW | IN_POSTER
setTrackID(trackId);
setDuration(duration);
if (width == 0 || height == 0) {
setVolume(0x0100);
}
setMatrix(0x00010000, 0); setMatrix(0x00010000, 0);
setMatrix(0x00010000, 4); setMatrix(0x00010000, 4);
setMatrix(0x40000000, 8); setMatrix(0x40000000, 8);
setWidth(width << 16); setVolume(0x0100);
setHeight(height << 16);
} }
void TKHD::setCreationTime(uint64_t newCreationTime) { void TKHD::setCreationTime(uint64_t newCreationTime) {
@ -2325,7 +2368,7 @@ namespace MP4 {
MDHD::MDHD(uint64_t duration) { MDHD::MDHD(uint64_t duration) {
memcpy(data + 4, "mdhd", 4); memcpy(data + 4, "mdhd", 4);
//reserve an entire version 0 box //reserve an entire version 0 box
if (!reserve(0, 8, 32)) { if (!reserve(0, 9, 32)) {
return;//on fail, cancel all the things return;//on fail, cancel all the things
} }
memset(data + payloadOffset, 0, 24); //set all bytes (32 - 8) to zeroes memset(data + payloadOffset, 0, 24); //set all bytes (32 - 8) to zeroes
@ -2529,6 +2572,12 @@ namespace MP4 {
} }
STSCEntry::STSCEntry(unsigned int _first, unsigned int _count, unsigned int _index){
firstChunk = _first;
samplesPerChunk = _count;
sampleDescriptionIndex = _index;
}
STSC::STSC(char v, uint32_t f) { STSC::STSC(char v, uint32_t f) {
memcpy(data + 4, "stsc", 4); memcpy(data + 4, "stsc", 4);
setVersion(v); setVersion(v);
@ -2853,6 +2902,8 @@ namespace MP4 {
PASP::PASP() { PASP::PASP() {
memcpy(data + 4, "pasp", 4); memcpy(data + 4, "pasp", 4);
setHSpacing(1);
setVSpacing(1);
} }
void PASP::setHSpacing(uint32_t newVal) { void PASP::setHSpacing(uint32_t newVal) {
@ -2880,6 +2931,25 @@ namespace MP4 {
} }
VisualSampleEntry::VisualSampleEntry() { VisualSampleEntry::VisualSampleEntry() {
initialize();
}
VisualSampleEntry::VisualSampleEntry(DTSC::Track & track){
initialize();
setDataReferenceIndex(1);
setWidth(track.width);
setHeight(track.height);
if (track.codec == "H264") {
setCodec("avc1");
MP4::AVCC avccBox;
avccBox.setPayload(track.init);
setCLAP(avccBox);
}
MP4::PASP paspBox;
setPASP(paspBox);
}
void VisualSampleEntry::initialize(){
memcpy(data + 4, "erro", 4); memcpy(data + 4, "erro", 4);
setHorizResolution(0x00480000); setHorizResolution(0x00480000);
setVertResolution(0x00480000); setVertResolution(0x00480000);
@ -2933,7 +3003,9 @@ namespace MP4 {
} }
void VisualSampleEntry::setCompressorName(std::string newCompressorName) { void VisualSampleEntry::setCompressorName(std::string newCompressorName) {
newCompressorName.resize(32, ' '); if (newCompressorName.size() > 32){
newCompressorName.resize(32, ' ');
}
setString(newCompressorName, 42); setString(newCompressorName, 42);
} }
@ -2962,6 +3034,15 @@ namespace MP4 {
return ret; return ret;
} }
void VisualSampleEntry::setPASP(Box & pasp) {
int writePlace = 78;
Box tmpBox = getBox(78);
if (tmpBox.getType () != "erro"){
writePlace = 78 + getBoxLen(78);
}
setBox(pasp, writePlace);
}
Box & VisualSampleEntry::getPASP() { Box & VisualSampleEntry::getPASP() {
static Box ret = Box((char *)"\000\000\000\010erro", false); static Box ret = Box((char *)"\000\000\000\010erro", false);
if (payloadSize() < 84) { //if the EntryBox is not big enough to hold a CLAP/PASP if (payloadSize() < 84) { //if the EntryBox is not big enough to hold a CLAP/PASP
@ -2996,6 +3077,31 @@ namespace MP4 {
} }
AudioSampleEntry::AudioSampleEntry() { AudioSampleEntry::AudioSampleEntry() {
initialize();
}
AudioSampleEntry::AudioSampleEntry(DTSC::Track & track) {
initialize();
if (track.codec == "AAC" || track.codec == "MP3") {
setCodec("mp4a");
}
if (track.codec == "AC3") {
setCodec("ac-3");
}
setDataReferenceIndex(1);
setSampleRate(track.rate);
setChannelCount(track.channels);
setSampleSize(track.size);
if (track.codec == "AC3") {
MP4::DAC3 dac3Box(track.rate, track.channels);
setCodecBox(dac3Box);
} else { //other codecs use the ESDS box
MP4::ESDS esdsBox(track.init);
setCodecBox(esdsBox);
}
}
void AudioSampleEntry::initialize() {
memcpy(data + 4, "erro", 4); memcpy(data + 4, "erro", 4);
setChannelCount(2); setChannelCount(2);
setSampleSize(16); setSampleSize(16);
@ -3282,67 +3388,75 @@ namespace MP4 {
memcpy(data + 4, "elst", 4); memcpy(data + 4, "elst", 4);
} }
void ELST::setCount(uint32_t newVal){
setInt32(newVal, 4);
}
uint32_t ELST::getCount(){
return getInt32(4);
}
void ELST::setSegmentDuration(uint64_t newVal) { void ELST::setSegmentDuration(uint64_t newVal) {
if (getVersion() == 1) { if (getVersion() == 1) {
setInt64(newVal, 4); setInt64(newVal, 8);
} else {
setInt32(newVal, 4);
}
}
uint64_t ELST::getSegmentDuration() {
if (getVersion() == 1) {
return getInt64(4);
} else {
return getInt32(4);
}
}
void ELST::setMediaTime(uint64_t newVal) {
if (getVersion() == 1) {
setInt64(newVal, 12);
} else { } else {
setInt32(newVal, 8); setInt32(newVal, 8);
} }
} }
uint64_t ELST::getMediaTime() { uint64_t ELST::getSegmentDuration() {
if (getVersion() == 1) { if (getVersion() == 1) {
return getInt64(12); return getInt64(8);
} else { } else {
return getInt32(8); return getInt32(8);
} }
} }
void ELST::setMediaTime(uint64_t newVal) {
if (getVersion() == 1) {
setInt64(newVal, 16);
} else {
setInt32(newVal, 12);
}
}
uint64_t ELST::getMediaTime() {
if (getVersion() == 1) {
return getInt64(16);
} else {
return getInt32(12);
}
}
void ELST::setMediaRateInteger(uint16_t newVal) { void ELST::setMediaRateInteger(uint16_t newVal) {
if (getVersion() == 1) { if (getVersion() == 1) {
setInt16(newVal, 20); setInt16(newVal, 24);
} else { } else {
setInt16(newVal, 12); setInt16(newVal, 16);
} }
} }
uint16_t ELST::getMediaRateInteger() { uint16_t ELST::getMediaRateInteger() {
if (getVersion() == 1) { if (getVersion() == 1) {
return getInt16(20); return getInt16(24);
} else { } else {
return getInt16(12); return getInt16(16);
} }
} }
void ELST::setMediaRateFraction(uint16_t newVal) { void ELST::setMediaRateFraction(uint16_t newVal) {
if (getVersion() == 1) { if (getVersion() == 1) {
setInt16(newVal, 22); setInt16(newVal, 26);
} else { } else {
setInt16(newVal, 14); setInt16(newVal, 18);
} }
} }
uint16_t ELST::getMediaRateFraction() { uint16_t ELST::getMediaRateFraction() {
if (getVersion() == 1) { if (getVersion() == 1) {
return getInt16(22); return getInt16(26);
} else { } else {
return getInt16(14); return getInt16(18);
} }
} }
@ -3350,6 +3464,7 @@ namespace MP4 {
std::stringstream r; std::stringstream r;
r << std::string(indent, ' ') << "[elst] Edit List Box (" << boxedSize() << ")" << std::endl; r << std::string(indent, ' ') << "[elst] Edit List Box (" << boxedSize() << ")" << std::endl;
r << fullBox::toPrettyString(indent); r << fullBox::toPrettyString(indent);
r << std::string(indent + 1, ' ') << "Count: " << getCount() << std::endl;
r << std::string(indent + 1, ' ') << "SegmentDuration: " << getSegmentDuration() << std::endl; r << std::string(indent + 1, ' ') << "SegmentDuration: " << getSegmentDuration() << std::endl;
r << std::string(indent + 1, ' ') << "MediaTime: " << getMediaTime() << std::endl; r << std::string(indent + 1, ' ') << "MediaTime: " << getMediaTime() << std::endl;
r << std::string(indent + 1, ' ') << "MediaRateInteger: " << getMediaRateInteger() << std::endl; r << std::string(indent + 1, ' ') << "MediaRateInteger: " << getMediaRateInteger() << std::endl;
@ -3357,4 +3472,3 @@ namespace MP4 {
return r.str(); return r.str();
} }
} }

View file

@ -235,7 +235,7 @@ namespace MP4 {
class DAC3: public Box { class DAC3: public Box {
public: public:
DAC3(); DAC3(unsigned int rate, unsigned int channels);
char getSampleRateCode();//2bits char getSampleRateCode();//2bits
void setSampleRateCode(char newVal);//2bits void setSampleRateCode(char newVal);//2bits
char getBitStreamIdentification();//5bits char getBitStreamIdentification();//5bits
@ -282,7 +282,7 @@ namespace MP4 {
class TREX: public fullBox { class TREX: public fullBox {
public: public:
TREX(); TREX(unsigned int trackId = 0);
void setTrackID(uint32_t newTrackID); void setTrackID(uint32_t newTrackID);
uint32_t getTrackID(); uint32_t getTrackID();
void setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex); void setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex);
@ -472,6 +472,8 @@ namespace MP4 {
class TKHD: public fullBox { class TKHD: public fullBox {
public: public:
TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height); TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height);
TKHD(DTSC::Track & track, bool fragmented);
void setCreationTime(uint64_t newCreationTime); void setCreationTime(uint64_t newCreationTime);
uint64_t getCreationTime(); uint64_t getCreationTime();
void setModificationTime(uint64_t newModificationTime); void setModificationTime(uint64_t newModificationTime);
@ -497,6 +499,8 @@ namespace MP4 {
void setHeight(uint32_t newHeight); void setHeight(uint32_t newHeight);
uint32_t getHeight(); uint32_t getHeight();
std::string toPrettyString(uint32_t indent = 0); std::string toPrettyString(uint32_t indent = 0);
protected:
void initialize();
}; };
class MDHD: public fullBox { class MDHD: public fullBox {
@ -546,10 +550,12 @@ namespace MP4 {
std::string toPrettyString(uint32_t indent = 0); std::string toPrettyString(uint32_t indent = 0);
}; };
struct STSCEntry { class STSCEntry {
uint32_t firstChunk; public:
uint32_t samplesPerChunk; STSCEntry(unsigned int _first = 0, unsigned int _count = 0, unsigned int _index = 0);
uint32_t sampleDescriptionIndex; uint32_t firstChunk;
uint32_t samplesPerChunk;
uint32_t sampleDescriptionIndex;
}; };
class STSC: public fullBox { class STSC: public fullBox {
@ -638,6 +644,8 @@ namespace MP4 {
///\todo set default values ///\todo set default values
public: public:
VisualSampleEntry(); VisualSampleEntry();
VisualSampleEntry(DTSC::Track & track);
void initialize();
void setCodec(const char * newCodec); void setCodec(const char * newCodec);
void setWidth(uint16_t newWidth); void setWidth(uint16_t newWidth);
uint16_t getWidth(); uint16_t getWidth();
@ -656,6 +664,7 @@ namespace MP4 {
Box & getCLAP(); Box & getCLAP();
void setCLAP(Box & clap); void setCLAP(Box & clap);
Box & getPASP(); Box & getPASP();
void setPASP(Box & pasp);
std::string toPrettyVisualString(uint32_t index = 0, std::string = ""); std::string toPrettyVisualString(uint32_t index = 0, std::string = "");
}; };
@ -663,6 +672,8 @@ namespace MP4 {
public: public:
///\todo set default values ///\todo set default values
AudioSampleEntry(); AudioSampleEntry();
AudioSampleEntry(DTSC::Track & track);
void initialize();
void setCodec(const char * newCodec); void setCodec(const char * newCodec);
void setChannelCount(uint16_t newChannelCount); void setChannelCount(uint16_t newChannelCount);
uint16_t getChannelCount(); uint16_t getChannelCount();
@ -768,6 +779,8 @@ namespace MP4 {
class ELST: public fullBox { class ELST: public fullBox {
public: public:
ELST(); ELST();
void setCount(uint32_t newVal);
uint32_t getCount();
void setSegmentDuration(uint64_t newVal); void setSegmentDuration(uint64_t newVal);
uint64_t getSegmentDuration(); uint64_t getSegmentDuration();
void setMediaTime(uint64_t newVal); void setMediaTime(uint64_t newVal);

View file

@ -50,10 +50,12 @@ namespace Mist {
sought = false; sought = false;
isInitialized = false; isInitialized = false;
isBlocking = false; isBlocking = false;
completeKeysOnly = false;
lastStats = 0; lastStats = 0;
maxSkipAhead = 7500; maxSkipAhead = 7500;
minSkipAhead = 5000; minSkipAhead = 5000;
realTime = 1000; realTime = 1000;
completeKeyReadyTimeOut = false;
if (myConn){ if (myConn){
setBlocking(true); setBlocking(true);
}else{ }else{
@ -862,6 +864,47 @@ namespace Mist {
Util::sleep(nxt.time - (((Util::getMS() - firstTime)*1000)+minSkipAhead)/realTime); Util::sleep(nxt.time - (((Util::getMS() - firstTime)*1000)+minSkipAhead)/realTime);
} }
} }
//delay the stream until its current keyframe is complete
if (completeKeysOnly){
bool completeKeyReady = false;
int timeoutTries = 40;//attempts to updateMeta before timeOut and moving on; default is approximately 10 seconds
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
if (it->second.keys.size() >1){
int thisTimeoutTries = ((it->second.lastms - it->second.firstms) / (it->second.keys.size()-1)) / 125;
if (thisTimeoutTries > timeoutTries) timeoutTries = thisTimeoutTries;
}
}
while(!completeKeyReady && timeoutTries>0){
completeKeyReady = true;
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
if (!it->second.keys.size() || it->second.keys.rbegin()->getTime() + it->second.keys.rbegin()->getLength() <= nxt.time ){
completeKeyReady = false;
break;
}
}
if (!completeKeyReady){
if (completeKeyReadyTimeOut){
INSANE_MSG("Complete Key not ready and time-out is being skipped");
timeoutTries = 0;
}else{
INSANE_MSG("Timeout: %d",timeoutTries);
timeoutTries--;//we count down
stats();
Util::wait(250);
updateMeta();
}
}
}
if (timeoutTries<=0){
if (!completeKeyReadyTimeOut){
INFO_MSG("Wait for keyframe Timeout triggered! Ended to avoid endless loops");
}
completeKeyReadyTimeOut = true;
}else{
//untimeout handling
completeKeyReadyTimeOut = false;
}
}
if (curPage[nxt.tid]){ if (curPage[nxt.tid]){
if (nxt.offset < curPage[nxt.tid].len){ if (nxt.offset < curPage[nxt.tid].len){
unsigned long long nextTime = getDTSCTime(curPage[nxt.tid].mapped, nxt.offset); unsigned long long nextTime = getDTSCTime(curPage[nxt.tid].mapped, nxt.offset);

View file

@ -92,6 +92,7 @@ namespace Mist {
std::map<unsigned long, unsigned long> nxtKeyNum;///< Contains the number of the next key, for page seeking purposes. std::map<unsigned long, unsigned long> nxtKeyNum;///< Contains the number of the next key, for page seeking purposes.
std::set<sortedPageInfo> buffer;///< A sorted list of next-to-be-loaded packets. std::set<sortedPageInfo> buffer;///< A sorted list of next-to-be-loaded packets.
bool sought;///<If a seek has been done, this is set to true. Used for seeking on prepareNext(). bool sought;///<If a seek has been done, this is set to true. Used for seeking on prepareNext().
bool completeKeyReadyTimeOut;//a bool to see if there has been a keyframe TimeOut for complete keys in Live
protected://these are to be messed with by child classes protected://these are to be messed with by child classes
IPC::sharedClient statsPage;///< Shared memory used for statistics reporting. IPC::sharedClient statsPage;///< Shared memory used for statistics reporting.
bool isBlocking;///< If true, indicates that myConn is blocking. bool isBlocking;///< If true, indicates that myConn is blocking.
@ -102,6 +103,7 @@ namespace Mist {
unsigned int maxSkipAhead;///< Maximum ms that we will go ahead of the intended timestamps. unsigned int maxSkipAhead;///< Maximum ms that we will go ahead of the intended timestamps.
unsigned int minSkipAhead;///< Minimum ms that we will go ahead of the intended timestamps. unsigned int minSkipAhead;///< Minimum ms that we will go ahead of the intended timestamps.
unsigned int realTime;///< Playback speed in ms of data per second. eg: 0 is infinite, 1000 real-time, 5000 is 0.2X speed, 500 = 2X speed. unsigned int realTime;///< Playback speed in ms of data per second. eg: 0 is infinite, 1000 real-time, 5000 is 0.2X speed, 500 = 2X speed.
bool completeKeysOnly;///< Bool if we send whole keys only, so the metadata is complete and the output knows in advance what will be sent.
//Read/write status variables //Read/write status variables
Socket::Connection & myConn;///< Connection to the client. Socket::Connection & myConn;///< Connection to the client.

View file

@ -129,31 +129,7 @@ namespace Mist {
ase.setSampleRate(myMeta.tracks[tid].rate); ase.setSampleRate(myMeta.tracks[tid].rate);
ase.setChannelCount(myMeta.tracks[tid].channels); ase.setChannelCount(myMeta.tracks[tid].channels);
ase.setSampleSize(myMeta.tracks[tid].size); ase.setSampleSize(myMeta.tracks[tid].size);
MP4::DAC3 dac3Box; MP4::DAC3 dac3Box(myMeta.tracks[tid].rate, myMeta.tracks[tid].channels);
switch (myMeta.tracks[tid].rate){
case 48000:
dac3Box.setSampleRateCode(0);
break;
case 44100:
dac3Box.setSampleRateCode(1);
break;
case 32000:
dac3Box.setSampleRateCode(2);
break;
default:
dac3Box.setSampleRateCode(3);
break;
}
/// \todo the next settings are set to generic values, we might want to make these flexible
dac3Box.setBitStreamIdentification(8);//check the docs, this is a weird property
dac3Box.setBitStreamMode(0);//set to main, mixed audio
dac3Box.setAudioConfigMode(2);///\todo find out if ACMode should be different
if (myMeta.tracks[tid].channels > 4){
dac3Box.setLowFrequencyEffectsChannelOn(1);
}else{
dac3Box.setLowFrequencyEffectsChannelOn(0);
}
dac3Box.setFrameSizeCode(20);//should be OK, but test this.
ase.setCodecBox(dac3Box); ase.setCodecBox(dac3Box);
} }

View file

@ -141,31 +141,7 @@ namespace Mist {
ase.setChannelCount(thisTrack.channels); ase.setChannelCount(thisTrack.channels);
ase.setSampleSize(thisTrack.size); ase.setSampleSize(thisTrack.size);
if (myMeta.tracks[*it].codec == "AC3"){ if (myMeta.tracks[*it].codec == "AC3"){
MP4::DAC3 dac3Box; MP4::DAC3 dac3Box(thisTrack.rate, thisTrack.channels);
switch (myMeta.tracks[*it].rate){
case 48000:
dac3Box.setSampleRateCode(0);
break;
case 44100:
dac3Box.setSampleRateCode(1);
break;
case 32000:
dac3Box.setSampleRateCode(2);
break;
default:
dac3Box.setSampleRateCode(3);
break;
}
/// \todo the next settings are set to generic values, we might want to make these flexible
dac3Box.setBitStreamIdentification(8);//check the docs, this is a weird property
dac3Box.setBitStreamMode(0);//set to main, mixed audio
dac3Box.setAudioConfigMode(2);///\todo find out if ACMode should be different
if (thisTrack.channels > 4){
dac3Box.setLowFrequencyEffectsChannelOn(1);
}else{
dac3Box.setLowFrequencyEffectsChannelOn(0);
}
dac3Box.setFrameSizeCode(20);//should be OK, but test this.
ase.setCodecBox(dac3Box); ase.setCodecBox(dac3Box);
}else{//other codecs use the ESDS box }else{//other codecs use the ESDS box
MP4::ESDS esdsBox(thisTrack.init); MP4::ESDS esdsBox(thisTrack.init);