2011-10-11 08:44:27 -05:00
/**
2013-09-09 23:32:16 -05:00
* @ file
* @ brief Header file for Frame class
2013-09-12 17:52:10 -05:00
* @ author Jonathan Thomas < jonathan @ openshot . org >
*
* @ section LICENSE
*
2014-03-29 18:49:22 -05:00
* Copyright ( c ) 2008 - 2014 OpenShot Studios , LLC
* < http : //www.openshotstudios.com/>. This file is part of
* OpenShot Library ( libopenshot ) , an open - source project dedicated to
* delivering high quality video editing and animation solutions to the
* world . For more information visit < http : //www.openshot.org/>.
2013-09-12 17:52:10 -05:00
*
2014-03-29 18:49:22 -05:00
* OpenShot Library ( libopenshot ) is free software : you can redistribute it
2014-07-11 16:52:14 -05:00
* and / or modify it under the terms of the GNU Lesser General Public License
2014-03-29 18:49:22 -05:00
* as published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
2013-09-12 17:52:10 -05:00
*
2014-03-29 18:49:22 -05:00
* OpenShot Library ( libopenshot ) is distributed in the hope that it will be
* useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2014-07-11 16:52:14 -05:00
* GNU Lesser General Public License for more details .
2013-09-12 17:52:10 -05:00
*
2014-07-11 16:52:14 -05:00
* You should have received a copy of the GNU Lesser General Public License
2014-03-29 18:49:22 -05:00
* along with OpenShot Library . If not , see < http : //www.gnu.org/licenses/>.
2011-10-11 08:44:27 -05:00
*/
2013-09-12 17:52:10 -05:00
# ifndef OPENSHOT_FRAME_H
# define OPENSHOT_FRAME_H
2011-10-11 08:44:27 -05:00
/// Do not include the juce unittest headers, because it collides with unittest++
2012-08-05 15:17:37 -05:00
# ifndef __JUCE_UNITTEST_JUCEHEADER__
# define __JUCE_UNITTEST_JUCEHEADER__
# endif
2013-06-09 01:08:23 -05:00
# ifndef _NDEBUG
// Define NO debug for JUCE on mac os
# define _NDEBUG
# endif
2011-10-11 08:44:27 -05:00
# include <iomanip>
# include <sstream>
# include <queue>
2012-10-17 09:57:02 -05:00
# include <tr1/memory>
2013-02-06 02:09:21 -06:00
# include <unistd.h>
2011-10-11 08:44:27 -05:00
# include "Magick++.h"
2012-06-16 02:12:48 -05:00
# include "JuceLibraryCode/JuceHeader.h"
2015-02-05 00:11:55 -06:00
# include "ChannelLayouts.h"
2011-10-11 08:44:27 -05:00
# include "AudioBufferSource.h"
2012-08-05 15:17:37 -05:00
# include "AudioResampler.h"
2011-12-11 20:42:50 -06:00
# include "Fraction.h"
2013-06-06 12:12:08 -05:00
# include "Sleep.h"
2011-10-11 08:44:27 -05:00
using namespace std ;
namespace openshot
{
/**
2013-09-09 23:32:16 -05:00
* @ brief This class represents a single frame of video ( i . e . image & audio data )
2011-10-11 08:44:27 -05:00
*
* FileReaders ( such as FFmpegReader ) use instances of this class to store the individual frames of video ,
2013-09-15 22:21:19 -05:00
* which include both the image data ( i . e . pixels ) and audio samples . An openshot : : Frame also has many debug
* methods , such as the ability to display the image ( using X11 ) , play the audio samples ( using JUCE ) , or
* display the audio waveform as an image .
*
* FileWriters ( such as FFmpegWriter ) use instances of this class to create new video files , image files , or
* video streams . So , think of these openshot : : Frame instances as the smallest unit of work in a video
* editor .
*
* There are many ways to create an instance of an openshot : : Frame :
* @ code
*
* // Most basic: a blank frame (300x200 blank image, 48kHz audio silence)
* Frame ( ) ;
*
* // Image only settings (48kHz audio silence)
* Frame ( 1 , // Frame number
* 720 , // Width of image
* 480 , // Height of image
* " #000000 " // HTML color code of background color
* ) ;
*
* // Image only from pixel array (48kHz audio silence)
* Frame ( number , // Frame number
* 720 , // Width of image
* 480 , // Height of image
* " RGBA " , // Color format / map
* Magick : : CharPixel , // Storage format / data type
* buffer // Array of image data (pixels)
* ) ;
*
* // Audio only (300x200 blank image)
* Frame ( number , // Frame number
* 44100 , // Sample rate of audio stream
* 2 // Number of audio channels
* ) ;
*
* // Image and Audio settings (user defines all key settings)
* Frame ( number , // Frame number
* 720 , // Width of image
* 480 , // Height of image
* " #000000 " // HTML color code of background color
* 44100 , // Sample rate of audio stream
* 2 // Number of audio channels
* ) ;
*
* // Some methods require a shared pointer to an openshot::Frame object.
* tr1 : : shared_ptr < Frame > f ( new Frame ( 1 , 720 , 480 , " #000000 " , 44100 , 2 ) ) ;
*
* @ endcode
2011-10-11 08:44:27 -05:00
*/
class Frame
{
private :
2012-10-17 09:57:02 -05:00
tr1 : : shared_ptr < Magick : : Image > image ;
tr1 : : shared_ptr < Magick : : Image > wave_image ;
tr1 : : shared_ptr < juce : : AudioSampleBuffer > audio ;
2011-12-11 20:42:50 -06:00
Fraction pixel_ratio ;
2012-07-02 00:51:10 -05:00
int channels ;
2015-02-05 00:11:55 -06:00
ChannelLayout channel_layout ;
2012-10-26 00:27:44 -05:00
int width ;
int height ;
2015-02-05 00:11:55 -06:00
int sample_rate ;
2012-07-02 00:51:10 -05:00
2011-10-11 08:44:27 -05:00
public :
2012-07-02 00:51:10 -05:00
int number ; ///< This is the frame number (starting at 1)
2011-10-11 08:44:27 -05:00
/// Constructor - blank frame (300x200 blank image, 48kHz audio silence)
Frame ( ) ;
/// Constructor - image only (48kHz audio silence)
Frame ( int number , int width , int height , string color ) ;
/// Constructor - image only from pixel array (48kHz audio silence)
2011-10-24 08:22:21 -05:00
Frame ( int number , int width , int height , const string map , const Magick : : StorageType type , const void * pixels_ ) ;
2011-10-11 08:44:27 -05:00
/// Constructor - audio only (300x200 blank image)
Frame ( int number , int samples , int channels ) ;
/// Constructor - image & audio
Frame ( int number , int width , int height , string color , int samples , int channels ) ;
/// Copy constructor
Frame ( const Frame & other ) ;
/// Assignment operator
2013-01-12 12:45:55 -06:00
//Frame& operator= (const Frame& other);
/// Destructor
~ Frame ( ) ;
2011-10-11 08:44:27 -05:00
2012-10-12 00:54:53 -05:00
/// Add (or replace) pixel data to the frame (based on a solid color)
void AddColor ( int width , int height , string color ) ;
2012-08-11 21:13:05 -05:00
/// Add (or replace) pixel data to the frame
void AddImage ( int width , int height , const string map , const Magick : : StorageType type , const void * pixels_ ) ;
2012-08-29 15:29:15 -05:00
/// Add (or replace) pixel data to the frame
2012-10-17 09:57:02 -05:00
void AddImage ( tr1 : : shared_ptr < Magick : : Image > new_image ) ;
2012-08-29 15:29:15 -05:00
2012-10-18 02:58:09 -05:00
/// Add (or replace) pixel data to the frame (for only the odd or even lines)
void AddImage ( tr1 : : shared_ptr < Magick : : Image > new_image , bool only_odd_lines ) ;
2012-08-11 21:13:05 -05:00
/// Add audio samples to a specific channel
2012-11-29 16:32:48 -06:00
void AddAudio ( bool replaceSamples , int destChannel , int destStartSample , const float * source , int numSamples , float gainToApplyToSource ) ;
/// Apply gain ramp (i.e. fading volume)
void ApplyGainRamp ( int destChannel , int destStartSample , int numSamples , float initial_gain , float final_gain ) ;
2012-08-11 21:13:05 -05:00
2012-10-29 01:47:39 -05:00
/// Composite a new image on top of the existing image
void AddImage ( tr1 : : shared_ptr < Magick : : Image > new_image , float alpha ) ;
2012-08-11 21:13:05 -05:00
/// Experimental method to add effects to this frame
void AddEffect ( string name ) ;
2012-08-29 16:07:47 -05:00
/// Experimental method to add overlay images to this frame
void AddOverlay ( Frame * frame ) ;
2012-10-12 00:54:53 -05:00
/// Experimental method to add the frame number on top of the image
void AddOverlayNumber ( int overlay_number ) ;
2015-02-05 00:11:55 -06:00
/// Channel Layout of audio samples. A frame needs to keep track of this, since Writers do not always
/// know the original channel layout of a frame's audio samples (i.e. mono, stereo, 5 point surround, etc...)
ChannelLayout ChannelsLayout ( ) ;
// Set the channel layout of audio samples (i.e. mono, stereo, 5 point surround, etc...)
void ChannelsLayout ( ChannelLayout new_channel_layout ) { channel_layout = new_channel_layout ; } ;
2012-08-22 17:31:12 -05:00
/// Clear the waveform image (and deallocate it's memory)
void ClearWaveform ( ) ;
2011-10-11 08:44:27 -05:00
/// Copy data and pointers from another Frame instance
void DeepCopy ( const Frame & other ) ;
/// Display the frame image to the screen (primarily used for debugging reasons)
void Display ( ) ;
2011-10-24 17:32:26 -05:00
/// Display the wave form
2012-08-22 17:31:12 -05:00
void DisplayWaveform ( ) ;
2011-10-24 17:32:26 -05:00
2012-07-09 01:22:11 -05:00
/// Get an array of sample data
float * GetAudioSamples ( int channel ) ;
2012-07-30 02:37:19 -05:00
/// Get an array of sample data (all channels interleaved together), using any sample rate
2015-02-05 00:11:55 -06:00
float * GetInterleavedAudioSamples ( int new_sample_rate , AudioResampler * resampler , int * sample_count ) ;
// Get a planar array of sample data, using any sample rate
float * GetPlanarAudioSamples ( int new_sample_rate , AudioResampler * resampler , int * sample_count ) ;
2012-07-24 12:50:17 -05:00
2012-07-09 01:22:11 -05:00
/// Get number of audio channels
int GetAudioChannelsCount ( ) ;
/// Get number of audio channels
int GetAudioSamplesCount ( ) ;
2014-01-27 19:03:46 +08:00
juce : : AudioSampleBuffer * GetAudioSampleBuffer ( ) ;
2012-10-11 17:30:32 -05:00
/// Get the size in bytes of this frame (rough estimate)
int64 GetBytes ( ) ;
2012-08-29 16:07:47 -05:00
/// Get pointer to Magick++ image object
2012-10-17 09:57:02 -05:00
tr1 : : shared_ptr < Magick : : Image > GetImage ( ) ;
2012-08-29 16:07:47 -05:00
2015-02-05 00:11:55 -06:00
/// Set Pixel Aspect Ratio
Fraction GetPixelRatio ( ) { return pixel_ratio ; } ;
2011-10-11 08:44:27 -05:00
/// Get pixel data (as packets)
const Magick : : PixelPacket * GetPixels ( ) ;
/// Get pixel data (for only a single scan-line)
const Magick : : PixelPacket * GetPixels ( int row ) ;
/// Get height of image
int GetHeight ( ) ;
2014-01-28 17:17:38 -06:00
/// Calculate the # of samples per video frame (for the current frame number)
int GetSamplesPerFrame ( Fraction fps , int sample_rate ) ;
/// Calculate the # of samples per video frame (for a specific frame number and frame rate)
static int GetSamplesPerFrame ( int frame_number , Fraction fps , int sample_rate ) ;
2012-08-22 17:31:12 -05:00
/// Get an audio waveform image
2012-11-29 23:11:50 -06:00
tr1 : : shared_ptr < Magick : : Image > GetWaveform ( int width , int height , int Red , int Green , int Blue ) ;
2012-08-22 17:31:12 -05:00
/// Get an audio waveform image pixels
2012-11-29 23:11:50 -06:00
const Magick : : PixelPacket * GetWaveformPixels ( int width , int height , int Red , int Green , int Blue ) ;
2012-08-22 17:31:12 -05:00
2011-10-11 08:44:27 -05:00
/// Get height of image
int GetWidth ( ) ;
2012-10-10 02:36:53 -05:00
/// Rotate the image
void Rotate ( float degrees ) ;
2015-02-05 00:11:55 -06:00
/// Get the original sample rate of this frame's audio data
int SampleRate ( ) ;
/// Set the original sample rate of this frame's audio data
void SampleRate ( int orig_sample_rate ) { sample_rate = orig_sample_rate ; } ;
2012-08-05 16:43:09 -05:00
/// Save the frame image to the specified path. The image format is determined from the extension (i.e. image.PNG, image.JPEG)
void Save ( string path , float scale ) ;
2011-10-11 08:44:27 -05:00
2013-02-10 21:16:46 -06:00
/// Set frame number
void SetFrameNumber ( int number ) ;
2012-08-11 21:13:05 -05:00
/// Set Pixel Aspect Ratio
void SetPixelRatio ( int num , int den ) ;
2011-10-24 08:22:21 -05:00
2014-05-20 00:57:27 -05:00
/// 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).
/// This method allows for masks, overlays, background color, and much more accurate resizing (including padding and centering)
void Thumbnail ( string path , int new_width , int new_height , string mask_path , string overlay_path ,
string background_color , bool ignore_aspect ) throw ( InvalidFile ) ;
2013-01-26 23:02:21 -06:00
/// Make colors in a specific range transparent
void TransparentColors ( string color , double fuzz ) ;
2011-10-11 08:44:27 -05:00
/// Play audio samples for this frame
2015-02-05 00:11:55 -06:00
void Play ( ) ;
2011-10-11 08:44:27 -05:00
} ;
}
# endif