diff --git a/src/Qt/PlayerPrivate.cpp b/src/Qt/PlayerPrivate.cpp index 0594513b..e09d7415 100644 --- a/src/Qt/PlayerPrivate.cpp +++ b/src/Qt/PlayerPrivate.cpp @@ -26,13 +26,13 @@ namespace openshot , audioPlayback(new openshot::AudioPlaybackThread()) , videoPlayback(new openshot::VideoPlaybackThread(rb)) , videoCache(new openshot::VideoCacheThread()) - , speed(1), reader(NULL), last_video_position(1) + , speed(1), reader(NULL), last_video_position(1), max_sleep_ms(3000) { } // Destructor PlayerPrivate::~PlayerPrivate() { - stopPlayback(1000); + stopPlayback(); delete audioPlayback; delete videoCache; delete videoPlayback; @@ -128,7 +128,10 @@ namespace openshot } // Sleep (leaving the video frame on the screen for the correct amount of time) - if (sleep_time > sleep_time.zero()) { + // Don't sleep too long though (in some extreme cases, for example when stopping threads + // and shutting down, the video_frame_diff can jump to a crazy big number, and we don't + // want to sleep too long (max of X seconds) + if (sleep_time > sleep_time.zero() && sleep_time.count() < max_sleep_ms) { std::this_thread::sleep_for(sleep_time); } @@ -169,18 +172,18 @@ namespace openshot { if (video_position < 0) return false; - stopPlayback(-1); + stopPlayback(); startThread(1); return true; } // Stop video/audio playback - void PlayerPrivate::stopPlayback(int timeOutMilliseconds) + void PlayerPrivate::stopPlayback() { - if (audioPlayback->isThreadRunning() && reader->info.has_audio) audioPlayback->stopThread(timeOutMilliseconds); - if (videoCache->isThreadRunning() && reader->info.has_video) videoCache->stopThread(timeOutMilliseconds); - if (videoPlayback->isThreadRunning() && reader->info.has_video) videoPlayback->stopThread(timeOutMilliseconds); - if (isThreadRunning()) stopThread(timeOutMilliseconds); + if (audioPlayback->isThreadRunning() && reader->info.has_audio) audioPlayback->stopThread(max_sleep_ms); + if (videoCache->isThreadRunning() && reader->info.has_video) videoCache->stopThread(max_sleep_ms); + if (videoPlayback->isThreadRunning() && reader->info.has_video) videoPlayback->stopThread(max_sleep_ms); + if (isThreadRunning()) stopThread(max_sleep_ms); } } diff --git a/src/Qt/PlayerPrivate.h b/src/Qt/PlayerPrivate.h index 75c984a3..acfd3783 100644 --- a/src/Qt/PlayerPrivate.h +++ b/src/Qt/PlayerPrivate.h @@ -39,6 +39,7 @@ namespace openshot int speed; /// The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...) openshot::RendererBase *renderer; int64_t last_video_position; /// The last frame actually displayed + int max_sleep_ms; /// The max milliseconds to sleep (when syncing audio and video) /// Constructor PlayerPrivate(openshot::RendererBase *rb); @@ -52,7 +53,7 @@ namespace openshot bool startPlayback(); /// Stop the video/audio playback - void stopPlayback(int timeOutMilliseconds = -1); + void stopPlayback(); /// Get the next frame (based on speed and direction) std::shared_ptr getFrame(); diff --git a/src/Timeline.cpp b/src/Timeline.cpp index e37b56e2..20349c3f 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -897,7 +897,7 @@ std::shared_ptr Timeline::GetFrame(int64_t requested_frame) final_cache->Add(new_frame); // Return frame (or blank frame) - return final_cache->GetFrame(requested_frame); + return new_frame; } }