diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index ba3718e7..01e3e97d 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -206,8 +206,8 @@ int FFmpegReader::IsHardwareDecodeSupported(int codecid) void FFmpegReader::Open() { // Open reader if not already open if (!is_open) { - // Prevent calls to GetFrame when Closing - const std::lock_guard lock(processingMutex); + // Prevent async calls to the following code + const std::lock_guard lock(getFrameMutex); // Initialize format context pFormatCtx = NULL; @@ -580,8 +580,8 @@ void FFmpegReader::Open() { void FFmpegReader::Close() { // Close all objects, if reader is 'open' if (is_open) { - // Prevent calls to GetFrame when Closing - const std::lock_guard lock(processingMutex); + // Prevent async calls to the following code + const std::lock_guard lock(getFrameMutex); // Mark as "closed" is_open = false; @@ -881,13 +881,16 @@ std::shared_ptr FFmpegReader::GetFrame(int64_t requested_frame) { // Return the cached frame return frame; } else { - // Check the cache a 2nd time (due to a potential previous lock) + + // Prevent async calls to the remainder of this code + const std::lock_guard lock(getFrameMutex); + + // Check the cache a 2nd time (due to the potential previous lock) frame = final_cache.GetFrame(requested_frame); if (frame) { // Debug output ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetFrame", "returned cached frame on 2nd look", requested_frame); - // Return the cached frame } else { // Frame is not in cache // Reset seek count @@ -2078,6 +2081,9 @@ bool FFmpegReader::IsPartialFrame(int64_t requested_frame) { // Check the working queue, and move finished frames to the finished queue void FFmpegReader::CheckWorkingFrames(int64_t requested_frame) { + // Prevent async calls to the following code + const std::lock_guard lock(getFrameMutex); + // Get a list of current working queue frames in the cache (in-progress frames) std::vector> working_frames = working_cache.GetFrames(); std::vector>::iterator working_itr; diff --git a/src/FrameMapper.cpp b/src/FrameMapper.cpp index 2206cdb1..480c9846 100644 --- a/src/FrameMapper.cpp +++ b/src/FrameMapper.cpp @@ -84,6 +84,9 @@ void FrameMapper::AddField(Field field) // Clear both the fields & frames lists void FrameMapper::Clear() { + // Prevent async calls to the following code + const std::lock_guard lock(getFrameMutex); + // Clear the fields & frames lists fields.clear(); fields.shrink_to_fit(); @@ -104,6 +107,9 @@ void FrameMapper::Init() // Skip initialization return; + // Prevent async calls to the following code + const std::lock_guard lock(getFrameMutex); + // Clear the fields & frames lists Clear(); diff --git a/src/Qt/AudioPlaybackThread.cpp b/src/Qt/AudioPlaybackThread.cpp index 76f0d309..23fa406a 100644 --- a/src/Qt/AudioPlaybackThread.cpp +++ b/src/Qt/AudioPlaybackThread.cpp @@ -152,7 +152,7 @@ namespace openshot std::shared_ptr AudioPlaybackThread::getFrame() { if (source) return source->getFrame(); - return std::shared_ptr(); + return std::shared_ptr(); } // Seek the audio thread diff --git a/src/ReaderBase.h b/src/ReaderBase.h index 27f97e65..aca12ff2 100644 --- a/src/ReaderBase.h +++ b/src/ReaderBase.h @@ -77,7 +77,6 @@ namespace openshot protected: /// Mutex for multiple threads std::recursive_mutex getFrameMutex; - std::recursive_mutex processingMutex; openshot::ClipBase* clip; ///< Pointer to the parent clip instance (if any) public: diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 41223452..61bf5905 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -853,9 +853,6 @@ bool Timeline::isEqual(double a, double b) // Get an openshot::Frame object for a specific frame number of this reader. std::shared_ptr Timeline::GetFrame(int64_t requested_frame) { - // Get lock (to prevent the same frame from being generated by more than 1 thread) - const std::lock_guard lock(getFrameMutex); - // Adjust out of bounds frame number if (requested_frame < 1) requested_frame = 1; @@ -874,6 +871,9 @@ std::shared_ptr Timeline::GetFrame(int64_t requested_frame) } else { + // Prevent async calls to the following code + const std::lock_guard lock(getFrameMutex); + // Get a list of clips that intersect with the requested section of timeline // This also opens the readers for intersecting clips, and marks non-intersecting clips as 'needs closing' std::vector nearby_clips;