diff --git a/bindings/python/openshot.i b/bindings/python/openshot.i index 20990b2c..ca3d97b3 100644 --- a/bindings/python/openshot.i +++ b/bindings/python/openshot.i @@ -38,7 +38,7 @@ #ifdef USE_IMAGEMAGICK %shared_ptr(Magick::Image) #endif -%shared_ptr(juce::AudioSampleBuffer) +%shared_ptr(juce::AudioBuffer) %shared_ptr(openshot::Frame) %{ diff --git a/bindings/ruby/openshot.i b/bindings/ruby/openshot.i index bd79dcd3..bc8432ab 100644 --- a/bindings/ruby/openshot.i +++ b/bindings/ruby/openshot.i @@ -38,7 +38,7 @@ #ifdef USE_IMAGEMAGICK %shared_ptr(Magick::Image) #endif -%shared_ptr(juce::AudioSampleBuffer) +%shared_ptr(juce::AudioBuffer) %shared_ptr(openshot::Frame) /* Template specializations */ diff --git a/src/AudioBufferSource.cpp b/src/AudioBufferSource.cpp index e71cfacc..695b0766 100644 --- a/src/AudioBufferSource.cpp +++ b/src/AudioBufferSource.cpp @@ -16,14 +16,14 @@ using namespace std; using namespace openshot; // Default constructor -AudioBufferSource::AudioBufferSource(juce::AudioSampleBuffer *audio_buffer) +AudioBufferSource::AudioBufferSource(juce::AudioBuffer *audio_buffer) : position(0), repeat(false), buffer(audio_buffer) { } // Destructor AudioBufferSource::~AudioBufferSource() { - // forget the AudioSampleBuffer. It still exists; we just don't know about it. + // forget the AudioBuffer. It still exists; we just don't know about it. buffer = NULL; } @@ -115,8 +115,8 @@ void AudioBufferSource::setLooping (bool shouldLoop) repeat = shouldLoop; } -// Use a different AudioSampleBuffer for this source -void AudioBufferSource::setBuffer (juce::AudioSampleBuffer *audio_buffer) +// Use a different AudioBuffer for this source +void AudioBufferSource::setBuffer (juce::AudioBuffer *audio_buffer) { buffer = audio_buffer; setNextReadPosition(0); diff --git a/src/AudioBufferSource.h b/src/AudioBufferSource.h index c164819f..173ccf43 100644 --- a/src/AudioBufferSource.h +++ b/src/AudioBufferSource.h @@ -13,30 +13,28 @@ #ifndef OPENSHOT_AUDIOBUFFERSOURCE_H #define OPENSHOT_AUDIOBUFFERSOURCE_H -#include -#include +#include +#include -/// This namespace is the default namespace for all code in the openshot library namespace openshot { - /** - * @brief This class is used to expose an AudioSampleBuffer as an AudioSource in JUCE. + * @brief This class is used to expose an AudioBuffer as an AudioSource in JUCE. * - * The JUCE library cannot play audio directly from an AudioSampleBuffer, so this class exposes - * an AudioSampleBuffer as a AudioSource, so that JUCE can play the audio. + * The JUCE library cannot play audio directly from an AudioBuffer, so this class exposes + * an AudioBuffer as a AudioSource, so that JUCE can play the audio. */ class AudioBufferSource : public juce::PositionableAudioSource { private: int position; bool repeat; - juce::AudioSampleBuffer *buffer; + juce::AudioBuffer *buffer; public: /// @brief Default constructor /// @param audio_buffer This buffer contains the samples you want to play through JUCE. - AudioBufferSource(juce::AudioSampleBuffer *audio_buffer); + AudioBufferSource(juce::AudioBuffer *audio_buffer); /// Destructor ~AudioBufferSource(); @@ -69,7 +67,7 @@ namespace openshot void setLooping (bool shouldLoop); /// Update the internal buffer used by this source - void setBuffer (juce::AudioSampleBuffer *audio_buffer); + void setBuffer (juce::AudioBuffer *audio_buffer); }; } diff --git a/src/AudioReaderSource.cpp b/src/AudioReaderSource.cpp index 8b103ced..7a1a96e3 100644 --- a/src/AudioReaderSource.cpp +++ b/src/AudioReaderSource.cpp @@ -15,8 +15,6 @@ #include "Frame.h" #include "ZmqLogger.h" -#include - using namespace std; using namespace openshot; @@ -26,7 +24,7 @@ AudioReaderSource::AudioReaderSource( ) : position(0), size(buffer_size), - buffer(new juce::AudioSampleBuffer(audio_reader->info.channels, buffer_size)), + buffer(new juce::AudioBuffer(audio_reader->info.channels, buffer_size)), speed(1), reader(audio_reader), frame_number(starting_frame_number), @@ -63,7 +61,7 @@ void AudioReaderSource::GetMoreSamplesFromReader() estimated_frame = frame_number; // Init new buffer - juce::AudioSampleBuffer *new_buffer = new juce::AudioSampleBuffer(reader->info.channels, size); + juce::AudioBuffer *new_buffer = new juce::AudioSampleBuffer(reader->info.channels, size); new_buffer->clear(); // Move the remaining samples into new buffer (if any) @@ -132,7 +130,7 @@ void AudioReaderSource::GetMoreSamplesFromReader() } // Reverse an audio buffer -juce::AudioSampleBuffer* AudioReaderSource::reverse_buffer(juce::AudioSampleBuffer* buffer) +juce::AudioBuffer* AudioReaderSource::reverse_buffer(juce::AudioSampleBuffer* buffer) { int number_of_samples = buffer->getNumSamples(); int channels = buffer->getNumChannels(); @@ -141,7 +139,7 @@ juce::AudioSampleBuffer* AudioReaderSource::reverse_buffer(juce::AudioSampleBuff ZmqLogger::Instance()->AppendDebugMethod("AudioReaderSource::reverse_buffer", "number_of_samples", number_of_samples, "channels", channels); // Reverse array (create new buffer to hold the reversed version) - juce::AudioSampleBuffer *reversed = new juce::AudioSampleBuffer(channels, number_of_samples); + juce::AudioBuffer *reversed = new juce::AudioSampleBuffer(channels, number_of_samples); reversed->clear(); for (int channel = 0; channel < channels; channel++) @@ -276,7 +274,7 @@ void AudioReaderSource::setLooping (bool shouldLoop) } // Update the internal buffer used by this source -void AudioReaderSource::setBuffer (juce::AudioSampleBuffer *audio_buffer) +void AudioReaderSource::setBuffer (juce::AudioBuffer *audio_buffer) { buffer = audio_buffer; setNextReadPosition(0); diff --git a/src/AudioReaderSource.h b/src/AudioReaderSource.h index dcca52b5..2d04d210 100644 --- a/src/AudioReaderSource.h +++ b/src/AudioReaderSource.h @@ -15,12 +15,13 @@ #include "ReaderBase.h" -#include +#include +#include /// This namespace is the default namespace for all code in the openshot library namespace openshot { - + class Frame; /** * @brief This class is used to expose any ReaderBase derived class as an AudioSource in JUCE. * @@ -32,7 +33,7 @@ namespace openshot int position; /// The position of the audio source (index of buffer) bool repeat; /// Repeat the audio source when finished int size; /// The size of the internal buffer - juce::AudioSampleBuffer *buffer; /// The audio sample buffer + juce::AudioBuffer *buffer; /// The audio sample buffer int speed; /// The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...) ReaderBase *reader; /// The reader to pull samples from @@ -46,7 +47,7 @@ namespace openshot void GetMoreSamplesFromReader(); /// Reverse an audio buffer (for backwards audio) - juce::AudioSampleBuffer* reverse_buffer(juce::AudioSampleBuffer* buffer); + juce::AudioBuffer* reverse_buffer(juce::AudioSampleBuffer* buffer); public: @@ -87,7 +88,7 @@ namespace openshot void setLooping (bool shouldLoop); /// Update the internal buffer used by this source - void setBuffer (juce::AudioSampleBuffer *audio_buffer); + void setBuffer (juce::AudioBuffer *audio_buffer); const ReaderInfo & getReaderInfo() const { return reader->info; } diff --git a/src/AudioResampler.cpp b/src/AudioResampler.cpp index 841a2aa5..cfdc7e95 100644 --- a/src/AudioResampler.cpp +++ b/src/AudioResampler.cpp @@ -34,7 +34,7 @@ AudioResampler::AudioResampler() resample_source = new juce::ResamplingAudioSource(buffer_source, false, 2); // Init resampled buffer - resampled_buffer = new juce::AudioSampleBuffer(2, 1); + resampled_buffer = new juce::AudioBuffer(2, 1); resampled_buffer->clear(); // Init callback buffer @@ -56,7 +56,7 @@ AudioResampler::~AudioResampler() } // Sets the audio buffer and updates the key settings -void AudioResampler::SetBuffer(juce::AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate) +void AudioResampler::SetBuffer(juce::AudioBuffer *new_buffer, double sample_rate, double new_sample_rate) { if (sample_rate <= 0) sample_rate = 44100; @@ -71,7 +71,7 @@ void AudioResampler::SetBuffer(juce::AudioSampleBuffer *new_buffer, double sampl } // Sets the audio buffer and key settings -void AudioResampler::SetBuffer(juce::AudioSampleBuffer *new_buffer, double ratio) +void AudioResampler::SetBuffer(juce::AudioBuffer *new_buffer, double ratio) { // Update buffer & buffer source buffer = new_buffer; @@ -102,7 +102,7 @@ void AudioResampler::SetBuffer(juce::AudioSampleBuffer *new_buffer, double ratio } // Get the resampled audio buffer -juce::AudioSampleBuffer* AudioResampler::GetResampledBuffer() +juce::AudioBuffer* AudioResampler::GetResampledBuffer() { // Resample the current frame's audio buffer (into the temp callback buffer) resample_source->getNextAudioBlock(resample_callback_buffer); diff --git a/src/AudioResampler.h b/src/AudioResampler.h index 6d655be7..73c38c73 100644 --- a/src/AudioResampler.h +++ b/src/AudioResampler.h @@ -14,7 +14,10 @@ #define OPENSHOT_RESAMPLER_H #include "AudioBufferSource.h" -#include + +#include +#include +#include namespace openshot { @@ -26,8 +29,8 @@ namespace openshot { */ class AudioResampler { private: - juce::AudioSampleBuffer *buffer; - juce::AudioSampleBuffer *resampled_buffer; + juce::AudioBuffer *buffer; + juce::AudioBuffer *resampled_buffer; openshot::AudioBufferSource *buffer_source; juce::ResamplingAudioSource *resample_source; juce::AudioSourceChannelInfo resample_callback_buffer; @@ -49,15 +52,15 @@ namespace openshot { /// @param new_buffer The buffer of audio samples needing to be resampled /// @param sample_rate The original sample rate of the buffered samples /// @param new_sample_rate The requested sample rate you need - void SetBuffer(juce::AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate); + void SetBuffer(juce::AudioBuffer *new_buffer, double sample_rate, double new_sample_rate); /// @brief Sets the audio buffer and key settings /// @param new_buffer The buffer of audio samples needing to be resampled /// @param ratio The multiplier that needs to be applied to the sample rate (this is how resampling happens) - void SetBuffer(juce::AudioSampleBuffer *new_buffer, double ratio); + void SetBuffer(juce::AudioBuffer *new_buffer, double ratio); /// Get the resampled audio buffer - juce::AudioSampleBuffer* GetResampledBuffer(); + juce::AudioBuffer* GetResampledBuffer(); }; } diff --git a/src/CVObjectDetection.cpp b/src/CVObjectDetection.cpp index f8e50005..2b3cc8e0 100644 --- a/src/CVObjectDetection.cpp +++ b/src/CVObjectDetection.cpp @@ -16,8 +16,9 @@ #include #include "CVObjectDetection.h" -#include "objdetectdata.pb.h" +#include "Exceptions.h" +#include "objdetectdata.pb.h" #include using namespace std; diff --git a/src/CVStabilization.cpp b/src/CVStabilization.cpp index 9621c42a..79a4890d 100644 --- a/src/CVStabilization.cpp +++ b/src/CVStabilization.cpp @@ -16,6 +16,7 @@ #include #include "CVStabilization.h" +#include "Exceptions.h" #include "stabilizedata.pb.h" #include diff --git a/src/CVTracker.cpp b/src/CVTracker.cpp index a701ea1f..b96cd13c 100644 --- a/src/CVTracker.cpp +++ b/src/CVTracker.cpp @@ -20,6 +20,7 @@ #include "OpenCVUtilities.h" #include "CVTracker.h" #include "trackerdata.pb.h" +#include "Exceptions.h" using namespace openshot; using google::protobuf::util::TimeUtil; diff --git a/src/CacheBase.cpp b/src/CacheBase.cpp index b5f3c750..09cddb51 100644 --- a/src/CacheBase.cpp +++ b/src/CacheBase.cpp @@ -16,15 +16,12 @@ using namespace std; using namespace openshot; // Default constructor, no max frames -CacheBase::CacheBase() : max_bytes(0) { - // Init the critical section - cacheCriticalSection = new CriticalSection(); -} +CacheBase::CacheBase() : CacheBase::CacheBase(0) { } // Constructor that sets the max frames to cache CacheBase::CacheBase(int64_t max_bytes) : max_bytes(max_bytes) { - // Init the critical section - cacheCriticalSection = new CriticalSection(); + // Init the mutex + cacheMutex = new std::recursive_mutex(); } // Set maximum bytes to a different amount based on a ReaderInfo struct diff --git a/src/CacheBase.h b/src/CacheBase.h index bd3f9115..8ed89935 100644 --- a/src/CacheBase.h +++ b/src/CacheBase.h @@ -14,11 +14,10 @@ #define OPENSHOT_CACHE_BASE_H #include +#include #include "Json.h" -#include - namespace openshot { class Frame; @@ -35,8 +34,8 @@ namespace openshot { std::string cache_type; ///< This is a friendly type name of the derived cache instance int64_t max_bytes; ///< This is the max number of bytes to cache (0 = no limit) - /// Section lock for multiple threads - juce::CriticalSection *cacheCriticalSection; + /// Mutex for multiple threads + std::recursive_mutex *cacheMutex; public: diff --git a/src/CacheDisk.cpp b/src/CacheDisk.cpp index 5a748f2b..bf66bcd9 100644 --- a/src/CacheDisk.cpp +++ b/src/CacheDisk.cpp @@ -81,7 +81,7 @@ void CacheDisk::CalculateRanges() { if (needs_range_processing) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Sort ordered frame #s, and calculate JSON ranges std::sort(ordered_frame_numbers.begin(), ordered_frame_numbers.end()); @@ -139,16 +139,15 @@ CacheDisk::~CacheDisk() frame_numbers.clear(); ordered_frame_numbers.clear(); - // remove critical section - delete cacheCriticalSection; - cacheCriticalSection = NULL; + // remove mutex + delete cacheMutex; } // Add a Frame to the cache void CacheDisk::Add(std::shared_ptr frame) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); int64_t frame_number = frame->number; // Freshen frame if it already exists @@ -207,7 +206,7 @@ void CacheDisk::Add(std::shared_ptr frame) std::shared_ptr CacheDisk::GetFrame(int64_t frame_number) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Does frame exists in cache? if (frames.count(frame_number)) { @@ -277,7 +276,7 @@ std::shared_ptr CacheDisk::GetFrame(int64_t frame_number) std::shared_ptr CacheDisk::GetSmallestFrame() { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Loop through frame numbers std::deque::iterator itr; @@ -300,7 +299,7 @@ std::shared_ptr CacheDisk::GetSmallestFrame() int64_t CacheDisk::GetBytes() { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); int64_t total_bytes = 0; @@ -322,7 +321,7 @@ void CacheDisk::Remove(int64_t frame_number) void CacheDisk::Remove(int64_t start_frame_number, int64_t end_frame_number) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Loop through frame numbers std::deque::iterator itr; @@ -374,7 +373,7 @@ void CacheDisk::MoveToFront(int64_t frame_number) if (frames.count(frame_number)) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Loop through frame numbers std::deque::iterator itr; @@ -397,7 +396,7 @@ void CacheDisk::MoveToFront(int64_t frame_number) void CacheDisk::Clear() { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Clear all containers frames.clear(); @@ -418,7 +417,7 @@ void CacheDisk::Clear() int64_t CacheDisk::Count() { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Return the number of frames in the cache return frames.size(); @@ -431,7 +430,7 @@ void CacheDisk::CleanUp() if (max_bytes > 0) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); while (GetBytes() > max_bytes && frame_numbers.size() > 20) { diff --git a/src/CacheMemory.cpp b/src/CacheMemory.cpp index 8e5bc4f0..73c20f89 100644 --- a/src/CacheMemory.cpp +++ b/src/CacheMemory.cpp @@ -40,9 +40,8 @@ CacheMemory::~CacheMemory() frame_numbers.clear(); ordered_frame_numbers.clear(); - // remove critical section - delete cacheCriticalSection; - cacheCriticalSection = NULL; + // remove mutex + delete cacheMutex; } @@ -52,7 +51,7 @@ void CacheMemory::CalculateRanges() { if (needs_range_processing) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Sort ordered frame #s, and calculate JSON ranges std::sort(ordered_frame_numbers.begin(), ordered_frame_numbers.end()); @@ -109,7 +108,7 @@ void CacheMemory::CalculateRanges() { void CacheMemory::Add(std::shared_ptr frame) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); int64_t frame_number = frame->number; // Freshen frame if it already exists @@ -134,7 +133,7 @@ void CacheMemory::Add(std::shared_ptr frame) std::shared_ptr CacheMemory::GetFrame(int64_t frame_number) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Does frame exists in cache? if (frames.count(frame_number)) @@ -150,7 +149,7 @@ std::shared_ptr CacheMemory::GetFrame(int64_t frame_number) std::shared_ptr CacheMemory::GetSmallestFrame() { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Loop through frame numbers std::deque::iterator itr; @@ -173,7 +172,7 @@ std::shared_ptr CacheMemory::GetSmallestFrame() int64_t CacheMemory::GetBytes() { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); int64_t total_bytes = 0; @@ -197,7 +196,7 @@ void CacheMemory::Remove(int64_t frame_number) void CacheMemory::Remove(int64_t start_frame_number, int64_t end_frame_number) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Loop through frame numbers std::deque::iterator itr; @@ -232,7 +231,7 @@ void CacheMemory::Remove(int64_t start_frame_number, int64_t end_frame_number) void CacheMemory::MoveToFront(int64_t frame_number) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Does frame exists in cache? if (frames.count(frame_number)) @@ -258,7 +257,7 @@ void CacheMemory::MoveToFront(int64_t frame_number) void CacheMemory::Clear() { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); frames.clear(); frame_numbers.clear(); @@ -270,7 +269,7 @@ void CacheMemory::Clear() int64_t CacheMemory::Count() { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); // Return the number of frames in the cache return frames.size(); @@ -283,7 +282,7 @@ void CacheMemory::CleanUp() if (max_bytes > 0) { // Create a scoped lock, to protect the cache from multiple threads - const GenericScopedLock lock(*cacheCriticalSection); + const std::lock_guard lock(*cacheMutex); while (GetBytes() > max_bytes && frame_numbers.size() > 20) { diff --git a/src/ChannelLayouts.h b/src/ChannelLayouts.h index 68250241..a53a75f1 100644 --- a/src/ChannelLayouts.h +++ b/src/ChannelLayouts.h @@ -57,7 +57,6 @@ enum ChannelLayout }; - } #endif diff --git a/src/ChunkReader.h b/src/ChunkReader.h index 9faae27f..7caf6bb5 100644 --- a/src/ChunkReader.h +++ b/src/ChunkReader.h @@ -18,12 +18,11 @@ #include "ReaderBase.h" #include "Json.h" -#include "CacheMemory.h" namespace openshot { + class CacheBase; class Frame; - /** * @brief This struct holds the location of a frame within a chunk. * @@ -119,7 +118,7 @@ namespace openshot void SetChunkSize(int64_t new_size) { chunk_size = new_size; }; /// Get the cache object used by this reader (always return NULL for this reader) - openshot::CacheMemory* GetCache() override { return nullptr; }; + openshot::CacheBase* GetCache() override { return nullptr; }; /// @brief Get an openshot::Frame object for a specific frame number of this reader. /// @returns The requested frame (containing the image and audio) diff --git a/src/ChunkWriter.cpp b/src/ChunkWriter.cpp index 446fdcc6..b5598d9e 100644 --- a/src/ChunkWriter.cpp +++ b/src/ChunkWriter.cpp @@ -12,6 +12,7 @@ #include "ChunkWriter.h" #include "Exceptions.h" +#include "Frame.h" using namespace openshot; diff --git a/src/Clip.cpp b/src/Clip.cpp index 81d2e524..f5f2724a 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -11,6 +11,8 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "Clip.h" + +#include "AudioResampler.h" #include "Exceptions.h" #include "FFmpegReader.h" #include "FrameMapper.h" @@ -453,13 +455,13 @@ std::string Clip::get_file_extension(std::string path) } // Reverse an audio buffer -void Clip::reverse_buffer(juce::AudioSampleBuffer* buffer) +void Clip::reverse_buffer(juce::AudioBuffer* buffer) { int number_of_samples = buffer->getNumSamples(); int channels = buffer->getNumChannels(); // Reverse array (create new buffer to hold the reversed version) - juce::AudioSampleBuffer *reversed = new juce::AudioSampleBuffer(channels, number_of_samples); + juce::AudioBuffer *reversed = new juce::AudioSampleBuffer(channels, number_of_samples); reversed->clear(); for (int channel = 0; channel < channels; channel++) @@ -491,10 +493,10 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num // Check for a valid time map curve if (time.GetLength() > 1) { - const juce::GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); // create buffer and resampler - juce::AudioSampleBuffer *samples = NULL; + juce::AudioBuffer *samples = NULL; if (!resampler) resampler = new AudioResampler(); @@ -514,10 +516,10 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num if (time.GetRepeatFraction(frame_number).den > 1) { // SLOWING DOWN AUDIO // Resample data, and return new buffer pointer - juce::AudioSampleBuffer *resampled_buffer = NULL; + juce::AudioBuffer *resampled_buffer = NULL; // SLOW DOWN audio (split audio) - samples = new juce::AudioSampleBuffer(channels, number_of_samples); + samples = new juce::AudioBuffer(channels, number_of_samples); samples->clear(); // Loop through channels, and get audio samples @@ -561,7 +563,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num reader->info.channels); // Allocate a new sample buffer for these delta frames - samples = new juce::AudioSampleBuffer(channels, total_delta_samples); + samples = new juce::AudioBuffer(channels, total_delta_samples); samples->clear(); // Loop through each frame in this delta @@ -569,7 +571,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num delta_frame <= new_frame_number; delta_frame++) { // buffer to hold detal samples int number_of_delta_samples = GetOrCreateFrame(delta_frame)->GetAudioSamplesCount(); - juce::AudioSampleBuffer *delta_samples = new juce::AudioSampleBuffer(channels, + juce::AudioBuffer *delta_samples = new juce::AudioSampleBuffer(channels, number_of_delta_samples); delta_samples->clear(); @@ -605,7 +607,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num reader->info.channels); // Allocate a new sample buffer for these delta frames - samples = new juce::AudioSampleBuffer(channels, total_delta_samples); + samples = new juce::AudioBuffer(channels, total_delta_samples); samples->clear(); // Loop through each frame in this delta @@ -613,7 +615,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num delta_frame >= new_frame_number; delta_frame--) { // buffer to hold delta samples int number_of_delta_samples = GetOrCreateFrame(delta_frame)->GetAudioSamplesCount(); - juce::AudioSampleBuffer *delta_samples = new juce::AudioSampleBuffer(channels, + juce::AudioBuffer *delta_samples = new juce::AudioSampleBuffer(channels, number_of_delta_samples); delta_samples->clear(); @@ -644,7 +646,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num resampler->SetBuffer(samples, float(start) / float(number_of_samples)); // Resample data, and return new buffer pointer - juce::AudioSampleBuffer *buffer = resampler->GetResampledBuffer(); + juce::AudioBuffer *buffer = resampler->GetResampledBuffer(); // Add the newly resized audio samples to the current frame for (int channel = 0; channel < channels; channel++) @@ -656,7 +658,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num } else { // Use the samples on this frame (but maybe reverse them if needed) - samples = new juce::AudioSampleBuffer(channels, number_of_samples); + samples = new juce::AudioBuffer(channels, number_of_samples); samples->clear(); // Loop through channels, and get audio samples diff --git a/src/Clip.h b/src/Clip.h index 011e3f03..c6dffbd2 100644 --- a/src/Clip.h +++ b/src/Clip.h @@ -25,24 +25,23 @@ #include #include -#include -#include "AudioResampler.h" #include "ClipBase.h" +#include "ReaderBase.h" + #include "Color.h" #include "Enums.h" #include "EffectBase.h" -#include "Effects.h" #include "EffectInfo.h" -#include "Frame.h" #include "KeyFrame.h" #include "TrackedObjectBase.h" -#include "ReaderBase.h" -#include +#include namespace openshot { + class AudioResampler; class EffectInfo; + class Frame; /// Comparison method for sorting effect pointers (by Position, Layer, and Order). Effects are sorted /// from lowest layer to top layer (since that is sequence clips are combined), and then by @@ -90,8 +89,8 @@ namespace openshot { */ class Clip : public openshot::ClipBase, public openshot::ReaderBase { protected: - /// Section lock for multiple threads - juce::CriticalSection getFrameCriticalSection; + /// Mutex for multiple threads + std::recursive_mutex getFrameMutex; /// Init default settings for a clip void init_settings(); @@ -149,7 +148,7 @@ namespace openshot { void sort_effects(); /// Reverse an audio buffer - void reverse_buffer(juce::AudioSampleBuffer* buffer); + void reverse_buffer(juce::AudioBuffer* buffer); public: @@ -201,7 +200,7 @@ namespace openshot { std::shared_ptr GetAttachedObject() const { return parentTrackedObject; }; /// Return a pointer to the clip this clip is attached to Clip* GetAttachedClip() const { return parentClipObject; }; - + /// Return the type name of the class std::string Name() override { return "Clip"; }; diff --git a/src/CrashHandler.cpp b/src/CrashHandler.cpp index fca7f890..26018cc5 100644 --- a/src/CrashHandler.cpp +++ b/src/CrashHandler.cpp @@ -12,6 +12,10 @@ #include "CrashHandler.h" +#include +#include +#include + using namespace std; using namespace openshot; @@ -302,4 +306,4 @@ void CrashHandler::printStackTrace(FILE *out, unsigned int max_frames) fprintf(out, "---- End of Stack Trace ----\n"); ZmqLogger::Instance()->LogToFile("---- End of Stack Trace ----\n"); -} \ No newline at end of file +} diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp index 6105324a..f289b306 100644 --- a/src/DummyReader.cpp +++ b/src/DummyReader.cpp @@ -113,7 +113,7 @@ std::shared_ptr DummyReader::GetFrame(int64_t requested_frame) if (dummy_cache_count == 0 && image_frame) { // Create a scoped lock, allowing only a single thread to run the following code at one time - const GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); // Always return same frame (regardless of which frame number was requested) image_frame->number = requested_frame; @@ -121,7 +121,7 @@ std::shared_ptr DummyReader::GetFrame(int64_t requested_frame) } else if (dummy_cache_count > 0) { // Create a scoped lock, allowing only a single thread to run the following code at one time - const GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); // Get a frame from the dummy cache std::shared_ptr f = dummy_cache->GetFrame(requested_frame); diff --git a/src/EffectInfo.cpp b/src/EffectInfo.cpp index 91be9358..7512084d 100644 --- a/src/EffectInfo.cpp +++ b/src/EffectInfo.cpp @@ -11,10 +11,10 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "EffectInfo.h" +#include "Effects.h" using namespace openshot; - // Generate JSON string of this object std::string EffectInfo::Json() { @@ -103,7 +103,7 @@ EffectBase* EffectInfo::CreateEffect(std::string effect_type) { else if(effect_type == "Tracker") return new Tracker(); - + else if(effect_type == "Object Detector") return new ObjectDetection(); #endif diff --git a/src/EffectInfo.h b/src/EffectInfo.h index 13b497ac..c6f14980 100644 --- a/src/EffectInfo.h +++ b/src/EffectInfo.h @@ -13,13 +13,12 @@ #ifndef OPENSHOT_EFFECT_INFO_H #define OPENSHOT_EFFECT_INFO_H -#include "Effects.h" - - +#include "Json.h" namespace openshot { class Clip; + class EffectBase; /** * @brief This class returns a listing of all effects supported by libopenshot * diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index f1ef5922..19d038bf 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -13,6 +13,10 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later +#include // for std::this_thread::sleep_for +#include // for std::chrono::milliseconds +#include + #include "FFmpegUtilities.h" #include "FFmpegReader.h" @@ -20,9 +24,6 @@ #include "Timeline.h" #include "ZmqLogger.h" -#include // for std::this_thread::sleep_for -#include // for std::chrono::milliseconds - #define ENABLE_VAAPI 0 #if USE_HW_ACCEL @@ -583,7 +584,7 @@ void FFmpegReader::Close() { // Clear processed lists { - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processed_video_frames.clear(); processed_audio_frames.clear(); processing_video_frames.clear(); @@ -904,7 +905,7 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame) { int processing_video_frames_size = 0; int processing_audio_frames_size = 0; { - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processing_video_frames_size = processing_video_frames.size(); processing_audio_frames_size = processing_audio_frames.size(); } @@ -912,7 +913,7 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame) { // Wait if too many frames are being processed while (processing_video_frames_size + processing_audio_frames_size >= minimum_packets) { std::this_thread::sleep_for(std::chrono::milliseconds(3)); - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processing_video_frames_size = processing_video_frames.size(); processing_audio_frames_size = processing_audio_frames.size(); } @@ -1236,7 +1237,7 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame) { pFrame = NULL; // Add video frame to list of processing video frames - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processing_video_frames[current_frame] = current_frame; // Create variables for a RGB Frame (since most videos are not in RGB, we must convert it) @@ -1368,7 +1369,7 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame) { // Remove video frame from list of processing video frames { - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processing_video_frames.erase(current_frame); processed_video_frames[current_frame] = current_frame; } @@ -1467,7 +1468,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr // Add audio frame to list of processing audio frames { - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processing_audio_frames.insert(std::pair(previous_packet_location.frame, previous_packet_location.frame)); } @@ -1490,7 +1491,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr // Add audio frame to list of processing audio frames { - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processing_audio_frames.insert(std::pair(previous_packet_location.frame, previous_packet_location.frame)); } @@ -1645,7 +1646,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr // Remove audio frame from list of processing audio frames { - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); // Update all frames as completed for (int64_t f = target_frame; f < starting_frame_number; f++) { // Remove the frame # from the processing list. NOTE: If more than one thread is @@ -1685,7 +1686,7 @@ void FFmpegReader::Seek(int64_t requested_frame) { int processing_video_frames_size = 0; int processing_audio_frames_size = 0; { - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processing_video_frames_size = processing_video_frames.size(); processing_audio_frames_size = processing_audio_frames.size(); } @@ -1696,7 +1697,7 @@ void FFmpegReader::Seek(int64_t requested_frame) { // Wait for any processing frames to complete while (processing_video_frames_size + processing_audio_frames_size > 0) { std::this_thread::sleep_for(std::chrono::milliseconds(3)); - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processing_video_frames_size = processing_video_frames.size(); processing_audio_frames_size = processing_audio_frames.size(); } @@ -1707,7 +1708,7 @@ void FFmpegReader::Seek(int64_t requested_frame) { // Clear processed lists { - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); processing_audio_frames.clear(); processing_video_frames.clear(); processed_video_frames.clear(); @@ -1930,7 +1931,7 @@ int64_t FFmpegReader::ConvertVideoPTStoFrame(int64_t pts) { // Sometimes frames are missing due to varying timestamps, or they were dropped. Determine // if we are missing a video frame. - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); while (current_video_frame < frame) { if (!missing_video_frames.count(current_video_frame)) { ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ConvertVideoPTStoFrame (tracking missing frame)", "current_video_frame", current_video_frame, "previous_video_frame", previous_video_frame); @@ -2023,7 +2024,7 @@ AudioLocation FFmpegReader::GetAudioPTSLocation(int64_t pts) { // Debug output ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAudioPTSLocation (Audio Gap Ignored - too big)", "Previous location frame", previous_packet_location.frame, "Target Frame", location.frame, "Target Audio Sample", location.sample_start, "pts", pts); - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); for (int64_t audio_frame = previous_packet_location.frame; audio_frame < location.frame; audio_frame++) { if (!missing_audio_frames.count(audio_frame)) { ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAudioPTSLocation (tracking missing frame)", "missing_audio_frame", audio_frame, "previous_audio_frame", previous_packet_location.frame, "new location frame", location.frame); @@ -2047,7 +2048,7 @@ std::shared_ptr FFmpegReader::CreateFrame(int64_t requested_frame) { if (!output) { // Lock - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); // (re-)Check working cache output = working_cache.GetFrame(requested_frame); @@ -2089,7 +2090,7 @@ bool FFmpegReader::IsPartialFrame(int64_t requested_frame) { // Check if a frame is missing and attempt to replace its frame image (and bool FFmpegReader::CheckMissingFrame(int64_t requested_frame) { // Lock - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); // Increment check count for this frame (or init to 1) ++checked_frames[requested_frame]; @@ -2205,7 +2206,7 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream, int64_t requested_fram bool is_video_ready = false; bool is_audio_ready = false; { // limit scope of next few lines - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); is_video_ready = processed_video_frames.count(f->number); is_audio_ready = processed_audio_frames.count(f->number); @@ -2268,7 +2269,7 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream, int64_t requested_fram // Add to missing cache (if another frame depends on it) { - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); if (missing_video_frames_source.count(f->number)) { // Debug output ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::CheckWorkingFrames (add frame to missing cache)", "f->number", f->number, "is_seek_trash", is_seek_trash, "Missing Cache Count", missing_frames.Count(), "Working Cache Count", working_cache.Count(), "Final Cache Count", final_cache.Count()); @@ -2420,7 +2421,7 @@ int64_t FFmpegReader::GetSmallestVideoFrame() { // Loop through frame numbers std::map::iterator itr; int64_t smallest_frame = -1; - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); for (itr = processing_video_frames.begin(); itr != processing_video_frames.end(); ++itr) { if (itr->first < smallest_frame || smallest_frame == -1) smallest_frame = itr->first; @@ -2435,7 +2436,7 @@ int64_t FFmpegReader::GetSmallestAudioFrame() { // Loop through frame numbers std::map::iterator itr; int64_t smallest_frame = -1; - const GenericScopedLock lock(processingCriticalSection); + const std::lock_guard lock(processingMutex); for (itr = processing_audio_frames.begin(); itr != processing_audio_frames.end(); ++itr) { if (itr->first < smallest_frame || smallest_frame == -1) smallest_frame = itr->first; diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 0a608cef..f1a7c24f 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -17,6 +17,7 @@ #include "FFmpegWriter.h" #include "Exceptions.h" +#include "Frame.h" #include diff --git a/src/Frame.cpp b/src/Frame.cpp index 155ba2b4..f1817051 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -16,7 +16,13 @@ #include #include "Frame.h" -#include + +#include "AudioBufferSource.h" +#include "AudioResampler.h" + +#include +#include +#include #include #include @@ -41,7 +47,7 @@ using namespace openshot; // Constructor - image & audio Frame::Frame(int64_t number, int width, int height, std::string color, int samples, int channels) - : audio(std::make_shared(channels, samples)), + : audio(std::make_shared>(channels, samples)), number(number), width(width), height(height), pixel_ratio(1,1), color(color), qbuffer(NULL), channels(channels), channel_layout(LAYOUT_STEREO), @@ -99,7 +105,7 @@ void Frame::DeepCopy(const Frame& other) if (other.image) image = std::make_shared(*(other.image)); if (other.audio) - audio = std::make_shared(*(other.audio)); + audio = std::make_shared>(*(other.audio)); if (other.wave_image) wave_image = std::make_shared(*(other.wave_image)); } @@ -319,7 +325,7 @@ float* Frame::GetAudioSamples(int channel) float* Frame::GetPlanarAudioSamples(int new_sample_rate, AudioResampler* resampler, int* sample_count) { float *output = NULL; - juce::AudioSampleBuffer *buffer(audio.get()); + juce::AudioBuffer *buffer(audio.get()); int num_of_channels = audio->getNumChannels(); int num_of_samples = GetAudioSamplesCount(); @@ -365,7 +371,7 @@ float* Frame::GetPlanarAudioSamples(int new_sample_rate, AudioResampler* resampl float* Frame::GetInterleavedAudioSamples(int new_sample_rate, AudioResampler* resampler, int* sample_count) { float *output = NULL; - juce::AudioSampleBuffer *buffer(audio.get()); + juce::AudioBuffer *buffer(audio.get()); int num_of_channels = audio->getNumChannels(); int num_of_samples = GetAudioSamplesCount(); @@ -409,7 +415,7 @@ float* Frame::GetInterleavedAudioSamples(int new_sample_rate, AudioResampler* re // Get number of audio channels int Frame::GetAudioChannelsCount() { - const juce::GenericScopedLock lock(addingAudioSection); + const std::lock_guard lock(addingAudioMutex); if (audio) return audio->getNumChannels(); else @@ -419,11 +425,11 @@ int Frame::GetAudioChannelsCount() // Get number of audio samples int Frame::GetAudioSamplesCount() { - const juce::GenericScopedLock lock(addingAudioSection); + const std::lock_guard lock(addingAudioMutex); return max_audio_sample; } -juce::AudioSampleBuffer *Frame::GetAudioSampleBuffer() +juce::AudioBuffer *Frame::GetAudioSampleBuffer() { return audio.get(); } @@ -724,7 +730,7 @@ int Frame::constrain(int color_value) void Frame::AddColor(int new_width, int new_height, std::string new_color) { - const juce::GenericScopedLock lock(addingImageSection); + const std::lock_guard lock(addingImageMutex); // Update parameters width = new_width; height = new_height; @@ -736,7 +742,7 @@ void Frame::AddColor(int new_width, int new_height, std::string new_color) void Frame::AddColor(const QColor& new_color) { // Create new image object, and fill with pixel data - const juce::GenericScopedLock lock(addingImageSection); + const std::lock_guard lock(addingImageMutex); image = std::make_shared(width, height, QImage::Format_RGBA8888_Premultiplied); // Fill with solid color @@ -751,9 +757,9 @@ void Frame::AddImage( { // Create new buffer { - const juce::GenericScopedLock lock(addingImageSection); + const std::lock_guard lock(addingImageMutex); qbuffer = pixels_; - } // Release addingImageSection lock + } // Release addingImageMutex lock // Create new image object from pixel data auto new_image = std::make_shared( @@ -775,7 +781,7 @@ void Frame::AddImage(std::shared_ptr new_image) return; // assign image data - const juce::GenericScopedLock lock(addingImageSection); + const std::lock_guard lock(addingImageMutex); image = new_image; // Always convert to Format_RGBA8888_Premultiplied (if different) @@ -815,7 +821,7 @@ void Frame::AddImage(std::shared_ptr new_image, bool only_odd_lines) } // Get the frame's image - const juce::GenericScopedLock lock(addingImageSection); + const std::lock_guard lock(addingImageMutex); unsigned char *pixels = image->bits(); const unsigned char *new_pixels = new_image->constBits(); @@ -840,7 +846,7 @@ void Frame::AddImage(std::shared_ptr new_image, bool only_odd_lines) // Resize audio container to hold more (or less) samples and channels void Frame::ResizeAudio(int channels, int length, int rate, ChannelLayout layout) { - const juce::GenericScopedLock lock(addingAudioSection); + const std::lock_guard lock(addingAudioMutex); // Resize JUCE audio buffer audio->setSize(channels, length, true, true, false); @@ -853,7 +859,7 @@ void Frame::ResizeAudio(int channels, int length, int rate, ChannelLayout layout // Add audio samples to a specific channel void Frame::AddAudio(bool replaceSamples, int destChannel, int destStartSample, const float* source, int numSamples, float gainToApplyToSource = 1.0f) { - const juce::GenericScopedLock lock(addingAudioSection); + const std::lock_guard lock(addingAudioMutex); // Clamp starting sample to 0 int destStartSampleAdjusted = max(destStartSample, 0); @@ -882,7 +888,7 @@ void Frame::AddAudio(bool replaceSamples, int destChannel, int destStartSample, // Apply gain ramp (i.e. fading volume) void Frame::ApplyGainRamp(int destChannel, int destStartSample, int numSamples, float initial_gain = 0.0f, float final_gain = 1.0f) { - const juce::GenericScopedLock lock(addingAudioSection); + const std::lock_guard lock(addingAudioMutex); // Apply gain ramp audio->applyGainRamp(destChannel, destStartSample, numSamples, initial_gain, final_gain); @@ -1087,7 +1093,7 @@ void Frame::cleanUpBuffer(void *info) // Add audio silence void Frame::AddAudioSilence(int numSamples) { - const juce::GenericScopedLock lock(addingAudioSection); + const std::lock_guard lock(addingAudioMutex); // Resize audio container audio->setSize(channels, numSamples, false, true, false); diff --git a/src/Frame.h b/src/Frame.h index fdf78239..a7c41427 100644 --- a/src/Frame.h +++ b/src/Frame.h @@ -21,16 +21,14 @@ #undef int64 #endif -#include #include +#include +#include +#include #include "ChannelLayouts.h" -#include "AudioBufferSource.h" -#include "AudioResampler.h" #include "Fraction.h" -#include - #include #include @@ -43,8 +41,14 @@ namespace Magick { class QApplication; +namespace juce { + template class AudioBuffer; +} + namespace openshot { + class AudioBufferSource; + class AudioResampler; /** * @brief This class represents a single frame of video (i.e. image & audio data) * @@ -97,8 +101,8 @@ namespace openshot std::shared_ptr wave_image; std::shared_ptr previewApp; - juce::CriticalSection addingImageSection; - juce::CriticalSection addingAudioSection; + std::recursive_mutex addingImageMutex; + std::recursive_mutex addingAudioMutex; const unsigned char *qbuffer; openshot::Fraction pixel_ratio; int channels; @@ -117,7 +121,7 @@ namespace openshot int constrain(int color_value); public: - std::shared_ptr audio; + std::shared_ptr> audio; int64_t number; ///< This is the frame number (starting at 1) bool has_audio_data; ///< This frame has been loaded with audio data bool has_image_data; ///< This frame has been loaded with pixel data @@ -212,7 +216,7 @@ namespace openshot /// Get number of audio samples int GetAudioSamplesCount(); - juce::AudioSampleBuffer *GetAudioSampleBuffer(); + juce::AudioBuffer *GetAudioSampleBuffer(); /// Get the size in bytes of this frame (rough estimate) int64_t GetBytes(); diff --git a/src/FrameMapper.cpp b/src/FrameMapper.cpp index 59e03782..c405bf26 100644 --- a/src/FrameMapper.cpp +++ b/src/FrameMapper.cpp @@ -391,7 +391,7 @@ std::shared_ptr FrameMapper::GetFrame(int64_t requested_frame) if (final_frame) return final_frame; // Create a scoped lock, allowing only a single thread to run the following code at one time - const GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); // Find parent properties (if any) Clip *parent = (Clip *) ParentClip(); @@ -649,7 +649,7 @@ void FrameMapper::Close() if (reader) { // Create a scoped lock, allowing only a single thread to run the following code at one time - const GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); ZmqLogger::Instance()->AppendDebugMethod("FrameMapper::Close"); diff --git a/src/ImageWriter.cpp b/src/ImageWriter.cpp index eb98d7e7..4c69ef1f 100644 --- a/src/ImageWriter.cpp +++ b/src/ImageWriter.cpp @@ -15,6 +15,8 @@ #include "ImageWriter.h" #include "Exceptions.h" +#include "Frame.h" +#include "ZmqLogger.h" using namespace openshot; diff --git a/src/Qt/AudioPlaybackThread.cpp b/src/Qt/AudioPlaybackThread.cpp index be2585e6..2cde742e 100644 --- a/src/Qt/AudioPlaybackThread.cpp +++ b/src/Qt/AudioPlaybackThread.cpp @@ -12,10 +12,13 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "AudioPlaybackThread.h" +#include "Settings.h" #include // for std::this_thread::sleep_for #include // for std::chrono::milliseconds +using namespace juce; + namespace openshot { diff --git a/src/Qt/AudioPlaybackThread.h b/src/Qt/AudioPlaybackThread.h index 1ae460dd..cd8192f4 100644 --- a/src/Qt/AudioPlaybackThread.h +++ b/src/Qt/AudioPlaybackThread.h @@ -14,11 +14,14 @@ #ifndef OPENSHOT_AUDIO_PLAYBACK_THREAD_H #define OPENSHOT_AUDIO_PLAYBACK_THREAD_H -#include "../ReaderBase.h" -#include "../RendererBase.h" -#include "../AudioReaderSource.h" -#include "../AudioDeviceInfo.h" -#include "../Settings.h" +#include "ReaderBase.h" +#include "RendererBase.h" +#include "AudioReaderSource.h" +#include "AudioDeviceInfo.h" + +#include +#include +#include namespace openshot { diff --git a/src/Qt/VideoCacheThread.cpp b/src/Qt/VideoCacheThread.cpp index e642cddc..2c9d8e7b 100644 --- a/src/Qt/VideoCacheThread.cpp +++ b/src/Qt/VideoCacheThread.cpp @@ -11,7 +11,11 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "VideoCacheThread.h" + +#include "CacheBase.h" #include "Exceptions.h" +#include "Frame.h" +#include "OpenMPUtilities.h" #include "ZmqLogger.h" #include diff --git a/src/Qt/VideoCacheThread.h b/src/Qt/VideoCacheThread.h index 5778eeff..7ef1da8b 100644 --- a/src/Qt/VideoCacheThread.h +++ b/src/Qt/VideoCacheThread.h @@ -13,10 +13,10 @@ #ifndef OPENSHOT_VIDEO_CACHE_THREAD_H #define OPENSHOT_VIDEO_CACHE_THREAD_H -#include "../OpenMPUtilities.h" -#include "../ReaderBase.h" -#include "../RendererBase.h" -#include "../CacheBase.h" +#include "ReaderBase.h" + +#include +#include namespace openshot { diff --git a/src/Qt/VideoPlaybackThread.cpp b/src/Qt/VideoPlaybackThread.cpp index 87c9cdd9..f8df00cc 100644 --- a/src/Qt/VideoPlaybackThread.cpp +++ b/src/Qt/VideoPlaybackThread.cpp @@ -14,6 +14,10 @@ #include "VideoPlaybackThread.h" #include "ZmqLogger.h" +#include "Frame.h" +#include "RendererBase.h" +#include "ZmqLogger.h" + namespace openshot { // Constructor diff --git a/src/Qt/VideoPlaybackThread.h b/src/Qt/VideoPlaybackThread.h index ccb912c0..67bd55c7 100644 --- a/src/Qt/VideoPlaybackThread.h +++ b/src/Qt/VideoPlaybackThread.h @@ -14,11 +14,13 @@ #ifndef OPENSHOT_VIDEO_PLAYBACK_THREAD_H #define OPENSHOT_VIDEO_PLAYBACK_THREAD_H -#include "../ReaderBase.h" -#include "../RendererBase.h" +#include +#include namespace openshot { + class Frame; + class RendererBase; using juce::Thread; using juce::WaitableEvent; diff --git a/src/QtImageReader.cpp b/src/QtImageReader.cpp index ab24e074..ba31bfa0 100644 --- a/src/QtImageReader.cpp +++ b/src/QtImageReader.cpp @@ -11,10 +11,10 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "QtImageReader.h" -#include "Exceptions.h" -#include "Settings.h" + #include "Clip.h" #include "CacheMemory.h" +#include "Exceptions.h" #include "Timeline.h" #include @@ -147,8 +147,8 @@ std::shared_ptr QtImageReader::GetFrame(int64_t requested_frame) if (!is_open) throw ReaderClosed("The Image is closed. Call Open() before calling this method.", path.toStdString()); - // Create a scoped lock, allowing only a single thread to run the following code at one time - const GenericScopedLock lock(getFrameCriticalSection); + // Create a scoped lock, allowing only a single thread to run the following code at one time + const std::lock_guard lock(getFrameMutex); // Calculate max image size QSize current_max_size = calculate_max_size(); diff --git a/src/QtImageReader.h b/src/QtImageReader.h index b4eae09f..fefae02c 100644 --- a/src/QtImageReader.h +++ b/src/QtImageReader.h @@ -41,6 +41,11 @@ class QImage; #include #include +#include +#include + +class QImage; + namespace openshot { // Forward decl diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index b29afa3b..a5c9b0dd 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -13,6 +13,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "QtTextReader.h" +#include "CacheBase.h" #include "Exceptions.h" #include "Frame.h" diff --git a/src/QtTextReader.h b/src/QtTextReader.h index 60e9ae0b..f9a5216d 100644 --- a/src/QtTextReader.h +++ b/src/QtTextReader.h @@ -19,7 +19,6 @@ #include -#include "CacheMemory.h" #include "Enums.h" #include @@ -30,6 +29,7 @@ namespace openshot { // Forward decls class CacheBase; + class Frame; /** * @brief This class uses Qt libraries, to create frames with "Text", and return diff --git a/src/ReaderBase.cpp b/src/ReaderBase.cpp index 95267a69..c2cf0552 100644 --- a/src/ReaderBase.cpp +++ b/src/ReaderBase.cpp @@ -20,6 +20,7 @@ #include "Json.h" + using namespace openshot; /// Constructor for the base reader, where many things are initialized. diff --git a/src/ReaderBase.h b/src/ReaderBase.h index 3279ca33..27f97e65 100644 --- a/src/ReaderBase.h +++ b/src/ReaderBase.h @@ -15,6 +15,8 @@ #include #include +#include +#include #include #include @@ -22,14 +24,11 @@ #include "Fraction.h" #include "Json.h" -#include - namespace openshot { - class ClipBase; class CacheBase; + class ClipBase; class Frame; - /** * @brief This struct contains info about a media file, such as height, width, frames per second, etc... * @@ -76,9 +75,9 @@ namespace openshot class ReaderBase { protected: - /// Section lock for multiple threads - juce::CriticalSection getFrameCriticalSection; - juce::CriticalSection processingCriticalSection; + /// 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 20349c3f..0de6045f 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -468,7 +468,7 @@ int64_t Timeline::GetMaxFrame() { void Timeline::apply_mapper_to_clip(Clip* clip) { // Get lock (prevent getting frames while this happens) - const GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); // Determine type of reader ReaderBase* clip_reader = NULL; @@ -773,7 +773,7 @@ std::shared_ptr Timeline::GetFrame(int64_t requested_frame) else { // Create a scoped lock, allowing only a single thread to run the following code at one time - const GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); // Check for open reader (or throw exception) if (!is_open) @@ -1005,7 +1005,7 @@ Json::Value Timeline::JsonValue() const { void Timeline::SetJson(const std::string value) { // Get lock (prevent getting frames while this happens) - const GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); // Parse JSON string into JSON objects try @@ -1047,7 +1047,7 @@ void Timeline::SetJsonValue(const Json::Value root) { // When a clip is attached to an object, it searches for the object // on it's parent timeline. Setting the parent timeline of the clip here // allows attaching it to an object when exporting the project (because) - // the exporter script initializes the clip and it's effects + // the exporter script initializes the clip and it's effects // before setting its parent timeline. c->ParentTimeline(this); @@ -1101,7 +1101,7 @@ void Timeline::SetJsonValue(const Json::Value root) { void Timeline::ApplyJsonDiff(std::string value) { // Get lock (prevent getting frames while this happens) - const GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); // Parse JSON string into JSON objects try @@ -1480,7 +1480,7 @@ void Timeline::apply_json_to_timeline(Json::Value change) { void Timeline::ClearAllCache() { // Get lock (prevent getting frames while this happens) - const GenericScopedLock lock(getFrameCriticalSection); + const std::lock_guard lock(getFrameMutex); // Clear primary cache final_cache->Clear(); diff --git a/src/WriterBase.cpp b/src/WriterBase.cpp index 23534df1..58f213a6 100644 --- a/src/WriterBase.cpp +++ b/src/WriterBase.cpp @@ -15,6 +15,8 @@ #include "WriterBase.h" #include "Exceptions.h" +#include "Frame.h" +#include "ReaderBase.h" using namespace openshot; diff --git a/src/WriterBase.h b/src/WriterBase.h index 0b928815..1be233a2 100644 --- a/src/WriterBase.h +++ b/src/WriterBase.h @@ -17,12 +17,12 @@ #include "ChannelLayouts.h" #include "Fraction.h" -#include "Frame.h" -#include "ReaderBase.h" -#include "ZmqLogger.h" +#include "Json.h" namespace openshot { + class ReaderBase; + class Frame; /** * @brief This struct contains info about encoding a media file, such as height, width, frames per second, etc... * diff --git a/src/ZmqLogger.cpp b/src/ZmqLogger.cpp index 0b195790..2b39769e 100644 --- a/src/ZmqLogger.cpp +++ b/src/ZmqLogger.cpp @@ -12,6 +12,7 @@ #include "ZmqLogger.h" #include "Exceptions.h" +#include "Settings.h" #if USE_RESVG == 1 #include "ResvgQt.h" @@ -62,7 +63,7 @@ ZmqLogger *ZmqLogger::Instance() void ZmqLogger::Connection(std::string new_connection) { // Create a scoped lock, allowing only a single thread to run the following code at one time - const juce::GenericScopedLock lock(loggerCriticalSection); + const std::lock_guard lock(loggerMutex); // Does anything need to happen? if (new_connection == connection) @@ -106,7 +107,7 @@ void ZmqLogger::Log(std::string message) return; // Create a scoped lock, allowing only a single thread to run the following code at one time - const juce::GenericScopedLock lock(loggerCriticalSection); + const std::lock_guard lock(loggerMutex); // Send message over socket (ZeroMQ) zmq::message_t reply (message.length()); @@ -183,7 +184,7 @@ void ZmqLogger::AppendDebugMethod(std::string method_name, { // Create a scoped lock, allowing only a single thread to run the following code at one time - const juce::GenericScopedLock lock(loggerCriticalSection); + const std::lock_guard lock(loggerMutex); std::stringstream message; message << std::fixed << std::setprecision(4); diff --git a/src/ZmqLogger.h b/src/ZmqLogger.h index a12b9ce4..e2be22e5 100644 --- a/src/ZmqLogger.h +++ b/src/ZmqLogger.h @@ -14,19 +14,12 @@ #define OPENSHOT_LOGGER_H -#include -#include #include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include "Settings.h" +#include namespace openshot { @@ -38,7 +31,7 @@ namespace openshot { */ class ZmqLogger { private: - juce::CriticalSection loggerCriticalSection; + std::recursive_mutex loggerMutex; std::string connection; // Logfile related vars diff --git a/src/audio_effects/Compressor.cpp b/src/audio_effects/Compressor.cpp index baad073a..a35edf21 100644 --- a/src/audio_effects/Compressor.cpp +++ b/src/audio_effects/Compressor.cpp @@ -1,7 +1,7 @@ /** * @file * @brief Source file for Compressor audio effect class - * @author + * @author * * @ref License */ @@ -12,18 +12,16 @@ #include "Compressor.h" #include "Exceptions.h" +#include "Frame.h" using namespace openshot; -/// Blank constructor, useful when using Json to load the effect properties -Compressor::Compressor() : threshold(-10), ratio(1), attack(1), release(1), makeup_gain(1), bypass(false) { - // Init effect properties - init_effect_details(); -} +Compressor::Compressor() : Compressor::Compressor(-10, 1, 1, 1, 1, false) {} -// Default constructor -Compressor::Compressor(Keyframe new_threshold, Keyframe new_ratio, Keyframe new_attack, Keyframe new_release, Keyframe new_makeup_gain, Keyframe new_bypass) : - threshold(new_threshold), ratio(new_ratio), attack(new_attack), release(new_release), makeup_gain(new_makeup_gain), bypass(new_bypass) +Compressor::Compressor(Keyframe new_threshold, Keyframe new_ratio, Keyframe new_attack, Keyframe new_release, Keyframe new_makeup_gain, Keyframe new_bypass) : + threshold(new_threshold), ratio(new_ratio), attack(new_attack), + release(new_release), makeup_gain(new_makeup_gain), bypass(new_bypass), + input_level(0.0), yl_prev(0.0) { // Init effect properties init_effect_details(); @@ -41,9 +39,6 @@ void Compressor::init_effect_details() info.description = "Reduce the volume of loud sounds or amplify quiet sounds."; info.has_audio = true; info.has_video = false; - - input_level = 0.0f; - yl_prev = 0.0f; } // This method is required for all derived classes of EffectBase, and returns a @@ -58,7 +53,7 @@ std::shared_ptr Compressor::GetFrame(std::shared_ptrSampleRate(); inverseE = 1.0f / M_E; - + if ((bool)bypass.GetValue(frame_number)) return frame; @@ -74,7 +69,7 @@ std::shared_ptr Compressor::GetFrame(std::shared_ptr #include -#include +#include +#include namespace openshot { - + class Frame; /** * @brief This class adds a compressor into the audio * @@ -37,7 +37,7 @@ namespace openshot private: /// Init effect settings void init_effect_details(); - + public: Keyframe threshold; @@ -47,7 +47,7 @@ namespace openshot Keyframe makeup_gain; Keyframe bypass; - juce::AudioSampleBuffer mixed_down_input; + juce::AudioBuffer mixed_down_input; float xl; float yl; float xg; @@ -76,8 +76,8 @@ namespace openshot /// /// @returns A new openshot::Frame object /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. - std::shared_ptr GetFrame(int64_t frame_number) override { - return GetFrame(std::make_shared(), frame_number); + std::shared_ptr GetFrame(int64_t frame_number) override { + return GetFrame(std::make_shared(), frame_number); } /// @brief This method is required for all derived classes of ClipBase, and returns a diff --git a/src/audio_effects/Delay.cpp b/src/audio_effects/Delay.cpp index 3c432c8c..ff886d79 100644 --- a/src/audio_effects/Delay.cpp +++ b/src/audio_effects/Delay.cpp @@ -1,7 +1,7 @@ /** * @file * @brief Source file for Delay audio effect class - * @author + * @author * * @ref License */ @@ -12,6 +12,7 @@ #include "Delay.h" #include "Exceptions.h" +#include "Frame.h" using namespace openshot; @@ -84,7 +85,7 @@ std::shared_ptr Delay::GetFrame(std::shared_ptr #include -#include -#include +#include +#include namespace openshot { + class Frame; /** * @brief This class adds a delay into the audio @@ -39,9 +39,9 @@ namespace openshot void init_effect_details(); public: - Keyframe delay_time; + Keyframe delay_time; - juce::AudioSampleBuffer delay_buffer; + juce::AudioBuffer delay_buffer; int delay_buffer_samples; int delay_buffer_channels; int delay_write_position; @@ -59,8 +59,8 @@ namespace openshot /// /// @returns A new openshot::Frame object /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. - std::shared_ptr GetFrame(int64_t frame_number) override { - return GetFrame(std::make_shared(), frame_number); + std::shared_ptr GetFrame(int64_t frame_number) override { + return GetFrame(std::make_shared(), frame_number); } void setup(std::shared_ptr frame); diff --git a/src/audio_effects/Distortion.h b/src/audio_effects/Distortion.h index 3125a59a..ba7cf892 100644 --- a/src/audio_effects/Distortion.h +++ b/src/audio_effects/Distortion.h @@ -1,7 +1,7 @@ /** * @file * @brief Header file for Distortion audio effect class - * @author + * @author * * @ref License */ @@ -14,22 +14,22 @@ #define OPENSHOT_DISTORTION_AUDIO_EFFECT_H #define _USE_MATH_DEFINES -#include "../EffectBase.h" +#include "EffectBase.h" -#include "../Frame.h" -#include "../Json.h" -#include "../KeyFrame.h" -#include "../Enums.h" +#include "Json.h" +#include "KeyFrame.h" +#include "Enums.h" #include #include -#include -// #include +#include +#include +#include namespace openshot { - + class Frame; /** * @brief This class adds a distortion into the audio * @@ -42,8 +42,8 @@ namespace openshot public: openshot::DistortionType distortion_type; - Keyframe input_gain; - Keyframe output_gain; + Keyframe input_gain; + Keyframe output_gain; Keyframe tone; /// Blank constructor, useful when using Json to load the effect properties @@ -60,8 +60,8 @@ namespace openshot /// /// @returns A new openshot::Frame object /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. - std::shared_ptr GetFrame(int64_t frame_number) override { - return GetFrame(std::make_shared(), frame_number); + std::shared_ptr GetFrame(int64_t frame_number) override { + return GetFrame(std::make_shared(), frame_number); } /// @brief This method is required for all derived classes of ClipBase, and returns a diff --git a/src/audio_effects/Echo.cpp b/src/audio_effects/Echo.cpp index a58bed15..7667c62d 100644 --- a/src/audio_effects/Echo.cpp +++ b/src/audio_effects/Echo.cpp @@ -1,7 +1,7 @@ /** * @file * @brief Source file for Echo audio effect class - * @author + * @author * * @ref License */ @@ -12,17 +12,13 @@ #include "Echo.h" #include "Exceptions.h" +#include "Frame.h" using namespace openshot; -/// Blank constructor, useful when using Json to load the effect properties -Echo::Echo() : echo_time(0.1), feedback(0.5), mix(0.5) { - // Init effect properties - init_effect_details(); -} +Echo::Echo() : Echo::Echo(0.1, 0.5, 0.5) { } -// Default constructor -Echo::Echo(Keyframe new_echo_time, Keyframe new_feedback, Keyframe new_mix) : +Echo::Echo(Keyframe new_echo_time, Keyframe new_feedback, Keyframe new_mix) : echo_time(new_echo_time), feedback(new_feedback), mix(new_mix) { // Init effect properties @@ -87,7 +83,7 @@ std::shared_ptr Echo::GetFrame(std::shared_ptr float read_position = fmodf((float)local_write_position - echo_time_value + (float)echo_buffer_samples, echo_buffer_samples); int local_read_position = floorf(read_position); - if (local_read_position != local_write_position) + if (local_read_position != local_write_position) { float fraction = read_position - (float)local_read_position; float echoed1 = echo_data[(local_read_position + 0)]; diff --git a/src/audio_effects/Echo.h b/src/audio_effects/Echo.h index 597ec180..8d16e292 100644 --- a/src/audio_effects/Echo.h +++ b/src/audio_effects/Echo.h @@ -1,7 +1,7 @@ /** * @file * @brief Header file for Echo audio effect class - * @author + * @author * * @ref License */ @@ -13,20 +13,20 @@ #ifndef OPENSHOT_ECHO_AUDIO_EFFECT_H #define OPENSHOT_ECHO_AUDIO_EFFECT_H -#include "../EffectBase.h" +#include "EffectBase.h" -#include "../Frame.h" -#include "../Json.h" -#include "../KeyFrame.h" +#include "Json.h" +#include "KeyFrame.h" #include #include -#include -#include +#include +#include namespace openshot { + class Frame; /** * @brief This class adds a echo into the audio @@ -39,11 +39,11 @@ namespace openshot void init_effect_details(); public: - Keyframe echo_time; - Keyframe feedback; + Keyframe echo_time; + Keyframe feedback; Keyframe mix; - juce::AudioSampleBuffer echo_buffer; + juce::AudioBuffer echo_buffer; int echo_buffer_samples; int echo_buffer_channels; int echo_write_position; @@ -61,8 +61,8 @@ namespace openshot /// /// @returns A new openshot::Frame object /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. - std::shared_ptr GetFrame(int64_t frame_number) override { - return GetFrame(std::make_shared(), frame_number); + std::shared_ptr GetFrame(int64_t frame_number) override { + return GetFrame(std::make_shared(), frame_number); } void setup(std::shared_ptr frame); diff --git a/src/audio_effects/Expander.cpp b/src/audio_effects/Expander.cpp index 2c023de2..d08cc340 100644 --- a/src/audio_effects/Expander.cpp +++ b/src/audio_effects/Expander.cpp @@ -1,7 +1,7 @@ /** * @file * @brief Source file for Expander audio effect class - * @author + * @author * * @ref License */ @@ -12,6 +12,7 @@ #include "Expander.h" #include "Exceptions.h" +#include "Frame.h" using namespace openshot; @@ -22,7 +23,7 @@ Expander::Expander() : threshold(-10), ratio(1), attack(1), release(1), makeup_g } // Default constructor -Expander::Expander(Keyframe new_threshold, Keyframe new_ratio, Keyframe new_attack, Keyframe new_release, Keyframe new_makeup_gain, Keyframe new_bypass) : +Expander::Expander(Keyframe new_threshold, Keyframe new_ratio, Keyframe new_attack, Keyframe new_release, Keyframe new_makeup_gain, Keyframe new_bypass) : threshold(new_threshold), ratio(new_ratio), attack(new_attack), release(new_release), makeup_gain(new_makeup_gain), bypass(new_bypass) { // Init effect properties @@ -60,7 +61,7 @@ std::shared_ptr Expander::GetFrame(std::shared_ptrSampleRate(); inverseE = 1.0f / M_E; - + if ((bool)bypass.GetValue(frame_number)) return frame; @@ -76,12 +77,12 @@ std::shared_ptr Expander::GetFrame(std::shared_ptr T) yg = xg; else diff --git a/src/audio_effects/Expander.h b/src/audio_effects/Expander.h index 921cd055..202bbd16 100644 --- a/src/audio_effects/Expander.h +++ b/src/audio_effects/Expander.h @@ -1,7 +1,7 @@ /** * @file * @brief Header file for Expander audio effect class - * @author + * @author * * @ref License */ @@ -13,20 +13,21 @@ #ifndef OPENSHOT_EXPANDER_AUDIO_EFFECT_H #define OPENSHOT_EXPANDER_AUDIO_EFFECT_H -#include "../EffectBase.h" +#include "EffectBase.h" -#include "../Frame.h" -#include "../Json.h" -#include "../KeyFrame.h" -#include "../Enums.h" +#include "Json.h" +#include "KeyFrame.h" +#include "Enums.h" #include #include -#include +#include +#include namespace openshot { + class Frame; /** * @brief This class adds a expander (or noise gate) into the audio @@ -37,7 +38,7 @@ namespace openshot private: /// Init effect settings void init_effect_details(); - + public: Keyframe threshold; @@ -47,7 +48,7 @@ namespace openshot Keyframe makeup_gain; Keyframe bypass; - juce::AudioSampleBuffer mixed_down_input; + juce::AudioBuffer mixed_down_input; float xl; float yl; float xg; @@ -76,8 +77,8 @@ namespace openshot /// /// @returns A new openshot::Frame object /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. - std::shared_ptr GetFrame(int64_t frame_number) override { - return GetFrame(std::make_shared(), frame_number); + std::shared_ptr GetFrame(int64_t frame_number) override { + return GetFrame(std::make_shared(), frame_number); } /// @brief This method is required for all derived classes of ClipBase, and returns a diff --git a/src/audio_effects/Noise.cpp b/src/audio_effects/Noise.cpp index 5347ea12..df869d67 100644 --- a/src/audio_effects/Noise.cpp +++ b/src/audio_effects/Noise.cpp @@ -1,7 +1,7 @@ /** * @file * @brief Source file for Noise audio effect class - * @author + * @author * * @ref License */ @@ -12,6 +12,10 @@ #include "Noise.h" #include "Exceptions.h" +#include "Frame.h" + +#include +#include using namespace openshot; @@ -59,7 +63,7 @@ std::shared_ptr Noise::GetFrame(std::shared_ptr #include -#include -// #include +#include +#include namespace openshot { + class Frame; /** * @brief This class adds a equalization into the audio @@ -41,8 +41,8 @@ namespace openshot void init_effect_details(); public: - openshot::FilterType filter_type; - Keyframe frequency; + openshot::FilterType filter_type; + Keyframe frequency; Keyframe q_factor; Keyframe gain; bool initialized; @@ -52,7 +52,7 @@ namespace openshot /// Default constructor /// - /// @param new_level + /// @param new_level ParametricEQ(openshot::FilterType new_filter_type, Keyframe new_frequency, Keyframe new_gain, Keyframe new_q_factor); /// @brief This method is required for all derived classes of ClipBase, and returns a @@ -61,8 +61,8 @@ namespace openshot /// /// @returns A new openshot::Frame object /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. - std::shared_ptr GetFrame(int64_t frame_number) override { - return GetFrame(std::make_shared(), frame_number); + std::shared_ptr GetFrame(int64_t frame_number) override { + return GetFrame(std::make_shared(), frame_number); } /// @brief This method is required for all derived classes of ClipBase, and returns a @@ -86,7 +86,7 @@ namespace openshot /// of all properties at any time) std::string PropertiesJSON(int64_t requested_frame) const override; - class Filter : public IIRFilter + class Filter : public juce::IIRFilter { public: void updateCoefficients (const double discrete_frequency, diff --git a/src/audio_effects/Robotization.cpp b/src/audio_effects/Robotization.cpp index be3aeccd..c3a3792e 100644 --- a/src/audio_effects/Robotization.cpp +++ b/src/audio_effects/Robotization.cpp @@ -1,7 +1,7 @@ /** * @file * @brief Source file for Robotization audio effect class - * @author + * @author * * @ref License */ @@ -12,9 +12,10 @@ #include "Robotization.h" #include "Exceptions.h" +#include "Frame.h" using namespace openshot; - +using namespace juce; /// Blank constructor, useful when using Json to load the effect properties Robotization::Robotization() : fft_size(FFT_SIZE_512), hop_size(HOP_SIZE_2), window_type(RECTANGULAR), stft(*this) { @@ -23,7 +24,7 @@ Robotization::Robotization() : fft_size(FFT_SIZE_512), hop_size(HOP_SIZE_2), win } // Default constructor -Robotization::Robotization(openshot::FFTSize new_fft_size, openshot::HopSize new_hop_size, openshot::WindowType new_window_type) : +Robotization::Robotization(openshot::FFTSize new_fft_size, openshot::HopSize new_hop_size, openshot::WindowType new_window_type) : fft_size(new_fft_size), hop_size(new_hop_size), window_type(new_window_type), stft(*this) { // Init effect properties @@ -48,14 +49,14 @@ void Robotization::init_effect_details() // modified openshot::Frame object std::shared_ptr Robotization::GetFrame(std::shared_ptr frame, int64_t frame_number) { - const ScopedLock sl (lock); + const std::lock_guard lock(mutex); ScopedNoDenormals noDenormals; const int num_input_channels = frame->audio->getNumChannels(); const int num_output_channels = frame->audio->getNumChannels(); const int num_samples = frame->audio->getNumSamples(); - const int hop_size_value = 1 << ((int)hop_size + 1); - const int fft_size_value = 1 << ((int)fft_size + 5); + const int hop_size_value = 1 << ((int)hop_size + 1); + const int fft_size_value = 1 << ((int)fft_size + 5); stft.setup(num_output_channels); stft.updateParameters((int)fft_size_value, @@ -157,7 +158,7 @@ std::string Robotization::PropertiesJSON(int64_t requested_frame) const { root["fft_size"]["choices"].append(add_property_choice_json("512", FFT_SIZE_512, fft_size)); root["fft_size"]["choices"].append(add_property_choice_json("1024", FFT_SIZE_1024, fft_size)); root["fft_size"]["choices"].append(add_property_choice_json("2048", FFT_SIZE_2048, fft_size)); - + // Add hop_size choices (dropdown style) root["hop_size"]["choices"].append(add_property_choice_json("1/2", HOP_SIZE_2, hop_size)); root["hop_size"]["choices"].append(add_property_choice_json("1/4", HOP_SIZE_4, hop_size)); @@ -168,7 +169,7 @@ std::string Robotization::PropertiesJSON(int64_t requested_frame) const { root["window_type"]["choices"].append(add_property_choice_json("Bart Lett", BART_LETT, window_type)); root["window_type"]["choices"].append(add_property_choice_json("Hann", HANN, window_type)); root["window_type"]["choices"].append(add_property_choice_json("Hamming", HAMMING, window_type)); - + // Return formatted string return root.toStyledString(); -} \ No newline at end of file +} diff --git a/src/audio_effects/Robotization.h b/src/audio_effects/Robotization.h index 02dc6a4b..cf24b7f7 100644 --- a/src/audio_effects/Robotization.h +++ b/src/audio_effects/Robotization.h @@ -1,7 +1,7 @@ /** * @file * @brief Header file for Robotization audio effect class - * @author + * @author * * @ref License */ @@ -14,22 +14,26 @@ #define OPENSHOT_ROBOTIZATION_AUDIO_EFFECT_H #define _USE_MATH_DEFINES -#include "../EffectBase.h" +#include +#include +#include + +#include "EffectBase.h" -#include "../Frame.h" -#include "../Json.h" -#include "../KeyFrame.h" -#include "../Enums.h" #include "STFT.h" -#include -#include -#include -#include - +#include "Json.h" +#include "KeyFrame.h" +#include "Enums.h" +namespace juce { + namespace dsp { + class FFT; + } +} namespace openshot { + class Frame; /** * @brief This class adds a robotization effect into the audio @@ -60,8 +64,8 @@ namespace openshot /// /// @returns A new openshot::Frame object /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. - std::shared_ptr GetFrame(int64_t frame_number) override { - return GetFrame(std::make_shared(), frame_number); + std::shared_ptr GetFrame(int64_t frame_number) override { + return GetFrame(std::make_shared(), frame_number); } /// @brief This method is required for all derived classes of ClipBase, and returns a @@ -97,11 +101,11 @@ namespace openshot Robotization &parent; }; - juce::CriticalSection lock; + std::recursive_mutex mutex; RobotizationEffect stft; std::unique_ptr fft; }; -} +} // namespace -#endif +#endif // OPENSHOT_ROBOTIZATION_AUDIO_EFFECT_H diff --git a/src/audio_effects/STFT.cpp b/src/audio_effects/STFT.cpp index 043b2134..ba5d6816 100644 --- a/src/audio_effects/STFT.cpp +++ b/src/audio_effects/STFT.cpp @@ -18,7 +18,7 @@ void STFT::updateParameters(const int new_fft_size, const int new_overlap, const updateWindow(new_window_type); } -void STFT::process(juce::AudioSampleBuffer &block) +void STFT::process(juce::AudioBuffer &block) { num_samples = block.getNumSamples(); diff --git a/src/audio_effects/STFT.h b/src/audio_effects/STFT.h index 9cd1505d..43f04eba 100644 --- a/src/audio_effects/STFT.h +++ b/src/audio_effects/STFT.h @@ -8,8 +8,12 @@ #define OPENSHOT_STFT_AUDIO_EFFECT_H #define _USE_MATH_DEFINES -#include "../EffectBase.h" -#include "../Enums.h" +#include "EffectBase.h" +#include "Enums.h" + +#include +#include +#include namespace openshot { @@ -18,23 +22,23 @@ namespace openshot { public: STFT() : num_channels (1) { } - + virtual ~STFT() { } void setup(const int num_input_channels); - void process(juce::AudioSampleBuffer &block); + void process(juce::AudioBuffer &block); void updateParameters(const int new_fft_size, const int new_overlap, const int new_window_type); virtual void updateFftSize(const int new_fft_size); - + virtual void updateHopSize(const int new_overlap); virtual void updateWindow(const int new_window_type); - + private: - + virtual void modification(const int channel); virtual void analysis(const int channel); @@ -49,10 +53,10 @@ namespace openshot std::unique_ptr fft; int input_buffer_length; - juce::AudioSampleBuffer input_buffer; + juce::AudioBuffer input_buffer; int output_buffer_length; - juce::AudioSampleBuffer output_buffer; + juce::AudioBuffer output_buffer; juce::HeapBlock fft_window; juce::HeapBlock> time_domain_buffer; diff --git a/src/audio_effects/Whisperization.cpp b/src/audio_effects/Whisperization.cpp index aff1f8d0..41162a2c 100644 --- a/src/audio_effects/Whisperization.cpp +++ b/src/audio_effects/Whisperization.cpp @@ -1,7 +1,7 @@ /** * @file * @brief Source file for Whisperization audio effect class - * @author + * @author * * @ref License */ @@ -12,8 +12,10 @@ #include "Whisperization.h" #include "Exceptions.h" +#include "Frame.h" using namespace openshot; +using namespace juce; /// Blank constructor, useful when using Json to load the effect properties Whisperization::Whisperization() : fft_size(FFT_SIZE_512), hop_size(HOP_SIZE_8), window_type(RECTANGULAR), stft(*this) { @@ -22,7 +24,7 @@ Whisperization::Whisperization() : fft_size(FFT_SIZE_512), hop_size(HOP_SIZE_8), } // Default constructor -Whisperization::Whisperization(openshot::FFTSize new_fft_size, openshot::HopSize new_hop_size, openshot::WindowType new_window_type) : +Whisperization::Whisperization(openshot::FFTSize new_fft_size, openshot::HopSize new_hop_size, openshot::WindowType new_window_type) : fft_size(new_fft_size), hop_size(new_hop_size), window_type(new_window_type), stft(*this) { // Init effect properties @@ -47,14 +49,14 @@ void Whisperization::init_effect_details() // modified openshot::Frame object std::shared_ptr Whisperization::GetFrame(std::shared_ptr frame, int64_t frame_number) { - const ScopedLock sl (lock); + const std::lock_guard lock(mutex); ScopedNoDenormals noDenormals; const int num_input_channels = frame->audio->getNumChannels(); const int num_output_channels = frame->audio->getNumChannels(); const int num_samples = frame->audio->getNumSamples(); - const int hop_size_value = 1 << ((int)hop_size + 1); - const int fft_size_value = 1 << ((int)fft_size + 5); + const int hop_size_value = 1 << ((int)hop_size + 1); + const int fft_size_value = 1 << ((int)fft_size + 5); stft.setup(num_output_channels); stft.updateParameters((int)fft_size_value, @@ -77,7 +79,7 @@ void Whisperization::WhisperizationEffect::modification(const int channel) frequency_domain_buffer[index].real(magnitude * cosf(phase)); frequency_domain_buffer[index].imag(magnitude * sinf(phase)); - + if (index > 0 && index < fft_size / 2) { frequency_domain_buffer[fft_size - index].real(magnitude * cosf (phase)); frequency_domain_buffer[fft_size - index].imag(magnitude * sinf (-phase)); @@ -164,7 +166,7 @@ std::string Whisperization::PropertiesJSON(int64_t requested_frame) const { root["fft_size"]["choices"].append(add_property_choice_json("512", FFT_SIZE_512, fft_size)); root["fft_size"]["choices"].append(add_property_choice_json("1024", FFT_SIZE_1024, fft_size)); root["fft_size"]["choices"].append(add_property_choice_json("2048", FFT_SIZE_2048, fft_size)); - + // Add hop_size choices (dropdown style) root["hop_size"]["choices"].append(add_property_choice_json("1/2", HOP_SIZE_2, hop_size)); root["hop_size"]["choices"].append(add_property_choice_json("1/4", HOP_SIZE_4, hop_size)); @@ -175,7 +177,7 @@ std::string Whisperization::PropertiesJSON(int64_t requested_frame) const { root["window_type"]["choices"].append(add_property_choice_json("Bart Lett", BART_LETT, window_type)); root["window_type"]["choices"].append(add_property_choice_json("Hann", HANN, window_type)); root["window_type"]["choices"].append(add_property_choice_json("Hamming", HAMMING, window_type)); - + // Return formatted string return root.toStyledString(); diff --git a/src/audio_effects/Whisperization.h b/src/audio_effects/Whisperization.h index b5a4ae1e..5a75d237 100644 --- a/src/audio_effects/Whisperization.h +++ b/src/audio_effects/Whisperization.h @@ -1,7 +1,7 @@ /** * @file * @brief Header file for whisperization audio effect class - * @author + * @author * * @ref License */ @@ -14,23 +14,26 @@ #define OPENSHOT_WHISPERIZATION_AUDIO_EFFECT_H #define _USE_MATH_DEFINES +#include +#include +#include + #include "../EffectBase.h" -#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" #include "../Enums.h" #include "STFT.h" -#include -#include -#include -#include - +namespace juce { + namespace dsp { + class FFT; + } +} namespace openshot { - + class Frame; /** * @brief This class adds a whisperization effect into the audio * @@ -60,8 +63,8 @@ namespace openshot /// /// @returns A new openshot::Frame object /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. - std::shared_ptr GetFrame(int64_t frame_number) override { - return GetFrame(std::make_shared(), frame_number); + std::shared_ptr GetFrame(int64_t frame_number) override { + return GetFrame(std::make_shared(), frame_number); } /// @brief This method is required for all derived classes of ClipBase, and returns a @@ -97,7 +100,7 @@ namespace openshot Whisperization &parent; }; - juce::CriticalSection lock; + std::recursive_mutex mutex; WhisperizationEffect stft; std::unique_ptr fft; }; diff --git a/src/effects/Mask.cpp b/src/effects/Mask.cpp index 2c46a359..69f6e63f 100644 --- a/src/effects/Mask.cpp +++ b/src/effects/Mask.cpp @@ -11,12 +11,17 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "Mask.h" + #include "Exceptions.h" + +#include "ReaderBase.h" +#include "ChunkReader.h" #include "FFmpegReader.h" +#include "QtImageReader.h" + #ifdef USE_IMAGEMAGICK #include "ImageReader.h" #endif -#include "ReaderBase.h" using namespace openshot; diff --git a/src/effects/ObjectDetection.h b/src/effects/ObjectDetection.h index 0bbe8d28..d45ab4c6 100644 --- a/src/effects/ObjectDetection.h +++ b/src/effects/ObjectDetection.h @@ -18,7 +18,7 @@ #include -#include +#include "OpenCVUtilities.h" #include "Json.h" #include "KeyFrame.h" diff --git a/tests/CVTracker.cpp b/tests/CVTracker.cpp index 19d0c0fa..c5b014bc 100644 --- a/tests/CVTracker.cpp +++ b/tests/CVTracker.cpp @@ -19,6 +19,7 @@ #include "Clip.h" #include "CVTracker.h" // for FrameData, CVTracker #include "ProcessingController.h" +#include "Exceptions.h" using namespace openshot; diff --git a/tests/Clip.cpp b/tests/Clip.cpp index a31241dc..b875b79c 100644 --- a/tests/Clip.cpp +++ b/tests/Clip.cpp @@ -21,10 +21,12 @@ #include "Clip.h" #include "Enums.h" +#include "Exceptions.h" #include "Frame.h" #include "Fraction.h" #include "Timeline.h" #include "Json.h" +#include "effects/Negate.h" using namespace openshot; diff --git a/tests/FrameMapper.cpp b/tests/FrameMapper.cpp index 6065bf50..65429347 100644 --- a/tests/FrameMapper.cpp +++ b/tests/FrameMapper.cpp @@ -15,6 +15,7 @@ #include "CacheMemory.h" #include "Clip.h" #include "DummyReader.h" +#include "Exceptions.h" #include "FFmpegReader.h" #include "Fraction.h" #include "Frame.h" diff --git a/tests/KeyFrame.cpp b/tests/KeyFrame.cpp index 806d1847..1826befb 100644 --- a/tests/KeyFrame.cpp +++ b/tests/KeyFrame.cpp @@ -16,16 +16,18 @@ #include #include "KeyFrame.h" -#include "Exceptions.h" #include "Coordinate.h" -#include "Fraction.h" #include "Clip.h" +#include "Exceptions.h" +#include "FFmpegReader.h" +#include "Fraction.h" +#include "Point.h" #include "Timeline.h" + #ifdef USE_OPENCV #include "effects/Tracker.h" #include "TrackedObjectBBox.h" #endif -#include "Point.h" using namespace openshot; diff --git a/tests/QtImageReader.cpp b/tests/QtImageReader.cpp index 2b33cd0b..146b3de9 100644 --- a/tests/QtImageReader.cpp +++ b/tests/QtImageReader.cpp @@ -15,8 +15,9 @@ #include #include "QtImageReader.h" -#include "Frame.h" #include "Clip.h" +#include "Exceptions.h" +#include "Frame.h" #include "Timeline.h" using namespace openshot;