Fixes for playlist support

Track matching fixes:
  Input MP4 is not getting dimensions properly, causing resume to not find a collision
    Fixed by overwriting dimensions when media frames are read
  Detecting collisions using track identifier can cause issues (ie audio_AAC_2ch_44100hz_eng VS audio_AAC_2ch_44100hz)
    Fixed by matching using init data, then check by identifier if there is more than 1 match

Fixed buffering code for playlist streams, ensuring correct page creation:
  In resume mode new pages do not get created, but existing one(s) fill up
    Keyframes were not being recognized due to them being deleted during track switching
      Fixed by changing negotiationProxy::bufferNext:
        Removed seemingly unnecessary function which cleared keyframes
      Lastly, the offset of a resumed track seems wrong
        Added to NegotiationProxy::continueNegotiate
          pagesByTrack[tid][firstPage].curOffset = 0;
        Added to negotiationProxy::bufferSinglePacket:
          if (!pagesByTrack[tid][currentPageNum].curOffset) {
            pagesByTrack[tid][currentPageNum].firstTime = packet.getTime();
          }

Fixed numbering for keys from the buffer when accepting tracks (was amount of buffered keys, not last key number)
This commit is contained in:
Marco 2021-02-15 14:16:47 +01:00 committed by Thulinma
parent 01b65ed301
commit c9cd529927
3 changed files with 37 additions and 16 deletions

View file

@ -741,7 +741,11 @@ namespace Mist {
//Write the final mapped track number and keyframe number to the user page element //Write the final mapped track number and keyframe number to the user page element
//This is used to resume pushing as well as pushing new tracks //This is used to resume pushing as well as pushing new tracks
userConn.setTrackId(index, finalMap); userConn.setTrackId(index, finalMap);
userConn.setKeynum(index, myMeta.tracks[finalMap].keys.size()); if (myMeta.tracks[finalMap].keys.size()){
userConn.setKeynum(index, myMeta.tracks[finalMap].keys.rbegin()->getNumber());
}else{
userConn.setKeynum(index, 0);
}
continue; continue;
} }
//Set the temporary track id for this item, and increase the temporary value for use with the next track //Set the temporary track id for this item, and increase the temporary value for use with the next track
@ -800,14 +804,27 @@ namespace Mist {
continue; continue;
} }
std::string trackIdentifier = trackMeta.tracks.find(value)->second.getIdentifier(); //Get the identifier for the track, and attempt colision detection.
DEBUG_MSG(DLVL_HIGH, "Attempting colision detection for track %s", trackIdentifier.c_str()); ///\todo Maybe switch to a new form of detecting collisions, especially with regards to multiple audio languages and camera angles.
//Get the identifier for the track, and attempt colission detection.
int collidesWith = -1; int collidesWith = -1;
std::string newTrackIdentifier = trackMeta.tracks.find(value)->second.getIdentifier();
std::string newTrackInit = trackMeta.tracks.find(value)->second.init;
INFO_MSG("Attempting colision detection for track %s", newTrackIdentifier.c_str());
//First check for matches on INIT data
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) { for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) {
//If the identifier of an existing track and the current track match, assume the are the same track and reject the negotiated one. if (it->second.init == newTrackInit) {
///\todo Maybe switch to a new form of detecting collisions, especially with regards to multiple audio languages and camera angles. // It is the first match
if (it->second.getIdentifier() == trackIdentifier) { if (collidesWith == -1){
collidesWith = it->first;
}
// More than one match: check if identifier matches
else if (it->second.getIdentifier() == newTrackIdentifier) {
collidesWith = it->first;
break;
}
}
else if (it->second.getIdentifier() == newTrackIdentifier) {
collidesWith = it->first; collidesWith = it->first;
break; break;
} }

View file

