diff --git a/client/media/CVideoHandler.cpp b/client/media/CVideoHandler.cpp index 3932aa1d6..41e2eb6a6 100644 --- a/client/media/CVideoHandler.cpp +++ b/client/media/CVideoHandler.cpp @@ -173,6 +173,7 @@ void CVideoInstance::openVideo() { openContext(); openCodec(findVideoStream()); + startTime = std::chrono::high_resolution_clock::now(); } void CVideoInstance::prepareOutput(float scaleFactor, bool useTextureOutput) @@ -391,9 +392,16 @@ void CVideoInstance::tick(uint32_t msPassed) if(videoEnded()) throw std::runtime_error("Video already ended!"); - frameTime += msPassed / 1000.0; + auto nowTime = std::chrono::high_resolution_clock::now(); + double difference = std::chrono::duration_cast(nowTime - startTime).count() / 1000.0; - if(frameTime >= getCurrentFrameEndTime()) + int frameskipCounter = 0; + while(!videoEnded() && difference >= getCurrentFrameEndTime() + getCurrentFrameDuration() && frameskipCounter < MAX_FRAMESKIP) // Frameskip + { + decodeNextFrame(); + frameskipCounter++; + } + if(!videoEnded() && difference >= getCurrentFrameEndTime()) loadNextFrame(); } diff --git a/client/media/CVideoHandler.h b/client/media/CVideoHandler.h index 42e48eaff..b4a3c7c81 100644 --- a/client/media/CVideoHandler.h +++ b/client/media/CVideoHandler.h @@ -77,10 +77,12 @@ class CVideoInstance final : public IVideoInstance, public FFMpegStream SDL_Surface * surface = nullptr; Point dimensions; - /// video playback current progress, in seconds - double frameTime = 0.0; + /// video playback start time point + std::chrono::high_resolution_clock::time_point startTime; void prepareOutput(float scaleFactor, bool useTextureOutput); + + const int MAX_FRAMESKIP = 5; public: ~CVideoInstance();