OpenShot Library | libopenshot  0.2.2
Timeline.h
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Header file for Timeline class
4  * @author Jonathan Thomas <jonathan@openshot.org>
5  *
6  * @section LICENSE
7  *
8  * Copyright (c) 2008-2014 OpenShot Studios, LLC
9  * <http://www.openshotstudios.com/>. This file is part of
10  * OpenShot Library (libopenshot), an open-source project dedicated to
11  * delivering high quality video editing and animation solutions to the
12  * world. For more information visit <http://www.openshot.org/>.
13  *
14  * OpenShot Library (libopenshot) is free software: you can redistribute it
15  * and/or modify it under the terms of the GNU Lesser General Public License
16  * as published by the Free Software Foundation, either version 3 of the
17  * License, or (at your option) any later version.
18  *
19  * OpenShot Library (libopenshot) is distributed in the hope that it will be
20  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
26  */
27 
28 #ifndef OPENSHOT_TIMELINE_H
29 #define OPENSHOT_TIMELINE_H
30 
31 #include <list>
32 #include <memory>
33 #include <QtGui/QImage>
34 #include <QtGui/QPainter>
35 #include "CacheBase.h"
36 #include "CacheDisk.h"
37 #include "CacheMemory.h"
38 #include "Color.h"
39 #include "Clip.h"
40 #include "CrashHandler.h"
41 #include "Point.h"
42 #include "EffectBase.h"
43 #include "Effects.h"
44 #include "EffectInfo.h"
45 #include "Fraction.h"
46 #include "Frame.h"
47 #include "FrameMapper.h"
48 #include "KeyFrame.h"
49 #include "OpenMPUtilities.h"
50 #include "ReaderBase.h"
51 
52 using namespace std;
53 using namespace openshot;
54 
55 namespace openshot {
56 
57  /// Comparison method for sorting clip pointers (by Layer and then Position). Clips are sorted
58  /// from lowest layer to top layer (since that is the sequence they need to be combined), and then
59  /// by position (left to right).
60  struct CompareClips{
61  bool operator()( Clip* lhs, Clip* rhs){
62  if( lhs->Layer() < rhs->Layer() ) return true;
63  if( lhs->Layer() == rhs->Layer() && lhs->Position() <= rhs->Position() ) return true;
64  return false;
65  }};
66 
67  /// Comparison method for sorting effect pointers (by Position, Layer, and Order). Effects are sorted
68  /// from lowest layer to top layer (since that is sequence clips are combined), and then by
69  /// position, and then by effect order.
71  bool operator()( EffectBase* lhs, EffectBase* rhs){
72  if( lhs->Layer() < rhs->Layer() ) return true;
73  if( lhs->Layer() == rhs->Layer() && lhs->Position() < rhs->Position() ) return true;
74  if( lhs->Layer() == rhs->Layer() && lhs->Position() == rhs->Position() && lhs->Order() > rhs->Order() ) return true;
75  return false;
76  }};
77 
78  /**
79  * @brief This class represents a timeline
80  *
81  * The timeline is one of the <b>most important</b> features of a video editor, and controls all
82  * aspects of how video, image, and audio clips are combined together, and how the final
83  * video output will be rendered. It has a collection of layers and clips, that arrange,
84  * sequence, and generate the final video output.
85  *
86  * The <b>following graphic</b> displays a timeline, and how clips can be arranged, scaled, and layered together. It
87  * also demonstrates how the viewport can be scaled smaller than the canvas, which can be used to zoom and pan around the
88  * canvas (i.e. pan & scan).
89  * \image html /doc/images/Timeline_Layers.png
90  *
91  * The <b>following graphic</b> displays how the playhead determines which frames to combine and layer.
92  * \image html /doc/images/Playhead.png
93  *
94  * Lets take a look at what the code looks like:
95  * @code
96  * // Create a Timeline
97  * Timeline t(1280, // width
98  * 720, // height
99  * Fraction(25,1), // framerate
100  * 44100, // sample rate
101  * 2 // channels
102  * );
103  *
104  * // Create some clips
105  * Clip c1(new ImageReader("MyAwesomeLogo.jpeg"));
106  * Clip c2(new FFmpegReader("BackgroundVideo.webm"));
107  *
108  * // CLIP 1 (logo) - Set some clip properties (with Keyframes)
109  * c1.Position(0.0); // Set the position or location (in seconds) on the timeline
110  * c1.gravity = GRAVITY_LEFT; // Set the alignment / gravity of the clip (position on the screen)
111  * c1.scale = SCALE_CROP; // Set the scale mode (how the image is resized to fill the screen)
112  * c1.Layer(1); // Set the layer of the timeline (higher layers cover up images of lower layers)
113  * c1.Start(0.0); // Set the starting position of the video (trim the left side of the video)
114  * c1.End(16.0); // Set the ending position of the video (trim the right side of the video)
115  * c1.alpha.AddPoint(1, 0.0); // Set the alpha to transparent on frame #1
116  * c1.alpha.AddPoint(500, 0.0); // Keep the alpha transparent until frame #500
117  * c1.alpha.AddPoint(565, 1.0); // Animate the alpha from transparent to visible (between frame #501 and #565)
118  *
119  * // CLIP 2 (background video) - Set some clip properties (with Keyframes)
120  * c2.Position(0.0); // Set the position or location (in seconds) on the timeline
121  * c2.Start(10.0); // Set the starting position of the video (trim the left side of the video)
122  * c2.Layer(0); // Set the layer of the timeline (higher layers cover up images of lower layers)
123  * c2.alpha.AddPoint(1, 1.0); // Set the alpha to visible on frame #1
124  * c2.alpha.AddPoint(150, 0.0); // Animate the alpha to transparent (between frame 2 and frame #150)
125  * c2.alpha.AddPoint(360, 0.0, LINEAR); // Keep the alpha transparent until frame #360
126  * c2.alpha.AddPoint(384, 1.0); // Animate the alpha to visible (between frame #360 and frame #384)
127  *
128  * // Add clips to timeline
129  * t.AddClip(&c1);
130  * t.AddClip(&c2);
131  *
132  * // Open the timeline reader
133  * t.Open();
134  *
135  * // Get frame number 1 from the timeline (This will generate a new frame, made up from the previous clips and settings)
136  * std::shared_ptr<Frame> f = t.GetFrame(1);
137  *
138  * // Now that we have an openshot::Frame object, lets have some fun!
139  * f->Display(); // Display the frame on the screen
140  *
141  * // Close the timeline reader
142  * t.Close();
143  * @endcode
144  */
145  class Timeline : public ReaderBase {
146  private:
147  bool is_open; ///<Is Timeline Open?
148  bool auto_map_clips; ///< Auto map framerates and sample rates to all clips
149  list<Clip*> clips; ///<List of clips on this timeline
150  list<Clip*> closing_clips; ///<List of clips that need to be closed
151  map<Clip*, Clip*> open_clips; ///<List of 'opened' clips on this timeline
152  list<EffectBase*> effects; ///<List of clips on this timeline
153  CacheBase *final_cache; ///<Final cache of timeline frames
154 
155  /// Process a new layer of video or audio
156  void add_layer(std::shared_ptr<Frame> new_frame, Clip* source_clip, int64_t clip_frame_number, int64_t timeline_frame_number, bool is_top_clip, float max_volume);
157 
158  /// Apply a FrameMapper to a clip which matches the settings of this timeline
159  void apply_mapper_to_clip(Clip* clip);
160 
161  /// Apply JSON Diffs to various objects contained in this timeline
162  void apply_json_to_clips(Json::Value change); ///<Apply JSON diff to clips
163  void apply_json_to_effects(Json::Value change); ///< Apply JSON diff to effects
164  void apply_json_to_effects(Json::Value change, EffectBase* existing_effect); ///<Apply JSON diff to a specific effect
165  void apply_json_to_timeline(Json::Value change); ///<Apply JSON diff to timeline properties
166 
167  /// Calculate time of a frame number, based on a framerate
168  double calculate_time(int64_t number, Fraction rate);
169 
170  /// Find intersecting (or non-intersecting) openshot::Clip objects
171  ///
172  /// @returns A list of openshot::Clip objects
173  /// @param requested_frame The frame number that is requested.
174  /// @param number_of_frames The number of frames to check
175  /// @param include Include or Exclude intersecting clips
176  vector<Clip*> find_intersecting_clips(int64_t requested_frame, int number_of_frames, bool include);
177 
178  /// Get or generate a blank frame
179  std::shared_ptr<Frame> GetOrCreateFrame(Clip* clip, int64_t number);
180 
181  /// Apply effects to the source frame (if any)
182  std::shared_ptr<Frame> apply_effects(std::shared_ptr<Frame> frame, int64_t timeline_frame_number, int layer);
183 
184  /// Compare 2 floating point numbers for equality
185  bool isEqual(double a, double b);
186 
187  /// Sort clips by position on the timeline
188  void sort_clips();
189 
190  /// Sort effects by position on the timeline
191  void sort_effects();
192 
193  /// Update the list of 'opened' clips
194  void update_open_clips(Clip *clip, bool does_clip_intersect);
195 
196  public:
197 
198  /// @brief Default Constructor for the timeline (which sets the canvas width and height and FPS)
199  /// @param width The width of the timeline (and thus, the generated openshot::Frame objects)
200  /// @param height The height of the timeline (and thus, the generated openshot::Frame objects)
201  /// @param fps The frames rate of the timeline
202  /// @param sample_rate The sample rate of the timeline's audio
203  /// @param channels The number of audio channels of the timeline
204  /// @param channel_layout The channel layout (i.e. mono, stereo, 3 point surround, etc...)
205  Timeline(int width, int height, Fraction fps, int sample_rate, int channels, ChannelLayout channel_layout);
206 
207  /// @brief Add an openshot::Clip to the timeline
208  /// @param clip Add an openshot::Clip to the timeline. A clip can contain any type of Reader.
209  void AddClip(Clip* clip);
210 
211  /// @brief Add an effect to the timeline
212  /// @param effect Add an effect to the timeline. An effect can modify the audio or video of an openshot::Frame.
213  void AddEffect(EffectBase* effect);
214 
215  /// Apply the timeline's framerate and samplerate to all clips
216  void ApplyMapperToClips();
217 
218  /// Determine if clips are automatically mapped to the timeline's framerate and samplerate
219  bool AutoMapClips() { return auto_map_clips; };
220 
221  /// @brief Automatically map all clips to the timeline's framerate and samplerate
222  void AutoMapClips(bool auto_map) { auto_map_clips = auto_map; };
223 
224  /// Clear all cache for this timeline instance, and all clips, mappers, and readers under it
225  void ClearAllCache();
226 
227  /// Return a list of clips on the timeline
228  list<Clip*> Clips() { return clips; };
229 
230  /// Close the timeline reader (and any resources it was consuming)
231  void Close();
232 
233  /// Return the list of effects on the timeline
234  list<EffectBase*> Effects() { return effects; };
235 
236  /// Get the cache object used by this reader
237  CacheBase* GetCache() { return final_cache; };
238 
239  /// Get the cache object used by this reader
240  void SetCache(CacheBase* new_cache);
241 
242  /// Get an openshot::Frame object for a specific frame number of this timeline.
243  ///
244  /// @returns The requested frame (containing the image)
245  /// @param requested_frame The frame number that is requested.
246  std::shared_ptr<Frame> GetFrame(int64_t requested_frame);
247 
248  // Curves for the viewport
249  Keyframe viewport_scale; ///<Curve representing the scale of the viewport (0 to 100)
250  Keyframe viewport_x; ///<Curve representing the x coordinate for the viewport
251  Keyframe viewport_y; ///<Curve representing the y coordinate for the viewport
252 
253  // Background color
254  Color color; ///<Background color of timeline canvas
255 
256  /// Determine if reader is open or closed
257  bool IsOpen() { return is_open; };
258 
259  /// Return the type name of the class
260  string Name() { return "Timeline"; };
261 
262  /// Get and Set JSON methods
263  string Json(); ///< Generate JSON string of this object
264  void SetJson(string value); ///< Load JSON string into this object
265  Json::Value JsonValue(); ///< Generate Json::JsonValue for this object
266  void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object
267 
268  /// @brief Apply a special formatted JSON object, which represents a change to the timeline (add, update, delete)
269  /// This is primarily designed to keep the timeline (and its child objects... such as clips and effects) in sync
270  /// with another application... such as OpenShot Video Editor (http://www.openshot.org).
271  /// @param value A JSON string containing a key, value, and type of change.
272  void ApplyJsonDiff(string value);
273 
274  /// Open the reader (and start consuming resources)
275  void Open();
276 
277  /// @brief Remove an openshot::Clip from the timeline
278  /// @param clip Remove an openshot::Clip from the timeline.
279  void RemoveClip(Clip* clip);
280 
281  /// @brief Remove an effect from the timeline
282  /// @param effect Remove an effect from the timeline.
283  void RemoveEffect(EffectBase* effect);
284  };
285 
286 
287 }
288 
289 #endif
openshot::EffectBase
This abstract class is the base class, used by all effects in libopenshot.
Definition: EffectBase.h:66
Point.h
Header file for Point class.
Clip.h
Header file for Clip class.
Fraction.h
Header file for Fraction class.
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: AudioBufferSource.h:45
openshot::EffectBase::Order
int Order()
Get the order that this effect should be executed.
Definition: EffectBase.h:104
openshot::Clip
This class represents a clip (used to arrange readers on the timeline)
Definition: Clip.h:109
openshot::Fraction
This class represents a fraction.
Definition: Fraction.h:42
openshot::Timeline::Clips
list< Clip * > Clips()
Return a list of clips on the timeline.
Definition: Timeline.h:228
CacheDisk.h
Header file for CacheDisk class.
EffectBase.h
Header file for EffectBase class.
KeyFrame.h
Header file for the Keyframe class.
openshot::CacheBase
All cache managers in libopenshot are based on this CacheBase class.
Definition: CacheBase.h:45
Effects.h
This header includes all commonly used effects for libopenshot, for ease-of-use.
CacheBase.h
Header file for CacheBase class.
openshot::CompareEffects::operator()
bool operator()(EffectBase *lhs, EffectBase *rhs)
Definition: Timeline.h:71
FrameMapper.h
Header file for the FrameMapper class.
openshot::Timeline::viewport_scale
Keyframe viewport_scale
Curve representing the scale of the viewport (0 to 100)
Definition: Timeline.h:249
openshot::Color
This class represents a color (used on the timeline and clips)
Definition: Color.h:42
openshot::Timeline::AutoMapClips
void AutoMapClips(bool auto_map)
Automatically map all clips to the timeline's framerate and samplerate.
Definition: Timeline.h:222
openshot::Keyframe
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
Definition: KeyFrame.h:64
CrashHandler.h
Header file for CrashHandler class.
EffectInfo.h
Header file for the EffectInfo class.
openshot::Timeline
This class represents a timeline.
Definition: Timeline.h:145
CacheMemory.h
Header file for CacheMemory class.
openshot::CompareEffects
Definition: Timeline.h:70
openshot::Timeline::viewport_y
Keyframe viewport_y
Curve representing the y coordinate for the viewport.
Definition: Timeline.h:251
openshot::Timeline::Effects
list< EffectBase * > Effects()
Return the list of effects on the timeline.
Definition: Timeline.h:234
Frame.h
Header file for Frame class.
openshot::Timeline::Name
string Name()
Return the type name of the class.
Definition: Timeline.h:260
ReaderBase.h
Header file for ReaderBase class.
openshot::CompareClips::operator()
bool operator()(Clip *lhs, Clip *rhs)
Definition: Timeline.h:61
openshot::CompareClips
Definition: Timeline.h:60
OpenMPUtilities.h
Header file for OpenMPUtilities (set some common macros)
openshot::ClipBase::Layer
int Layer()
Get layer of clip on timeline (lower number is covered by higher numbers)
Definition: ClipBase.h:84
openshot::ReaderBase
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:96
openshot::Timeline::AutoMapClips
bool AutoMapClips()
Determine if clips are automatically mapped to the timeline's framerate and samplerate.
Definition: Timeline.h:219
Color.h
Header file for Color class.
openshot::ChannelLayout
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
Definition: ChannelLayouts.h:43
openshot::Timeline::IsOpen
bool IsOpen()
Determine if reader is open or closed.
Definition: Timeline.h:257
openshot::Timeline::GetCache
CacheBase * GetCache()
Get the cache object used by this reader.
Definition: Timeline.h:237
openshot::Timeline::color
Color color
Background color of timeline canvas.
Definition: Timeline.h:254
openshot::Timeline::viewport_x
Keyframe viewport_x
Curve representing the x coordinate for the viewport.
Definition: Timeline.h:250
openshot::ClipBase::Position
float Position()
Get position on timeline (in seconds)
Definition: ClipBase.h:83