diff --git a/include/Clip.h b/include/Clip.h index b1869a90..58eacab7 100644 --- a/include/Clip.h +++ b/include/Clip.h @@ -112,7 +112,10 @@ namespace openshot { // File Reader object ReaderBase* reader; - bool manage_reader; + + /// If we allocated a reader, we store it here to free it later + /// (reader member variable itself may have been replaced) + ReaderBase* allocated_reader; /// Adjust frame number minimum value int64_t adjust_frame_number_minimum(int64_t frame_number); diff --git a/include/DummyReader.h b/include/DummyReader.h index 559215de..e9bce1b5 100644 --- a/include/DummyReader.h +++ b/include/DummyReader.h @@ -64,6 +64,8 @@ namespace openshot /// Constructor for DummyReader. DummyReader(Fraction fps, int width, int height, int sample_rate, int channels, float duration); + virtual ~DummyReader(); + /// Close File void Close(); diff --git a/include/Timeline.h b/include/Timeline.h index 97923153..eecafec1 100644 --- a/include/Timeline.h +++ b/include/Timeline.h @@ -30,6 +30,7 @@ #include #include +#include #include #include #include "CacheBase.h" @@ -152,6 +153,7 @@ namespace openshot { map open_clips; /// effects; /// allocated_frame_mappers; /// all the frame mappers we allocated and must free /// Process a new layer of video or audio void add_layer(std::shared_ptr new_frame, Clip* source_clip, int64_t clip_frame_number, int64_t timeline_frame_number, bool is_top_clip, float max_volume); diff --git a/src/Clip.cpp b/src/Clip.cpp index 207494e3..2099705d 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -101,9 +101,6 @@ void Clip::init_settings() // Init audio and video overrides has_audio = Keyframe(-1.0); has_video = Keyframe(-1.0); - - // Default pointers - manage_reader = false; } // Init reader's rotation (if any) @@ -131,14 +128,14 @@ void Clip::init_reader_rotation() { } // Default Constructor for a clip -Clip::Clip() : reader(NULL), resampler(NULL), audio_cache(NULL) +Clip::Clip() : resampler(NULL), audio_cache(NULL), reader(NULL), allocated_reader(NULL) { // Init all default settings init_settings(); } // Constructor with reader -Clip::Clip(ReaderBase* new_reader) : reader(new_reader), resampler(NULL), audio_cache(NULL) +Clip::Clip(ReaderBase* new_reader) : resampler(NULL), audio_cache(NULL), reader(new_reader), allocated_reader(NULL) { // Init all default settings init_settings(); @@ -152,7 +149,7 @@ Clip::Clip(ReaderBase* new_reader) : reader(new_reader), resampler(NULL), audio_ } // Constructor with filepath -Clip::Clip(string path) : reader(NULL), resampler(NULL), audio_cache(NULL) +Clip::Clip(string path) : resampler(NULL), audio_cache(NULL), reader(NULL), allocated_reader(NULL) { // Init all default settings init_settings(); @@ -194,7 +191,7 @@ Clip::Clip(string path) : reader(NULL), resampler(NULL), audio_cache(NULL) // Update duration if (reader) { End(reader->info.duration); - manage_reader = true; + allocated_reader = reader; init_reader_rotation(); } } @@ -203,9 +200,9 @@ Clip::Clip(string path) : reader(NULL), resampler(NULL), audio_cache(NULL) Clip::~Clip() { // Delete the reader if clip created it - if (manage_reader && reader) { - delete reader; - reader = NULL; + if (allocated_reader) { + delete allocated_reader; + allocated_reader = NULL; } // Close the resampler @@ -968,7 +965,7 @@ void Clip::SetJsonValue(Json::Value root) { // mark as managed reader and set parent if (reader) { reader->SetClip(this); - manage_reader = true; + allocated_reader = reader; } // Re-Open reader (if needed) diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp index 8fe039ab..dc77db5b 100644 --- a/src/DummyReader.cpp +++ b/src/DummyReader.cpp @@ -71,6 +71,9 @@ DummyReader::DummyReader(Fraction fps, int width, int height, int sample_rate, i Close(); } +DummyReader::~DummyReader() { +} + // Open image file void DummyReader::Open() { diff --git a/src/FrameMapper.cpp b/src/FrameMapper.cpp index cf6955f2..ca2038a9 100644 --- a/src/FrameMapper.cpp +++ b/src/FrameMapper.cpp @@ -62,7 +62,6 @@ FrameMapper::~FrameMapper() { // Auto Close if not already Close(); - delete reader; reader = NULL; } diff --git a/src/Timeline.cpp b/src/Timeline.cpp index e40de562..8692d17f 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -71,8 +71,12 @@ Timeline::Timeline(int width, int height, Fraction fps, int sample_rate, int cha } Timeline::~Timeline() { - delete final_cache; - final_cache = NULL; + if (is_open) + // Auto Close if not already + Close(); + + delete final_cache; + final_cache = NULL; } // Add an openshot::Clip to the timeline @@ -128,7 +132,9 @@ void Timeline::apply_mapper_to_clip(Clip* clip) } else { // Create a new FrameMapper to wrap the current reader - clip_reader = (ReaderBase*) new FrameMapper(clip->Reader(), info.fps, PULLDOWN_NONE, info.sample_rate, info.channels, info.channel_layout); + FrameMapper* mapper = new FrameMapper(clip->Reader(), info.fps, PULLDOWN_NONE, info.sample_rate, info.channels, info.channel_layout); + allocated_frame_mappers.insert(mapper); + clip_reader = (ReaderBase*) mapper; } // Update the mapping @@ -642,6 +648,16 @@ void Timeline::Close() update_open_clips(clip, false); } + // Free all allocated frame mappers + set::iterator frame_mapper_itr; + for (frame_mapper_itr=allocated_frame_mappers.begin(); frame_mapper_itr != allocated_frame_mappers.end(); ++frame_mapper_itr) + { + // Get frame mapper object from the iterator + FrameMapper *frame_mapper = (*frame_mapper_itr); + delete frame_mapper; + } + allocated_frame_mappers.clear(); + // Mark timeline as closed is_open = false;