From 76fc1ef571d214be6bd38d8f4d9ac6e30e280ba8 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 9 Aug 2019 20:50:28 -0400 Subject: [PATCH 01/33] QtImageReader: Safer ReSVG file extension checks This changes the type of the private `path` variable to QString internally (which we were converting it to for a bunch of operations anyway), and uses QString's more robust string-manipulation and comparison methods to ensure that only filenames that _end in_ an .svg/.svgz extension (case-insensitively) are recognized as SVG files. Previously, a filename such as "Title.svg.png" would be interpreted as an SVG file. The change in QString type is purely internal, all of the class's interfaces remain the same, and accept `std::string path`. We simply convert it to/from QString at opposite places in the code, now. --- include/QtImageReader.h | 2 +- src/QtImageReader.cpp | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/QtImageReader.h b/include/QtImageReader.h index 814e3cb3..02f00347 100644 --- a/include/QtImageReader.h +++ b/include/QtImageReader.h @@ -67,7 +67,7 @@ namespace openshot class QtImageReader : public ReaderBase { private: - string path; + QString path; std::shared_ptr image; ///> Original image (full quality) std::shared_ptr cached_image; ///> Scaled for performance bool is_open; ///> Is Reader opened diff --git a/src/QtImageReader.cpp b/src/QtImageReader.cpp index 9107e51f..af2a79f9 100644 --- a/src/QtImageReader.cpp +++ b/src/QtImageReader.cpp @@ -44,14 +44,14 @@ using namespace openshot; -QtImageReader::QtImageReader(string path) : path(path), is_open(false) +QtImageReader::QtImageReader(string path) : path{QString::fromStdString(path)}, is_open(false) { // 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) +QtImageReader::QtImageReader(string path, bool inspect_reader) : path{QString::fromStdString(path)}, is_open(false) { // Open and Close the reader, to populate its attributes (such as height, width, etc...) if (inspect_reader) { @@ -77,12 +77,12 @@ void QtImageReader::Open() // If defined and found in CMake, utilize the libresvg for parsing // SVG files and rasterizing them to QImages. // Only use resvg for files ending in '.svg' or '.svgz' - if (path.find(".svg") != std::string::npos || path.find(".svgz") != std::string::npos) { + if (path.toLower().endsWith(".svg") || path.toLower().endsWith(".svgz")) { - ResvgRenderer renderer(QString::fromStdString(path)); + ResvgRenderer renderer(path); if (!renderer.isValid()) { // Attempt to open file (old method using Qt5 limited SVG parsing) - success = image->load(QString::fromStdString(path)); + success = image->load(path); if (success) { image = std::shared_ptr(new QImage(image->convertToFormat(QImage::Format_RGBA8888))); } @@ -98,20 +98,20 @@ void QtImageReader::Open() } else { // Attempt to open file (old method) - success = image->load(QString::fromStdString(path)); + success = image->load(path); if (success) image = std::shared_ptr(new QImage(image->convertToFormat(QImage::Format_RGBA8888))); } #else // Attempt to open file using Qt's build in image processing capabilities - success = image->load(QString::fromStdString(path)); + success = image->load(path); if (success) image = std::shared_ptr(new QImage(image->convertToFormat(QImage::Format_RGBA8888))); #endif if (!success) // raise exception - throw InvalidFile("File could not be opened.", path); + throw InvalidFile("File could not be opened.", path.toStdString()); // Update image properties info.has_audio = false; @@ -171,7 +171,7 @@ std::shared_ptr QtImageReader::GetFrame(int64_t requested_frame) { // Check for open reader (or throw exception) if (!is_open) - throw ReaderClosed("The Image is closed. Call Open() before calling this method.", path); + throw ReaderClosed("The Image is closed. Call Open() before calling this method.", path.toStdString()); // Create a scoped lock, allowing only a single thread to run the following code at one time const GenericScopedLock lock(getFrameCriticalSection); @@ -228,8 +228,8 @@ std::shared_ptr QtImageReader::GetFrame(int64_t requested_frame) // If defined and found in CMake, utilize the libresvg for parsing // SVG files and rasterizing them to QImages. // Only use resvg for files ending in '.svg' or '.svgz' - if (path.find(".svg") != std::string::npos || path.find(".svgz") != std::string::npos) { - ResvgRenderer renderer(QString::fromStdString(path)); + if (path.toLower().endsWith(".svg") || path.toLower().endsWith(".svgz")) { + ResvgRenderer renderer(path); if (renderer.isValid()) { // Scale SVG size to keep aspect ratio, and fill the max_size as best as possible QSize svg_size(renderer.defaultSize().width(), renderer.defaultSize().height()); @@ -289,7 +289,7 @@ Json::Value QtImageReader::JsonValue() { // Create root json object Json::Value root = ReaderBase::JsonValue(); // get parent properties root["type"] = "QtImageReader"; - root["path"] = path; + root["path"] = path.toStdString(); // return JsonValue return root; @@ -332,7 +332,7 @@ void QtImageReader::SetJsonValue(Json::Value root) { // Set data from Json (if key is found) if (!root["path"].isNull()) - path = root["path"].asString(); + path = QString::fromStdString(root["path"].asString()); // Re-Open path, and re-init everything (if needed) if (is_open) From 141e6ba61e901d26e4e4c19b10c711c9cc203cab Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 10 Aug 2019 11:31:08 -0400 Subject: [PATCH 02/33] Use std::stoll to convert JSON values --- include/CacheBase.h | 1 + include/ChunkReader.h | 2 +- include/ReaderBase.h | 2 +- src/CacheBase.cpp | 2 +- src/ChunkReader.cpp | 6 +++--- src/ReaderBase.cpp | 4 ++-- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/CacheBase.h b/include/CacheBase.h index 3760e84b..d954e411 100644 --- a/include/CacheBase.h +++ b/include/CacheBase.h @@ -32,6 +32,7 @@ #define OPENSHOT_CACHE_BASE_H #include +#include #include "Frame.h" #include "Exceptions.h" #include "Json.h" diff --git a/include/ChunkReader.h b/include/ChunkReader.h index 5b330b70..a5f2ec6a 100644 --- a/include/ChunkReader.h +++ b/include/ChunkReader.h @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include "Json.h" #include "CacheMemory.h" diff --git a/include/ReaderBase.h b/include/ReaderBase.h index 0d14ea19..eef29fba 100644 --- a/include/ReaderBase.h +++ b/include/ReaderBase.h @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include "CacheMemory.h" #include "ChannelLayouts.h" diff --git a/src/CacheBase.cpp b/src/CacheBase.cpp index 0016694a..b808896e 100644 --- a/src/CacheBase.cpp +++ b/src/CacheBase.cpp @@ -71,5 +71,5 @@ void CacheBase::SetJsonValue(Json::Value root) { // Set data from Json (if key is found) if (!root["max_bytes"].isNull()) - max_bytes = atoll(root["max_bytes"].asString().c_str()); + max_bytes = std::stoll(root["max_bytes"].asString()); } diff --git a/src/ChunkReader.cpp b/src/ChunkReader.cpp index 9fc8756c..0836f09f 100644 --- a/src/ChunkReader.cpp +++ b/src/ChunkReader.cpp @@ -94,7 +94,7 @@ void ChunkReader::load_json() info.has_video = root["has_video"].asBool(); info.has_audio = root["has_audio"].asBool(); info.duration = root["duration"].asDouble(); - info.file_size = atoll(root["file_size"].asString().c_str()); + info.file_size = std::stoll(root["file_size"].asString()); info.height = root["height"].asInt(); info.width = root["width"].asInt(); info.pixel_format = root["pixel_format"].asInt(); @@ -106,7 +106,7 @@ void ChunkReader::load_json() info.display_ratio.num = root["display_ratio"]["num"].asInt(); info.display_ratio.den = root["display_ratio"]["den"].asInt(); info.vcodec = root["vcodec"].asString(); - info.video_length = atoll(root["video_length"].asString().c_str()); + info.video_length = std::stoll(root["video_length"].asString()); info.video_stream_index = root["video_stream_index"].asInt(); info.video_timebase.num = root["video_timebase"]["num"].asInt(); info.video_timebase.den = root["video_timebase"]["den"].asInt(); @@ -316,7 +316,7 @@ void ChunkReader::SetJsonValue(Json::Value root) { if (!root["path"].isNull()) path = root["path"].asString(); if (!root["chunk_size"].isNull()) - chunk_size = atoll(root["chunk_size"].asString().c_str()); + chunk_size = std::stoll(root["chunk_size"].asString()); if (!root["chunk_version"].isNull()) version = (ChunkVersion) root["chunk_version"].asInt(); diff --git a/src/ReaderBase.cpp b/src/ReaderBase.cpp index 30706866..e23fdd85 100644 --- a/src/ReaderBase.cpp +++ b/src/ReaderBase.cpp @@ -181,7 +181,7 @@ void ReaderBase::SetJsonValue(Json::Value root) { if (!root["duration"].isNull()) info.duration = root["duration"].asDouble(); if (!root["file_size"].isNull()) - info.file_size = atoll(root["file_size"].asString().c_str()); + info.file_size = std::stoll(root["file_size"].asString()); if (!root["height"].isNull()) info.height = root["height"].asInt(); if (!root["width"].isNull()) @@ -211,7 +211,7 @@ void ReaderBase::SetJsonValue(Json::Value root) { if (!root["vcodec"].isNull()) info.vcodec = root["vcodec"].asString(); if (!root["video_length"].isNull()) - info.video_length = atoll(root["video_length"].asString().c_str()); + info.video_length = std::stoll(root["video_length"].asString()); if (!root["video_stream_index"].isNull()) info.video_stream_index = root["video_stream_index"].asInt(); if (!root["video_timebase"].isNull() && root["video_timebase"].isObject()) { From c4126aef2c6001901f2b8004e6db99fa0d5f18ad Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 11 Aug 2019 12:49:42 -0400 Subject: [PATCH 03/33] Bindings: Apply #defines for optional libs The resetting of `CMAKE_SWIG_FLAGS` to the empty string in the bindings' CMakeLists.txt files was clearing away the definitions for things like `USE_IMAGEMAGICK` and `USE_BLACKMAGIC`, causing the bindings to be built _without_ those classes even if they're available in the library. --- src/bindings/python/CMakeLists.txt | 1 - src/bindings/ruby/CMakeLists.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index 9afabd41..5c143e0b 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -48,7 +48,6 @@ if (PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) ### Enable C++ support in SWIG set_property(SOURCE openshot.i PROPERTY CPLUSPLUS ON) set_property(SOURCE openshot.i PROPERTY SWIG_MODULE_NAME openshot) - SET(CMAKE_SWIG_FLAGS "") ### Suppress a ton of warnings in the generated SWIG C++ code set(SWIG_CXX_FLAGS "-Wno-unused-variable -Wno-unused-function -Wno-deprecated-copy -Wno-class-memaccess -Wno-cast-function-type \ diff --git a/src/bindings/ruby/CMakeLists.txt b/src/bindings/ruby/CMakeLists.txt index 4b962e73..c7eb1d78 100644 --- a/src/bindings/ruby/CMakeLists.txt +++ b/src/bindings/ruby/CMakeLists.txt @@ -50,7 +50,6 @@ IF (RUBY_FOUND) set_property(SOURCE openshot.i PROPERTY CPLUSPLUS ON) set_property(SOURCE openshot.i PROPERTY SWIG_MODULE_NAME openshot) - SET(CMAKE_SWIG_FLAGS "") ### Suppress a ton of warnings in the generated SWIG C++ code set(SWIG_CXX_FLAGS "-Wno-unused-variable -Wno-unused-function -Wno-deprecated-copy -Wno-class-memaccess -Wno-cast-function-type \ -Wno-unused-parameter -Wno-catch-value -Wno-sign-compare -Wno-ignored-qualifiers") From c4a6ead569116d966bb0318a3b70561536f6a531 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 20 Aug 2019 04:32:47 -0400 Subject: [PATCH 04/33] FFmpegReader: Detect interlaced video Move interlace detection to UpdateVideoInfo() so it'll be done before we read any frames, and use the field_order member of the codec attributes (an AVFieldOrder enum) as the data source. --- src/FFmpegReader.cpp | 53 +++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c9e21271..38a1f610 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -729,6 +729,31 @@ void FFmpegReader::UpdateVideoInfo() { info.display_ratio.num = size.num; info.display_ratio.den = size.den; + // Get scan type and order from codec context/params + if (!check_interlace) { + check_interlace = true; + AVFieldOrder field_order = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->field_order; + switch(field_order) { + case AV_FIELD_PROGRESSIVE: + info.interlaced_frame = false; + break; + case AV_FIELD_TT: + case AV_FIELD_TB: + info.interlaced_frame = true; + info.top_field_first = true; + break; + case AV_FIELD_BT: + case AV_FIELD_BB: + info.interlaced_frame = true; + info.top_field_first = false; + break; + case AV_FIELD_UNKNOWN: + // Check again later? + check_interlace = false; + break; + } + } + // Set the video timebase info.video_timebase.num = pStream->time_base.num; info.video_timebase.den = pStream->time_base.den; @@ -1078,14 +1103,14 @@ bool FFmpegReader::GetAVFrame() { ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAVFrame (Packet not sent)"); } else { - AVFrame *next_frame2; - if (hw_de_on && hw_de_supported) { - next_frame2 = AV_ALLOCATE_FRAME(); - } - else - { - next_frame2 = next_frame; - } + AVFrame *next_frame2; + if (hw_de_on && hw_de_supported) { + next_frame2 = AV_ALLOCATE_FRAME(); + } + else + { + next_frame2 = next_frame; + } pFrame = AV_ALLOCATE_FRAME(); while (ret >= 0) { ret = avcodec_receive_frame(pCodecCtx, next_frame2); @@ -1119,11 +1144,6 @@ bool FFmpegReader::GetAVFrame() { av_image_alloc(pFrame->data, pFrame->linesize, info.width, info.height, (AVPixelFormat)(pStream->codecpar->format), 1); av_image_copy(pFrame->data, pFrame->linesize, (const uint8_t**)next_frame->data, next_frame->linesize, (AVPixelFormat)(pStream->codecpar->format), info.width, info.height); - if (!check_interlace) { - check_interlace = true; - info.interlaced_frame = next_frame->interlaced_frame; - info.top_field_first = next_frame->top_field_first; - } } } if (hw_de_on && hw_de_supported) { @@ -1143,13 +1163,6 @@ bool FFmpegReader::GetAVFrame() { avpicture_alloc((AVPicture *) pFrame, pCodecCtx->pix_fmt, info.width, info.height); av_picture_copy((AVPicture *) pFrame, (AVPicture *) next_frame, pCodecCtx->pix_fmt, info.width, info.height); - - // Detect interlaced frame (only once) - if (!check_interlace) { - check_interlace = true; - info.interlaced_frame = next_frame->interlaced_frame; - info.top_field_first = next_frame->top_field_first; - } } #endif } From 49749d52c2775d81bc99baad3bf5adb074b434b0 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 27 Aug 2019 15:46:31 -0400 Subject: [PATCH 05/33] Exceptions.h: Optional file_path args Makes nearly all `file_path` arguments optional, unless the exception deals with file operations specifically (e.g. InvalidFile still requires file_path) --- include/Exceptions.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/Exceptions.h b/include/Exceptions.h index c5228f13..c6914d4b 100644 --- a/include/Exceptions.h +++ b/include/Exceptions.h @@ -111,7 +111,7 @@ namespace openshot { { public: std::string file_path; - InvalidChannels(std::string message, std::string file_path) + InvalidChannels(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidChannels() noexcept {} }; @@ -121,7 +121,7 @@ namespace openshot { { public: std::string file_path; - InvalidCodec(std::string message, std::string file_path) + InvalidCodec(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidCodec() noexcept {} }; @@ -141,7 +141,7 @@ namespace openshot { { public: std::string file_path; - InvalidFormat(std::string message, std::string file_path) + InvalidFormat(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidFormat() noexcept {} }; @@ -151,7 +151,7 @@ namespace openshot { { public: std::string file_path; - InvalidJSON(std::string message, std::string file_path) + InvalidJSON(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidJSON() noexcept {} }; @@ -161,7 +161,7 @@ namespace openshot { { public: std::string file_path; - InvalidOptions(std::string message, std::string file_path) + InvalidOptions(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidOptions() noexcept {} }; @@ -171,7 +171,7 @@ namespace openshot { { public: std::string file_path; - InvalidSampleRate(std::string message, std::string file_path) + InvalidSampleRate(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidSampleRate() noexcept {} }; @@ -191,7 +191,7 @@ namespace openshot { { public: std::string file_path; - NoStreamsFound(std::string message, std::string file_path) + NoStreamsFound(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~NoStreamsFound() noexcept {} }; @@ -223,7 +223,7 @@ namespace openshot { { public: std::string file_path; - OutOfMemory(std::string message, std::string file_path) + OutOfMemory(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~OutOfMemory() noexcept {} }; @@ -233,7 +233,7 @@ namespace openshot { { public: std::string file_path; - ReaderClosed(std::string message, std::string file_path) + ReaderClosed(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~ReaderClosed() noexcept {} }; @@ -243,7 +243,7 @@ namespace openshot { { public: std::string file_path; - ResampleError(std::string message, std::string file_path) + ResampleError(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~ResampleError() noexcept {} }; @@ -253,7 +253,7 @@ namespace openshot { { public: std::string file_path; - TooManySeeks(std::string message, std::string file_path) + TooManySeeks(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~TooManySeeks() noexcept {} }; @@ -263,7 +263,7 @@ namespace openshot { { public: std::string file_path; - WriterClosed(std::string message, std::string file_path) + WriterClosed(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~WriterClosed() noexcept {} }; From 366ff2c5e64ba5f0b46b5b73feeb3fbf3f841ac0 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 27 Aug 2019 15:47:39 -0400 Subject: [PATCH 06/33] src: Don't pass "" file_path args to exceptions --- src/CacheDisk.cpp | 4 ++-- src/CacheMemory.cpp | 4 ++-- src/ChunkReader.cpp | 4 ++-- src/Clip.cpp | 16 ++++++++-------- src/Color.cpp | 4 ++-- src/Coordinate.cpp | 4 ++-- src/DecklinkReader.cpp | 4 ++-- src/DecklinkWriter.cpp | 2 +- src/DummyReader.cpp | 4 ++-- src/EffectBase.cpp | 4 ++-- src/FFmpegReader.cpp | 4 ++-- src/FrameMapper.cpp | 6 +++--- src/ImageReader.cpp | 4 ++-- src/KeyFrame.cpp | 4 ++-- src/Point.cpp | 4 ++-- src/Profiles.cpp | 4 ++-- src/QtImageReader.cpp | 4 ++-- src/TextReader.cpp | 4 ++-- src/Timeline.cpp | 10 +++++----- src/WriterBase.cpp | 4 ++-- 20 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/CacheDisk.cpp b/src/CacheDisk.cpp index b1b1876b..9b345478 100644 --- a/src/CacheDisk.cpp +++ b/src/CacheDisk.cpp @@ -519,7 +519,7 @@ void CacheDisk::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -529,7 +529,7 @@ void CacheDisk::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/CacheMemory.cpp b/src/CacheMemory.cpp index 7bd480e4..4ffed949 100644 --- a/src/CacheMemory.cpp +++ b/src/CacheMemory.cpp @@ -372,7 +372,7 @@ void CacheMemory::SetJson(string value) { delete reader; if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -382,7 +382,7 @@ void CacheMemory::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/ChunkReader.cpp b/src/ChunkReader.cpp index 9fc8756c..a463c90e 100644 --- a/src/ChunkReader.cpp +++ b/src/ChunkReader.cpp @@ -292,7 +292,7 @@ void ChunkReader::SetJson(string value) { delete reader; if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -302,7 +302,7 @@ void ChunkReader::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/Clip.cpp b/src/Clip.cpp index 3bf6030d..7e82ff01 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -235,7 +235,7 @@ ReaderBase* Clip::Reader() return 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.", ""); + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method."); } // Open the internal reader @@ -252,7 +252,7 @@ void Clip::Open() } else // Throw error if reader not initialized - throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method.", ""); + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method."); } // Close the internal reader @@ -266,7 +266,7 @@ void Clip::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.", ""); + 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. @@ -282,7 +282,7 @@ float Clip::End() fps = 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.", ""); + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method."); return float(time.GetLength()) / fps; } @@ -350,7 +350,7 @@ std::shared_ptr Clip::GetFrame(int64_t requested_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.", ""); + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method."); } // Get file extension @@ -394,7 +394,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num // Check for valid reader if (!reader) // Throw error if reader not initialized - throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method.", ""); + throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method."); // Check for a valid time map curve if (time.Values.size() > 1) @@ -812,7 +812,7 @@ void Clip::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -822,7 +822,7 @@ void Clip::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/Color.cpp b/src/Color.cpp index b219e695..1c314aa9 100644 --- a/src/Color.cpp +++ b/src/Color.cpp @@ -120,7 +120,7 @@ void Color::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -130,7 +130,7 @@ void Color::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/Coordinate.cpp b/src/Coordinate.cpp index 739d693f..eaa65dea 100644 --- a/src/Coordinate.cpp +++ b/src/Coordinate.cpp @@ -83,7 +83,7 @@ void Coordinate::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -93,7 +93,7 @@ void Coordinate::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/DecklinkReader.cpp b/src/DecklinkReader.cpp index 3af5e3fc..4ce30149 100644 --- a/src/DecklinkReader.cpp +++ b/src/DecklinkReader.cpp @@ -278,7 +278,7 @@ void DecklinkReader::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -288,7 +288,7 @@ void DecklinkReader::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/DecklinkWriter.cpp b/src/DecklinkWriter.cpp index 7dcede04..4ebbd1f0 100644 --- a/src/DecklinkWriter.cpp +++ b/src/DecklinkWriter.cpp @@ -234,7 +234,7 @@ void DecklinkWriter::WriteFrame(std::shared_ptr frame) { // Check for open reader (or throw exception) if (!is_open) - throw WriterClosed("The DecklinkWriter is closed. Call Open() before calling this method.", ""); + throw WriterClosed("The DecklinkWriter is closed. Call Open() before calling this method."); delegate->WriteFrame(frame); } diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp index 346430dc..bdfb7cb5 100644 --- a/src/DummyReader.cpp +++ b/src/DummyReader.cpp @@ -156,7 +156,7 @@ void DummyReader::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -166,7 +166,7 @@ void DummyReader::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/EffectBase.cpp b/src/EffectBase.cpp index 30909420..77bfec9b 100644 --- a/src/EffectBase.cpp +++ b/src/EffectBase.cpp @@ -112,7 +112,7 @@ void EffectBase::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -122,7 +122,7 @@ void EffectBase::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c9e21271..b617156f 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -2445,7 +2445,7 @@ void FFmpegReader::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { // Set all values that match @@ -2453,7 +2453,7 @@ void FFmpegReader::SetJson(string value) { } catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/FrameMapper.cpp b/src/FrameMapper.cpp index ff7cf1ce..40d1899e 100644 --- a/src/FrameMapper.cpp +++ b/src/FrameMapper.cpp @@ -75,7 +75,7 @@ ReaderBase* FrameMapper::Reader() return reader; else // Throw error if reader not initialized - throw ReaderClosed("No Reader has been initialized for FrameMapper. Call Reader(*reader) before calling this method.", ""); + throw ReaderClosed("No Reader has been initialized for FrameMapper. Call Reader(*reader) before calling this method."); } void FrameMapper::AddField(int64_t frame) @@ -707,7 +707,7 @@ void FrameMapper::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -717,7 +717,7 @@ void FrameMapper::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/ImageReader.cpp b/src/ImageReader.cpp index a0b7e8f3..b719ee3d 100644 --- a/src/ImageReader.cpp +++ b/src/ImageReader.cpp @@ -169,7 +169,7 @@ void ImageReader::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -179,7 +179,7 @@ void ImageReader::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/KeyFrame.cpp b/src/KeyFrame.cpp index 94618135..37e005d9 100644 --- a/src/KeyFrame.cpp +++ b/src/KeyFrame.cpp @@ -379,7 +379,7 @@ void Keyframe::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -389,7 +389,7 @@ void Keyframe::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/Point.cpp b/src/Point.cpp index fd23da55..72eedebc 100644 --- a/src/Point.cpp +++ b/src/Point.cpp @@ -146,7 +146,7 @@ void Point::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -156,7 +156,7 @@ void Point::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/Profiles.cpp b/src/Profiles.cpp index e57f7aa3..752bdb1e 100644 --- a/src/Profiles.cpp +++ b/src/Profiles.cpp @@ -177,7 +177,7 @@ void Profile::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -187,7 +187,7 @@ void Profile::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/QtImageReader.cpp b/src/QtImageReader.cpp index 9107e51f..e223510e 100644 --- a/src/QtImageReader.cpp +++ b/src/QtImageReader.cpp @@ -310,7 +310,7 @@ void QtImageReader::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -320,7 +320,7 @@ void QtImageReader::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/TextReader.cpp b/src/TextReader.cpp index 27f503e1..e92ec285 100644 --- a/src/TextReader.cpp +++ b/src/TextReader.cpp @@ -230,7 +230,7 @@ void TextReader::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -240,7 +240,7 @@ void TextReader::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 296e7a93..b8dabf68 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -746,7 +746,7 @@ std::shared_ptr Timeline::GetFrame(int64_t requested_frame) // Check for open reader (or throw exception) if (!is_open) - throw ReaderClosed("The Timeline is closed. Call Open() before calling this method.", ""); + throw ReaderClosed("The Timeline is closed. Call Open() before calling this method."); // Check cache again (due to locking) #pragma omp critical (T_GetFrame) @@ -1040,7 +1040,7 @@ void Timeline::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -1050,7 +1050,7 @@ void Timeline::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } @@ -1139,7 +1139,7 @@ void Timeline::ApplyJsonDiff(string value) { if (!success || !root.isArray()) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid).", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)."); try { @@ -1167,7 +1167,7 @@ void Timeline::ApplyJsonDiff(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/WriterBase.cpp b/src/WriterBase.cpp index f677215a..3344c55a 100644 --- a/src/WriterBase.cpp +++ b/src/WriterBase.cpp @@ -209,7 +209,7 @@ void WriterBase::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -219,7 +219,7 @@ void WriterBase::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } From 291719ff05503163e1f8400b321bd4c1536e8ab0 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 27 Aug 2019 15:48:46 -0400 Subject: [PATCH 07/33] Effects: No "" file_path args to exceptions --- src/effects/Bars.cpp | 4 ++-- src/effects/Blur.cpp | 4 ++-- src/effects/Brightness.cpp | 4 ++-- src/effects/ChromaKey.cpp | 4 ++-- src/effects/ColorShift.cpp | 4 ++-- src/effects/Crop.cpp | 4 ++-- src/effects/Deinterlace.cpp | 4 ++-- src/effects/Hue.cpp | 4 ++-- src/effects/Mask.cpp | 4 ++-- src/effects/Negate.cpp | 4 ++-- src/effects/Pixelate.cpp | 4 ++-- src/effects/Saturation.cpp | 4 ++-- src/effects/Shift.cpp | 4 ++-- src/effects/Wave.cpp | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/effects/Bars.cpp b/src/effects/Bars.cpp index 6d731d9c..9748db99 100644 --- a/src/effects/Bars.cpp +++ b/src/effects/Bars.cpp @@ -151,7 +151,7 @@ void Bars::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -161,7 +161,7 @@ void Bars::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Blur.cpp b/src/effects/Blur.cpp index 7946e249..d4f7c19d 100644 --- a/src/effects/Blur.cpp +++ b/src/effects/Blur.cpp @@ -288,7 +288,7 @@ void Blur::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -298,7 +298,7 @@ void Blur::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Brightness.cpp b/src/effects/Brightness.cpp index 3a1a4bdb..4ffd69f3 100644 --- a/src/effects/Brightness.cpp +++ b/src/effects/Brightness.cpp @@ -142,7 +142,7 @@ void Brightness::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -152,7 +152,7 @@ void Brightness::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/ChromaKey.cpp b/src/effects/ChromaKey.cpp index 2e2dc511..9c7124e6 100644 --- a/src/effects/ChromaKey.cpp +++ b/src/effects/ChromaKey.cpp @@ -135,7 +135,7 @@ void ChromaKey::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -145,7 +145,7 @@ void ChromaKey::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/ColorShift.cpp b/src/effects/ColorShift.cpp index 10f22217..c16f0aa6 100644 --- a/src/effects/ColorShift.cpp +++ b/src/effects/ColorShift.cpp @@ -234,7 +234,7 @@ void ColorShift::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -244,7 +244,7 @@ void ColorShift::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Crop.cpp b/src/effects/Crop.cpp index 7ff6ec0b..3e9a2fa3 100644 --- a/src/effects/Crop.cpp +++ b/src/effects/Crop.cpp @@ -150,7 +150,7 @@ void Crop::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -160,7 +160,7 @@ void Crop::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Deinterlace.cpp b/src/effects/Deinterlace.cpp index 65f00ff6..8bcd1a8e 100644 --- a/src/effects/Deinterlace.cpp +++ b/src/effects/Deinterlace.cpp @@ -129,7 +129,7 @@ void Deinterlace::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -139,7 +139,7 @@ void Deinterlace::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Hue.cpp b/src/effects/Hue.cpp index fd33272d..eefaf4d9 100644 --- a/src/effects/Hue.cpp +++ b/src/effects/Hue.cpp @@ -136,7 +136,7 @@ void Hue::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -146,7 +146,7 @@ void Hue::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Mask.cpp b/src/effects/Mask.cpp index 9f19475d..c2f49545 100644 --- a/src/effects/Mask.cpp +++ b/src/effects/Mask.cpp @@ -189,7 +189,7 @@ void Mask::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -199,7 +199,7 @@ void Mask::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Negate.cpp b/src/effects/Negate.cpp index 938030bc..94022aee 100644 --- a/src/effects/Negate.cpp +++ b/src/effects/Negate.cpp @@ -90,7 +90,7 @@ void Negate::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -100,7 +100,7 @@ void Negate::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Pixelate.cpp b/src/effects/Pixelate.cpp index d7c3fa12..ab211535 100644 --- a/src/effects/Pixelate.cpp +++ b/src/effects/Pixelate.cpp @@ -147,7 +147,7 @@ void Pixelate::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -157,7 +157,7 @@ void Pixelate::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Saturation.cpp b/src/effects/Saturation.cpp index 98818127..6e7b758b 100644 --- a/src/effects/Saturation.cpp +++ b/src/effects/Saturation.cpp @@ -147,7 +147,7 @@ void Saturation::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -157,7 +157,7 @@ void Saturation::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Shift.cpp b/src/effects/Shift.cpp index c22844e7..b4ab11b8 100644 --- a/src/effects/Shift.cpp +++ b/src/effects/Shift.cpp @@ -167,7 +167,7 @@ void Shift::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -177,7 +177,7 @@ void Shift::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } diff --git a/src/effects/Wave.cpp b/src/effects/Wave.cpp index 6e3bd48a..fa8ba6a7 100644 --- a/src/effects/Wave.cpp +++ b/src/effects/Wave.cpp @@ -150,7 +150,7 @@ void Wave::SetJson(string value) { if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -160,7 +160,7 @@ void Wave::SetJson(string value) { catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } } From 18c8b61b25df2b024a76df1f38ef9420c6b71fcd Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 27 Aug 2019 15:49:22 -0400 Subject: [PATCH 08/33] Clip_Tests.cpp: No InvalidJSON "" file_path args --- tests/Clip_Tests.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/Clip_Tests.cpp b/tests/Clip_Tests.cpp index 1b7475f4..5789780b 100644 --- a/tests/Clip_Tests.cpp +++ b/tests/Clip_Tests.cpp @@ -120,7 +120,7 @@ TEST(Clip_Properties) if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -132,7 +132,7 @@ TEST(Clip_Properties) catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } @@ -145,7 +145,7 @@ TEST(Clip_Properties) properties.c_str() + properties.size(), &root, &errors ); if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -157,7 +157,7 @@ TEST(Clip_Properties) catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } @@ -170,7 +170,7 @@ TEST(Clip_Properties) properties.c_str() + properties.size(), &root, &errors ); if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -181,7 +181,7 @@ TEST(Clip_Properties) catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } @@ -194,7 +194,7 @@ TEST(Clip_Properties) properties.c_str() + properties.size(), &root, &errors ); if (!success) // Raise exception - throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + throw InvalidJSON("JSON could not be parsed (or is invalid)"); try { @@ -206,7 +206,7 @@ TEST(Clip_Properties) catch (const std::exception& e) { // Error parsing JSON (or missing keys) - throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); } From 462f0b7930b0e51c37ef8615f23d4859b7b785c4 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 27 Aug 2019 20:48:56 -0400 Subject: [PATCH 09/33] Exception.h: Document parameters --- include/Exceptions.h | 129 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/include/Exceptions.h b/include/Exceptions.h index c6914d4b..28942050 100644 --- a/include/Exceptions.h +++ b/include/Exceptions.h @@ -61,6 +61,14 @@ namespace openshot { int64_t frame_number; int64_t chunk_number; int64_t chunk_frame; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param frame_number The frame number being processed + * @param chunk_number The chunk requested + * @param chunk_frame The chunk frame + */ ChunkNotFound(std::string message, int64_t frame_number, int64_t chunk_number, int64_t chunk_frame) : BaseException(message), frame_number(frame_number), chunk_number(chunk_number), chunk_frame(chunk_frame) { } virtual ~ChunkNotFound() noexcept {} @@ -71,6 +79,11 @@ namespace openshot { class DecklinkError : public BaseException { public: + /** + * @brief Constructor + * + * @param message A message to accompany the exception + */ DecklinkError(std::string message) : BaseException(message) { } virtual ~DecklinkError() noexcept {} @@ -81,6 +94,12 @@ namespace openshot { { public: int64_t frame_number; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param frame_number The frame number being processed + */ ErrorDecodingAudio(std::string message, int64_t frame_number) : BaseException(message), frame_number(frame_number) { } virtual ~ErrorDecodingAudio() noexcept {} @@ -91,6 +110,12 @@ namespace openshot { { public: int64_t frame_number; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param frame_number The frame number being processed + */ ErrorEncodingAudio(std::string message, int64_t frame_number) : BaseException(message), frame_number(frame_number) { } virtual ~ErrorEncodingAudio() noexcept {} @@ -101,6 +126,12 @@ namespace openshot { { public: int64_t frame_number; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param frame_number The frame number being processed + */ ErrorEncodingVideo(std::string message, int64_t frame_number) : BaseException(message), frame_number(frame_number) { } virtual ~ErrorEncodingVideo() noexcept {} @@ -111,6 +142,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ InvalidChannels(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidChannels() noexcept {} @@ -121,6 +158,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ InvalidCodec(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidCodec() noexcept {} @@ -131,6 +174,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path The input file being processed + */ InvalidFile(std::string message, std::string file_path) : BaseException(message), file_path(file_path) { } virtual ~InvalidFile() noexcept {} @@ -141,6 +190,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ InvalidFormat(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidFormat() noexcept {} @@ -151,6 +206,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ InvalidJSON(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidJSON() noexcept {} @@ -161,6 +222,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ InvalidOptions(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidOptions() noexcept {} @@ -171,6 +238,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ InvalidSampleRate(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~InvalidSampleRate() noexcept {} @@ -181,6 +254,12 @@ namespace openshot { { public: std::string json; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param json The json data being processed + */ InvalidJSONKey(std::string message, std::string json) : BaseException(message), json(json) { } virtual ~InvalidJSONKey() noexcept {} @@ -191,6 +270,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ NoStreamsFound(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~NoStreamsFound() noexcept {} @@ -202,6 +287,13 @@ namespace openshot { public: int64_t FrameRequested; int64_t MaxFrames; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param frame_requested The out-of-bounds frame number requested + * @param max_frames The maximum available frame number + */ OutOfBoundsFrame(std::string message, int64_t frame_requested, int64_t max_frames) : BaseException(message), FrameRequested(frame_requested), MaxFrames(max_frames) { } virtual ~OutOfBoundsFrame() noexcept {} @@ -213,6 +305,13 @@ namespace openshot { public: int PointRequested; int MaxPoints; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param point_requested The out-of-bounds point requested + * @param max_points The maximum available point value + */ OutOfBoundsPoint(std::string message, int point_requested, int max_points) : BaseException(message), PointRequested(point_requested), MaxPoints(max_points) { } virtual ~OutOfBoundsPoint() noexcept {} @@ -223,6 +322,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ OutOfMemory(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~OutOfMemory() noexcept {} @@ -233,6 +338,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ ReaderClosed(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~ReaderClosed() noexcept {} @@ -243,6 +354,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ ResampleError(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~ResampleError() noexcept {} @@ -253,6 +370,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The input file being processed + */ TooManySeeks(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~TooManySeeks() noexcept {} @@ -263,6 +386,12 @@ namespace openshot { { public: std::string file_path; + /** + * @brief Constructor + * + * @param message A message to accompany the exception + * @param file_path (optional) The output file being written + */ WriterClosed(std::string message, std::string file_path="") : BaseException(message), file_path(file_path) { } virtual ~WriterClosed() noexcept {} From 6ba4066cd765a80e5d47a817337ebfdf73da1419 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 27 Aug 2019 22:07:20 -0400 Subject: [PATCH 10/33] Add src/examples/Example.py --- src/examples/Example.py | 78 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100755 src/examples/Example.py diff --git a/src/examples/Example.py b/src/examples/Example.py new file mode 100755 index 00000000..20a82a8b --- /dev/null +++ b/src/examples/Example.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +""" + @file + @brief Python source file for openshot.py example + @author Jonathan Thomas + @author FeRD (Frank Dana) + + @ref License +""" + +# LICENSE +# +# Copyright (c) 2008-2019 OpenShot Studios, LLC +# . 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 . +# +# OpenShot Library (libopenshot) is free software: you can redistribute it +# and/or modify it under the terms of the GNU Lesser 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 (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 +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with OpenShot Library. If not, see . + +import sys + +# This can be run against an uninstalled build of libopenshot, just set the +# environment variable PYTHONPATH to the location of the Python bindings. +# +# For example: +# $ PYTHONPATH=../../build/src/bindings/python python3 Example.py +# +import openshot + + +# Create an FFmpegReader +r = openshot.FFmpegReader("sintel_trailer-720p.mp4") + +r.Open() # Open the reader +r.DisplayInfo() # Display metadata + +# Set up Writer +w = openshot.FFmpegWriter("pythonExample.mp4") + +w.SetAudioOptions(True, "libmp3lame", r.info.sample_rate, r.info.channels, r.info.channel_layout, 128000) +w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720, + openshot.Fraction(1, 1), False, False, 3000000) + +w.info.metadata["title"] = "testtest" +w.info.metadata["artist"] = "aaa" +w.info.metadata["album"] = "bbb" +w.info.metadata["year"] = "2015" +w.info.metadata["description"] = "ddd" +w.info.metadata["comment"] = "eee" +w.info.metadata["comment"] = "comment" +w.info.metadata["copyright"] = "copyright OpenShot!" + +# Open the Writer +w.Open() + +# Grab 30 frames from Reader and encode to Writer +for frame in range(100): + f = r.GetFrame(frame) + w.WriteFrame(f) + +# Close out Reader & Writer +w.Close() +r.Close() + +print("Completed successfully!") From 756e3a4abe6732798f813c288ea67d8bbebea55e Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 12 Sep 2019 00:13:53 -0400 Subject: [PATCH 11/33] Example.py: Remove useless `import sys` Codacy pointed out that there's absolutely no reason to be importing the sys module in this code. --- src/examples/Example.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/examples/Example.py b/src/examples/Example.py index 20a82a8b..a5d483f6 100755 --- a/src/examples/Example.py +++ b/src/examples/Example.py @@ -30,7 +30,6 @@ # You should have received a copy of the GNU Lesser General Public License # along with OpenShot Library. If not, see . -import sys # This can be run against an uninstalled build of libopenshot, just set the # environment variable PYTHONPATH to the location of the Python bindings. From e3b6478a0bcc7648cc8b749c3aedbab1600b9bd7 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 13 Sep 2019 07:43:46 -0400 Subject: [PATCH 12/33] FFmpegReader: Fix hardware device message - Don't precede with two blank lines - "Decodiing" was misspelled - Less cryptic text --- src/FFmpegReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c9e21271..dbe49b37 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -309,7 +309,7 @@ void FFmpegReader::Open() { char *adapter_ptr = NULL; int adapter_num; adapter_num = openshot::Settings::Instance()->HW_DE_DEVICE_SET; - fprintf(stderr, "\n\nDecodiing Device Nr: %d\n", adapter_num); + fprintf(stderr, "Hardware decoding device number: %d\n", adapter_num); // Set hardware pix format (callback) pCodecCtx->get_format = get_hw_dec_format; From 7fc214d803335edf55e8d712f13cb14015886074 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 13 Sep 2019 07:48:57 -0400 Subject: [PATCH 13/33] openshot-example: Path fixes Instead of the hardcoded `/home/jonathan/...` input path, load the input file from TEST_MEDIA_PATH, defined as in `tests/CMakeLists.txt` --- src/CMakeLists.txt | 8 ++++++++ src/examples/Example.cpp | 9 ++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6980dbae..3c46fa97 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -372,6 +372,14 @@ target_link_libraries(openshot ${REQUIRED_LIBRARIES}) # Create test executable add_executable(openshot-example examples/Example.cpp) +# Define path to test input files +SET(TEST_MEDIA_PATH "${PROJECT_SOURCE_DIR}/src/examples/") +IF (WIN32) + STRING(REPLACE "/" "\\\\" TEST_MEDIA_PATH TEST_MEDIA_PATH) +ENDIF(WIN32) +target_compile_definitions(openshot-example PRIVATE + -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) + # Link test executable to the new library target_link_libraries(openshot-example openshot) diff --git a/src/examples/Example.cpp b/src/examples/Example.cpp index eec8d00e..f532408a 100644 --- a/src/examples/Example.cpp +++ b/src/examples/Example.cpp @@ -43,12 +43,15 @@ int main(int argc, char* argv[]) { s->HARDWARE_DECODER = 2; // 1 VA-API, 2 NVDEC s->HW_DE_DEVICE_SET = 0; - FFmpegReader r9("/home/jonathan/Videos/sintel_trailer-720p.mp4"); + std::string input_filepath = TEST_MEDIA_PATH; + input_filepath += "sintel_trailer-720p.mp4"; + + FFmpegReader r9(input_filepath); r9.Open(); r9.DisplayInfo(); /* WRITER ---------------- */ - FFmpegWriter w9("/home/jonathan/metadata.mp4"); + FFmpegWriter w9("metadata.mp4"); // Set options w9.SetAudioOptions(true, "libmp3lame", r9.info.sample_rate, r9.info.channels, r9.info.channel_layout, 128000); @@ -83,4 +86,4 @@ int main(int argc, char* argv[]) { cout << "Completed successfully!" << endl; return 0; -} \ No newline at end of file +} From 918122632cb395382b257e6edd7ad54d98056bf9 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 13 Sep 2019 08:24:15 -0400 Subject: [PATCH 14/33] FFmpegWriter: Source formatting --- src/FFmpegWriter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 94d03e76..f85e09ad 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -172,7 +172,7 @@ void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, i AVCodec *new_codec; // Check if the codec selected is a hardware accelerated codec #if IS_FFMPEG_3_2 - #if defined(__linux__) + #if defined(__linux__) if ( (strcmp(codec.c_str(),"h264_vaapi") == 0)) { new_codec = avcodec_find_encoder_by_name(codec.c_str()); hw_en_on = 1; @@ -194,7 +194,7 @@ void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, i hw_en_supported = 0; } } -#elif defined(_WIN32) + #elif defined(_WIN32) if ( (strcmp(codec.c_str(),"h264_dxva2") == 0)) { new_codec = avcodec_find_encoder_by_name(codec.c_str()); hw_en_on = 1; @@ -216,7 +216,7 @@ void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, i hw_en_supported = 0; } } -#elif defined(__APPLE__) + #elif defined(__APPLE__) if ( (strcmp(codec.c_str(),"h264_videotoolbox") == 0)) { new_codec = avcodec_find_encoder_by_name(codec.c_str()); hw_en_on = 1; @@ -229,9 +229,9 @@ void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, i hw_en_on = 0; hw_en_supported = 0; } -#else // is FFmpeg 3 but not linux + #else // is FFmpeg 3 but not linux new_codec = avcodec_find_encoder_by_name(codec.c_str()); -#endif //__linux__ + #endif //__linux__ #else // not ffmpeg 3 new_codec = avcodec_find_encoder_by_name(codec.c_str()); #endif //IS_FFMPEG_3_2 From ee618a0c5c3d6b0f4c746e5e2c73e4379c4d5854 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 13 Sep 2019 11:22:30 -0400 Subject: [PATCH 15/33] Example.cpp: Finish indentation cleanup --- src/examples/Example.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/examples/Example.cpp b/src/examples/Example.cpp index f532408a..9e5ee369 100644 --- a/src/examples/Example.cpp +++ b/src/examples/Example.cpp @@ -39,9 +39,9 @@ using namespace openshot; int main(int argc, char* argv[]) { - Settings *s = Settings::Instance(); - s->HARDWARE_DECODER = 2; // 1 VA-API, 2 NVDEC - s->HW_DE_DEVICE_SET = 0; + Settings *s = Settings::Instance(); + s->HARDWARE_DECODER = 2; // 1 VA-API, 2 NVDEC, 6 VDPAU + s->HW_DE_DEVICE_SET = 0; std::string input_filepath = TEST_MEDIA_PATH; input_filepath += "sintel_trailer-720p.mp4"; @@ -83,7 +83,7 @@ int main(int argc, char* argv[]) { // Close timeline r9.Close(); - cout << "Completed successfully!" << endl; + cout << "Completed successfully!" << endl; return 0; } From ac7b106c5bbecc8a2cb4a082f71481f62bd78fe4 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 15 Sep 2019 01:35:02 -0400 Subject: [PATCH 16/33] Travis updates (Bionic, Qt 5.12, config) --- .travis.yml | 135 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 50 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2e7db59d..8c3c64d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,53 +1,88 @@ -dist: xenial -sudo: required +language: cpp + +# This section uses a rather esoteric (and tricky!) feature of YAML, +# &aliases and *anchors, to build package lists out of sublists without +# repeating their contents. Basically, '&name' creates an alias for the +# given data, which can then be referenced using the anchor '*name'. +addons: + apt: + packages: &p_common # Packages common to all Ubuntu builds + - cmake + - swig + - libopenshot-audio-dev + - libmagick++-dev + - libunittest++-dev + - libzmq3-dev + - qtbase5-dev + - qtmultimedia5-dev + - doxygen + - graphviz + packages: &ff_common # Common set of FFmpeg packages + - *p_common + - libfdk-aac-dev + - libavcodec-dev + - libavformat-dev + - libavdevice-dev + - libavutil-dev + - libavfilter-dev + - libswscale-dev + - libpostproc-dev + - libavresample-dev + - libswresample-dev matrix: include: - - language: cpp - name: "FFmpeg 2" - before_script: - - sudo add-apt-repository ppa:openshot.developers/libopenshot-daily -y - - sudo add-apt-repository ppa:beineri/opt-qt-5.10.0-xenial -y - - sudo apt-get update -qq - - sudo apt-get install gcc-4.8 cmake libavcodec-dev libavformat-dev libswscale-dev libavresample-dev libavutil-dev libopenshot-audio-dev libopenshot-dev libfdk-aac-dev libfdk-aac-dev libjsoncpp-dev libmagick++-dev libopenshot-audio-dev libunittest++-dev libzmq3-dev pkg-config python3-dev qtbase5-dev qtmultimedia5-dev swig -y - - sudo apt autoremove -y - script: - - mkdir -p build; cd build; - - cmake -D"CMAKE_BUILD_TYPE:STRING=Debug" ../ - - make VERBOSE=1 - - make os_test - - make install DESTDIR=dist/ - - - language: cpp - name: "FFmpeg 3" - before_script: - - sudo add-apt-repository ppa:openshot.developers/libopenshot-daily -y - - sudo add-apt-repository ppa:beineri/opt-qt-5.10.0-xenial -y - - sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y - - sudo apt-get update -qq - - sudo apt-get install gcc-4.8 cmake libavcodec-dev libavformat-dev libswscale-dev libavresample-dev libavutil-dev libopenshot-audio-dev libopenshot-dev libfdk-aac-dev libfdk-aac-dev libjsoncpp-dev libmagick++-dev libopenshot-audio-dev libunittest++-dev libzmq3-dev pkg-config python3-dev qtbase5-dev qtmultimedia5-dev swig -y - - sudo apt autoremove -y - script: - - mkdir -p build; cd build; - - cmake -D"CMAKE_BUILD_TYPE:STRING=Debug" ../ - - make VERBOSE=1 - - make os_test - - make install DESTDIR=dist/ - - - language: cpp - name: "FFmpeg 4" - before_script: - - sudo add-apt-repository ppa:openshot.developers/libopenshot-daily -y - - sudo add-apt-repository ppa:beineri/opt-qt-5.10.0-xenial -y - - sudo add-apt-repository ppa:jonathonf/ffmpeg -y - - sudo add-apt-repository ppa:jonathonf/ffmpeg-4 -y - - sudo add-apt-repository ppa:jonathonf/backports -y - - sudo apt-get update -qq - - sudo apt-get install gcc-4.8 cmake libavcodec58 libavformat58 libavcodec-dev libavformat-dev libswscale-dev libavresample-dev libavutil-dev libopenshot-audio-dev libopenshot-dev libfdk-aac-dev libfdk-aac-dev libjsoncpp-dev libmagick++-dev libopenshot-audio-dev libunittest++-dev libzmq3-dev pkg-config python3-dev qtbase5-dev qtmultimedia5-dev swig -y - - sudo apt autoremove -y - script: - - mkdir -p build; cd build; - - cmake -D"CMAKE_BUILD_TYPE:STRING=Debug" ../ - - make VERBOSE=1 - - make os_test - - make install DESTDIR=dist/ + - name: "FFmpeg 2 (Ubuntu 16.04 Xenial)" + env: BUILD_VERSION=ffmpeg2 + os: linux + dist: xenial + addons: + apt: + sources: + - sourceline: 'ppa:openshot.developers/libopenshot-daily' + - sourceline: 'ppa:beineri/opt-qt-5.10.0-xenial' + packages: + - *ff_common + + - name: "FFmpeg 3 (Ubuntu 18.04 Bionic)" + env: BUILD_VERSION=ffmpeg3 + os: linux + dist: bionic + addons: + apt: + sources: + - sourceline: 'ppa:openshot.developers/libopenshot-daily' + - sourceline: 'ppa:beineri/opt-qt-5.12.3-bionic' + packages: + - *ff_common + - qt5-default + + - name: "FFmpeg 4 (Ubuntu 18.04 Bionic)" + env: BUILD_VERSION=ffmpeg4 + os: linux + dist: bionic + addons: + apt: + sources: + - sourceline: 'ppa:openshot.developers/libopenshot-daily' + - sourceline: 'ppa:beineri/opt-qt-5.12.3-bionic' + - sourceline: 'ppa:jonathonf/ffmpeg-4' + packages: + - *ff_common + - qt5-default + - libavcodec58 + - libavformat58 + - libavdevice58 + - libavutil56 + - libavfilter7 + - libswscale5 + - libpostproc55 + - libavresample4 + - libswresample3 + +script: + - mkdir -p build; cd build; + - cmake -DCMAKE_BUILD_TYPE:STRING="Debug" ../ + - make VERBOSE=1 + - make os_test + - make install DESTDIR="$BUILD_VERSION" From 9b9e4a700848b339b2697d195d9bad6313e44061 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 13 Sep 2019 19:36:44 -0400 Subject: [PATCH 17/33] CMakeLists: Also detect cppzmq We don't _just_ use the ZeroMQ library, we also use the cppzmq bindings. Previously we weren't detecting for those at all. This adds a check for its configs, and adds its target to the openshot target linking (even though it's a header-only library). --- src/CMakeLists.txt | 15 +++++++++++---- tests/CMakeLists.txt | 7 +++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6980dbae..e5e8ee84 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,8 +6,8 @@ # # Copyright (c) 2008-2019 OpenShot Studios, LLC # . This file is part of -# OpenShot Library (libopenshot), an open-source project dedicated to -# delivering high quality video editing and animation solutions to the +# OpenShot Library (libopenshot), an open-source project dedicated to +# delivering high quality video editing and animation solutions to the # world. For more information visit . # # OpenShot Library (libopenshot) is free software: you can redistribute it @@ -161,7 +161,7 @@ IF (ENABLE_BLACKMAGIC) FIND_PACKAGE(BlackMagic) IF (BLACKMAGIC_FOUND) - # Include headers (needed for compile) + # Include Blackmagic headers (needed for compile) include_directories(${BLACKMAGIC_INCLUDE_DIR}) # define a global var (used in the C++) @@ -181,10 +181,17 @@ endif(OPENMP_FOUND) ################### ZEROMQ ##################### # Find ZeroMQ library (used for socket communication & logging) -FIND_PACKAGE(ZMQ REQUIRED) + +# Some platforms package the header-only cppzmq C++ bindings separately, +# others (Ubuntu) bundle them in with libzmq itself +find_package(cppzmq QUIET) +find_package(ZMQ REQUIRED) # Include ZeroMQ headers (needed for compile) include_directories(${ZMQ_INCLUDE_DIRS}) +if (cppzmq_FOUND) + include_directories(${cppzmq_INCLUDE_DIRS}) +endif() ################### RESVG ##################### # Find resvg library (used for rendering svg files) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5e18fcf3..42ca8ffc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -177,10 +177,17 @@ endif(OPENMP_FOUND) ################### ZEROMQ ##################### # Find ZeroMQ library (used for socket communication & logging) + +# Some platforms package the header-only cppzmq C++ bindings separately, +# others (Ubuntu) bundle them in with libzmq itself +find_package(cppzmq QUIET) FIND_PACKAGE(ZMQ REQUIRED) # Include ZeroMQ headers (needed for compile) include_directories(${ZMQ_INCLUDE_DIRS}) +if (cppzmq_FOUND) + include_directories(${cppzmq_INCLUDE_DIRS}) +endif() ################### RESVG ##################### # Find resvg library (used for rendering svg files) From 25ebb24b3608dd66a040bce46389de11b2a66dda Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 16 Sep 2019 09:55:21 -0400 Subject: [PATCH 18/33] Re-enable 'make test' on CMake 3.10+ --- tests/CMakeLists.txt | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5e18fcf3..28cbba35 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -202,7 +202,7 @@ endif(USE_SYSTEM_JSONCPP) IF (NOT DISABLE_TESTS) ############### SET TEST SOURCE FILES ################# - SET ( OPENSHOT_TEST_FILES tests.cpp + SET ( OPENSHOT_TEST_FILES Cache_Tests.cpp Clip_Tests.cpp Color_Tests.cpp @@ -220,6 +220,7 @@ IF (NOT DISABLE_TESTS) ################ TESTER EXECUTABLE ################# # Create unit test executable (openshot-test) + message (STATUS "Tests enabled, test executable will be built as tests/openshot-test") add_executable(openshot-test tests.cpp ${OPENSHOT_TEST_FILES} ) @@ -227,7 +228,24 @@ IF (NOT DISABLE_TESTS) # Link libraries to the new executable target_link_libraries(openshot-test openshot ${UNITTEST++_LIBRARY}) - #################### MAKE TEST ###################### + ##### RUNNING TESTS (make os_test / make test) ##### # Hook up the 'make os_test' target to the 'openshot-test' executable ADD_CUSTOM_TARGET(os_test COMMAND openshot-test) -ENDIF (NOT DISABLE_TESTS) + list(APPEND OS_TEST_CMDS "'make os_test'") + + # Also hook up 'make test', if possible + # This requires CMake 3.11+, where the CMP0037 policy + # configured to 'NEW' mode will not reserve target names + # unless the corresponding feature is actually used + if (POLICY CMP0037) + cmake_policy(SET CMP0037 NEW) + endif() + if (CMAKE_VERSION VERSION_GREATER 3.11) + message(STATUS "Cmake 3.11+ detected, enabling 'test' target") + add_custom_target(test COMMAND openshot-test) + list(APPEND OS_TEST_CMDS " or " "'make test'") + endif() + + string(CONCAT t ${OS_TEST_CMDS}) + message("\nTo run unit tests, use: ${t}") +endif() From 1de2ea21a67eae8179727f6a301b29c5d26c63dd Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 16 Sep 2019 13:47:03 -0400 Subject: [PATCH 19/33] /CMakeLists.txt: Move tests, add doc message --- CMakeLists.txt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24d3e19d..0809c04d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,14 +92,18 @@ ENDIF(WIN32) set(QT_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/Qt) FILE(GLOB QT_HEADER_FILES "${QT_HEADER_DIR}/*.h") -############## PROCESS SUB-DIRECTORIES ############## +############## PROCESS src/ DIRECTORIES ############## add_subdirectory(src) -add_subdirectory(tests) ################### DOCUMENTATION ################### # Find Doxygen (used for documentation) include(cmake/Modules/UseDoxygen.cmake) +# Doxygen was found +if (TARGET doc) + message(STATUS "Doxygen found, documentation target enabled") + message("\nTo compile documentation in doc/html, run: 'make doc'") + # Install docs, if the user builds them with `make doc` install(CODE "MESSAGE(\"Checking for documentation files to install...\")") install(CODE "MESSAGE(\"(Compile with 'make doc' command, requires Doxygen)\")") @@ -108,3 +112,8 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html/ DESTINATION ${CMAKE_INSTALL_DOCDIR}/API MESSAGE_NEVER # Don't spew about file copies OPTIONAL ) # No error if the docs aren't found +endif() + +############# PROCESS tests/ DIRECTORY ############## +add_subdirectory(tests) + From c78d030b5b7f828e975839be5b01303482a3ad87 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 18 Sep 2019 21:25:34 -0400 Subject: [PATCH 20/33] Delete FindPythonLibs.cmake Our copy of the module is outdated, and fails detecting Python 3.8. (Besides, we shouldn't be mirroring standard CMake modules.) --- cmake/Modules/FindPythonLibs.cmake | 294 ----------------------------- 1 file changed, 294 deletions(-) delete mode 100644 cmake/Modules/FindPythonLibs.cmake diff --git a/cmake/Modules/FindPythonLibs.cmake b/cmake/Modules/FindPythonLibs.cmake deleted file mode 100644 index e2ca1c79..00000000 --- a/cmake/Modules/FindPythonLibs.cmake +++ /dev/null @@ -1,294 +0,0 @@ -#.rst: -# FindPythonLibs -# -------------- -# -# Find python libraries -# -# This module finds if Python is installed and determines where the -# include files and libraries are. It also determines what the name of -# the library is. This code sets the following variables: -# -# :: -# -# PYTHONLIBS_FOUND - have the Python libs been found -# PYTHON_LIBRARIES - path to the python library -# PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated) -# PYTHON_INCLUDE_DIRS - path to where Python.h is found -# PYTHON_DEBUG_LIBRARIES - path to the debug library (deprecated) -# PYTHONLIBS_VERSION_STRING - version of the Python libs found (since CMake 2.8.8) -# -# -# -# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list -# of version numbers that should be taken into account when searching -# for Python. You need to set this variable before calling -# find_package(PythonLibs). -# -# If you'd like to specify the installation of Python to use, you should -# modify the following cache variables: -# -# :: -# -# PYTHON_LIBRARY - path to the python library -# PYTHON_INCLUDE_DIR - path to where Python.h is found -# -# If also calling find_package(PythonInterp), call find_package(PythonInterp) -# first to get the currently active Python version by default with a consistent -# version of PYTHON_LIBRARIES. - -#============================================================================= -# Copyright 2001-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -include(CMakeFindFrameworks) -# Search for the python framework on Apple. -CMAKE_FIND_FRAMEWORKS(Python) - -set(_PYTHON1_VERSIONS 1.6 1.5) -set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) -set(_PYTHON3_VERSIONS 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) - -if(PythonLibs_FIND_VERSION) - if(PythonLibs_FIND_VERSION_COUNT GREATER 1) - set(_PYTHON_FIND_MAJ_MIN "${PythonLibs_FIND_VERSION_MAJOR}.${PythonLibs_FIND_VERSION_MINOR}") - unset(_PYTHON_FIND_OTHER_VERSIONS) - if(PythonLibs_FIND_VERSION_EXACT) - if(_PYTHON_FIND_MAJ_MIN STREQUAL PythonLibs_FIND_VERSION) - set(_PYTHON_FIND_OTHER_VERSIONS "${PythonLibs_FIND_VERSION}") - else() - set(_PYTHON_FIND_OTHER_VERSIONS "${PythonLibs_FIND_VERSION}" "${_PYTHON_FIND_MAJ_MIN}") - endif() - else() - foreach(_PYTHON_V ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS}) - if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN) - list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V}) - endif() - endforeach() - endif() - unset(_PYTHON_FIND_MAJ_MIN) - else() - set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS}) - endif() -else() - set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS}) -endif() - -# Set up the versions we know about, in the order we will search. Always add -# the user supplied additional versions to the front. -# If FindPythonInterp has already found the major and minor version, -# insert that version between the user supplied versions and the stock -# version list. -set(_Python_VERSIONS ${Python_ADDITIONAL_VERSIONS}) -if(DEFINED PYTHON_VERSION_MAJOR AND DEFINED PYTHON_VERSION_MINOR) - list(APPEND _Python_VERSIONS ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) -endif() -list(APPEND _Python_VERSIONS ${_PYTHON_FIND_OTHER_VERSIONS}) - -unset(_PYTHON_FIND_OTHER_VERSIONS) -unset(_PYTHON1_VERSIONS) -unset(_PYTHON2_VERSIONS) -unset(_PYTHON3_VERSIONS) - -foreach(_CURRENT_VERSION ${_Python_VERSIONS}) - string(REPLACE "." "" _CURRENT_VERSION_NO_DOTS ${_CURRENT_VERSION}) - if(WIN32) - find_library(PYTHON_DEBUG_LIBRARY - NAMES python${_CURRENT_VERSION_NO_DOTS}_d python - PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs - ) - endif() - - find_library(PYTHON_LIBRARY - NAMES - python${_CURRENT_VERSION_NO_DOTS} - python${_CURRENT_VERSION}mu - python${_CURRENT_VERSION}m - python${_CURRENT_VERSION}u - python${_CURRENT_VERSION} - PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs - # Avoid finding the .dll in the PATH. We want the .lib. - NO_SYSTEM_ENVIRONMENT_PATH - ) - # Look for the static library in the Python config directory - find_library(PYTHON_LIBRARY - NAMES python${_CURRENT_VERSION_NO_DOTS} python${_CURRENT_VERSION} - # Avoid finding the .dll in the PATH. We want the .lib. - NO_SYSTEM_ENVIRONMENT_PATH - # This is where the static library is usually located - PATH_SUFFIXES python${_CURRENT_VERSION}/config - ) - - # For backward compatibility, honour value of PYTHON_INCLUDE_PATH, if - # PYTHON_INCLUDE_DIR is not set. - if(DEFINED PYTHON_INCLUDE_PATH AND NOT DEFINED PYTHON_INCLUDE_DIR) - set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}" CACHE PATH - "Path to where Python.h is found" FORCE) - endif() - - set(PYTHON_FRAMEWORK_INCLUDES) - if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR) - foreach(dir ${Python_FRAMEWORKS}) - set(PYTHON_FRAMEWORK_INCLUDES ${PYTHON_FRAMEWORK_INCLUDES} - ${dir}/Versions/${_CURRENT_VERSION}/include/python${_CURRENT_VERSION}) - endforeach() - endif() - - find_path(PYTHON_INCLUDE_DIR - NAMES Python.h - PATHS - ${PYTHON_FRAMEWORK_INCLUDES} - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include - PATH_SUFFIXES - python${_CURRENT_VERSION}mu - python${_CURRENT_VERSION}m - python${_CURRENT_VERSION}u - python${_CURRENT_VERSION} - ) - - # For backward compatibility, set PYTHON_INCLUDE_PATH. - set(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}") - - if(PYTHON_INCLUDE_DIR AND EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h") - file(STRINGS "${PYTHON_INCLUDE_DIR}/patchlevel.h" python_version_str - REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") - string(REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - PYTHONLIBS_VERSION_STRING "${python_version_str}") - unset(python_version_str) - endif() - - if(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR) - break() - endif() -endforeach() - -mark_as_advanced( - PYTHON_DEBUG_LIBRARY - PYTHON_LIBRARY - PYTHON_INCLUDE_DIR -) - -# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the -# cache entries because they are meant to specify the location of a single -# library. We now set the variables listed by the documentation for this -# module. -set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") -set(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}") - -# These variables have been historically named in this module different from -# what SELECT_LIBRARY_CONFIGURATIONS() expects. -set(PYTHON_LIBRARY_DEBUG "${PYTHON_DEBUG_LIBRARY}") -set(PYTHON_LIBRARY_RELEASE "${PYTHON_LIBRARY}") -include(SelectLibraryConfigurations) -SELECT_LIBRARY_CONFIGURATIONS(PYTHON) -# SELECT_LIBRARY_CONFIGURATIONS() sets ${PREFIX}_FOUND if it has a library. -# Unset this, this prefix doesn't match the module prefix, they are different -# for historical reasons. -unset(PYTHON_FOUND) - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs - REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS - VERSION_VAR PYTHONLIBS_VERSION_STRING) - -# PYTHON_ADD_MODULE( src1 src2 ... srcN) is used to build modules for python. -# PYTHON_WRITE_MODULES_HEADER() writes a header file you can include -# in your sources to initialize the static python modules -function(PYTHON_ADD_MODULE _NAME ) - get_property(_TARGET_SUPPORTS_SHARED_LIBS - GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS) - option(PYTHON_ENABLE_MODULE_${_NAME} "Add module ${_NAME}" TRUE) - option(PYTHON_MODULE_${_NAME}_BUILD_SHARED - "Add module ${_NAME} shared" ${_TARGET_SUPPORTS_SHARED_LIBS}) - - # Mark these options as advanced - mark_as_advanced(PYTHON_ENABLE_MODULE_${_NAME} - PYTHON_MODULE_${_NAME}_BUILD_SHARED) - - if(PYTHON_ENABLE_MODULE_${_NAME}) - if(PYTHON_MODULE_${_NAME}_BUILD_SHARED) - set(PY_MODULE_TYPE MODULE) - else() - set(PY_MODULE_TYPE STATIC) - set_property(GLOBAL APPEND PROPERTY PY_STATIC_MODULES_LIST ${_NAME}) - endif() - - set_property(GLOBAL APPEND PROPERTY PY_MODULES_LIST ${_NAME}) - add_library(${_NAME} ${PY_MODULE_TYPE} ${ARGN}) -# target_link_libraries(${_NAME} ${PYTHON_LIBRARIES}) - - if(PYTHON_MODULE_${_NAME}_BUILD_SHARED) - set_target_properties(${_NAME} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") - if(WIN32 AND NOT CYGWIN) - set_target_properties(${_NAME} PROPERTIES SUFFIX ".pyd") - endif() - endif() - - endif() -endfunction() - -function(PYTHON_WRITE_MODULES_HEADER _filename) - - get_property(PY_STATIC_MODULES_LIST GLOBAL PROPERTY PY_STATIC_MODULES_LIST) - - get_filename_component(_name "${_filename}" NAME) - string(REPLACE "." "_" _name "${_name}") - string(TOUPPER ${_name} _nameUpper) - set(_filename ${CMAKE_CURRENT_BINARY_DIR}/${_filename}) - - set(_filenameTmp "${_filename}.in") - file(WRITE ${_filenameTmp} "/*Created by cmake, do not edit, changes will be lost*/\n") - file(APPEND ${_filenameTmp} -"#ifndef ${_nameUpper} -#define ${_nameUpper} - -#include - -#ifdef __cplusplus -extern \"C\" { -#endif /* __cplusplus */ - -") - - foreach(_currentModule ${PY_STATIC_MODULES_LIST}) - file(APPEND ${_filenameTmp} "extern void init${PYTHON_MODULE_PREFIX}${_currentModule}(void);\n\n") - endforeach() - - file(APPEND ${_filenameTmp} -"#ifdef __cplusplus -} -#endif /* __cplusplus */ - -") - - - foreach(_currentModule ${PY_STATIC_MODULES_LIST}) - file(APPEND ${_filenameTmp} "int ${_name}_${_currentModule}(void) \n{\n static char name[]=\"${PYTHON_MODULE_PREFIX}${_currentModule}\"; return PyImport_AppendInittab(name, init${PYTHON_MODULE_PREFIX}${_currentModule});\n}\n\n") - endforeach() - - file(APPEND ${_filenameTmp} "void ${_name}_LoadAllPythonModules(void)\n{\n") - foreach(_currentModule ${PY_STATIC_MODULES_LIST}) - file(APPEND ${_filenameTmp} " ${_name}_${_currentModule}();\n") - endforeach() - file(APPEND ${_filenameTmp} "}\n\n") - file(APPEND ${_filenameTmp} "#ifndef EXCLUDE_LOAD_ALL_FUNCTION\nvoid CMakeLoadAllPythonModules(void)\n{\n ${_name}_LoadAllPythonModules();\n}\n#endif\n\n#endif\n") - -# with configure_file() cmake complains that you may not use a file created using file(WRITE) as input file for configure_file() - execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_filenameTmp}" "${_filename}" OUTPUT_QUIET ERROR_QUIET) - -endfunction() From c422f4f2451303da213f51155e27cb7539c64684 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 21 Sep 2019 01:43:30 -0400 Subject: [PATCH 21/33] Separate GetVersion impl, make Pythonic --- include/OpenShotVersion.h.in | 32 +++++++++++----------------- src/CMakeLists.txt | 1 + src/OpenShotVersion.cpp | 38 ++++++++++++++++++++++++++++++++++ src/bindings/python/openshot.i | 7 +++++++ 4 files changed, 58 insertions(+), 20 deletions(-) create mode 100644 src/OpenShotVersion.cpp diff --git a/include/OpenShotVersion.h.in b/include/OpenShotVersion.h.in index 89f4ed52..e15662b2 100644 --- a/include/OpenShotVersion.h.in +++ b/include/OpenShotVersion.h.in @@ -43,36 +43,28 @@ #define OPENSHOT_VERSION_SO @PROJECT_SO_VERSION@ /// Shared object version number. This increments any time the API and ABI changes (so old apps will no longer link) #include -using namespace std; namespace openshot { /// This struct holds version number information. Use the GetVersion() method to access the current version of libopenshot. struct OpenShotVersion { - int major; /// Major version number - int minor; /// Minor version number - int build; /// Build number - int so; /// Shared Object Number (incremented when API or ABI changes) + static const int Major = OPENSHOT_VERSION_MAJOR; /// Major version number + static const int Minor = OPENSHOT_VERSION_MINOR; /// Minor version number + static const int Build = OPENSHOT_VERSION_BUILD; /// Build number + static const int So = OPENSHOT_VERSION_SO; /// Shared Object Number (incremented when API or ABI changes) /// Get a string version of the version (i.e. "Major.Minor.Build") - string ToString() { - stringstream version_string; - version_string << major << "." << minor << "." << build; + inline static const std::string ToString() { + std::stringstream version_string; + version_string << Major << "." << Minor << "." << Build; return version_string.str(); } }; + static const openshot::OpenShotVersion Version; + /// Get the current version number of libopenshot (major, minor, and build number) - static OpenShotVersion GetVersion() { - OpenShotVersion version; - - // Set version info - version.major = OPENSHOT_VERSION_MAJOR; - version.minor = OPENSHOT_VERSION_MINOR; - version.build = OPENSHOT_VERSION_BUILD; - version.so = OPENSHOT_VERSION_SO; - - return version; - } + openshot::OpenShotVersion GetVersion(); } -#endif + +#endif // OPENSHOT_VERSION_H \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6980dbae..2625027c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -249,6 +249,7 @@ SET ( OPENSHOT_SOURCE_FILES Frame.cpp FrameMapper.cpp KeyFrame.cpp + OpenShotVersion.cpp ZmqLogger.cpp PlayerBase.cpp Point.cpp diff --git a/src/OpenShotVersion.cpp b/src/OpenShotVersion.cpp new file mode 100644 index 00000000..1bc73c3a --- /dev/null +++ b/src/OpenShotVersion.cpp @@ -0,0 +1,38 @@ +/** + * @file + * @brief Source file for GetVersion function + * @author Jonathan Thomas + * @author FeRD (Frank Dana) + * + * @ref License + */ + +/* LICENSE + * + * Copyright (c) 2008-2019 OpenShot Studios, LLC + * . 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 . + * + * OpenShot Library (libopenshot) is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser 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 (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 + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with OpenShot Library. If not, see . + */ + +#include "OpenShotVersion.h" + +namespace openshot { + OpenShotVersion GetVersion() { + return openshot::Version; + } +} \ No newline at end of file diff --git a/src/bindings/python/openshot.i b/src/bindings/python/openshot.i index 512224ef..63bdea33 100644 --- a/src/bindings/python/openshot.i +++ b/src/bindings/python/openshot.i @@ -120,6 +120,13 @@ } } +%extend openshot::OpenShotVersion { + // Give the struct a string representation + const std::string __str__() { + return std::string(openshot::OpenShotVersion::ToString()); + } +} + %include "OpenShotVersion.h" %include "../../../include/ReaderBase.h" %include "../../../include/WriterBase.h" From ba86744e6a53d9a1777167c77577fd3e9a56bfd1 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 21 Sep 2019 02:03:07 -0400 Subject: [PATCH 22/33] Use OPENSHOT_VERSION_FULL as Python str() --- src/bindings/python/openshot.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/python/openshot.i b/src/bindings/python/openshot.i index 63bdea33..6e90d2ca 100644 --- a/src/bindings/python/openshot.i +++ b/src/bindings/python/openshot.i @@ -123,7 +123,7 @@ %extend openshot::OpenShotVersion { // Give the struct a string representation const std::string __str__() { - return std::string(openshot::OpenShotVersion::ToString()); + return std::string(OPENSHOT_VERSION_FULL); } } From 9e0d194072a227ffc05283fbcd7c4ad1c44acd20 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Sun, 22 Sep 2019 01:37:32 -0400 Subject: [PATCH 23/33] Add comment re: updates to interlace params --- src/FFmpegReader.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 38a1f610..7b5230e9 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -752,6 +752,8 @@ void FFmpegReader::UpdateVideoInfo() { check_interlace = false; break; } + // check_interlace will prevent these checks being repeated, + // unless it was cleared because we got an AV_FIELD_UNKNOWN response. } // Set the video timebase From 1ec431f4460a06a7149e44f8abe6f66e70428ba7 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 25 Sep 2019 01:05:59 -0400 Subject: [PATCH 24/33] Simplify CMakeLists with loops --- src/CMakeLists.txt | 119 ++++++++++--------------------------------- tests/CMakeLists.txt | 76 ++++++--------------------- 2 files changed, 42 insertions(+), 153 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6980dbae..aeab95e5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,33 +82,14 @@ ENDIF (ImageMagick_FOUND) # Find FFmpeg libraries (used for video encoding / decoding) FIND_PACKAGE(FFmpeg REQUIRED) -IF (AVCODEC_FOUND) - include_directories(${AVCODEC_INCLUDE_DIRS}) -ENDIF (AVCODEC_FOUND) -IF (AVDEVICE_FOUND) - include_directories(${AVDEVICE_INCLUDE_DIRS}) -ENDIF (AVDEVICE_FOUND) -IF (AVFORMAT_FOUND) - include_directories(${AVFORMAT_INCLUDE_DIRS}) -ENDIF (AVFORMAT_FOUND) -IF (AVFILTER_FOUND) - include_directories(${AVFILTER_INCLUDE_DIRS}) -ENDIF (AVFILTER_FOUND) -IF (AVUTIL_FOUND) - include_directories(${AVUTIL_INCLUDE_DIRS}) -ENDIF (AVUTIL_FOUND) -IF (POSTPROC_FOUND) - include_directories(${POSTPROC_INCLUDE_DIRS}) -ENDIF (POSTPROC_FOUND) -IF (SWSCALE_FOUND) - include_directories(${SWSCALE_INCLUDE_DIRS}) -ENDIF (SWSCALE_FOUND) -IF (SWRESAMPLE_FOUND) - include_directories(${SWRESAMPLE_INCLUDE_DIRS}) -ENDIF (SWRESAMPLE_FOUND) -IF (AVRESAMPLE_FOUND) - include_directories(${AVRESAMPLE_INCLUDE_DIRS}) -ENDIF (AVRESAMPLE_FOUND) +foreach(ffmpeg_comp AVCODEC AVDEVICE AVFORMAT AVFILTER AVUTIL POSTPROC SWSCALE SWRESAMPLE AVRESAMPLE) + if(${ffmpeg_comp}_FOUND) + # message(STATUS "Adding include dir for ${ffmpeg_comp}") + include_directories(${${ffmpeg_comp}_INCLUDE_DIRS}) + add_definitions(${${ffmpeg_comp}_DEFINITIONS}) + list(APPEND FF_LIBRARIES ${${ffmpeg_comp}_LIBRARIES}) + endif() +endforeach() ################# LIBOPENSHOT-AUDIO ################### # Find JUCE-based openshot Audio libraries @@ -119,38 +100,17 @@ include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}) ################# QT5 ################### # Find QT5 libraries -find_package(Qt5Widgets REQUIRED) -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Multimedia REQUIRED) -find_package(Qt5MultimediaWidgets REQUIRED) - -# Include Qt headers (needed for compile) -include_directories(${Qt5Widgets_INCLUDE_DIRS}) -include_directories(${Qt5Core_INCLUDE_DIRS}) -include_directories(${Qt5Gui_INCLUDE_DIRS}) -include_directories(${Qt5Multimedia_INCLUDE_DIRS}) -include_directories(${Qt5MultimediaWidgets_INCLUDE_DIRS}) - -add_definitions(${Qt5Widgets_DEFINITIONS}) -add_definitions(${Qt5Core_DEFINITIONS}) -add_definitions(${Qt5Gui_DEFINITIONS}) -add_definitions(${Qt5Multimedia_DEFINITIONS}) -add_definitions(${Qt5MultimediaWidgets_DEFINITIONS}) - -SET(QT_LIBRARIES ${Qt5Widgets_LIBRARIES} - ${Qt5Core_LIBRARIES} - ${Qt5Gui_LIBRARIES} - ${Qt5Multimedia_LIBRARIES} - ${Qt5MultimediaWidgets_LIBRARIES}) - -# Set compiler flags for Qt -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Multimedia_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5MultimediaWidgets_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -ggdb ") +foreach(qt_lib Qt5Widgets Qt5Core Qt5Gui Qt5Multimedia Qt5MultimediaWidgets) + find_package(${qt_lib} REQUIRED) + # Header files + include_directories(${${qt_lib}_INCLUDE_DIRS}) + # Compiler definitions + add_definitions(${${qt_lib}_DEFINITIONS}) + # Other CFLAGS + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${qt_lib}_EXECUTABLE_COMPILE_FLAGS}") + # For use when linking + list(APPEND QT_LIBRARIES ${${qt_lib}_LIBRARIES}) +endforeach() # Manually moc Qt files qt5_wrap_cpp(MOC_FILES ${QT_HEADER_FILES}) @@ -309,59 +269,32 @@ set_target_properties(openshot ############### LINK LIBRARY ################# SET ( REQUIRED_LIBRARIES ${LIBOPENSHOT_AUDIO_LIBRARIES} + ${FF_LIBRARIES} ${QT_LIBRARIES} ${PROFILER} ${JSONCPP_LIBRARY} ${ZMQ_LIBRARIES} ) -IF (AVCODEC_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVCODEC_LIBRARIES} ) -ENDIF (AVCODEC_FOUND) -IF (AVDEVICE_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVDEVICE_LIBRARIES} ) -ENDIF (AVDEVICE_FOUND) -IF (AVFORMAT_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVFORMAT_LIBRARIES} ) -ENDIF (AVFORMAT_FOUND) -IF (AVFILTER_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVFILTER_LIBRARIES} ) -ENDIF (AVFILTER_FOUND) -IF (AVUTIL_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVUTIL_LIBRARIES} ) -ENDIF (AVUTIL_FOUND) -IF (POSTPROC_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${POSTPROC_LIBRARIES} ) -ENDIF (POSTPROC_FOUND) -IF (SWSCALE_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${SWSCALE_LIBRARIES} ) -ENDIF (SWSCALE_FOUND) -IF (SWRESAMPLE_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${SWRESAMPLE_LIBRARIES} ) -ENDIF (SWRESAMPLE_FOUND) -IF (AVRESAMPLE_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVRESAMPLE_LIBRARIES} ) -ENDIF (AVRESAMPLE_FOUND) - IF (RESVG_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${RESVG_LIBRARIES} ) + list(APPEND REQUIRED_LIBRARIES ${RESVG_LIBRARIES}) ENDIF(RESVG_FOUND) IF (OPENMP_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${OpenMP_CXX_FLAGS} ) + list(APPEND REQUIRED_LIBRARIES ${OpenMP_CXX_FLAGS}) ENDIF (OPENMP_FOUND) IF (ImageMagick_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${ImageMagick_LIBRARIES} ) + list(APPEND REQUIRED_LIBRARIES ${ImageMagick_LIBRARIES}) ENDIF (ImageMagick_FOUND) IF (BLACKMAGIC_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${BLACKMAGIC_LIBRARY_DIR} ) + list(APPEND REQUIRED_LIBRARIES ${BLACKMAGIC_LIBRARY_DIR}) ENDIF (BLACKMAGIC_FOUND) IF (WIN32) # Required for exception handling on Windows - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} "imagehlp" "dbghelp" ) + list(APPEND REQUIRED_LIBRARIES "imagehlp" "dbghelp" ) ENDIF(WIN32) # Link all referenced libraries @@ -400,7 +333,7 @@ add_subdirectory(bindings) set(LIB_INSTALL_DIR lib${LIB_SUFFIX}) # determine correct lib folder # Install primary library -INSTALL( TARGETS openshot +INSTALL(TARGETS openshot ARCHIVE DESTINATION ${LIB_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR} RUNTIME DESTINATION ${LIB_INSTALL_DIR} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5e18fcf3..afe780f9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -81,34 +81,13 @@ ENDIF (ImageMagick_FOUND) # Find FFmpeg libraries (used for video encoding / decoding) FIND_PACKAGE(FFmpeg REQUIRED) -# Include FFmpeg headers (needed for compile) -IF (AVCODEC_FOUND) - include_directories(${AVCODEC_INCLUDE_DIRS}) -ENDIF (AVCODEC_FOUND) -IF (AVDEVICE_FOUND) - include_directories(${AVDEVICE_INCLUDE_DIRS}) -ENDIF (AVDEVICE_FOUND) -IF (AVFORMAT_FOUND) - include_directories(${AVFORMAT_INCLUDE_DIRS}) -ENDIF (AVFORMAT_FOUND) -IF (AVFILTER_FOUND) - include_directories(${AVFILTER_INCLUDE_DIRS}) -ENDIF (AVFILTER_FOUND) -IF (AVUTIL_FOUND) - include_directories(${AVUTIL_INCLUDE_DIRS}) -ENDIF (AVUTIL_FOUND) -IF (POSTPROC_FOUND) - include_directories(${POSTPROC_INCLUDE_DIRS}) -ENDIF (POSTPROC_FOUND) -IF (SWSCALE_FOUND) - include_directories(${SWSCALE_INCLUDE_DIRS}) -ENDIF (SWSCALE_FOUND) -IF (SWRESAMPLE_FOUND) - include_directories(${SWRESAMPLE_INCLUDE_DIRS}) -ENDIF (SWRESAMPLE_FOUND) -IF (AVRESAMPLE_FOUND) - include_directories(${AVRESAMPLE_INCLUDE_DIRS}) -ENDIF (AVRESAMPLE_FOUND) +foreach(ffmpeg_comp AVCODEC AVDEVICE AVFORMAT AVFILTER AVUTIL POSTPROC SWSCALE SWRESAMPLE AVRESAMPLE) + if(${ffmpeg_comp}_FOUND) + # Include FFmpeg headers (needed for compile) + include_directories(${${ffmpeg_comp}_INCLUDE_DIRS}) + add_definitions(${${ffmpeg_comp}_DEFINITIONS}) + endif() +endforeach() ################# LIBOPENSHOT-AUDIO ################### # Find JUCE-based openshot Audio libraries @@ -119,38 +98,15 @@ include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}) ################# QT5 ################### # Find QT5 libraries -find_package(Qt5Widgets REQUIRED) -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Multimedia REQUIRED) -find_package(Qt5MultimediaWidgets REQUIRED) - -# Include Qt headers (needed for compile) -include_directories(${Qt5Widgets_INCLUDE_DIRS}) -include_directories(${Qt5Core_INCLUDE_DIRS}) -include_directories(${Qt5Gui_INCLUDE_DIRS}) -include_directories(${Qt5Multimedia_INCLUDE_DIRS}) -include_directories(${Qt5MultimediaWidgets_INCLUDE_DIRS}) - -add_definitions(${Qt5Widgets_DEFINITIONS}) -add_definitions(${Qt5Core_DEFINITIONS}) -add_definitions(${Qt5Gui_DEFINITIONS}) -add_definitions(${Qt5Multimedia_DEFINITIONS}) -add_definitions(${Qt5MultimediaWidgets_DEFINITIONS}) - -SET(QT_LIBRARIES ${Qt5Widgets_LIBRARIES} - ${Qt5Core_LIBRARIES} - ${Qt5Gui_LIBRARIES} - ${Qt5Multimedia_LIBRARIES} - ${Qt5MultimediaWidgets_LIBRARIES}) - -# Set compiler flags for Qt -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Multimedia_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5MultimediaWidgets_EXECUTABLE_COMPILE_FLAGS} ") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -ggdb ") +foreach(qt_lib Qt5Widgets Qt5Core Qt5Gui Qt5Multimedia Qt5MultimediaWidgets) + find_package(${qt_lib} REQUIRED) + # Header files + include_directories(${${qt_lib}_INCLUDE_DIRS}) + # Compiler definitions + add_definitions(${${qt_lib}_DEFINITIONS}) + # Other CFLAGS + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${qt_lib}_EXECUTABLE_COMPILE_FLAGS}") +endforeach() # Manually moc Qt files qt5_wrap_cpp(MOC_FILES ${QT_HEADER_FILES}) From 0658134df0040fbb7d5f5972c0fd2c44224e3b3c Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 25 Sep 2019 01:07:38 -0400 Subject: [PATCH 25/33] CMake: Add FeatureSummary --- src/CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aeab95e5..23d1192e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,6 +27,12 @@ # Pick up our include directories from the parent context include_directories(${OPENSHOT_INCLUDE_DIRS}) +####### Display summary of options/dependencies ###### +include(FeatureSummary) +#set_property(GLOBAL APPEND PROPERTY FeatureSummary_PKG_TYPES BUILD) +#find_package(FOO) +#set_package_properties(FOO PROPERTIES TYPE BUILD) + ################ OPTIONS ################## # Optional build settings for libopenshot OPTION(USE_SYSTEM_JSONCPP "Use system installed JsonCpp" OFF) @@ -328,6 +334,12 @@ ENDIF (BLACKMAGIC_FOUND) ############### INCLUDE SWIG BINDINGS ################ add_subdirectory(bindings) +########### PRINT FEATURE SUMMARY ############## +feature_summary(WHAT ALL + INCLUDE_QUIET_PACKAGES + DESCRIPTION "Build configuration:" + VAR featuresText) +message("\n${featuresText}") ############### INSTALL HEADERS & LIBRARY ################ set(LIB_INSTALL_DIR lib${LIB_SUFFIX}) # determine correct lib folder From 986f567ebf6c5a0e7b9024fc07c159c4d0354c8f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 25 Sep 2019 01:22:53 -0400 Subject: [PATCH 26/33] CMake: Eliminate duplicate include dirs --- src/CMakeLists.txt | 5 +++-- tests/CMakeLists.txt | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 23d1192e..040e45b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -90,12 +90,13 @@ FIND_PACKAGE(FFmpeg REQUIRED) foreach(ffmpeg_comp AVCODEC AVDEVICE AVFORMAT AVFILTER AVUTIL POSTPROC SWSCALE SWRESAMPLE AVRESAMPLE) if(${ffmpeg_comp}_FOUND) - # message(STATUS "Adding include dir for ${ffmpeg_comp}") - include_directories(${${ffmpeg_comp}_INCLUDE_DIRS}) + list(APPEND FF_INCLUDES ${${ffmpeg_comp}_INCLUDE_DIRS}) add_definitions(${${ffmpeg_comp}_DEFINITIONS}) list(APPEND FF_LIBRARIES ${${ffmpeg_comp}_LIBRARIES}) endif() endforeach() +list(REMOVE_DUPLICATES FF_INCLUDES) +include_directories(${FF_INCLUDES}) ################# LIBOPENSHOT-AUDIO ################### # Find JUCE-based openshot Audio libraries diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index afe780f9..5fb55bce 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -84,10 +84,12 @@ FIND_PACKAGE(FFmpeg REQUIRED) foreach(ffmpeg_comp AVCODEC AVDEVICE AVFORMAT AVFILTER AVUTIL POSTPROC SWSCALE SWRESAMPLE AVRESAMPLE) if(${ffmpeg_comp}_FOUND) # Include FFmpeg headers (needed for compile) - include_directories(${${ffmpeg_comp}_INCLUDE_DIRS}) + list(APPEND FF_INCLUDES ${${ffmpeg_comp}_INCLUDE_DIRS}) add_definitions(${${ffmpeg_comp}_DEFINITIONS}) endif() endforeach() +list(REMOVE_DUPLICATES FF_INCLUDES) +include_directories(${FF_INCLUDES}) ################# LIBOPENSHOT-AUDIO ################### # Find JUCE-based openshot Audio libraries @@ -101,12 +103,14 @@ include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}) foreach(qt_lib Qt5Widgets Qt5Core Qt5Gui Qt5Multimedia Qt5MultimediaWidgets) find_package(${qt_lib} REQUIRED) # Header files - include_directories(${${qt_lib}_INCLUDE_DIRS}) + list(APPEND QT_INCLUDES ${${qt_lib}_INCLUDE_DIRS}) # Compiler definitions add_definitions(${${qt_lib}_DEFINITIONS}) # Other CFLAGS set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${qt_lib}_EXECUTABLE_COMPILE_FLAGS}") endforeach() +list(REMOVE_DUPLICATES QT_INCLUDES) +include_directories(${QT_INCLUDES}) # Manually moc Qt files qt5_wrap_cpp(MOC_FILES ${QT_HEADER_FILES}) From ee4666f15bdbd149149589db01d1d88835eabf40 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 25 Sep 2019 05:53:00 -0400 Subject: [PATCH 27/33] Fix indentation --- src/CMakeLists.txt | 34 +++++++++++++++++----------------- tests/CMakeLists.txt | 24 ++++++++++++------------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 040e45b7..4045b7d0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -89,11 +89,11 @@ ENDIF (ImageMagick_FOUND) FIND_PACKAGE(FFmpeg REQUIRED) foreach(ffmpeg_comp AVCODEC AVDEVICE AVFORMAT AVFILTER AVUTIL POSTPROC SWSCALE SWRESAMPLE AVRESAMPLE) - if(${ffmpeg_comp}_FOUND) - list(APPEND FF_INCLUDES ${${ffmpeg_comp}_INCLUDE_DIRS}) - add_definitions(${${ffmpeg_comp}_DEFINITIONS}) - list(APPEND FF_LIBRARIES ${${ffmpeg_comp}_LIBRARIES}) - endif() + if(${ffmpeg_comp}_FOUND) + list(APPEND FF_INCLUDES ${${ffmpeg_comp}_INCLUDE_DIRS}) + add_definitions(${${ffmpeg_comp}_DEFINITIONS}) + list(APPEND FF_LIBRARIES ${${ffmpeg_comp}_LIBRARIES}) + endif() endforeach() list(REMOVE_DUPLICATES FF_INCLUDES) include_directories(${FF_INCLUDES}) @@ -108,15 +108,15 @@ include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}) ################# QT5 ################### # Find QT5 libraries foreach(qt_lib Qt5Widgets Qt5Core Qt5Gui Qt5Multimedia Qt5MultimediaWidgets) - find_package(${qt_lib} REQUIRED) - # Header files - include_directories(${${qt_lib}_INCLUDE_DIRS}) - # Compiler definitions - add_definitions(${${qt_lib}_DEFINITIONS}) - # Other CFLAGS - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${qt_lib}_EXECUTABLE_COMPILE_FLAGS}") - # For use when linking - list(APPEND QT_LIBRARIES ${${qt_lib}_LIBRARIES}) + find_package(${qt_lib} REQUIRED) + # Header files + include_directories(${${qt_lib}_INCLUDE_DIRS}) + # Compiler definitions + add_definitions(${${qt_lib}_DEFINITIONS}) + # Other CFLAGS + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${qt_lib}_EXECUTABLE_COMPILE_FLAGS}") + # For use when linking + list(APPEND QT_LIBRARIES ${${qt_lib}_LIBRARIES}) endforeach() # Manually moc Qt files @@ -337,9 +337,9 @@ add_subdirectory(bindings) ########### PRINT FEATURE SUMMARY ############## feature_summary(WHAT ALL - INCLUDE_QUIET_PACKAGES - DESCRIPTION "Build configuration:" - VAR featuresText) + INCLUDE_QUIET_PACKAGES + DESCRIPTION "Build configuration:" + VAR featuresText) message("\n${featuresText}") ############### INSTALL HEADERS & LIBRARY ################ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5fb55bce..ab44fa31 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -82,11 +82,11 @@ ENDIF (ImageMagick_FOUND) FIND_PACKAGE(FFmpeg REQUIRED) foreach(ffmpeg_comp AVCODEC AVDEVICE AVFORMAT AVFILTER AVUTIL POSTPROC SWSCALE SWRESAMPLE AVRESAMPLE) - if(${ffmpeg_comp}_FOUND) - # Include FFmpeg headers (needed for compile) - list(APPEND FF_INCLUDES ${${ffmpeg_comp}_INCLUDE_DIRS}) - add_definitions(${${ffmpeg_comp}_DEFINITIONS}) - endif() + if(${ffmpeg_comp}_FOUND) + # Include FFmpeg headers (needed for compile) + list(APPEND FF_INCLUDES ${${ffmpeg_comp}_INCLUDE_DIRS}) + add_definitions(${${ffmpeg_comp}_DEFINITIONS}) + endif() endforeach() list(REMOVE_DUPLICATES FF_INCLUDES) include_directories(${FF_INCLUDES}) @@ -101,13 +101,13 @@ include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}) ################# QT5 ################### # Find QT5 libraries foreach(qt_lib Qt5Widgets Qt5Core Qt5Gui Qt5Multimedia Qt5MultimediaWidgets) - find_package(${qt_lib} REQUIRED) - # Header files - list(APPEND QT_INCLUDES ${${qt_lib}_INCLUDE_DIRS}) - # Compiler definitions - add_definitions(${${qt_lib}_DEFINITIONS}) - # Other CFLAGS - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${qt_lib}_EXECUTABLE_COMPILE_FLAGS}") + find_package(${qt_lib} REQUIRED) + # Header files + list(APPEND QT_INCLUDES ${${qt_lib}_INCLUDE_DIRS}) + # Compiler definitions + add_definitions(${${qt_lib}_DEFINITIONS}) + # Other CFLAGS + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${qt_lib}_EXECUTABLE_COMPILE_FLAGS}") endforeach() list(REMOVE_DUPLICATES QT_INCLUDES) include_directories(${QT_INCLUDES}) From 1af92afc596842e7202047e31f438e2d0b32733f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 28 Sep 2019 21:43:59 -0400 Subject: [PATCH 28/33] SWIG: Use compactdefaultargs in bindings --- src/bindings/python/openshot.i | 7 +++++-- src/bindings/ruby/openshot.i | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/bindings/python/openshot.i b/src/bindings/python/openshot.i index 512224ef..732a1313 100644 --- a/src/bindings/python/openshot.i +++ b/src/bindings/python/openshot.i @@ -6,8 +6,8 @@ # # Copyright (c) 2008-2019 OpenShot Studios, LLC # . This file is part of -# OpenShot Library (libopenshot), an open-source project dedicated to -# delivering high quality video editing and animation solutions to the +# OpenShot Library (libopenshot), an open-source project dedicated to +# delivering high quality video editing and animation solutions to the # world. For more information visit . # # OpenShot Library (libopenshot) is free software: you can redistribute it @@ -30,6 +30,9 @@ /* Suppress warnings about ignored operator= */ %warnfilter(362); +/* Don't generate multiple wrappers for functions with default args */ +%feature("compactdefaultargs", "1"); + /* Enable inline documentation */ %feature("autodoc", "1"); diff --git a/src/bindings/ruby/openshot.i b/src/bindings/ruby/openshot.i index 1f3e0d99..872bbd55 100644 --- a/src/bindings/ruby/openshot.i +++ b/src/bindings/ruby/openshot.i @@ -6,8 +6,8 @@ # # Copyright (c) 2008-2019 OpenShot Studios, LLC # . This file is part of -# OpenShot Library (libopenshot), an open-source project dedicated to -# delivering high quality video editing and animation solutions to the +# OpenShot Library (libopenshot), an open-source project dedicated to +# delivering high quality video editing and animation solutions to the # world. For more information visit . # # OpenShot Library (libopenshot) is free software: you can redistribute it @@ -30,6 +30,9 @@ /* Suppress warnings about ignored operator= */ %warnfilter(362); +/* Don't generate multiple wrappers for functions with default args */ +%feature("compactdefaultargs", "1"); + /* Enable inline documentation */ %feature("autodoc", "1"); From 1435267b62ef8109b22f9ed9ee4221c1b499b8cb Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 1 Oct 2019 23:27:36 -0400 Subject: [PATCH 29/33] Add lock to CreateFrame (patch by laochen, #272) --- src/FFmpegReader.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c9e21271..6e8553f1 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -2002,7 +2002,15 @@ AudioLocation FFmpegReader::GetAudioPTSLocation(int64_t pts) { std::shared_ptr FFmpegReader::CreateFrame(int64_t requested_frame) { // Check working cache std::shared_ptr output = working_cache.GetFrame(requested_frame); + if (!output) { + // Lock + const GenericScopedLock lock(processingCriticalSection); + + // (re-)Check working cache + output = working_cache.GetFrame(requested_frame); + if(output) return output; + // Create a new frame on the working cache output = std::make_shared(requested_frame, info.width, info.height, "#000000", Frame::GetSamplesPerFrame(requested_frame, info.fps, info.sample_rate, info.channels), info.channels); output->SetPixelRatio(info.pixel_ratio.num, info.pixel_ratio.den); // update pixel ratio @@ -2015,8 +2023,7 @@ std::shared_ptr FFmpegReader::CreateFrame(int64_t requested_frame) { if (requested_frame > largest_frame_processed) largest_frame_processed = requested_frame; } - - // Return new frame + // Return frame return output; } From e070d047962a60f4a836ea96a278d8192489045d Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 2 Oct 2019 00:18:47 -0400 Subject: [PATCH 30/33] FFmpegReader::CheckMissingFrame std::map tweaks --- src/FFmpegReader.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c9e21271..98688cea 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -2042,18 +2042,11 @@ bool FFmpegReader::CheckMissingFrame(int64_t requested_frame) { // Lock const GenericScopedLock lock(processingCriticalSection); - // Init # of times this frame has been checked so far - int checked_count = 0; - // Increment check count for this frame (or init to 1) - if (checked_frames.count(requested_frame) == 0) - checked_frames[requested_frame] = 1; - else - checked_frames[requested_frame]++; - checked_count = checked_frames[requested_frame]; + ++checked_frames[requested_frame]; // Debug output - ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::CheckMissingFrame", "requested_frame", requested_frame, "has_missing_frames", has_missing_frames, "missing_video_frames.size()", missing_video_frames.size(), "checked_count", checked_count); + ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::CheckMissingFrame", "requested_frame", requested_frame, "has_missing_frames", has_missing_frames, "missing_video_frames.size()", missing_video_frames.size(), "checked_count", checked_frames[requested_frame]); // Missing frames (sometimes frame #'s are skipped due to invalid or missing timestamps) map::iterator itr; @@ -2066,7 +2059,7 @@ bool FFmpegReader::CheckMissingFrame(int64_t requested_frame) { // If MP3 with single video frame, handle this special case by copying the previously // decoded image to the new frame. Otherwise, it will spend a huge amount of // CPU time looking for missing images for all the audio-only frames. - if (checked_count > 8 && !missing_video_frames.count(requested_frame) && + if (checked_frames[requested_frame] > 8 && !missing_video_frames.count(requested_frame) && !processing_audio_frames.count(requested_frame) && processed_audio_frames.count(requested_frame) && last_frame && last_video_frame->has_image_data && aCodecId == AV_CODEC_ID_MP3 && (vCodecId == AV_CODEC_ID_MJPEGB || vCodecId == AV_CODEC_ID_MJPEG)) { missing_video_frames.insert(pair(requested_frame, last_video_frame->number)); @@ -2080,10 +2073,7 @@ bool FFmpegReader::CheckMissingFrame(int64_t requested_frame) { int64_t missing_source_frame = missing_video_frames.find(requested_frame)->second; // Increment missing source frame check count (or init to 1) - if (checked_frames.count(missing_source_frame) == 0) - checked_frames[missing_source_frame] = 1; - else - checked_frames[missing_source_frame]++; + ++checked_frames[missing_source_frame]; // Get the previous frame of this missing frame (if it's available in missing cache) std::shared_ptr parent_frame = missing_frames.GetFrame(missing_source_frame); From 39de350f1c68513dd2976e13d32f8a2133c018f0 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 2 Oct 2019 04:44:13 -0400 Subject: [PATCH 31/33] tests: Add tolerance to pixel value checks --- tests/FFmpegReader_Tests.cpp | 16 +++++------ tests/FFmpegWriter_Tests.cpp | 8 +++--- tests/ImageWriter_Tests.cpp | 8 +++--- tests/Timeline_Tests.cpp | 56 ++++++++++++++++++------------------ 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/tests/FFmpegReader_Tests.cpp b/tests/FFmpegReader_Tests.cpp index 68aba4bb..4b808d83 100644 --- a/tests/FFmpegReader_Tests.cpp +++ b/tests/FFmpegReader_Tests.cpp @@ -97,10 +97,10 @@ TEST(FFmpegReader_Check_Video_File) int pixel_index = 112 * 4; // pixel 112 (4 bytes per pixel) // Check image properties on scanline 10, pixel 112 - CHECK_EQUAL(21, (int)pixels[pixel_index]); - CHECK_EQUAL(191, (int)pixels[pixel_index + 1]); - CHECK_EQUAL(0, (int)pixels[pixel_index + 2]); - CHECK_EQUAL(255, (int)pixels[pixel_index + 3]); + CHECK_CLOSE(21, (int)pixels[pixel_index], 5); + CHECK_CLOSE(191, (int)pixels[pixel_index + 1], 5); + CHECK_CLOSE(0, (int)pixels[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)pixels[pixel_index + 3], 5); // Check pixel function CHECK_EQUAL(true, f->CheckPixel(10, 112, 21, 191, 0, 255, 5)); @@ -114,10 +114,10 @@ TEST(FFmpegReader_Check_Video_File) pixel_index = 112 * 4; // pixel 112 (4 bytes per pixel) // Check image properties on scanline 10, pixel 112 - CHECK_EQUAL(0, (int)pixels[pixel_index]); - CHECK_EQUAL(96, (int)pixels[pixel_index + 1]); - CHECK_EQUAL(188, (int)pixels[pixel_index + 2]); - CHECK_EQUAL(255, (int)pixels[pixel_index + 3]); + CHECK_CLOSE(0, (int)pixels[pixel_index], 5); + CHECK_CLOSE(96, (int)pixels[pixel_index + 1], 5); + CHECK_CLOSE(188, (int)pixels[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)pixels[pixel_index + 3], 5); // Check pixel function CHECK_EQUAL(true, f->CheckPixel(10, 112, 0, 96, 188, 255, 5)); diff --git a/tests/FFmpegWriter_Tests.cpp b/tests/FFmpegWriter_Tests.cpp index 8cb10e15..1cab8043 100644 --- a/tests/FFmpegWriter_Tests.cpp +++ b/tests/FFmpegWriter_Tests.cpp @@ -75,8 +75,8 @@ TEST(FFmpegWriter_Test_Webm) int pixel_index = 112 * 4; // pixel 112 (4 bytes per pixel) // Check image properties on scanline 10, pixel 112 - CHECK_EQUAL(23, (int)pixels[pixel_index]); - CHECK_EQUAL(23, (int)pixels[pixel_index + 1]); - CHECK_EQUAL(23, (int)pixels[pixel_index + 2]); - CHECK_EQUAL(255, (int)pixels[pixel_index + 3]); + CHECK_CLOSE(23, (int)pixels[pixel_index], 5); + CHECK_CLOSE(23, (int)pixels[pixel_index + 1], 5); + CHECK_CLOSE(23, (int)pixels[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)pixels[pixel_index + 3], 5); } diff --git a/tests/ImageWriter_Tests.cpp b/tests/ImageWriter_Tests.cpp index 4236b462..49202e96 100644 --- a/tests/ImageWriter_Tests.cpp +++ b/tests/ImageWriter_Tests.cpp @@ -75,9 +75,9 @@ TEST(ImageWriter_Test_Gif) int pixel_index = 230 * 4; // pixel 230 (4 bytes per pixel) // Check image properties - CHECK_EQUAL(20, (int)pixels[pixel_index]); - CHECK_EQUAL(18, (int)pixels[pixel_index + 1]); - CHECK_EQUAL(11, (int)pixels[pixel_index + 2]); - CHECK_EQUAL(255, (int)pixels[pixel_index + 3]); + CHECK_CLOSE(20, (int)pixels[pixel_index], 5); + CHECK_CLOSE(18, (int)pixels[pixel_index + 1], 5); + CHECK_CLOSE(11, (int)pixels[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)pixels[pixel_index + 3], 5); } #endif diff --git a/tests/Timeline_Tests.cpp b/tests/Timeline_Tests.cpp index 0bb42b89..77a3bcbc 100644 --- a/tests/Timeline_Tests.cpp +++ b/tests/Timeline_Tests.cpp @@ -121,64 +121,64 @@ TEST(Timeline_Check_Two_Track_Video) int pixel_index = 230 * 4; // pixel 230 (4 bytes per pixel) // Check image properties - CHECK_EQUAL(21, (int)f->GetPixels(pixel_row)[pixel_index]); - CHECK_EQUAL(191, (int)f->GetPixels(pixel_row)[pixel_index + 1]); - CHECK_EQUAL(0, (int)f->GetPixels(pixel_row)[pixel_index + 2]); - CHECK_EQUAL(255, (int)f->GetPixels(pixel_row)[pixel_index + 3]); + CHECK_CLOSE(21, (int)f->GetPixels(pixel_row)[pixel_index], 5); + CHECK_CLOSE(191, (int)f->GetPixels(pixel_row)[pixel_index + 1], 5); + CHECK_CLOSE(0, (int)f->GetPixels(pixel_row)[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)f->GetPixels(pixel_row)[pixel_index + 3], 5); // Get frame f = t.GetFrame(2); // Check image properties - CHECK_EQUAL(176, (int)f->GetPixels(pixel_row)[pixel_index]); - CHECK_EQUAL(0, (int)f->GetPixels(pixel_row)[pixel_index + 1]); - CHECK_EQUAL(186, (int)f->GetPixels(pixel_row)[pixel_index + 2]); - CHECK_EQUAL(255, (int)f->GetPixels(pixel_row)[pixel_index + 3]); + CHECK_CLOSE(176, (int)f->GetPixels(pixel_row)[pixel_index], 5); + CHECK_CLOSE(0, (int)f->GetPixels(pixel_row)[pixel_index + 1], 5); + CHECK_CLOSE(186, (int)f->GetPixels(pixel_row)[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)f->GetPixels(pixel_row)[pixel_index + 3], 5); // Get frame f = t.GetFrame(3); // Check image properties - CHECK_EQUAL(23, (int)f->GetPixels(pixel_row)[pixel_index]); - CHECK_EQUAL(190, (int)f->GetPixels(pixel_row)[pixel_index + 1]); - CHECK_EQUAL(0, (int)f->GetPixels(pixel_row)[pixel_index + 2]); - CHECK_EQUAL(255, (int)f->GetPixels(pixel_row)[pixel_index + 3]); + CHECK_CLOSE(23, (int)f->GetPixels(pixel_row)[pixel_index], 5); + CHECK_CLOSE(190, (int)f->GetPixels(pixel_row)[pixel_index + 1], 5); + CHECK_CLOSE(0, (int)f->GetPixels(pixel_row)[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)f->GetPixels(pixel_row)[pixel_index + 3], 5); // Get frame f = t.GetFrame(24); // Check image properties - CHECK_EQUAL(186, (int)f->GetPixels(pixel_row)[pixel_index]); - CHECK_EQUAL(106, (int)f->GetPixels(pixel_row)[pixel_index + 1]); - CHECK_EQUAL(0, (int)f->GetPixels(pixel_row)[pixel_index + 2]); - CHECK_EQUAL(255, (int)f->GetPixels(pixel_row)[pixel_index + 3]); + CHECK_CLOSE(186, (int)f->GetPixels(pixel_row)[pixel_index], 5); + CHECK_CLOSE(106, (int)f->GetPixels(pixel_row)[pixel_index + 1], 5); + CHECK_CLOSE(0, (int)f->GetPixels(pixel_row)[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)f->GetPixels(pixel_row)[pixel_index + 3], 5); // Get frame f = t.GetFrame(5); // Check image properties - CHECK_EQUAL(23, (int)f->GetPixels(pixel_row)[pixel_index]); - CHECK_EQUAL(190, (int)f->GetPixels(pixel_row)[pixel_index + 1]); - CHECK_EQUAL(0, (int)f->GetPixels(pixel_row)[pixel_index + 2]); - CHECK_EQUAL(255, (int)f->GetPixels(pixel_row)[pixel_index + 3]); + CHECK_CLOSE(23, (int)f->GetPixels(pixel_row)[pixel_index], 5); + CHECK_CLOSE(190, (int)f->GetPixels(pixel_row)[pixel_index + 1], 5); + CHECK_CLOSE(0, (int)f->GetPixels(pixel_row)[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)f->GetPixels(pixel_row)[pixel_index + 3], 5); // Get frame f = t.GetFrame(25); // Check image properties - CHECK_EQUAL(0, (int)f->GetPixels(pixel_row)[pixel_index]); - CHECK_EQUAL(94, (int)f->GetPixels(pixel_row)[pixel_index + 1]); - CHECK_EQUAL(186, (int)f->GetPixels(pixel_row)[pixel_index + 2]); - CHECK_EQUAL(255, (int)f->GetPixels(pixel_row)[pixel_index + 3]); + CHECK_CLOSE(0, (int)f->GetPixels(pixel_row)[pixel_index], 5); + CHECK_CLOSE(94, (int)f->GetPixels(pixel_row)[pixel_index + 1], 5); + CHECK_CLOSE(186, (int)f->GetPixels(pixel_row)[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)f->GetPixels(pixel_row)[pixel_index + 3], 5); // Get frame f = t.GetFrame(4); // Check image properties - CHECK_EQUAL(176, (int)f->GetPixels(pixel_row)[pixel_index]); - CHECK_EQUAL(0, (int)f->GetPixels(pixel_row)[pixel_index + 1]); - CHECK_EQUAL(186, (int)f->GetPixels(pixel_row)[pixel_index + 2]); - CHECK_EQUAL(255, (int)f->GetPixels(pixel_row)[pixel_index + 3]); + CHECK_CLOSE(176, (int)f->GetPixels(pixel_row)[pixel_index], 5); + CHECK_CLOSE(0, (int)f->GetPixels(pixel_row)[pixel_index + 1], 5); + CHECK_CLOSE(186, (int)f->GetPixels(pixel_row)[pixel_index + 2], 5); + CHECK_CLOSE(255, (int)f->GetPixels(pixel_row)[pixel_index + 3], 5); // Close reader t.Close(); From 43efabf102e85c03245c05b1692aa14a184f7e3d Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 7 Oct 2019 13:34:02 -0400 Subject: [PATCH 32/33] Qt/Video*Thread: ZMQ argument stragglers --- src/Qt/VideoCacheThread.cpp | 2 +- src/Qt/VideoPlaybackThread.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Qt/VideoCacheThread.cpp b/src/Qt/VideoCacheThread.cpp index fbe784f7..46b6f030 100644 --- a/src/Qt/VideoCacheThread.cpp +++ b/src/Qt/VideoCacheThread.cpp @@ -93,7 +93,7 @@ namespace openshot try { if (reader) { - ZmqLogger::Instance()->AppendDebugMethod("VideoCacheThread::run (cache frame)", "position", position, "current_display_frame", current_display_frame, "max_frames", max_frames, "needed_frames", (position - current_display_frame), "", -1, "", -1); + ZmqLogger::Instance()->AppendDebugMethod("VideoCacheThread::run (cache frame)", "position", position, "current_display_frame", current_display_frame, "max_frames", max_frames, "needed_frames", (position - current_display_frame)); // Force the frame to be generated reader->GetFrame(position); diff --git a/src/Qt/VideoPlaybackThread.cpp b/src/Qt/VideoPlaybackThread.cpp index 730a1d37..f1cff756 100644 --- a/src/Qt/VideoPlaybackThread.cpp +++ b/src/Qt/VideoPlaybackThread.cpp @@ -64,7 +64,7 @@ namespace openshot if (need_render && frame) { // Debug - ZmqLogger::Instance()->AppendDebugMethod("VideoPlaybackThread::run (before render)", "frame->number", frame->number, "need_render", need_render, "", -1, "", -1, "", -1, "", -1); + ZmqLogger::Instance()->AppendDebugMethod("VideoPlaybackThread::run (before render)", "frame->number", frame->number, "need_render", need_render); // Render the frame to the screen renderer->paint(frame); From 582a76a8a768d2d288cf172259248d62016465f4 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 8 Oct 2019 16:30:10 -0400 Subject: [PATCH 33/33] CMake: REQUIRE OpenMP, use (or create) targets OpenMP is now REQUIRED as the build will fail if it's not available. This PR updates the `find_package`, and creates the necessary targets for older CMake versions (3.9+ will do it automatically). The targets are then made PUBLIC dependencies of the openshot target, which causes the OpenMP configs to automatically propagate. The redundant OpenMP detection is removed from test/CMakeLists.txt. The detection code comes verbatim from this post, which also credits Modern CMake: https://iscinumpy.gitlab.io/post/omp-on-high-sierra/ --- src/CMakeLists.txt | 38 +++++++++++++++++++++++--------------- tests/CMakeLists.txt | 7 ------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 869dcfc6..9a015dd0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,8 +6,8 @@ # # Copyright (c) 2008-2019 OpenShot Studios, LLC # . This file is part of -# OpenShot Library (libopenshot), an open-source project dedicated to -# delivering high quality video editing and animation solutions to the +# OpenShot Library (libopenshot), an open-source project dedicated to +# delivering high quality video editing and animation solutions to the # world. For more information visit . # # OpenShot Library (libopenshot) is free software: you can redistribute it @@ -171,14 +171,6 @@ IF (ENABLE_BLACKMAGIC) ENDIF (BLACKMAGIC_FOUND) ENDIF (ENABLE_BLACKMAGIC) -################### OPENMP ##################### -# Check for OpenMP (used for multi-core processing) -FIND_PACKAGE(OpenMP) - -if (OPENMP_FOUND) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} ") -endif(OPENMP_FOUND) - ################### ZEROMQ ##################### # Find ZeroMQ library (used for socket communication & logging) FIND_PACKAGE(ZMQ REQUIRED) @@ -306,6 +298,24 @@ set_target_properties(openshot INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" ) +################### OPENMP ##################### +# Check for OpenMP (used for multi-core processing) + +# OpenMP is required by FFmpegReader/Writer +find_package(OpenMP REQUIRED) + +if(NOT TARGET OpenMP::OpenMP_CXX) + # Older CMake versions (< 3.9) don't create find targets. + add_library(OpenMP_TARGET INTERFACE) + add_library(OpenMP::OpenMP_CXX ALIAS OpenMP_TARGET) + target_compile_options(OpenMP_TARGET INTERFACE ${OpenMP_CXX_FLAGS}) + find_package(Threads REQUIRED) + target_link_libraries(OpenMP_TARGET INTERFACE Threads::Threads) + target_link_libraries(OpenMP_TARGET INTERFACE ${OpenMP_CXX_FLAGS}) +endif() + +target_link_libraries(openshot PUBLIC OpenMP::OpenMP_CXX) + ############### LINK LIBRARY ################# SET ( REQUIRED_LIBRARIES ${LIBOPENSHOT_AUDIO_LIBRARIES} @@ -347,10 +357,6 @@ IF (RESVG_FOUND) SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${RESVG_LIBRARIES} ) ENDIF(RESVG_FOUND) -IF (OPENMP_FOUND) - SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${OpenMP_CXX_FLAGS} ) -ENDIF (OPENMP_FOUND) - IF (ImageMagick_FOUND) SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${ImageMagick_LIBRARIES} ) ENDIF (ImageMagick_FOUND) @@ -365,8 +371,10 @@ IF (WIN32) ENDIF(WIN32) # Link all referenced libraries -target_link_libraries(openshot ${REQUIRED_LIBRARIES}) +target_link_libraries(openshot PUBLIC ${REQUIRED_LIBRARIES}) +# Pick up parameters from OpenMP target and propagate +target_link_libraries(openshot PUBLIC OpenMP::OpenMP_CXX) ############### CLI EXECUTABLE ################ # Create test executable diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index caefffb0..b515587e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -167,13 +167,6 @@ IF (ENABLE_BLACKMAGIC) ENDIF (BLACKMAGIC_FOUND) ENDIF (ENABLE_BLACKMAGIC) -################### OPENMP ##################### -# Check for OpenMP (used for multi-core processing) -FIND_PACKAGE(OpenMP) - -if (OPENMP_FOUND) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} ") -endif(OPENMP_FOUND) ################### ZEROMQ ##################### # Find ZeroMQ library (used for socket communication & logging)