From 6fec8fae70effaaa7a5dce4141ae43f64ca47eb7 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Mon, 6 Jun 2016 01:10:10 +0200 Subject: [PATCH] Improved MP4 delay, made MP4 live slightly more readable. --- src/output/output.cpp | 1 + src/output/output_progressive_mp4.cpp | 52 ++++++++++++++------------- src/output/output_progressive_mp4.h | 4 +-- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/output/output.cpp b/src/output/output.cpp index 2095b142..e6572586 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -961,6 +961,7 @@ namespace Mist { while(!completeKeyReady && timeoutTries>0){ completeKeyReady = true; for (std::set::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() ){ completeKeyReady = false; break; diff --git a/src/output/output_progressive_mp4.cpp b/src/output/output_progressive_mp4.cpp index 2bd6d8d6..7cb64628 100644 --- a/src/output/output_progressive_mp4.cpp +++ b/src/output/output_progressive_mp4.cpp @@ -45,6 +45,7 @@ namespace Mist { ///\todo This function does not indicate errors anywhere... maybe fix this... std::string OutProgressiveMP4::DTSCMeta2MP4Header(long long & size, int fragmented) { if (myMeta.live){ + realTime = 0; completeKeysOnly = true; } //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; uint64_t mdatSize = 8; MP4::MOOF moofBox; MP4::MFHD mfhdBox; - mfhdBox.setSequenceNumber(fragNum); + mfhdBox.setSequenceNumber(fragSeqNum); moofBox.setContent(mfhdBox, 0); unsigned int moofIndex = 1; std::vector 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** ///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... - void OutProgressiveMP4::buildFragment(int fragNum) { + void OutProgressiveMP4::buildFragment() { currentPartSet.clear(); 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 - 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()); - INSANE_MSG("Current Time: %llu, Current TrackID: %ld", thisPacket.getTime(), thisPacket.getTrackId()); - INSANE_MSG("Rbegin Number: %lu, Rbegin Time %llu, rBegin Length %lu", mainTrack.keys.rbegin()->getNumber(), mainTrack.keys.rbegin()->getTime(), mainTrack.keys.rbegin()->getLength()); - } 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()); + if (keyIndex < 0){ + WARN_MSG("Connection went out of buffer. Closing."); + myConn.close(); + }else{ + FAIL_MSG("Too far ahead - this should be impossible."); + } + return; } + long long int startms = mainTrack.keys[keyIndex].getTime(); long long int endms;// = startms; @@ -823,22 +829,18 @@ namespace Mist { } void OutProgressiveMP4::buildTrafPart() { - updateMeta();//we need to update meta //building set first - buildFragment(fragSeqNum);//map with metadata for keyframe - if (currentPartSet.size()) { - sendFragmentHeader(fragSeqNum++); - partListSent = 0; - //convert map to list here, apologies for inefficiency, but this works best - //partList = x1 * track y1 + x2 * track y2 * etc. - partListLength = 0; - //std::stringstream temp; - for (std::map::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(); + buildFragment();//map with metadata for keyframe + if (!currentPartSet.size()){return;}//we're seeking, send nothing + sendFragmentHeader(); + ++fragSeqNum; + partListSent = 0; + //convert map to list here, apologies for inefficiency, but this works best + //partList = x1 * track y1 + x2 * track y2 * etc. + partListLength = 0; + //std::stringstream temp; + for (std::map::iterator it = currentPartSet.begin(); it != currentPartSet.end(); it++) { + partListLength += it->second.lastPart - it->second.firstPart + 1; } } @@ -855,6 +857,7 @@ namespace Mist { if (!partListLength || partListSent >= partListLength) { buildTrafPart(); } + if (!partListLength){return;}//we're seeking, do not send anything./ //generate content in mdat, meaning: send right parts DONTEVEN_MSG("Sending tid: %ld size: %u", thisPacket.getTrackId() , 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 (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()); - INFO_MSG("myMeta live: %d", myMeta.live); perfect = false; myConn.close(); } diff --git a/src/output/output_progressive_mp4.h b/src/output/output_progressive_mp4.h index dbc1c593..6acbb019 100644 --- a/src/output/output_progressive_mp4.h +++ b/src/output/output_progressive_mp4.h @@ -43,8 +43,8 @@ namespace Mist { 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); //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 sendFragmentHeader(int fragNum);//this builds the moof box for fragmented MP4 + void buildFragment();//this builds the structure of the fragment header and stores it in a member variable + void sendFragmentHeader();//this builds the moof box for fragmented MP4 void findSeekPoint(long long byteStart, long long & seekPoint, unsigned int headerSize); void onHTTP(); void sendNext();