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

@ -50,10 +50,12 @@ namespace Mist {
sought = false;
isInitialized = false;
isBlocking = false;
completeKeysOnly = false;
lastStats = 0;
maxSkipAhead = 7500;
minSkipAhead = 5000;
realTime = 1000;
completeKeyReadyTimeOut = false;
if (myConn){
setBlocking(true);
}else{
@ -862,6 +864,47 @@ namespace Mist {
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 (nxt.offset < curPage[nxt.tid].len){
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::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 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
IPC::sharedClient statsPage;///< Shared memory used for statistics reporting.
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 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.
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
Socket::Connection & myConn;///< Connection to the client.

View file

@ -129,31 +129,7 @@ namespace Mist {
ase.setSampleRate(myMeta.tracks[tid].rate);
ase.setChannelCount(myMeta.tracks[tid].channels);
ase.setSampleSize(myMeta.tracks[tid].size);
MP4::DAC3 dac3Box;
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.
MP4::DAC3 dac3Box(myMeta.tracks[tid].rate, myMeta.tracks[tid].channels);
ase.setCodecBox(dac3Box);
}

View file

@ -141,31 +141,7 @@ namespace Mist {
ase.setChannelCount(thisTrack.channels);
ase.setSampleSize(thisTrack.size);
if (myMeta.tracks[*it].codec == "AC3"){
MP4::DAC3 dac3Box;
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.
MP4::DAC3 dac3Box(thisTrack.rate, thisTrack.channels);
ase.setCodecBox(dac3Box);
}else{//other codecs use the ESDS box
MP4::ESDS esdsBox(thisTrack.init);