@ -289,10 +289,10 @@ namespace Mist{
MP4::VisualSampleEntry & vEntryBox = (MP4::VisualSampleEntry&)sEntryBox; MP4::VisualSampleEntry & vEntryBox = (MP4::VisualSampleEntry&)sEntryBox;
myMeta.tracks[trackNo].type = "video"; myMeta.tracks[trackNo].type = "video";
myMeta.tracks[trackNo].codec = "H264"; myMeta.tracks[trackNo].codec = "H264";
if (!myMeta.tracks[trackNo].width){
myMeta.tracks[trackNo].width = vEntryBox.getWidth(); myMeta.tracks[trackNo].width = vEntryBox.getWidth();
myMeta.tracks[trackNo].height = vEntryBox.getHeight(); myMeta.tracks[trackNo].height = vEntryBox.getHeight();
}
MP4::Box initBox = vEntryBox.getCLAP(); MP4::Box initBox = vEntryBox.getCLAP();
if (initBox.isType("avcC")){ if (initBox.isType("avcC")){
myMeta.tracks[trackNo].init.assign(initBox.payload(), initBox.payloadSize()); myMeta.tracks[trackNo].init.assign(initBox.payload(), initBox.payloadSize());

View file

@ -381,9 +381,8 @@ namespace Mist {
if (myMeta.live){ if (myMeta.live){
myMeta.update(pack); myMeta.update(pack);
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) { // unsigned long cleanTrackID = pack.getTrackId();
it->second.clearParts(); // myMeta.tracks[cleanTrackID].removeOldKeyframes(pack.getTime() - pack.timeOffset);
}
} }
//End of brain melt //End of brain melt
@ -550,10 +549,14 @@ namespace Mist {
} }
//Take the last allocated page //Take the last allocated page
std::map<unsigned long, DTSCPageData>::reverse_iterator tmpIt = pagesByTrack[tid].rbegin(); std::map<unsigned long, DTSCPageData>::reverse_iterator tmpIt = pagesByTrack[tid].rbegin();
int currentPageNum = tmpIt->second.pageNum;
if (!pagesByTrack[tid][currentPageNum].curOffset) {
pagesByTrack[tid][currentPageNum].firstTime = packet.getTime();
}
//Compare on 8 mb boundary //Compare on 8 mb boundary
if (tmpIt->second.curOffset > FLIP_DATA_PAGE_SIZE || packet.getTime() - tmpIt->second.firstTime > FLIP_TARGET_DURATION) { if ((tmpIt->second.curOffset > FLIP_DATA_PAGE_SIZE || (packet.getTime() - tmpIt->second.firstTime) > FLIP_TARGET_DURATION) && tmpIt->second.keyNum > 0) {
//Create the book keeping data for the new page //Create the book keeping data for the new page
nextPageNum = tmpIt->second.pageNum + tmpIt->second.keyNum; nextPageNum = currentPageNum + tmpIt->second.keyNum;
HIGH_MSG("We should go to next page now, transition from %lu to %d", tmpIt->second.pageNum, nextPageNum); HIGH_MSG("We should go to next page now, transition from %lu to %d", tmpIt->second.pageNum, nextPageNum);
pagesByTrack[tid][nextPageNum].dataSize = DEFAULT_DATA_PAGE_SIZE; pagesByTrack[tid][nextPageNum].dataSize = DEFAULT_DATA_PAGE_SIZE;
pagesByTrack[tid][nextPageNum].pageNum = nextPageNum; pagesByTrack[tid][nextPageNum].pageNum = nextPageNum;
@ -812,6 +815,7 @@ namespace Mist {
pagesByTrack[tid][firstPage].dataSize = DEFAULT_DATA_PAGE_SIZE;//Initialize op 25mb pagesByTrack[tid][firstPage].dataSize = DEFAULT_DATA_PAGE_SIZE;//Initialize op 25mb
pagesByTrack[tid][firstPage].pageNum = firstPage; pagesByTrack[tid][firstPage].pageNum = firstPage;
pagesByTrack[tid][firstPage].firstTime = 0; pagesByTrack[tid][firstPage].firstTime = 0;
pagesByTrack[tid][firstPage].curOffset = 0;
} }
break; break;
} }