diff --git a/.travis.yml b/.travis.yml index 4afd8467..2e7db59d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,8 @@ matrix: - cmake -D"CMAKE_BUILD_TYPE:STRING=Debug" ../ - make VERBOSE=1 - make os_test - + - make install DESTDIR=dist/ + - language: cpp name: "FFmpeg 3" before_script: @@ -31,7 +32,8 @@ matrix: - cmake -D"CMAKE_BUILD_TYPE:STRING=Debug" ../ - make VERBOSE=1 - make os_test - + - make install DESTDIR=dist/ + - language: cpp name: "FFmpeg 4" before_script: @@ -48,3 +50,4 @@ matrix: - cmake -D"CMAKE_BUILD_TYPE:STRING=Debug" ../ - make VERBOSE=1 - make os_test + - make install DESTDIR=dist/ diff --git a/include/CacheBase.h b/include/CacheBase.h index af24b153..3760e84b 100644 --- a/include/CacheBase.h +++ b/include/CacheBase.h @@ -63,8 +63,6 @@ namespace openshot { /// @param max_bytes The maximum bytes to allow in the cache. Once exceeded, the cache will purge the oldest frames. CacheBase(int64_t max_bytes); - virtual ~CacheBase(); - /// @brief Add a Frame to the cache /// @param frame The openshot::Frame object needing to be cached. virtual void Add(std::shared_ptr frame) = 0; @@ -114,6 +112,7 @@ namespace openshot { virtual void SetJson(string value) = 0; ///< Load JSON string into this object virtual Json::Value JsonValue() = 0; ///< Generate Json::JsonValue for this object virtual void SetJsonValue(Json::Value root) = 0; ///< Load Json::JsonValue into this object + virtual ~CacheBase() = default; }; diff --git a/include/Clip.h b/include/Clip.h index 52be853e..c092c2ad 100644 --- a/include/Clip.h +++ b/include/Clip.h @@ -148,8 +148,8 @@ namespace openshot { void reverse_buffer(juce::AudioSampleBuffer* buffer); public: - GravityType gravity; ///< The gravity of a clip determines where it snaps to it's parent - ScaleType scale; ///< The scale determines how a clip should be resized to fit it's parent + GravityType gravity; ///< The gravity of a clip determines where it snaps to its parent + ScaleType scale; ///< The scale determines how a clip should be resized to fit its parent AnchorType anchor; ///< The anchor determines what parent a clip should snap to FrameDisplayType display; ///< The format to display the frame number (if any) VolumeMixType mixing; ///< What strategy should be followed when mixing audio with other clips diff --git a/include/ClipBase.h b/include/ClipBase.h index adbf11ef..ab3f0637 100644 --- a/include/ClipBase.h +++ b/include/ClipBase.h @@ -72,7 +72,6 @@ namespace openshot { /// Constructor for the base clip ClipBase() { }; - virtual ~ClipBase(); // Compare a clip using the Position() property bool operator< ( ClipBase& a) { return (Position() < a.Position()); } @@ -105,6 +104,7 @@ namespace openshot { /// of all properties at any time) virtual string PropertiesJSON(int64_t requested_frame) = 0; + virtual ~ClipBase() = default; }; diff --git a/include/EffectBase.h b/include/EffectBase.h index cd39c272..a16b6620 100644 --- a/include/EffectBase.h +++ b/include/EffectBase.h @@ -85,7 +85,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it @@ -108,6 +108,7 @@ namespace openshot /// Set the order that this effect should be executed. void Order(int new_order) { order = new_order; } + virtual ~EffectBase() = default; }; } diff --git a/include/FFmpegReader.h b/include/FFmpegReader.h index 923c8c18..894d3e5d 100644 --- a/include/FFmpegReader.h +++ b/include/FFmpegReader.h @@ -162,7 +162,7 @@ namespace openshot { /// Check the current seek position and determine if we need to seek again bool CheckSeek(bool is_video); - /// Check if a frame is missing and attempt to replace it's frame image (and + /// Check if a frame is missing and attempt to replace its frame image (and bool CheckMissingFrame(int64_t requested_frame); /// Check the working queue, and move finished frames to the finished queue @@ -210,10 +210,10 @@ namespace openshot { /// Read the stream until we find the requested Frame std::shared_ptr ReadStream(int64_t requested_frame); - /// Remove AVFrame from cache (and deallocate it's memory) + /// Remove AVFrame from cache (and deallocate its memory) void RemoveAVFrame(AVFrame *); - /// Remove AVPacket from cache (and deallocate it's memory) + /// Remove AVPacket from cache (and deallocate its memory) void RemoveAVPacket(AVPacket *); /// Seek to a specific Frame. This is not always frame accurate, it's more of an estimation on many codecs. @@ -240,7 +240,7 @@ namespace openshot { /// frame 1, or it throws one of the following exceptions. FFmpegReader(string path); - /// Constructor for FFmpegReader. This only opens the media file to inspect it's properties + /// Constructor for FFmpegReader. This only opens the media file to inspect its properties /// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful /// when you are inflating the object using JSON after instantiating it. FFmpegReader(string path, bool inspect_reader); diff --git a/include/FFmpegWriter.h b/include/FFmpegWriter.h index d27d8238..8b3a4673 100644 --- a/include/FFmpegWriter.h +++ b/include/FFmpegWriter.h @@ -84,7 +84,7 @@ namespace openshot { * FFmpegWriter w("/home/jonathan/NewVideo.webm"); * * // Set options - * w.SetAudioOptions(true, "libvorbis", 44100, 2, 128000); // Sample Rate: 44100, Channels: 2, Bitrate: 128000 + * w.SetAudioOptions(true, "libvorbis", 44100, 2, ChannelLayout::LAYOUT_STEREO, 128000); // Sample Rate: 44100, Channels: 2, Bitrate: 128000 * w.SetVideoOptions(true, "libvpx", openshot::Fraction(24,1), 720, 480, openshot::Fraction(1,1), false, false, 300000); // FPS: 24, Size: 720x480, Pixel Ratio: 1/1, Bitrate: 300000 * * // Open the writer @@ -111,7 +111,7 @@ namespace openshot { * FFmpegWriter w("/home/jonathan/NewVideo.webm"); * * // Set options - * w.SetAudioOptions(true, "libvorbis", 44100, 2, 128000); // Sample Rate: 44100, Channels: 2, Bitrate: 128000 + * w.SetAudioOptions(true, "libvorbis", 44100, 2, ChannelLayout::LAYOUT_STEREO, 128000); // Sample Rate: 44100, Channels: 2, Bitrate: 128000 * w.SetVideoOptions(true, "libvpx", openshot::Fraction(24,1), 720, 480, openshot::Fraction(1,1), false, false, 300000); // FPS: 24, Size: 720x480, Pixel Ratio: 1/1, Bitrate: 300000 * * // Prepare Streams (Optional method that must be called before any SetOption calls) diff --git a/include/Frame.h b/include/Frame.h index 40859e7c..cb855fe4 100644 --- a/include/Frame.h +++ b/include/Frame.h @@ -200,7 +200,7 @@ namespace openshot /// Clean up buffer after QImage is deleted static void cleanUpBuffer(void *info); - /// Clear the waveform image (and deallocate it's memory) + /// Clear the waveform image (and deallocate its memory) void ClearWaveform(); /// Copy data and pointers from another Frame instance diff --git a/include/ImageReader.h b/include/ImageReader.h index c4e1e8fc..b02d2f04 100644 --- a/include/ImageReader.h +++ b/include/ImageReader.h @@ -83,7 +83,7 @@ namespace openshot /// frame 1, or it throws one of the following exceptions. ImageReader(string path); - /// Constructor for ImageReader. This only opens the media file to inspect it's properties + /// Constructor for ImageReader. This only opens the media file to inspect its properties /// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful /// when you are inflating the object using JSON after instantiating it. ImageReader(string path, bool inspect_reader); diff --git a/include/ImageWriter.h b/include/ImageWriter.h index fb5385a3..c1d2726a 100644 --- a/include/ImageWriter.h +++ b/include/ImageWriter.h @@ -130,7 +130,7 @@ namespace openshot /// @param height Height in pixels of image /// @param quality Quality of image (0 to 100, 70 is default) /// @param loops Number of times to repeat the image (used on certain multi-frame image formats, such as GIF) - /// @param combine Combine frames into a single image (if possible), or save each frame as it's own image + /// @param combine Combine frames into a single image (if possible), or save each frame as its own image void SetVideoOptions(string format, Fraction fps, int width, int height, int quality, int loops, bool combine); diff --git a/include/PlayerBase.h b/include/PlayerBase.h index ecc8f5f2..f017c3f2 100644 --- a/include/PlayerBase.h +++ b/include/PlayerBase.h @@ -107,6 +107,7 @@ namespace openshot /// Set the Volume (1.0 = normal volume, <1.0 = quieter, >1.0 louder) virtual void Volume(float new_volume) = 0; + virtual ~PlayerBase() = default; }; } diff --git a/include/QtImageReader.h b/include/QtImageReader.h index a6f70165..814e3cb3 100644 --- a/include/QtImageReader.h +++ b/include/QtImageReader.h @@ -79,7 +79,7 @@ namespace openshot /// frame 1, or it throws one of the following exceptions. QtImageReader(string path); - /// Constructor for QtImageReader. This only opens the media file to inspect it's properties + /// Constructor for QtImageReader. This only opens the media file to inspect its properties /// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful /// when you are inflating the object using JSON after instantiating it. QtImageReader(string path, bool inspect_reader); diff --git a/include/ReaderBase.h b/include/ReaderBase.h index 4579ebb6..0d14ea19 100644 --- a/include/ReaderBase.h +++ b/include/ReaderBase.h @@ -110,8 +110,6 @@ namespace openshot /// Constructor for the base reader, where many things are initialized. ReaderBase(); - virtual ~ReaderBase(); - /// Information about the current media file ReaderInfo info; @@ -152,6 +150,8 @@ namespace openshot /// Open the reader (and start consuming resources, such as images or video files) virtual void Open() = 0; + + virtual ~ReaderBase() = default; }; } diff --git a/include/TextReader.h b/include/TextReader.h index 4cc9345c..7b276f7f 100644 --- a/include/TextReader.h +++ b/include/TextReader.h @@ -96,6 +96,7 @@ namespace openshot double size; string text_color; string background_color; + string text_background_color; std::shared_ptr image; MAGICK_DRAWABLE lines; bool is_open; @@ -116,9 +117,13 @@ namespace openshot /// @param font The font of the text /// @param size The size of the text /// @param text_color The color of the text - /// @param background_color The background color of the text (also supports Transparent) + /// @param background_color The background color of the text frame image (also supports Transparent) TextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string text, string font, double size, string text_color, string background_color); + /// Draw a box under rendered text using the specified color. + /// @param text_background_color The background color behind the text + void SetTextBackgroundColor(string color); + /// Close Reader void Close(); diff --git a/include/Timeline.h b/include/Timeline.h index a9ada689..3793f301 100644 --- a/include/Timeline.h +++ b/include/Timeline.h @@ -104,6 +104,7 @@ namespace openshot { * Fraction(25,1), // framerate * 44100, // sample rate * 2 // channels + * ChannelLayout::LAYOUT_STEREO, * ); * * // Create some clips diff --git a/include/WriterBase.h b/include/WriterBase.h index e03263ed..7620da64 100644 --- a/include/WriterBase.h +++ b/include/WriterBase.h @@ -119,6 +119,8 @@ namespace openshot /// Open the writer (and start initializing streams) virtual void Open() = 0; + + virtual ~WriterBase() = default; }; } diff --git a/include/effects/Bars.h b/include/effects/Bars.h index eb49a07f..515d2f11 100644 --- a/include/effects/Bars.h +++ b/include/effects/Bars.h @@ -83,7 +83,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Blur.h b/include/effects/Blur.h index cdb1402a..6d48c172 100644 --- a/include/effects/Blur.h +++ b/include/effects/Blur.h @@ -96,7 +96,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Brightness.h b/include/effects/Brightness.h index cb828442..fd43f784 100644 --- a/include/effects/Brightness.h +++ b/include/effects/Brightness.h @@ -83,7 +83,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/ChromaKey.h b/include/effects/ChromaKey.h index eca5cf74..4440302b 100644 --- a/include/effects/ChromaKey.h +++ b/include/effects/ChromaKey.h @@ -80,7 +80,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/ColorShift.h b/include/effects/ColorShift.h index ba2326f7..44c7269b 100644 --- a/include/effects/ColorShift.h +++ b/include/effects/ColorShift.h @@ -87,7 +87,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Crop.h b/include/effects/Crop.h index cbe61341..93b54e31 100644 --- a/include/effects/Crop.h +++ b/include/effects/Crop.h @@ -82,7 +82,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Deinterlace.h b/include/effects/Deinterlace.h index 14b13e21..1559a09e 100644 --- a/include/effects/Deinterlace.h +++ b/include/effects/Deinterlace.h @@ -76,7 +76,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Hue.h b/include/effects/Hue.h index 02d8cf9b..e6652391 100644 --- a/include/effects/Hue.h +++ b/include/effects/Hue.h @@ -73,7 +73,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Mask.h b/include/effects/Mask.h index c0782dc3..de48219c 100644 --- a/include/effects/Mask.h +++ b/include/effects/Mask.h @@ -95,7 +95,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Negate.h b/include/effects/Negate.h index 89969a9e..f2437fee 100644 --- a/include/effects/Negate.h +++ b/include/effects/Negate.h @@ -64,7 +64,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Pixelate.h b/include/effects/Pixelate.h index 5cb0cffb..06509894 100644 --- a/include/effects/Pixelate.h +++ b/include/effects/Pixelate.h @@ -82,7 +82,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Saturation.h b/include/effects/Saturation.h index cd714d6e..a24d01ee 100644 --- a/include/effects/Saturation.h +++ b/include/effects/Saturation.h @@ -80,7 +80,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Shift.h b/include/effects/Shift.h index c208ded6..db974ae2 100644 --- a/include/effects/Shift.h +++ b/include/effects/Shift.h @@ -76,7 +76,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/include/effects/Wave.h b/include/effects/Wave.h index ce2e8618..022173ea 100644 --- a/include/effects/Wave.h +++ b/include/effects/Wave.h @@ -82,7 +82,7 @@ namespace openshot /// modified openshot::Frame object /// /// The frame object is passed into this method, and a frame_number is passed in which - /// tells the effect which settings to use from it's keyframes (starting at 1). + /// tells the effect which settings to use from its keyframes (starting at 1). /// /// @returns The modified openshot::Frame object /// @param frame The frame object that needs the effect applied to it diff --git a/src/AudioResampler.cpp b/src/AudioResampler.cpp index 3aafb75d..d9c5a609 100644 --- a/src/AudioResampler.cpp +++ b/src/AudioResampler.cpp @@ -77,9 +77,9 @@ AudioResampler::~AudioResampler() void AudioResampler::SetBuffer(AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate) { if (sample_rate <= 0) - sample_rate == 44100; + sample_rate = 44100; if (new_sample_rate <= 0) - new_sample_rate == 44100; + new_sample_rate = 44100; // Set the sample ratio (the ratio of sample rate change) source_ratio = sample_rate / new_sample_rate; diff --git a/src/CacheBase.cpp b/src/CacheBase.cpp index 8270b393..0016694a 100644 --- a/src/CacheBase.cpp +++ b/src/CacheBase.cpp @@ -45,9 +45,6 @@ CacheBase::CacheBase(int64_t max_bytes) : max_bytes(max_bytes) { cacheCriticalSection = new CriticalSection(); }; -CacheBase::~CacheBase() { -}; - // Set maximum bytes to a different amount based on a ReaderInfo struct void CacheBase::SetMaxBytesFromInfo(int64_t number_of_frames, int width, int height, int sample_rate, int channels) { diff --git a/src/ChunkReader.cpp b/src/ChunkReader.cpp index 2ffe08be..8d5b466e 100644 --- a/src/ChunkReader.cpp +++ b/src/ChunkReader.cpp @@ -45,7 +45,7 @@ ChunkReader::ChunkReader(string path, ChunkVersion chunk_version) previous_location.number = 0; previous_location.frame = 0; - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) Open(); Close(); } diff --git a/src/Clip.cpp b/src/Clip.cpp index bee9841c..8c669042 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -272,7 +272,7 @@ void Clip::Close() // Get end position of clip (trim end of video), which can be affected by the time curve. float Clip::End() { - // if a time curve is present, use it's length + // if a time curve is present, use its length if (time.Points.size() > 1) { // Determine the FPS fo this clip diff --git a/src/ClipBase.cpp b/src/ClipBase.cpp index 1517a7e3..60bdb633 100644 --- a/src/ClipBase.cpp +++ b/src/ClipBase.cpp @@ -32,9 +32,6 @@ using namespace openshot; -ClipBase::~ClipBase() { -} - // Generate Json::JsonValue for this object Json::Value ClipBase::JsonValue() { diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp index 48fbfa69..aa1e6a56 100644 --- a/src/DummyReader.cpp +++ b/src/DummyReader.cpp @@ -69,7 +69,7 @@ DummyReader::DummyReader(Fraction fps, int width, int height, int sample_rate, i info.display_ratio.num = size.num; info.display_ratio.den = size.den; - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) Open(); Close(); } diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index f27dcf2f..10d89051 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -100,7 +100,7 @@ FFmpegReader::FFmpegReader(string path) missing_frames.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels); final_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels); - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) Open(); Close(); } @@ -122,7 +122,7 @@ FFmpegReader::FFmpegReader(string path, bool inspect_reader) missing_frames.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels); final_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels); - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) if (inspect_reader) { Open(); Close(); @@ -2027,7 +2027,7 @@ bool FFmpegReader::IsPartialFrame(int64_t requested_frame) { return seek_trash; } -// Check if a frame is missing and attempt to replace it's frame image (and +// Check if a frame is missing and attempt to replace its frame image (and bool FFmpegReader::CheckMissingFrame(int64_t requested_frame) { // Lock const GenericScopedLock lock(processingCriticalSection); @@ -2347,7 +2347,7 @@ void FFmpegReader::CheckFPS() { } } -// Remove AVFrame from cache (and deallocate it's memory) +// Remove AVFrame from cache (and deallocate its memory) void FFmpegReader::RemoveAVFrame(AVFrame *remove_frame) { // Remove pFrame (if exists) if (remove_frame) { @@ -2362,7 +2362,7 @@ void FFmpegReader::RemoveAVFrame(AVFrame *remove_frame) { } } -// Remove AVPacket from cache (and deallocate it's memory) +// Remove AVPacket from cache (and deallocate its memory) void FFmpegReader::RemoveAVPacket(AVPacket *remove_packet) { // deallocate memory for packet AV_FREE_PACKET(remove_packet); @@ -2427,7 +2427,7 @@ void FFmpegReader::SetJson(string value) { Json::Value root; Json::CharReaderBuilder rbuilder; Json::CharReader* reader(rbuilder.newCharReader()); - + string errors; bool success = reader->parse(value.c_str(), value.c_str() + value.size(), &root, &errors); diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index b20f6b23..663e8ab0 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -41,6 +41,9 @@ using namespace openshot; #pragma message "You are compiling only with software encode" #endif +// Multiplexer parameters temporary storage +AVDictionary *mux_dict = NULL; + #if IS_FFMPEG_3_2 int hw_en_on = 1; // Is set in UI int hw_en_supported = 0; // Is set by FFmpegWriter @@ -467,6 +470,17 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value) { ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::SetOption (" + (string)name + ")", "stream == VIDEO_STREAM", stream == VIDEO_STREAM, "", -1, "", -1, "", -1, "", -1, "", -1); + // Muxing dictionary is not part of the codec context. + // Just reusing SetOption function to set popular multiplexing presets. + } else if (name == "muxing_preset") { + if (value == "mp4_faststart") { + // 'moov' box to the beginning; only for MOV, MP4 + av_dict_set(&mux_dict, "movflags", "faststart", 0); + } else if (value == "mp4_fragmented") { + // write selfcontained fragmented file, minimum length of the fragment 8 sec; only for MOV, MP4 + av_dict_set(&mux_dict, "movflags", "frag_keyframe", 0); + av_dict_set(&mux_dict, "min_frag_duration", "8000000", 0); + } } else { throw InvalidOptions("The option is not valid for this codec.", path); } @@ -514,17 +528,29 @@ void FFmpegWriter::WriteHeader() { snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", path.c_str()); // Write the stream header, if any - // TODO: add avoptions / parameters instead of NULL // Add general metadata (if any) for (std::map::iterator iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) { av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0); } - if (avformat_write_header(oc, NULL) != 0) { + // Set multiplexing parameters + AVDictionary *dict = NULL; + + bool is_mp4 = strcmp(oc->oformat->name, "mp4"); + bool is_mov = strcmp(oc->oformat->name, "mov"); + // Set dictionary preset only for MP4 and MOV files + if (is_mp4 || is_mov) + av_dict_copy(&dict, mux_dict, 0); + + if (avformat_write_header(oc, &dict) != 0) { throw InvalidFile("Could not write header to file.", path); }; + // Free multiplexing dictionaries sets + if (dict) av_dict_free(&dict); + if (mux_dict) av_dict_free(&mux_dict); + // Mark as 'written' write_header = true; diff --git a/src/Frame.cpp b/src/Frame.cpp index 522b9a38..ccbb65d5 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -266,7 +266,7 @@ std::shared_ptr Frame::GetWaveform(int width, int height, int Red, int G return wave_image; } -// Clear the waveform image (and deallocate it's memory) +// Clear the waveform image (and deallocate its memory) void Frame::ClearWaveform() { if (wave_image) diff --git a/src/ImageReader.cpp b/src/ImageReader.cpp index 8da6782e..62439d82 100644 --- a/src/ImageReader.cpp +++ b/src/ImageReader.cpp @@ -37,14 +37,14 @@ using namespace openshot; ImageReader::ImageReader(string path) : path(path), is_open(false) { - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) Open(); Close(); } ImageReader::ImageReader(string path, bool inspect_reader) : path(path), is_open(false) { - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) if (inspect_reader) { Open(); Close(); diff --git a/src/KeyFrame.cpp b/src/KeyFrame.cpp index 71b785fa..31393d17 100644 --- a/src/KeyFrame.cpp +++ b/src/KeyFrame.cpp @@ -786,7 +786,7 @@ void Keyframe::ProcessSegment(int Segment, Point p1, Point p2) { // Add new value to the vector Coordinate new_coord(current_frame, current_value); - if (Segment == 0 || Segment > 0 && current_frame > p1.co.X) + if (Segment == 0 || (Segment > 0 && current_frame > p1.co.X)) // Add to "values" vector Values.push_back(new_coord); diff --git a/src/QtImageReader.cpp b/src/QtImageReader.cpp index 4ed258a0..bd1c4bc8 100644 --- a/src/QtImageReader.cpp +++ b/src/QtImageReader.cpp @@ -46,14 +46,14 @@ using namespace openshot; QtImageReader::QtImageReader(string path) : path(path), is_open(false) { - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) Open(); Close(); } QtImageReader::QtImageReader(string path, bool inspect_reader) : path(path), is_open(false) { - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) if (inspect_reader) { Open(); Close(); @@ -220,7 +220,7 @@ std::shared_ptr QtImageReader::GetFrame(int64_t requested_frame) } // Scale image smaller (or use a previous scaled image) - if (!cached_image || (cached_image && max_size.width() != max_width || max_size.height() != max_height)) { + if (!cached_image || (max_size.width() != max_width || max_size.height() != max_height)) { #if USE_RESVG == 1 // If defined and found in CMake, utilize the libresvg for parsing // SVG files and rasterizing them to QImages. diff --git a/src/ReaderBase.cpp b/src/ReaderBase.cpp index ece0684f..30706866 100644 --- a/src/ReaderBase.cpp +++ b/src/ReaderBase.cpp @@ -66,9 +66,6 @@ ReaderBase::ReaderBase() parent = NULL; } -ReaderBase::~ReaderBase() { -} - // Display file information void ReaderBase::DisplayInfo() { cout << fixed << setprecision(2) << boolalpha; diff --git a/src/TextReader.cpp b/src/TextReader.cpp index 27038283..9c664535 100644 --- a/src/TextReader.cpp +++ b/src/TextReader.cpp @@ -38,7 +38,7 @@ using namespace openshot; /// Default constructor (blank text) TextReader::TextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font("Arial"), size(10.0), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) { - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) Open(); Close(); } @@ -46,7 +46,15 @@ TextReader::TextReader() : width(1024), height(768), x_offset(0), y_offset(0), t TextReader::TextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string text, string font, double size, string text_color, string background_color) : width(width), height(height), x_offset(x_offset), y_offset(y_offset), text(text), font(font), size(size), text_color(text_color), background_color(background_color), is_open(false), gravity(gravity) { - // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + // Open and Close the reader, to populate its attributes (such as height, width, etc...) + Open(); + Close(); +} + +void TextReader::SetTextBackgroundColor(string color) { + text_background_color = color; + + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) plus the text background color Open(); Close(); } @@ -103,6 +111,10 @@ void TextReader::Open() lines.push_back(Magick::DrawablePointSize(size)); lines.push_back(Magick::DrawableText(x_offset, y_offset, text)); + if (!text_background_color.empty()) { + lines.push_back(Magick::DrawableTextUnderColor(Magick::Color(text_background_color))); + } + // Draw image image->draw(lines); @@ -196,6 +208,7 @@ Json::Value TextReader::JsonValue() { root["size"] = size; root["text_color"] = text_color; root["background_color"] = background_color; + root["text_background_color"] = text_background_color; root["gravity"] = gravity; // return JsonValue @@ -254,6 +267,8 @@ void TextReader::SetJsonValue(Json::Value root) { text_color = root["text_color"].asString(); if (!root["background_color"].isNull()) background_color = root["background_color"].asString(); + if (!root["text_background_color"].isNull()) + text_background_color = root["text_background_color"].asString(); if (!root["gravity"].isNull()) gravity = (GravityType) root["gravity"].asInt();