OpenShot Library | libopenshot  0.2.2
Frame.h
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Header file for Frame 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_FRAME_H
29 #define OPENSHOT_FRAME_H
30 
31 /// Do not include the juce unittest headers, because it collides with unittest++
32 #ifndef __JUCE_UNITTEST_JUCEHEADER__
33  #define __JUCE_UNITTEST_JUCEHEADER__
34 #endif
35 #ifndef _NDEBUG
36  // Define NO debug for JUCE on mac os
37  #define _NDEBUG
38 #endif
39 
40 #include <iomanip>
41 #include <sstream>
42 #include <queue>
43 #include <QtWidgets/QApplication>
44 #include <QtGui/QImage>
45 #include <QtGui/QColor>
46 #include <QtGui/QBitmap>
47 #include <QtCore/QString>
48 #include <QtCore/QVector>
49 #include <QtGui/QPainter>
50 #include <QtWidgets/QHBoxLayout>
51 #include <QtWidgets/QWidget>
52 #include <QtWidgets/QLabel>
53 #include <memory>
54 #include <unistd.h>
55 #include "ZmqLogger.h"
56 #ifdef USE_IMAGEMAGICK
57  #include "Magick++.h"
58 #endif
59 #include "JuceLibraryCode/JuceHeader.h"
60 #include "ChannelLayouts.h"
61 #include "AudioBufferSource.h"
62 #include "AudioResampler.h"
63 #include "Fraction.h"
64 
65 #pragma SWIG nowarn=362
66 using namespace std;
67 
68 namespace openshot
69 {
70  /**
71  * @brief This class represents a single frame of video (i.e. image & audio data)
72  *
73  * FileReaders (such as FFmpegReader) use instances of this class to store the individual frames of video,
74  * which include both the image data (i.e. pixels) and audio samples. An openshot::Frame also has many debug
75  * methods, such as the ability to display the image (using X11), play the audio samples (using JUCE), or
76  * display the audio waveform as an image.
77  *
78  * FileWriters (such as FFmpegWriter) use instances of this class to create new video files, image files, or
79  * video streams. So, think of these openshot::Frame instances as the smallest unit of work in a video
80  * editor.
81  *
82  * There are many ways to create an instance of an openshot::Frame:
83  * @code
84  *
85  * // Most basic: a blank frame (300x200 blank image, 48kHz audio silence)
86  * Frame();
87  *
88  * // Image only settings (48kHz audio silence)
89  * Frame(1, // Frame number
90  * 720, // Width of image
91  * 480, // Height of image
92  * "#000000" // HTML color code of background color
93  * );
94  *
95  * // Audio only (300x200 blank image)
96  * Frame(number, // Frame number
97  * 44100, // Sample rate of audio stream
98  * 2 // Number of audio channels
99  * );
100  *
101  * // Image and Audio settings (user defines all key settings)
102  * Frame(number, // Frame number
103  * 720, // Width of image
104  * 480, // Height of image
105  * "#000000" // HTML color code of background color
106  * 44100, // Sample rate of audio stream
107  * 2 // Number of audio channels
108  * );
109  *
110  * // Some methods require a shared pointer to an openshot::Frame object.
111  * std::shared_ptr<Frame> f(new Frame(1, 720, 480, "#000000", 44100, 2));
112  *
113  * @endcode
114  */
115  class Frame
116  {
117  private:
118  std::shared_ptr<QImage> image;
119  std::shared_ptr<QImage> wave_image;
120  std::shared_ptr<juce::AudioSampleBuffer> audio;
121  std::shared_ptr<QApplication> previewApp;
122  CriticalSection addingImageSection;
123  CriticalSection addingAudioSection;
124  const unsigned char *qbuffer;
125  Fraction pixel_ratio;
126  int channels;
127  ChannelLayout channel_layout;
128  int width;
129  int height;
130  int sample_rate;
131  string color;
132  int64_t max_audio_sample; ///< The max audio sample count added to this frame
133 
134  /// Constrain a color value from 0 to 255
135  int constrain(int color_value);
136 
137  public:
138  int64_t number; ///< This is the frame number (starting at 1)
139  bool has_audio_data; ///< This frame has been loaded with audio data
140  bool has_image_data; ///< This frame has been loaded with pixel data
141 
142 
143  /// Constructor - blank frame (300x200 blank image, 48kHz audio silence)
144  Frame();
145 
146  /// Constructor - image only (48kHz audio silence)
147  Frame(int64_t number, int width, int height, string color);
148 
149  /// Constructor - audio only (300x200 blank image)
150  Frame(int64_t number, int samples, int channels);
151 
152  /// Constructor - image & audio
153  Frame(int64_t number, int width, int height, string color, int samples, int channels);
154 
155  /// Copy constructor
156  Frame ( const Frame &other );
157 
158  /// Assignment operator
159  Frame& operator= (const Frame& other);
160 
161  /// Destructor
162  ~Frame();
163 
164  /// Add (or replace) pixel data to the frame (based on a solid color)
165  void AddColor(int new_width, int new_height, string new_color);
166 
167  /// Add (or replace) pixel data to the frame
168  void AddImage(int new_width, int new_height, int bytes_per_pixel, QImage::Format type, const unsigned char *pixels_);
169 
170  /// Add (or replace) pixel data to the frame
171  void AddImage(std::shared_ptr<QImage> new_image);
172 
173  /// Add (or replace) pixel data to the frame (for only the odd or even lines)
174  void AddImage(std::shared_ptr<QImage> new_image, bool only_odd_lines);
175 
176 #ifdef USE_IMAGEMAGICK
177  /// Add (or replace) pixel data to the frame from an ImageMagick Image
178  void AddMagickImage(std::shared_ptr<Magick::Image> new_image);
179 #endif
180 
181  /// Add audio samples to a specific channel
182  void AddAudio(bool replaceSamples, int destChannel, int destStartSample, const float* source, int numSamples, float gainToApplyToSource);
183 
184  /// Add audio silence
185  void AddAudioSilence(int numSamples);
186 
187  /// Apply gain ramp (i.e. fading volume)
188  void ApplyGainRamp(int destChannel, int destStartSample, int numSamples, float initial_gain, float final_gain);
189 
190  /// Channel Layout of audio samples. A frame needs to keep track of this, since Writers do not always
191  /// know the original channel layout of a frame's audio samples (i.e. mono, stereo, 5 point surround, etc...)
192  ChannelLayout ChannelsLayout();
193 
194  // Set the channel layout of audio samples (i.e. mono, stereo, 5 point surround, etc...)
195  void ChannelsLayout(ChannelLayout new_channel_layout) { channel_layout = new_channel_layout; };
196 
197  /// Clean up buffer after QImage is deleted
198  static void cleanUpBuffer(void *info);
199 
200  /// Clear the waveform image (and deallocate it's memory)
201  void ClearWaveform();
202 
203  /// Copy data and pointers from another Frame instance
204  void DeepCopy(const Frame& other);
205 
206  /// Display the frame image to the screen (primarily used for debugging reasons)
207  void Display();
208 
209  /// Display the wave form
210  void DisplayWaveform();
211 
212  /// Get magnitude of range of samples (if channel is -1, return average of all channels for that sample)
213  float GetAudioSample(int channel, int sample, int magnitude_range);
214 
215  /// Get an array of sample data
216  float* GetAudioSamples(int channel);
217 
218  /// Get an array of sample data (all channels interleaved together), using any sample rate
219  float* GetInterleavedAudioSamples(int new_sample_rate, AudioResampler* resampler, int* sample_count);
220 
221  // Get a planar array of sample data, using any sample rate
222  float* GetPlanarAudioSamples(int new_sample_rate, AudioResampler* resampler, int* sample_count);
223 
224  /// Get number of audio channels
225  int GetAudioChannelsCount();
226 
227  /// Get number of audio samples
228  int GetAudioSamplesCount();
229 
230  juce::AudioSampleBuffer *GetAudioSampleBuffer();
231 
232  /// Get the size in bytes of this frame (rough estimate)
233  int64_t GetBytes();
234 
235  /// Get pointer to Qt QImage image object
236  std::shared_ptr<QImage> GetImage();
237 
238 #ifdef USE_IMAGEMAGICK
239  /// Get pointer to ImageMagick image object
240  std::shared_ptr<Magick::Image> GetMagickImage();
241 #endif
242 
243  /// Set Pixel Aspect Ratio
244  Fraction GetPixelRatio() { return pixel_ratio; };
245 
246  /// Get pixel data (as packets)
247  const unsigned char* GetPixels();
248 
249  /// Get pixel data (for only a single scan-line)
250  const unsigned char* GetPixels(int row);
251 
252  /// Get height of image
253  int GetHeight();
254 
255  /// Calculate the # of samples per video frame (for the current frame number)
256  int GetSamplesPerFrame(Fraction fps, int sample_rate, int channels);
257 
258  /// Calculate the # of samples per video frame (for a specific frame number and frame rate)
259  static int GetSamplesPerFrame(int64_t frame_number, Fraction fps, int sample_rate, int channels);
260 
261  /// Get an audio waveform image
262  std::shared_ptr<QImage> GetWaveform(int width, int height, int Red, int Green, int Blue, int Alpha);
263 
264  /// Get an audio waveform image pixels
265  const unsigned char* GetWaveformPixels(int width, int height, int Red, int Green, int Blue, int Alpha);
266 
267  /// Get height of image
268  int GetWidth();
269 
270  /// Resize audio container to hold more (or less) samples and channels
271  void ResizeAudio(int channels, int length, int sample_rate, ChannelLayout channel_layout);
272 
273  /// Get the original sample rate of this frame's audio data
274  int SampleRate();
275 
276  /// Set the original sample rate of this frame's audio data
277  void SampleRate(int orig_sample_rate) { sample_rate = orig_sample_rate; };
278 
279  /// Save the frame image to the specified path. The image format can be BMP, JPG, JPEG, PNG, PPM, XBM, XPM
280  void Save(string path, float scale, string format="PNG", int quality=100);
281 
282  /// Set frame number
283  void SetFrameNumber(int64_t number);
284 
285  /// Set Pixel Aspect Ratio
286  void SetPixelRatio(int num, int den);
287 
288  /// Thumbnail the frame image with tons of options to the specified path. The image format is determined from the extension (i.e. image.PNG, image.JPEG).
289  /// This method allows for masks, overlays, background color, and much more accurate resizing (including padding and centering)
290  void Thumbnail(string path, int new_width, int new_height, string mask_path, string overlay_path,
291  string background_color, bool ignore_aspect, string format="png", int quality=100, float rotate=0.0);
292 
293  /// Play audio samples for this frame
294  void Play();
295  };
296 
297 }
298 
299 #endif
ChannelLayouts.h
Header file for ChannelLayout class.
Fraction.h
Header file for Fraction class.
openshot::Frame::has_audio_data
bool has_audio_data
This frame has been loaded with audio data.
Definition: Frame.h:139
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: AudioBufferSource.h:45
openshot::Fraction
This class represents a fraction.
Definition: Fraction.h:42
AudioBufferSource.h
Header file for AudioBufferSource class.
AudioResampler.h
Header file for AudioResampler class.
openshot::Frame
This class represents a single frame of video (i.e. image & audio data)
Definition: Frame.h:115
openshot::Frame::has_image_data
bool has_image_data
This frame has been loaded with pixel data.
Definition: Frame.h:140
openshot::AudioResampler
This class is used to resample audio data for many sequential frames.
Definition: AudioResampler.h:53
ZmqLogger.h
Header file for ZeroMQ-based Logger class.
openshot::Frame::ChannelsLayout
void ChannelsLayout(ChannelLayout new_channel_layout)
Definition: Frame.h:195
openshot::Frame::GetPixelRatio
Fraction GetPixelRatio()
Set Pixel Aspect Ratio.
Definition: Frame.h:244
openshot::Frame::SampleRate
void SampleRate(int orig_sample_rate)
Set the original sample rate of this frame's audio data.
Definition: Frame.h:277
openshot::ChannelLayout
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
Definition: ChannelLayouts.h:43
openshot::Frame::number
int64_t number
This is the frame number (starting at 1)
Definition: Frame.h:138