Improved MP4 delay, made MP4 live slightly more readable.

This commit is contained in:
Thulinma 2016-06-06 01:10:10 +02:00
parent b3bce527f8
commit 6fec8fae70
3 changed files with 30 additions and 27 deletions

View file

@ -961,6 +961,7 @@ namespace Mist {
while(!completeKeyReady && timeoutTries>0){ while(!completeKeyReady && timeoutTries>0){
completeKeyReady = true; completeKeyReady = true;
for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
if (myMeta.tracks[*it].type == "audio"){continue;}
if (!myMeta.tracks[*it].keys.size() || myMeta.tracks[*it].keys.rbegin()->getTime() + myMeta.tracks[*it].keys.rbegin()->getLength() <= thisPacket.getTime() ){ if (!myMeta.tracks[*it].keys.size() || myMeta.tracks[*it].keys.rbegin()->getTime() + myMeta.tracks[*it].keys.rbegin()->getLength() <= thisPacket.getTime() ){
completeKeyReady = false; completeKeyReady = false;
break; break;

View file

@ -45,6 +45,7 @@ namespace Mist {
///\todo This function does not indicate errors anywhere... maybe fix this... ///\todo This function does not indicate errors anywhere... maybe fix this...
std::string OutProgressiveMP4::DTSCMeta2MP4Header(long long & size, int fragmented) { std::string OutProgressiveMP4::DTSCMeta2MP4Header(long long & size, int fragmented) {
if (myMeta.live){ if (myMeta.live){
realTime = 0;
completeKeysOnly = true; completeKeysOnly = true;
} }
//Make sure we have a proper being value for the size... //Make sure we have a proper being value for the size...
@ -503,12 +504,12 @@ namespace Mist {
} }
} }
void OutProgressiveMP4::sendFragmentHeader(int fragNum) { void OutProgressiveMP4::sendFragmentHeader() {
long unsigned int dataOffset = 0; long unsigned int dataOffset = 0;
uint64_t mdatSize = 8; uint64_t mdatSize = 8;
MP4::MOOF moofBox; MP4::MOOF moofBox;
MP4::MFHD mfhdBox; MP4::MFHD mfhdBox;
mfhdBox.setSequenceNumber(fragNum); mfhdBox.setSequenceNumber(fragSeqNum);
moofBox.setContent(mfhdBox, 0); moofBox.setContent(mfhdBox, 0);
unsigned int moofIndex = 1; unsigned int moofIndex = 1;
std::vector<keyPart> trunOrderWithOffset; std::vector<keyPart> trunOrderWithOffset;
@ -764,19 +765,24 @@ namespace Mist {
///using the fragment number **FOR THIS USER, NOT ACTUAL FRAGMENT NUMBER, HAS NOTHING TO DO WITH ACTUAL FRAGMENTS EVEN** ///using the fragment number **FOR THIS USER, NOT ACTUAL FRAGMENT NUMBER, HAS NOTHING TO DO WITH ACTUAL FRAGMENTS EVEN**
///We take the corresponding keyframe and interframes of the main video track and take concurrent frames from its secondary (audio) tracks ///We take the corresponding keyframe and interframes of the main video track and take concurrent frames from its secondary (audio) tracks
///\todo See if we can use something more elegant than a member variable... ///\todo See if we can use something more elegant than a member variable...
void OutProgressiveMP4::buildFragment(int fragNum) { void OutProgressiveMP4::buildFragment() {
currentPartSet.clear(); currentPartSet.clear();
DTSC::Track & mainTrack = myMeta.tracks[vidTrack]; DTSC::Track & mainTrack = myMeta.tracks[vidTrack];
long int keyIndex = fragNum + fragKeyNumberShift - (mainTrack.keys.begin()->getNumber() - 1); //here we set the index of the video keyframe we are going to make a fragment of
long int keyIndex = fragSeqNum + fragKeyNumberShift - (mainTrack.keys.begin()->getNumber() - 1); //here we set the index of the video keyframe we are going to make a fragment of
if (keyIndex < 0 || keyIndex >= mainTrack.keys.size()) {//if the fragnum is not in the keys if (keyIndex < 0 || keyIndex >= mainTrack.keys.size()) {//if the fragnum is not in the keys
FAIL_MSG("Fragment Number %d not available. KeyShift: %ld FirstKeyNumber: %lu, Calculated KeyIndex: %ld, KeysInMeta: %lu", fragNum, fragKeyNumberShift, mainTrack.keys.begin()->getNumber(), keyIndex, mainTrack.keys.size()); if (keyIndex < 0){
INSANE_MSG("Current Time: %llu, Current TrackID: %ld", thisPacket.getTime(), thisPacket.getTrackId()); WARN_MSG("Connection went out of buffer. Closing.");
INSANE_MSG("Rbegin Number: %lu, Rbegin Time %llu, rBegin Length %lu", mainTrack.keys.rbegin()->getNumber(), mainTrack.keys.rbegin()->getTime(), mainTrack.keys.rbegin()->getLength()); myConn.close();
} else { }else{
INSANE_MSG("Fragment Number %d OK. KeyShift: %ld FirstKeyNumber: %lu, Calculated KeyIndex: %ld, KeysInMeta: %lu", fragNum, fragKeyNumberShift, mainTrack.keys.begin()->getNumber(), keyIndex, mainTrack.keys.size()); FAIL_MSG("Too far ahead - this should be impossible.");
}
return;
} }
long long int startms = mainTrack.keys[keyIndex].getTime(); long long int startms = mainTrack.keys[keyIndex].getTime();
long long int endms;// = startms; long long int endms;// = startms;
@ -823,22 +829,18 @@ namespace Mist {
} }
void OutProgressiveMP4::buildTrafPart() { void OutProgressiveMP4::buildTrafPart() {
updateMeta();//we need to update meta
//building set first //building set first
buildFragment(fragSeqNum);//map with metadata for keyframe buildFragment();//map with metadata for keyframe
if (currentPartSet.size()) { if (!currentPartSet.size()){return;}//we're seeking, send nothing
sendFragmentHeader(fragSeqNum++); sendFragmentHeader();
partListSent = 0; ++fragSeqNum;
//convert map to list here, apologies for inefficiency, but this works best partListSent = 0;
//partList = x1 * track y1 + x2 * track y2 * etc. //convert map to list here, apologies for inefficiency, but this works best
partListLength = 0; //partList = x1 * track y1 + x2 * track y2 * etc.
//std::stringstream temp; partListLength = 0;
for (std::map<long unsigned int, fragSet>::iterator it = currentPartSet.begin(); it != currentPartSet.end(); it++) { //std::stringstream temp;
partListLength += it->second.lastPart - it->second.firstPart + 1; for (std::map<long unsigned int, fragSet>::iterator it = currentPartSet.begin(); it != currentPartSet.end(); it++) {
} partListLength += it->second.lastPart - it->second.firstPart + 1;
} else {
WARN_MSG("Warning: partMap should not be empty, but it is! Possibly source stopped streaming");
myConn.close();
} }
} }
@ -855,6 +857,7 @@ namespace Mist {
if (!partListLength || partListSent >= partListLength) { if (!partListLength || partListSent >= partListLength) {
buildTrafPart(); buildTrafPart();
} }
if (!partListLength){return;}//we're seeking, do not send anything./
//generate content in mdat, meaning: send right parts //generate content in mdat, meaning: send right parts
DONTEVEN_MSG("Sending tid: %ld size: %u", thisPacket.getTrackId() , len); DONTEVEN_MSG("Sending tid: %ld size: %u", thisPacket.getTrackId() , len);
myConn.SendNow(dataPointer, len); myConn.SendNow(dataPointer, len);
@ -868,7 +871,6 @@ namespace Mist {
if (thisPacket.getTime() > sortSet.begin()->time || (unsigned long)thisPacket.getTrackId() > sortSet.begin()->trackID) { if (thisPacket.getTime() > sortSet.begin()->time || (unsigned long)thisPacket.getTrackId() > sortSet.begin()->trackID) {
if (perfect) { if (perfect) {
DEBUG_MSG(DLVL_WARN, "Warning: input is inconsistent. Expected %lu:%llu but got %ld:%llu - cancelling playback", sortSet.begin()->trackID, sortSet.begin()->time, thisPacket.getTrackId(), thisPacket.getTime()); DEBUG_MSG(DLVL_WARN, "Warning: input is inconsistent. Expected %lu:%llu but got %ld:%llu - cancelling playback", sortSet.begin()->trackID, sortSet.begin()->time, thisPacket.getTrackId(), thisPacket.getTime());
INFO_MSG("myMeta live: %d", myMeta.live);
perfect = false; perfect = false;
myConn.close(); myConn.close();
} }

View file

@ -43,8 +43,8 @@ namespace Mist {
void parseRange(std::string header, long long & byteStart, long long & byteEnd, long long & seekPoint, unsigned int headerSize); void parseRange(std::string header, long long & byteStart, long long & byteEnd, long long & seekPoint, unsigned int headerSize);
std::string DTSCMeta2MP4Header(long long & size, int fragmented = 0); std::string DTSCMeta2MP4Header(long long & size, int fragmented = 0);
//int fragmented values: 0 = non fragmented stream, 1 = frag stream main header //int fragmented values: 0 = non fragmented stream, 1 = frag stream main header
void buildFragment(int fragNum);//this builds the structure of the fragment header for fragment number fragNum, and stores it in a member variable void buildFragment();//this builds the structure of the fragment header and stores it in a member variable
void sendFragmentHeader(int fragNum);//this builds the moof box for fragmented MP4 void sendFragmentHeader();//this builds the moof box for fragmented MP4
void findSeekPoint(long long byteStart, long long & seekPoint, unsigned int headerSize); void findSeekPoint(long long byteStart, long long & seekPoint, unsigned int headerSize);
void onHTTP(); void onHTTP();
void sendNext(); void sendNext();