1 /** 2 * @file 3 * @brief Header file for Clip class 4 * @author Jonathan Thomas <jonathan@openshot.org> 5 * 6 * @ref License 7 */ 8 9 /* LICENSE 10 * 11 * Copyright (c) 2008-2019 OpenShot Studios, LLC 12 * <http://www.openshotstudios.com/>. This file is part of 13 * OpenShot Library (libopenshot), an open-source project dedicated to 14 * delivering high quality video editing and animation solutions to the 15 * world. For more information visit <http://www.openshot.org/>. 16 * 17 * OpenShot Library (libopenshot) is free software: you can redistribute it 18 * and/or modify it under the terms of the GNU Lesser General Public License 19 * as published by the Free Software Foundation, either version 3 of the 20 * License, or (at your option) any later version. 21 * 22 * OpenShot Library (libopenshot) is distributed in the hope that it will be 23 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU Lesser General Public License for more details. 26 * 27 * You should have received a copy of the GNU Lesser General Public License 28 * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>. 29 */ 30 31 #ifndef OPENSHOT_CLIP_H 32 #define OPENSHOT_CLIP_H 33 34 #ifdef USE_OPENCV 35 #define int64 opencv_broken_int 36 #define uint64 opencv_broken_uint 37 #include <opencv2/opencv.hpp> 38 #include <opencv2/core.hpp> 39 #undef uint64 40 #undef int64 41 42 #endif 43 44 #include <memory> 45 #include <string> 46 #include <QtGui/QImage> 47 48 #include "AudioResampler.h" 49 #include "ClipBase.h" 50 #include "Color.h" 51 #include "Enums.h" 52 #include "EffectBase.h" 53 #include "Effects.h" 54 #include "EffectInfo.h" 55 #include "Frame.h" 56 #include "KeyFrame.h" 57 #include "TrackedObjectBase.h" 58 #include "ReaderBase.h" 59 #include <OpenShotAudio.h> 60 61 62 namespace openshot { 63 class EffectInfo; 64 65 /// Comparison method for sorting effect pointers (by Position, Layer, and Order). Effects are sorted 66 /// from lowest layer to top layer (since that is sequence clips are combined), and then by 67 /// position, and then by effect order. 68 struct CompareClipEffects{ operatorCompareClipEffects69 bool operator()( openshot::EffectBase* lhs, openshot::EffectBase* rhs){ 70 if( lhs->Layer() < rhs->Layer() ) return true; 71 if( lhs->Layer() == rhs->Layer() && lhs->Position() < rhs->Position() ) return true; 72 if( lhs->Layer() == rhs->Layer() && lhs->Position() == rhs->Position() && lhs->Order() > rhs->Order() ) return true; 73 return false; 74 }}; 75 76 /** 77 * @brief This class represents a clip (used to arrange readers on the timeline) 78 * 79 * Each image, video, or audio file is represented on a layer as a clip. A clip has many 80 * properties that affect how it behaves on the timeline, such as its size, position, 81 * transparency, rotation, speed, volume, etc... 82 * 83 * @code 84 * // Create some clips 85 * Clip c1(new ImageReader("MyAwesomeLogo.jpeg")); 86 * Clip c2(new FFmpegReader("BackgroundVideo.webm")); 87 * 88 * // CLIP 1 (logo) - Set some clip properties (with openshot::Keyframes) 89 * c1.Position(0.0); // Set the position or location (in seconds) on the timeline 90 * c1.gravity = GRAVITY_LEFT; // Set the alignment / gravity of the clip (position on the screen) 91 * c1.scale = SCALE_CROP; // Set the scale mode (how the image is resized to fill the screen) 92 * c1.Layer(1); // Set the layer of the timeline (higher layers cover up images of lower layers) 93 * c1.Start(0.0); // Set the starting position of the video (trim the left side of the video) 94 * c1.End(16.0); // Set the ending position of the video (trim the right side of the video) 95 * c1.alpha.AddPoint(1, 0.0); // Set the alpha to transparent on frame #1 96 * c1.alpha.AddPoint(500, 0.0); // Keep the alpha transparent until frame #500 97 * c1.alpha.AddPoint(565, 1.0); // Animate the alpha from transparent to visible (between frame #501 and #565) 98 * 99 * // CLIP 2 (background video) - Set some clip properties (with openshot::Keyframes) 100 * c2.Position(0.0); // Set the position or location (in seconds) on the timeline 101 * c2.Start(10.0); // Set the starting position of the video (trim the left side of the video) 102 * c2.Layer(0); // Set the layer of the timeline (higher layers cover up images of lower layers) 103 * c2.alpha.AddPoint(1, 1.0); // Set the alpha to visible on frame #1 104 * c2.alpha.AddPoint(150, 0.0); // Animate the alpha to transparent (between frame 2 and frame #150) 105 * c2.alpha.AddPoint(360, 0.0, LINEAR); // Keep the alpha transparent until frame #360 106 * c2.alpha.AddPoint(384, 1.0); // Animate the alpha to visible (between frame #360 and frame #384) 107 * @endcode 108 */ 109 class Clip : public openshot::ClipBase, public openshot::ReaderBase { 110 protected: 111 /// Section lock for multiple threads 112 juce::CriticalSection getFrameCriticalSection; 113 114 /// Init default settings for a clip 115 void init_settings(); 116 117 /// Init reader info details 118 void init_reader_settings(); 119 120 /// Update default rotation from reader 121 void init_reader_rotation(); 122 123 private: 124 bool waveform; ///< Should a waveform be used instead of the clip's image 125 std::list<openshot::EffectBase*> effects; ///< List of clips on this timeline 126 bool is_open; ///< Is Reader opened 127 std::string parentObjectId; ///< Id of the bounding box that this clip is attached to 128 std::shared_ptr<openshot::TrackedObjectBase> parentTrackedObject; ///< Tracked object this clip is attached to 129 openshot::Clip* parentClipObject; ///< Clip object this clip is attached to 130 131 132 // Audio resampler (if time mapping) 133 openshot::AudioResampler *resampler; 134 135 // File Reader object 136 openshot::ReaderBase* reader; 137 138 /// If we allocated a reader, we store it here to free it later 139 /// (reader member variable itself may have been replaced) 140 openshot::ReaderBase* allocated_reader; 141 142 /// Adjust frame number minimum value 143 int64_t adjust_frame_number_minimum(int64_t frame_number); 144 145 /// Apply effects to the source frame (if any) 146 void apply_effects(std::shared_ptr<openshot::Frame> frame); 147 148 /// Apply keyframes to an openshot::Frame and use an existing QImage as a background image (if any) 149 void apply_keyframes(std::shared_ptr<Frame> frame, std::shared_ptr<QImage> background_canvas); 150 151 /// Get QTransform from keyframes 152 QTransform get_transform(std::shared_ptr<Frame> frame, int width, int height); 153 154 /// Get file extension 155 std::string get_file_extension(std::string path); 156 157 /// Get a frame object or create a blank one 158 std::shared_ptr<openshot::Frame> GetOrCreateFrame(int64_t number); 159 160 /// Adjust the audio and image of a time mapped frame 161 void get_time_mapped_frame(std::shared_ptr<openshot::Frame> frame, int64_t frame_number); 162 163 /// Compare 2 floating point numbers 164 bool isEqual(double a, double b); 165 166 /// Sort effects by order 167 void sort_effects(); 168 169 /// Reverse an audio buffer 170 void reverse_buffer(juce::AudioSampleBuffer* buffer); 171 172 173 public: 174 openshot::GravityType gravity; ///< The gravity of a clip determines where it snaps to its parent 175 openshot::ScaleType scale; ///< The scale determines how a clip should be resized to fit its parent 176 openshot::AnchorType anchor; ///< The anchor determines what parent a clip should snap to 177 openshot::FrameDisplayType display; ///< The format to display the frame number (if any) 178 openshot::VolumeMixType mixing; ///< What strategy should be followed when mixing audio with other clips 179 180 #ifdef USE_OPENCV 181 bool COMPILED_WITH_CV = true; 182 #else 183 bool COMPILED_WITH_CV = false; 184 #endif 185 186 /// Default Constructor 187 Clip(); 188 189 /// @brief Constructor with filepath (reader is automatically created... by guessing file extensions) 190 /// @param path The path of a reader (video file, image file, etc...). The correct reader will be used automatically. 191 Clip(std::string path); 192 193 /// @brief Constructor with reader 194 /// @param new_reader The reader to be used by this clip 195 Clip(openshot::ReaderBase* new_reader); 196 197 /// Destructor 198 virtual ~Clip(); 199 200 /// Get the cache object (always return NULL for this reader) GetCache()201 openshot::CacheMemory* GetCache() override { return NULL; }; 202 203 /// Determine if reader is open or closed IsOpen()204 bool IsOpen() override { return is_open; }; 205 206 /// Get and set the object id that this clip is attached to GetAttachedId()207 std::string GetAttachedId() const { return parentObjectId; }; 208 /// Set id of the object id that this clip is attached to SetAttachedId(std::string value)209 void SetAttachedId(std::string value) { parentObjectId = value; }; 210 211 /// Attach clip to Tracked Object or to another Clip 212 void AttachToObject(std::string object_id); 213 214 /// Set the pointer to the trackedObject this clip is attached to 215 void SetAttachedObject(std::shared_ptr<openshot::TrackedObjectBase> trackedObject); 216 /// Set the pointer to the clip this clip is attached to 217 void SetAttachedClip(Clip* clipObject); 218 /// Return a pointer to the trackedObject this clip is attached to GetAttachedObject()219 std::shared_ptr<openshot::TrackedObjectBase> GetAttachedObject() const { return parentTrackedObject; }; 220 /// Return a pointer to the clip this clip is attached to GetAttachedClip()221 Clip* GetAttachedClip() const { return parentClipObject; }; 222 223 /// Return the type name of the class Name()224 std::string Name() override { return "Clip"; }; 225 226 /// @brief Add an effect to the clip 227 /// @param effect Add an effect to the clip. An effect can modify the audio or video of an openshot::Frame. 228 void AddEffect(openshot::EffectBase* effect); 229 230 /// Close the internal reader 231 void Close() override; 232 233 /// Return the list of effects on the timeline Effects()234 std::list<openshot::EffectBase*> Effects() { return effects; }; 235 236 /// Look up an effect by ID 237 openshot::EffectBase* GetEffect(const std::string& id); 238 239 /// @brief Get an openshot::Frame object for a specific frame number of this clip. The image size and number 240 /// of samples match the source reader. 241 /// 242 /// @returns A new openshot::Frame object 243 /// @param frame_number The frame number (starting at 1) of the clip 244 std::shared_ptr<openshot::Frame> GetFrame(int64_t frame_number) override; 245 246 /// @brief Get an openshot::Frame object for a specific frame number of this clip. The image size and number 247 /// of samples match the background_frame passed in and the timeline (if available). 248 /// 249 /// A new openshot::Frame objects is returned, based on a copy from the source image, with all keyframes and clip effects 250 /// rendered/rasterized. 251 /// 252 /// @returns The modified openshot::Frame object 253 /// @param background_frame The frame object to use as a background canvas (i.e. an existing Timeline openshot::Frame instance) 254 /// @param frame_number The frame number (starting at 1) of the clip. The image size and number 255 /// of samples match the background_frame passed in and the timeline (if available) 256 std::shared_ptr<openshot::Frame> GetFrame(std::shared_ptr<openshot::Frame> background_frame, int64_t frame_number) override; 257 258 /// @brief Get an openshot::Frame object for a specific frame number of this clip. The image size and number 259 /// of samples match the background_frame passed in and the timeline (if available). 260 /// 261 /// A new openshot::Frame objects is returned, based on a copy from the source image, with all keyframes and clip effects 262 /// rendered/rasterized. 263 /// 264 /// @returns The modified openshot::Frame object 265 /// @param background_frame The frame object to use as a background canvas (i.e. an existing Timeline openshot::Frame instance) 266 /// @param frame_number The frame number (starting at 1) of the clip on the timeline. The image size and number 267 /// of samples match the timeline. 268 /// @param options The openshot::TimelineInfoStruct pointer, with more details about this specific timeline clip, 269 /// such as, if it's a top clip. This info is used to apply global transitions and masks, if needed. 270 std::shared_ptr<openshot::Frame> GetFrame(std::shared_ptr<openshot::Frame> background_frame, int64_t frame_number, openshot::TimelineInfoStruct* options); 271 272 /// Open the internal reader 273 void Open() override; 274 275 /// @brief Set the current reader 276 /// @param new_reader The reader to be used by this clip 277 void Reader(openshot::ReaderBase* new_reader); 278 279 /// Get the current reader 280 openshot::ReaderBase* Reader(); 281 282 // Override End() method 283 float End() const; ///< Get end position (in seconds) of clip (trim end of video), which can be affected by the time curve. End(float value)284 void End(float value) { end = value; } ///< Set end position (in seconds) of clip (trim end of video) 285 286 // Get and Set JSON methods 287 std::string Json() const override; ///< Generate JSON string of this object 288 void SetJson(const std::string value) override; ///< Load JSON string into this object 289 Json::Value JsonValue() const override; ///< Generate Json::Value for this object 290 void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 291 292 /// Get all properties for a specific frame (perfect for a UI to display the current state 293 /// of all properties at any time) 294 std::string PropertiesJSON(int64_t requested_frame) const override; 295 296 /// @brief Remove an effect from the clip 297 /// @param effect Remove an effect from the clip. 298 void RemoveEffect(openshot::EffectBase* effect); 299 300 // Waveform property Waveform()301 bool Waveform() { return waveform; } ///< Get the waveform property of this clip Waveform(bool value)302 void Waveform(bool value) { waveform = value; } ///< Set the waveform property of this clip 303 304 // Scale, Location, and Alpha curves 305 openshot::Keyframe scale_x; ///< Curve representing the horizontal scaling in percent (0 to 1) 306 openshot::Keyframe scale_y; ///< Curve representing the vertical scaling in percent (0 to 1) 307 openshot::Keyframe location_x; ///< Curve representing the relative X position in percent based on the gravity (-1 to 1) 308 openshot::Keyframe location_y; ///< Curve representing the relative Y position in percent based on the gravity (-1 to 1) 309 openshot::Keyframe alpha; ///< Curve representing the alpha (1 to 0) 310 311 // Rotation and Shear curves (origin point (x,y) is adjustable for both rotation and shear) 312 openshot::Keyframe rotation; ///< Curve representing the rotation (0 to 360) 313 openshot::Keyframe shear_x; ///< Curve representing X shear angle in degrees (-45.0=left, 45.0=right) 314 openshot::Keyframe shear_y; ///< Curve representing Y shear angle in degrees (-45.0=down, 45.0=up) 315 openshot::Keyframe origin_x; ///< Curve representing X origin point (0.0=0% (left), 1.0=100% (right)) 316 openshot::Keyframe origin_y; ///< Curve representing Y origin point (0.0=0% (top), 1.0=100% (bottom)) 317 318 // Time and Volume curves 319 openshot::Keyframe time; ///< Curve representing the frames over time to play (used for speed and direction of video) 320 openshot::Keyframe volume; ///< Curve representing the volume (0 to 1) 321 322 /// Curve representing the color of the audio wave form 323 openshot::Color wave_color; 324 325 // Perspective curves 326 openshot::Keyframe perspective_c1_x; ///< Curves representing X for coordinate 1 327 openshot::Keyframe perspective_c1_y; ///< Curves representing Y for coordinate 1 328 openshot::Keyframe perspective_c2_x; ///< Curves representing X for coordinate 2 329 openshot::Keyframe perspective_c2_y; ///< Curves representing Y for coordinate 2 330 openshot::Keyframe perspective_c3_x; ///< Curves representing X for coordinate 3 331 openshot::Keyframe perspective_c3_y; ///< Curves representing Y for coordinate 3 332 openshot::Keyframe perspective_c4_x; ///< Curves representing X for coordinate 4 333 openshot::Keyframe perspective_c4_y; ///< Curves representing Y for coordinate 4 334 335 // Audio channel filter and mappings 336 openshot::Keyframe channel_filter; ///< A number representing an audio channel to filter (clears all other channels) 337 openshot::Keyframe channel_mapping; ///< A number representing an audio channel to output (only works when filtering a channel) 338 339 // Override has_video and has_audio properties of clip (and their readers) 340 openshot::Keyframe has_audio; ///< An optional override to determine if this clip has audio (-1=undefined, 0=no, 1=yes) 341 openshot::Keyframe has_video; ///< An optional override to determine if this clip has video (-1=undefined, 0=no, 1=yes) 342 }; 343 } // namespace 344 345 #endif // OPENSHOT_CLIP_H 346