diff --git a/include/Clip.h b/include/Clip.h index a48da245..da875e87 100644 --- a/include/Clip.h +++ b/include/Clip.h @@ -113,11 +113,11 @@ namespace openshot { */ class Clip { private: - float position; /// get_time_mapped_frame(tr1::shared_ptr frame, int frame_number); + tr1::shared_ptr get_time_mapped_frame(tr1::shared_ptr frame, int frame_number) throw(ReaderClosed); /// Calculate the # of samples per video frame (for a specific frame number) - int GetSamplesPerFrame(int frame_number, Fraction rate); + int GetSamplesPerFrame(int frame_number, Fraction rate) throw(ReaderClosed); /// Init default settings for a clip void init_settings(); @@ -145,9 +145,9 @@ namespace openshot { void reverse_buffer(juce::AudioSampleBuffer* buffer); public: - GravityType gravity; /// GetFrame(int requested_frame) throw(ReaderClosed); /// Open the internal reader - void Open() throw(InvalidFile); + void Open() throw(InvalidFile, ReaderClosed); /// @brief Set the current reader /// @param reader The reader to be used by this clip void Reader(ReaderBase* reader); /// Get the current reader - ReaderBase* Reader(); + ReaderBase* Reader() throw(ReaderClosed); /// Get basic properties - float Position() { return position; } /// + * + * @section LICENSE + * + * Copyright (c) 2008-2013 OpenShot Studios, LLC + * (http://www.openshotstudios.com). This file is part of + * OpenShot Library (http://www.openshot.org), an open-source project + * dedicated to delivering high quality video editing and animation solutions + * to the world. + * + * OpenShot Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenShot Library 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 + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenShot Library. If not, see . + */ + +#ifndef OPENSHOT_EFFECT_BASE_H +#define OPENSHOT_EFFECT_BASE_H + +#include +#include +#include +#include "Frame.h" + +using namespace std; + +namespace openshot +{ + /** + * @brief This struct contains info about an effect, such as the name, video or audio effect, etc... + * + * Each derived class of EffectBase is responsible for updating this struct to reflect accurate information + * about the underlying effect. Derived classes of EffectBase should call the InitEffectInfo() method to initialize the + * default values of this struct. + */ + struct EffectInfo + { + string name; ///< The name of the effect + string description; ///< The description of this effect and what it does + bool has_video; ///< Determines if this effect manipulates the image of a frame + bool has_audio; ///< Determines if this effect manipulates the audio of a frame + float position; ///< The position on the clip (in seconds) where this effect should start being applied + }; + + /** + * @brief This abstract class is the base class, used by all effects in libopenshot. + * + * Effects are types of classes that manipulate the image or audio data of an openshot::Frame object. + * The only requirements for an 'effect', is to derive from this base class, implement the Apply() + * method, and call the InitEffectInfo() method. + */ + class EffectBase + { + public: + /// Information about the current effect + EffectInfo info; + + /// Display effect information in the standard output stream (stdout) + void DisplayInfo(); + + /// This method is required for all derived classes of EffectBase, and returns a + /// new openshot::Frame object, which is made by copying the image and audio + /// of the original frame, and modifying the image or audio data. + /// + /// @returns The requested frame of a clip (a new openshot::Frame object with copied data) + /// @param number The frame number of the clip that is requested (and needs the effect applied). + virtual tr1::shared_ptr GetFrame(int number) = 0; + + /// This method is required for all derived classes of EffectBase, and returns the + /// original openshot::Frame object, but first modifies the original frame's image or + /// audio data. + /// + /// @returns The requested frame of a clip (the original openshot::Frame object with modified data) + /// @param number The frame number of the clip that is requested (and needs the effect applied). + virtual tr1::shared_ptr Apply(int number) = 0; + + /// Initialize the values of the EffectInfo struct. It is important for derived classes to call + /// this method, or the EffectInfo struct values will not be initialized. + void InitEffectInfo(); + }; + +} + +#endif diff --git a/include/FrameMapper.h b/include/FrameMapper.h index 3c39bc8a..0c68b038 100644 --- a/include/FrameMapper.h +++ b/include/FrameMapper.h @@ -129,8 +129,6 @@ namespace openshot */ class FrameMapper : public ReaderBase { private: - vector fields; // List of all fields - vector frames; // List of all frames bool field_toggle; // Internal odd / even toggle (used when building the mapping) Framerate original; // The original frame rate Framerate target; // The target frame rate @@ -152,6 +150,10 @@ namespace openshot int GetSamplesPerFrame(int frame_number, Fraction rate); public: + // Init some containers + vector fields; // List of all fields + vector frames; // List of all frames + /// Default constructor for FrameMapper class FrameMapper(ReaderBase *reader, Framerate target, PulldownType pulldown); diff --git a/include/OpenShot.h b/include/OpenShot.h index cd2caff9..b2e9482b 100644 --- a/include/OpenShot.h +++ b/include/OpenShot.h @@ -104,6 +104,7 @@ #include "DecklinkWriter.h" #endif #include "DummyReader.h" +#include "EffectBase.h" #include "Exceptions.h" #include "ReaderBase.h" #include "WriterBase.h" diff --git a/include/Point.h b/include/Point.h index f7d8f7a5..5e0feae4 100644 --- a/include/Point.h +++ b/include/Point.h @@ -82,6 +82,9 @@ namespace openshot InterpolationType interpolation; ///< This is the interpolation mode HandleType handle_type; ///< This is the handle mode + /// Default constructor (defaults to 0,0) + Point(); + /// Constructor which creates a single coordinate at X=0 Point(float y); diff --git a/include/ReaderBase.h b/include/ReaderBase.h index 174302ed..593a78af 100644 --- a/include/ReaderBase.h +++ b/include/ReaderBase.h @@ -91,7 +91,7 @@ namespace openshot /// Display file information in the standard output stream (stdout) void DisplayInfo(); - /// This method is required for all derived classes of ReaderBase, and return the + /// This method is required for all derived classes of ReaderBase, and returns the /// openshot::Frame object, which contains the image and audio information for that /// frame of video. /// diff --git a/include/Timeline.h b/include/Timeline.h index 5ef8a5cb..a983b6d7 100644 --- a/include/Timeline.h +++ b/include/Timeline.h @@ -43,6 +43,7 @@ #include "Cache.h" #include "Color.h" #include "Clip.h" +#include "EffectBase.h" #include "ReaderBase.h" #include "Fraction.h" #include "Frame.h" @@ -137,6 +138,7 @@ namespace openshot { list clips; /// closing_clips; /// open_clips; /// effects; /// Clips() { return clips; }; + + /// Close the timeline reader (and any resources it was consuming) void Close(); + /// Return the list of effects on the timeline + list Effects() { return effects; }; + /// Get the framerate of this timeline Framerate FrameRate() { return fps; }; @@ -209,6 +217,14 @@ namespace openshot { /// Open the reader (and start consuming resources) void Open(); + /// @brief Remove an openshot::Clip from the timeline + /// @param clip Remove an openshot::Clip from the timeline. + void RemoveClip(Clip* clip); + + /// @brief Remove an effect from the timeline + /// @param effect Remove an effect from the timeline. + void RemoveEffect(EffectBase* effect); + /// Sort clips by position on the timeline void SortClips(); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24241a72..ac29a3a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -108,6 +108,7 @@ SET ( OPENSHOT_SOURCE_FILES DummyReader.cpp ReaderBase.cpp WriterBase.cpp + EffectBase.cpp FFmpegReader.cpp FFmpegWriter.cpp Fraction.cpp diff --git a/src/Clip.cpp b/src/Clip.cpp index 13b87b4e..e9652db2 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -83,6 +83,7 @@ void Clip::init_settings() // Default pointers file_reader = NULL; resampler = NULL; + audio_cache = NULL; } // Default Constructor for a clip @@ -162,13 +163,17 @@ void Clip::Reader(ReaderBase* reader) } /// Get the current reader -ReaderBase* Clip::Reader() +ReaderBase* Clip::Reader() throw(ReaderClosed) { - return file_reader; + if (file_reader) + return file_reader; + else + // Throw error if reader not initialized + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method.", ""); } // Open the internal reader -void Clip::Open() throw(InvalidFile) +void Clip::Open() throw(InvalidFile, ReaderClosed) { if (file_reader) { @@ -179,17 +184,23 @@ void Clip::Open() throw(InvalidFile) if (end == 0.0) End(file_reader->info.duration); } + else + // Throw error if reader not initialized + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method.", ""); } // Close the internal reader -void Clip::Close() +void Clip::Close() throw(ReaderClosed) { if (file_reader) file_reader->Close(); + else + // Throw error if reader not initialized + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method.", ""); } // Get end position of clip (trim end of video), which can be affected by the time curve. -float Clip::End() +float Clip::End() throw(ReaderClosed) { // if a time curve is present, use it's length if (time.Points.size() > 1) @@ -199,6 +210,9 @@ float Clip::End() if (file_reader) // file reader fps = file_reader->info.fps.ToFloat(); + else + // Throw error if reader not initialized + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method.", ""); return float(time.GetLength()) / fps; } @@ -210,22 +224,28 @@ float Clip::End() // Get an openshot::Frame object for a specific frame number of this reader. tr1::shared_ptr Clip::GetFrame(int requested_frame) throw(ReaderClosed) { - // Adjust out of bounds frame number - requested_frame = adjust_frame_number_minimum(requested_frame); + if (file_reader) + { + // Adjust out of bounds frame number + requested_frame = adjust_frame_number_minimum(requested_frame); - // Is a time map detected - int new_frame_number = requested_frame; - if (time.Values.size() > 1) - new_frame_number = time.GetInt(requested_frame); + // Is a time map detected + int new_frame_number = requested_frame; + if (time.Values.size() > 1) + new_frame_number = time.GetInt(requested_frame); - // Now that we have re-mapped what frame number is needed, go and get the frame pointer - tr1::shared_ptr frame = file_reader->GetFrame(new_frame_number); + // Now that we have re-mapped what frame number is needed, go and get the frame pointer + tr1::shared_ptr frame = file_reader->GetFrame(new_frame_number); - // Get time mapped frame number (used to increase speed, change direction, etc...) - tr1::shared_ptr new_frame = get_time_mapped_frame(frame, requested_frame); + // Get time mapped frame number (used to increase speed, change direction, etc...) + tr1::shared_ptr new_frame = get_time_mapped_frame(frame, requested_frame); - // Return processed 'frame' - return new_frame; + // Return processed 'frame' + return new_frame; + } + else + // Throw error if reader not initialized + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method.", ""); } // Get file extension @@ -264,8 +284,13 @@ void Clip::reverse_buffer(juce::AudioSampleBuffer* buffer) } // Adjust the audio and image of a time mapped frame -tr1::shared_ptr Clip::get_time_mapped_frame(tr1::shared_ptr frame, int frame_number) +tr1::shared_ptr Clip::get_time_mapped_frame(tr1::shared_ptr frame, int frame_number) throw(ReaderClosed) { + // Check for valid reader + if (!file_reader) + // Throw error if reader not initialized + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method.", ""); + tr1::shared_ptr new_frame; // Check for a valid time map curve @@ -493,8 +518,13 @@ int Clip::adjust_frame_number_minimum(int frame_number) } // Calculate the # of samples per video frame (for a specific frame number) -int Clip::GetSamplesPerFrame(int frame_number, Fraction rate) +int Clip::GetSamplesPerFrame(int frame_number, Fraction rate) throw(ReaderClosed) { + // Check for valid reader + if (!file_reader) + // Throw error if reader not initialized + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method.", ""); + // Get the total # of samples for the previous frame, and the current frame (rounded) double fps = rate.Reciprocal().ToDouble(); double previous_samples = round((file_reader->info.sample_rate * fps) * (frame_number - 1)); diff --git a/src/EffectBase.cpp b/src/EffectBase.cpp new file mode 100644 index 00000000..27d2ac23 --- /dev/null +++ b/src/EffectBase.cpp @@ -0,0 +1,55 @@ +/** + * @file + * @brief Source file for EffectBase class + * @author Jonathan Thomas + * + * @section LICENSE + * + * Copyright (c) 2008-2013 OpenShot Studios, LLC + * (http://www.openshotstudios.com). This file is part of + * OpenShot Library (http://www.openshot.org), an open-source project + * dedicated to delivering high quality video editing and animation solutions + * to the world. + * + * OpenShot Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenShot Library 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 + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenShot Library. If not, see . + */ + +#include "../include/EffectBase.h" + +using namespace openshot; + +// Initialize the values of the FileInfo struct +void EffectBase::InitEffectInfo() +{ + info.has_video = false; + info.has_audio = false; + info.position = 0.0; + info.name = ""; + info.description = ""; +} + +// Display file information +void EffectBase::DisplayInfo() { + cout << fixed << setprecision(2) << boolalpha; + cout << "----------------------------" << endl; + cout << "----- Effect Information -----" << endl; + cout << "----------------------------" << endl; + cout << "--> Name: " << info.name << endl; + cout << "--> Description: " << info.description << endl; + cout << "--> Has Video: " << info.has_video << endl; + cout << "--> Has Audio: " << info.has_audio << endl; + cout << "--> Position: " << info.position << " Seconds" << endl; + cout << "----------------------------" << endl; +} + diff --git a/src/Point.cpp b/src/Point.cpp index 9132e962..21527036 100644 --- a/src/Point.cpp +++ b/src/Point.cpp @@ -30,6 +30,16 @@ using namespace std; using namespace openshot; +// Default constructor (defaults to 0,0) +Point::Point() : interpolation(BEZIER), handle_type(AUTO) +{ + // set new coorinate + co = Coordinate(0, 0); + + // set handles + Initialize_Handles(); +} + // Constructor which creates a single coordinate at X=0 Point::Point(float y) : interpolation(BEZIER), handle_type(AUTO) { diff --git a/src/Timeline.cpp b/src/Timeline.cpp index acbac92b..3c6a5e0a 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -71,6 +71,19 @@ void Timeline::AddClip(Clip* clip) SortClips(); } +// Add an effect to the timeline +void Timeline::AddEffect(EffectBase* effect) +{ + // Add effect to list + effects.push_back(effect); +} + +// Remove an effect from the timeline +void Timeline::RemoveEffect(EffectBase* effect) +{ + effects.remove(effect); +} + // Remove an openshot::Clip to the timeline void Timeline::RemoveClip(Clip* clip) { diff --git a/src/openshot.i b/src/openshot.i index 46d00c7e..14e3b22f 100644 --- a/src/openshot.i +++ b/src/openshot.i @@ -29,6 +29,8 @@ %include "typemaps.i" %include "std_string.i" +%include "std_list.i" +%include "std_vector.i" /* Unhandled STL Exception Handling */ %include @@ -37,6 +39,7 @@ #define SWIG_SHARED_PTR_SUBNAMESPACE tr1 %include + /* Mark these classes as shared_ptr classes */ %shared_ptr(Magick::Image) %shared_ptr(juce::AudioSampleBuffer) @@ -52,6 +55,7 @@ #include "../include/ChunkWriter.h" #include "../include/Coordinate.h" #include "../include/DummyReader.h" +#include "../include/EffectBase.h" #include "../include/Exceptions.h" #include "../include/FFmpegReader.h" #include "../include/FFmpegWriter.h" @@ -86,6 +90,7 @@ %include "../include/DecklinkWriter.h" #endif %include "../include/DummyReader.h" +%include "../include/EffectBase.h" %include "../include/Exceptions.h" %include "../include/FFmpegReader.h" %include "../include/FFmpegWriter.h" @@ -98,4 +103,15 @@ %include "../include/Point.h" %include "../include/KeyFrame.h" %include "../include/TextReader.h" -%include "../include/Timeline.h" \ No newline at end of file +%include "../include/Timeline.h" + +/* Wrap std templates (list, vector, etc...) */ +namespace std { + %template(ClipList) list; + %template(EffectBaseList) list; + %template(CoordinateVector) vector; + %template(PointsVector) vector; + %template(FieldVector) vector; + %template(MappedFrameVector) vector; + +} \ No newline at end of file