Improved seek function for real-time protocols
This commit is contained in:
parent
791fc5eae9
commit
01e15663e9
3 changed files with 23 additions and 3 deletions
|
@ -592,7 +592,8 @@ namespace Mist{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prepares all tracks from selectedTracks for seeking to the specified ms position.
|
/// Prepares all tracks from selectedTracks for seeking to the specified ms position.
|
||||||
void Output::seek(unsigned long long pos){
|
/// If toKey is true, clips the seek to the nearest keyframe if the main track is a video track.
|
||||||
|
void Output::seek(unsigned long long pos, bool toKey){
|
||||||
sought = true;
|
sought = true;
|
||||||
if (!isInitialized){
|
if (!isInitialized){
|
||||||
initialize();
|
initialize();
|
||||||
|
@ -602,6 +603,25 @@ namespace Mist{
|
||||||
if (myMeta.live){
|
if (myMeta.live){
|
||||||
updateMeta();
|
updateMeta();
|
||||||
}
|
}
|
||||||
|
if (toKey){
|
||||||
|
long unsigned int mainTrack = getMainSelectedTrack();
|
||||||
|
//abort toKey if there are no keys in the main track
|
||||||
|
if (!myMeta.tracks.count(mainTrack) || !myMeta.tracks[mainTrack].keys.size()){
|
||||||
|
WARN_MSG("Sync-seeking impossible (main track invalid); performing regular seek instead");
|
||||||
|
seek(pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DTSC::Track & Trk = myMeta.tracks[mainTrack];
|
||||||
|
if (Trk.type == "video"){
|
||||||
|
unsigned long long seekPos = 0;
|
||||||
|
for (std::deque<DTSC::Key>::iterator it = Trk.keys.begin(); it != Trk.keys.end(); ++it){
|
||||||
|
unsigned long long currPos = it->getTime();
|
||||||
|
if (currPos > pos){break;}//stop if we're past the point we wanted
|
||||||
|
seekPos = currPos;
|
||||||
|
}
|
||||||
|
pos = seekPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
MEDIUM_MSG("Seeking to %llums", pos);
|
MEDIUM_MSG("Seeking to %llums", pos);
|
||||||
std::set<long unsigned int> seekTracks = selectedTracks;
|
std::set<long unsigned int> seekTracks = selectedTracks;
|
||||||
for (std::set<long unsigned int>::iterator it = seekTracks.begin(); it != seekTracks.end(); it++){
|
for (std::set<long unsigned int>::iterator it = seekTracks.begin(); it != seekTracks.end(); it++){
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Mist {
|
||||||
//non-virtual generic functions
|
//non-virtual generic functions
|
||||||
virtual int run();
|
virtual int run();
|
||||||
virtual void stats(bool force = false);
|
virtual void stats(bool force = false);
|
||||||
void seek(unsigned long long pos);
|
void seek(unsigned long long pos, bool toKey = false);
|
||||||
bool seek(unsigned int tid, unsigned long long pos, bool getNextKey = false);
|
bool seek(unsigned int tid, unsigned long long pos, bool getNextKey = false);
|
||||||
void stop();
|
void stop();
|
||||||
uint64_t currentTime();
|
uint64_t currentTime();
|
||||||
|
|
|
@ -711,7 +711,7 @@ namespace Mist {
|
||||||
amfReply.getContentP(3)->addContent(AMF::Object("details", "DDV"));
|
amfReply.getContentP(3)->addContent(AMF::Object("details", "DDV"));
|
||||||
amfReply.getContentP(3)->addContent(AMF::Object("clientid", (double)1337));
|
amfReply.getContentP(3)->addContent(AMF::Object("clientid", (double)1337));
|
||||||
sendCommand(amfReply, playMessageType, playStreamId);
|
sendCommand(amfReply, playMessageType, playStreamId);
|
||||||
seek((long long int)amfData.getContentP(3)->NumValue());
|
seek((long long int)amfData.getContentP(3)->NumValue(), true);
|
||||||
|
|
||||||
//send a status reply
|
//send a status reply
|
||||||
AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
|
AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
|
||||||
|
|
Loading…
Add table
Reference in a new issue