OpenShot Library | libopenshot  0.3.3
EffectBase.cpp
Go to the documentation of this file.
1 
9 // Copyright (c) 2008-2019 OpenShot Studios, LLC
10 //
11 // SPDX-License-Identifier: LGPL-3.0-or-later
12 
13 #include <iostream>
14 #include <iomanip>
15 
16 #include "EffectBase.h"
17 
18 #include "Exceptions.h"
19 #include "Timeline.h"
20 
21 using namespace openshot;
22 
23 // Initialize the values of the EffectInfo struct
25 {
26  // Init clip settings
27  Position(0.0);
28  Layer(0);
29  Start(0.0);
30  End(0.0);
31  Order(0);
32  ParentClip(NULL);
33  parentEffect = NULL;
34 
35  info.has_video = false;
36  info.has_audio = false;
37  info.has_tracked_object = false;
38  info.name = "";
39  info.description = "";
41  info.apply_before_clip = true;
42 }
43 
44 // Display file information
45 void EffectBase::DisplayInfo(std::ostream* out) {
46  *out << std::fixed << std::setprecision(2) << std::boolalpha;
47  *out << "----------------------------" << std::endl;
48  *out << "----- Effect Information -----" << std::endl;
49  *out << "----------------------------" << std::endl;
50  *out << "--> Name: " << info.name << std::endl;
51  *out << "--> Description: " << info.description << std::endl;
52  *out << "--> Has Video: " << info.has_video << std::endl;
53  *out << "--> Has Audio: " << info.has_audio << std::endl;
54  *out << "--> Apply Before Clip Keyframes: " << info.apply_before_clip << std::endl;
55  *out << "--> Order: " << order << std::endl;
56  *out << "----------------------------" << std::endl;
57 }
58 
59 // Constrain a color value from 0 to 255
60 int EffectBase::constrain(int color_value)
61 {
62  // Constrain new color from 0 to 255
63  if (color_value < 0)
64  color_value = 0;
65  else if (color_value > 255)
66  color_value = 255;
67 
68  return color_value;
69 }
70 
71 // Generate JSON string of this object
72 std::string EffectBase::Json() const {
73 
74  // Return formatted string
75  return JsonValue().toStyledString();
76 }
77 
78 // Generate Json::Value for this object
79 Json::Value EffectBase::JsonValue() const {
80 
81  // Create root json object
82  Json::Value root = ClipBase::JsonValue(); // get parent properties
83  root["name"] = info.name;
84  root["class_name"] = info.class_name;
85  root["description"] = info.description;
86  root["parent_effect_id"] = info.parent_effect_id;
87  root["has_video"] = info.has_video;
88  root["has_audio"] = info.has_audio;
89  root["has_tracked_object"] = info.has_tracked_object;
90  root["apply_before_clip"] = info.apply_before_clip;
91  root["order"] = Order();
92 
93  // return JsonValue
94  return root;
95 }
96 
97 // Load JSON string into this object
98 void EffectBase::SetJson(const std::string value) {
99 
100  // Parse JSON string into JSON objects
101  try
102  {
103  Json::Value root = openshot::stringToJson(value);
104  // Set all values that match
105  SetJsonValue(root);
106  }
107  catch (const std::exception& e)
108  {
109  // Error parsing JSON (or missing keys)
110  throw InvalidJSON("JSON is invalid (missing keys or invalid data types)");
111  }
112 }
113 
114 // Load Json::Value into this object
115 void EffectBase::SetJsonValue(const Json::Value root) {
116 
117  if (ParentTimeline()){
118  // Get parent timeline
119  Timeline* parentTimeline = static_cast<Timeline *>(ParentTimeline());
120 
121  // Get the list of effects on the timeline
122  std::list<EffectBase*> effects = parentTimeline->ClipEffects();
123 
124  // TODO: Fix recursive call for Object Detection
125 
126  // // Loop through the effects and check if we have a child effect linked to this effect
127  for (auto const& effect : effects){
128  // Set the properties of all effects which parentEffect points to this
129  if ((effect->info.parent_effect_id == this->Id()) && (effect->Id() != this->Id()))
130  effect->SetJsonValue(root);
131  }
132  }
133 
134  // Set this effect properties with the parent effect properties (except the id and parent_effect_id)
135  Json::Value my_root;
136  if (parentEffect){
137  my_root = parentEffect->JsonValue();
138  my_root["id"] = this->Id();
139  my_root["parent_effect_id"] = this->info.parent_effect_id;
140  } else {
141  my_root = root;
142  }
143 
144  // Set parent data
145  ClipBase::SetJsonValue(my_root);
146 
147  // Set data from Json (if key is found)
148  if (!my_root["order"].isNull())
149  Order(my_root["order"].asInt());
150 
151  if (!my_root["apply_before_clip"].isNull())
152  info.apply_before_clip = my_root["apply_before_clip"].asBool();
153 
154  if (!my_root["parent_effect_id"].isNull()){
155  info.parent_effect_id = my_root["parent_effect_id"].asString();
156  if (info.parent_effect_id.size() > 0 && info.parent_effect_id != "" && parentEffect == NULL)
158  else
159  parentEffect = NULL;
160  }
161 }
162 
163 // Generate Json::Value for this object
164 Json::Value EffectBase::JsonInfo() const {
165 
166  // Create root json object
167  Json::Value root;
168  root["name"] = info.name;
169  root["class_name"] = info.class_name;
170  root["description"] = info.description;
171  root["has_video"] = info.has_video;
172  root["has_audio"] = info.has_audio;
173 
174  // return JsonValue
175  return root;
176 }
177 
178 // Get all properties for a specific frame
179 Json::Value EffectBase::BasePropertiesJSON(int64_t requested_frame) const {
180  // Generate JSON properties list
181  Json::Value root;
182  root["id"] = add_property_json("ID", 0.0, "string", Id(), NULL, -1, -1, true, requested_frame);
183  root["position"] = add_property_json("Position", Position(), "float", "", NULL, 0, 30 * 60 * 60 * 48, false, requested_frame);
184  root["layer"] = add_property_json("Track", Layer(), "int", "", NULL, 0, 20, false, requested_frame);
185  root["start"] = add_property_json("Start", Start(), "float", "", NULL, 0, 30 * 60 * 60 * 48, false, requested_frame);
186  root["end"] = add_property_json("End", End(), "float", "", NULL, 0, 30 * 60 * 60 * 48, false, requested_frame);
187  root["duration"] = add_property_json("Duration", Duration(), "float", "", NULL, 0, 30 * 60 * 60 * 48, true, requested_frame);
188 
189  // Add replace_image choices (dropdown style)
190  root["apply_before_clip"] = add_property_json("Apply Before Clip Keyframes", info.apply_before_clip, "int", "", NULL, 0, 1, false, requested_frame);
191  root["apply_before_clip"]["choices"].append(add_property_choice_json("Yes", true, info.apply_before_clip));
192  root["apply_before_clip"]["choices"].append(add_property_choice_json("No", false, info.apply_before_clip));
193 
194  // Set the parent effect which properties this effect will inherit
195  root["parent_effect_id"] = add_property_json("Parent", 0.0, "string", info.parent_effect_id, NULL, -1, -1, false, requested_frame);
196 
197  return root;
198 }
199 
202  return clip;
203 }
204 
207  clip = new_clip;
208 }
209 
210 // Set the parent effect from which this properties will be set to
211 void EffectBase::SetParentEffect(std::string parentEffect_id) {
212 
213  // Get parent Timeline
214  Timeline* parentTimeline = static_cast<Timeline *>(ParentTimeline());
215 
216  if (parentTimeline){
217 
218  // Get a pointer to the parentEffect
219  EffectBase* parentEffectPtr = parentTimeline->GetClipEffect(parentEffect_id);
220 
221  if (parentEffectPtr){
222  // Set the parent Effect
223  parentEffect = parentEffectPtr;
224 
225  // Set the properties of this effect with the parent effect's properties
226  Json::Value EffectJSON = parentEffect->JsonValue();
227  EffectJSON["id"] = this->Id();
228  EffectJSON["parent_effect_id"] = this->info.parent_effect_id;
229  this->SetJsonValue(EffectJSON);
230  }
231  }
232  return;
233 }
234 
235 // Return the ID of this effect's parent clip
236 std::string EffectBase::ParentClipId() const{
237  if(clip)
238  return clip->Id();
239  else
240  return "";
241 }
openshot::ClipBase::add_property_json
Json::Value add_property_json(std::string name, float value, std::string type, std::string memo, const Keyframe *keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame) const
Generate JSON for a property.
Definition: ClipBase.cpp:96
openshot::stringToJson
const Json::Value stringToJson(const std::string value)
Definition: Json.cpp:16
openshot::EffectBase
This abstract class is the base class, used by all effects in libopenshot.
Definition: EffectBase.h:53
openshot::EffectBase::info
EffectInfoStruct info
Information about the current effect.
Definition: EffectBase.h:69
openshot::EffectBase::JsonInfo
Json::Value JsonInfo() const
Generate JSON object of meta data / info.
Definition: EffectBase.cpp:164
openshot::EffectInfoStruct::apply_before_clip
bool apply_before_clip
Apply effect before we evaluate the clip's keyframes.
Definition: EffectBase.h:43
openshot::ClipBase::End
virtual void End(float value)
Set end position (in seconds) of clip (trim end of video)
Definition: ClipBase.cpp:53
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:28
openshot::EffectBase::ParentClip
openshot::ClipBase * ParentClip()
Parent clip object of this effect (which can be unparented and NULL)
Definition: EffectBase.cpp:201
openshot::ClipBase::add_property_choice_json
Json::Value add_property_choice_json(std::string name, int value, int selected_value) const
Generate JSON choice for a property (dropdown properties)
Definition: ClipBase.cpp:132
openshot::EffectBase::JsonValue
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: EffectBase.cpp:79
Timeline.h
Header file for Timeline class.
openshot::EffectBase::DisplayInfo
void DisplayInfo(std::ostream *out=&std::cout)
Display effect information in the standard output stream (stdout)
Definition: EffectBase.cpp:45
EffectBase.h
Header file for EffectBase class.
openshot::ClipBase::Position
void Position(float value)
Set the Id of this clip object
Definition: ClipBase.cpp:19
openshot::EffectBase::Json
virtual std::string Json() const
Generate JSON string of this object.
Definition: EffectBase.cpp:72
openshot::EffectBase::SetParentEffect
void SetParentEffect(std::string parentEffect_id)
Set the parent effect from which this properties will be set to.
Definition: EffectBase.cpp:211
openshot::ClipBase::SetJsonValue
virtual void SetJsonValue(const Json::Value root)=0
Load Json::Value into this object.
Definition: ClipBase.cpp:80
openshot::ClipBase::JsonValue
virtual Json::Value JsonValue() const =0
Generate Json::Value for this object.
Definition: ClipBase.cpp:64
openshot::EffectBase::BasePropertiesJSON
Json::Value BasePropertiesJSON(int64_t requested_frame) const
Generate JSON object of base properties (recommended to be used by all effects)
Definition: EffectBase.cpp:179
openshot::EffectBase::parentEffect
EffectBase * parentEffect
Parent effect (which properties will set this effect properties)
Definition: EffectBase.h:63
openshot::InvalidJSON
Exception for invalid JSON.
Definition: Exceptions.h:217
openshot::Timeline
This class represents a timeline.
Definition: Timeline.h:148
openshot::Timeline::ClipEffects
std::list< openshot::EffectBase * > ClipEffects() const
Return the list of effects on all clips.
Definition: Timeline.cpp:444
openshot::EffectBase::InitEffectInfo
void InitEffectInfo()
Definition: EffectBase.cpp:24
openshot::EffectInfoStruct::has_audio
bool has_audio
Determines if this effect manipulates the audio of a frame.
Definition: EffectBase.h:41
openshot::EffectInfoStruct::has_tracked_object
bool has_tracked_object
Determines if this effect track objects through the clip.
Definition: EffectBase.h:42
openshot::ClipBase::Start
void Start(float value)
Set start position (in seconds) of clip (trim start of video)
Definition: ClipBase.cpp:42
openshot::EffectBase::ParentClipId
std::string ParentClipId() const
Return the ID of this effect's parent clip.
Definition: EffectBase.cpp:236
openshot::EffectBase::Order
int Order() const
Get the order that this effect should be executed.
Definition: EffectBase.h:116
openshot::EffectInfoStruct::class_name
std::string class_name
The class name of the effect.
Definition: EffectBase.h:36
openshot::EffectInfoStruct::description
std::string description
The description of this effect and what it does.
Definition: EffectBase.h:38
openshot::EffectInfoStruct::has_video
bool has_video
Determines if this effect manipulates the image of a frame.
Definition: EffectBase.h:40
openshot::ClipBase::Id
void Id(std::string value)
Definition: ClipBase.h:94
openshot::EffectBase::constrain
int constrain(int color_value)
Constrain a color value from 0 to 255.
Definition: EffectBase.cpp:60
openshot::EffectInfoStruct::parent_effect_id
std::string parent_effect_id
Id of the parent effect (if there is one)
Definition: EffectBase.h:39
openshot::EffectInfoStruct::name
std::string name
The name of the effect.
Definition: EffectBase.h:37
openshot::Timeline::GetClipEffect
openshot::EffectBase * GetClipEffect(const std::string &id)
Look up a clip effect by ID.
Definition: Timeline.cpp:431
openshot::ClipBase
This abstract class is the base class, used by all clips in libopenshot.
Definition: ClipBase.h:33
openshot::EffectBase::SetJson
virtual void SetJson(const std::string value)
Load JSON string into this object.
Definition: EffectBase.cpp:98
openshot::ClipBase::Layer
void Layer(int value)
Set layer of clip on timeline (lower number is covered by higher numbers)
Definition: ClipBase.cpp:31
Exceptions.h
Header file for all Exception classes.
openshot::EffectBase::SetJsonValue
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: EffectBase.cpp:115
openshot::EffectBase::clip
openshot::ClipBase * clip
Pointer to the parent clip instance (if any)
Definition: EffectBase.h:59