3030using namespace openshot ;
3131
3232// / Blank constructor, useful when using Json to load the effect properties
33- Mask::Mask () : reader(NULL ), replace_image(false ) {
33+ Mask::Mask () : reader(NULL ), replace_image(false ), needs_refresh( true ) {
3434 // Init effect properties
3535 init_effect_details ();
3636}
3737
3838// Default constructor
3939Mask::Mask (ReaderBase *mask_reader, Keyframe mask_brightness, Keyframe mask_contrast) :
40- reader(mask_reader), brightness(mask_brightness), contrast(mask_contrast), replace_image(false )
40+ reader(mask_reader), brightness(mask_brightness), contrast(mask_contrast), replace_image(false ), needs_refresh( true )
4141{
4242 // Init effect properties
4343 init_effect_details ();
@@ -77,7 +77,7 @@ std::shared_ptr<Frame> Mask::GetFrame(std::shared_ptr<Frame> frame, int64_t fram
7777 // Get mask image (if missing or different size than frame image)
7878 #pragma omp critical (open_mask_reader)
7979 {
80- if (!original_mask || !reader->info .has_single_image ||
80+ if (!original_mask || !reader->info .has_single_image || needs_refresh ||
8181 (original_mask && original_mask->size () != frame_image->size ())) {
8282
8383 // Only get mask if needed
@@ -91,6 +91,9 @@ std::shared_ptr<Frame> Mask::GetFrame(std::shared_ptr<Frame> frame, int64_t fram
9191 }
9292 }
9393
94+ // Refresh no longer needed
95+ needs_refresh = false ;
96+
9497 // Get pixel arrays
9598 unsigned char *pixels = (unsigned char *) frame_image->bits ();
9699 unsigned char *mask_pixels = (unsigned char *) original_mask->bits ();
@@ -206,47 +209,51 @@ void Mask::SetJsonValue(Json::Value root) {
206209 contrast.SetJsonValue (root[" contrast" ]);
207210 if (!root[" reader" ].isNull ()) // does Json contain a reader?
208211 {
209-
210- if (!root[" reader" ][" type" ].isNull ()) // does the reader Json contain a 'type'?
212+ #pragma omp critical (open_mask_reader)
211213 {
212- // Close previous reader (if any)
213- if (reader)
214+ // This reader has changed, so refresh cached assets
215+ needs_refresh = true ;
216+
217+ if (!root[" reader" ][" type" ].isNull ()) // does the reader Json contain a 'type'?
214218 {
215- // Close and delete existing reader (if any)
216- reader->Close ();
217- delete reader;
218- reader = NULL ;
219- }
219+ // Close previous reader (if any)
220+ if (reader) {
221+ // Close and delete existing reader (if any)
222+ reader->Close ();
223+ delete reader;
224+ reader = NULL ;
225+ }
220226
221- // Create new reader (and load properties)
222- string type = root[" reader" ][" type" ].asString ();
227+ // Create new reader (and load properties)
228+ string type = root[" reader" ][" type" ].asString ();
223229
224- if (type == " FFmpegReader" ) {
230+ if (type == " FFmpegReader" ) {
225231
226- // Create new reader
227- reader = new FFmpegReader (root[" reader" ][" path" ].asString ());
228- reader->SetJsonValue (root[" reader" ]);
232+ // Create new reader
233+ reader = new FFmpegReader (root[" reader" ][" path" ].asString ());
234+ reader->SetJsonValue (root[" reader" ]);
229235
230- #ifdef USE_IMAGEMAGICK
231- } else if (type == " ImageReader" ) {
236+ #ifdef USE_IMAGEMAGICK
237+ } else if (type == " ImageReader" ) {
232238
233- // Create new reader
234- reader = new ImageReader (root[" reader" ][" path" ].asString ());
235- reader->SetJsonValue (root[" reader" ]);
236- #endif
239+ // Create new reader
240+ reader = new ImageReader (root[" reader" ][" path" ].asString ());
241+ reader->SetJsonValue (root[" reader" ]);
242+ #endif
237243
238- } else if (type == " QtImageReader" ) {
244+ } else if (type == " QtImageReader" ) {
239245
240- // Create new reader
241- reader = new QtImageReader (root[" reader" ][" path" ].asString ());
242- reader->SetJsonValue (root[" reader" ]);
246+ // Create new reader
247+ reader = new QtImageReader (root[" reader" ][" path" ].asString ());
248+ reader->SetJsonValue (root[" reader" ]);
243249
244- } else if (type == " ChunkReader" ) {
250+ } else if (type == " ChunkReader" ) {
245251
246- // Create new reader
247- reader = new ChunkReader (root[" reader" ][" path" ].asString (), (ChunkVersion) root[" reader" ][" chunk_version" ].asInt ());
248- reader->SetJsonValue (root[" reader" ]);
252+ // Create new reader
253+ reader = new ChunkReader (root[" reader" ][" path" ].asString (), (ChunkVersion) root[" reader" ][" chunk_version" ].asInt ());
254+ reader->SetJsonValue (root[" reader" ]);
249255
256+ }
250257 }
251258
252259 }
@@ -275,6 +282,11 @@ string Mask::PropertiesJSON(int64_t requested_frame) {
275282 root[" brightness" ] = add_property_json (" Brightness" , brightness.GetValue (requested_frame), " float" , " " , &brightness, -1.0 , 1.0 , false , requested_frame);
276283 root[" contrast" ] = add_property_json (" Contrast" , contrast.GetValue (requested_frame), " float" , " " , &contrast, 0 , 20 , false , requested_frame);
277284
285+ if (reader)
286+ root[" reader" ] = add_property_json (" Source" , 0.0 , " reader" , reader->Json (), NULL , 0 , 1 , false , requested_frame);
287+ else
288+ root[" reader" ] = add_property_json (" Source" , 0.0 , " reader" , " {}" , NULL , 0 , 1 , false , requested_frame);
289+
278290 // Return formatted string
279291 return root.toStyledString ();
280292}
0 commit comments