From b851508c9f3d53f667f55f4611de0ce41b44e7fd Mon Sep 17 00:00:00 2001 From: jediserg Date: Tue, 25 Jun 2019 03:41:28 -0700 Subject: [PATCH 01/50] --add QtTextWriter (it's based on TextReader and use Qt instead image magick) --- include/QtTextReader.h | 147 +++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/QtTextReader.cpp | 262 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 410 insertions(+) create mode 100644 include/QtTextReader.h create mode 100644 src/QtTextReader.cpp diff --git a/include/QtTextReader.h b/include/QtTextReader.h new file mode 100644 index 00000000..60023a87 --- /dev/null +++ b/include/QtTextReader.h @@ -0,0 +1,147 @@ +/** + * @file + * @brief Header file for QtTextReader class + * @author Jonathan Thomas + * + * @section LICENSE + * + * Copyright (c) 2008-2014 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 . + */ + +#ifndef OPENSHOT_QT_TEXT_READER_H +#define OPENSHOT_QT_TEXT_READER_H + +#include "ReaderBase.h" + +#include +#include +#include +#include +#include +#include +#include "CacheMemory.h" +#include "Enums.h" +#include "Exceptions.h" + +using namespace std; + +class QImage; + +namespace openshot +{ + + /** + * @brief This class uses the ImageMagick++ libraries, to create frames with "Text", and return + * openshot::Frame objects. + * + * All system fonts are supported, including many different font properties, such as size, color, + * alignment, padding, etc... + * + * @code + * // Create a reader to generate an openshot::Frame containing text + * QtTextReader r(720, // width + * 480, // height + * 5, // x_offset + * 5, // y_offset + * GRAVITY_CENTER, // gravity + * "Check out this Text!", // text + * "Arial", // font + * 15.0, // size + * "#fff000", // text_color + * "#000000" // background_color + * ); + * r.Open(); // Open the reader + * + * // Get frame number 1 from the video (in fact, any frame # you request will return the same frame) + * std::shared_ptr f = r.GetFrame(1); + * + * // Now that we have an openshot::Frame object, lets have some fun! + * f->Display(); // Display the frame on the screen + * + * // Close the reader + * r.Close(); + * @endcode + */ + class QtTextReader : public ReaderBase + { + private: + int width; + int height; + int x_offset; + int y_offset; + string text; + string font; + double size; + string text_color; + string background_color; + std::shared_ptr image; + bool is_open; + GravityType gravity; + + public: + + /// Default constructor (blank text) + QtTextReader(); + + /// @brief Constructor for QtTextReader with all parameters. + /// @param width The width of the requested openshot::Frame (not the size of the text) + /// @param height The height of the requested openshot::Frame (not the size of the text) + /// @param x_offset The number of pixels to offset the text on the X axis (horizontal) + /// @param y_offset The number of pixels to offset the text on the Y axis (vertical) + /// @param gravity The alignment / gravity of the text + /// @param text The text you want to generate / display + /// @param font The font of the text + /// @param size The size of the text + /// @param text_color The color of the text + /// @param background_color The background color of the text (also supports Transparent) + QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string text, string font, double size, string text_color, string background_color); + + /// Close Reader + void Close(); + + /// Get the cache object used by this reader (always returns NULL for this object) + CacheMemory* GetCache() { return NULL; }; + + /// Get an openshot::Frame object for a specific frame number of this reader. All numbers + /// return the same Frame, since they all share the same image data. + /// + /// @returns The requested frame (containing the image) + /// @param requested_frame The frame number that is requested. + std::shared_ptr GetFrame(int64_t requested_frame); + + /// Determine if reader is open or closed + bool IsOpen() { return is_open; }; + + /// Return the type name of the class + string Name() { return "QtTextReader"; }; + + /// Get and Set JSON methods + string Json(); ///< Generate JSON string of this object + void SetJson(string value); ///< Load JSON string into this object + Json::Value JsonValue(); ///< Generate Json::JsonValue for this object + void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object + + /// Open Reader - which is called by the constructor automatically + void Open(); + }; + +} + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0c4ff990..7df1b69b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -215,6 +215,7 @@ SET ( OPENSHOT_SOURCE_FILES QtImageReader.cpp QtPlayer.cpp Timeline.cpp + QtTextReader.cpp # Qt Video Player ${QT_PLAYER_FILES} diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp new file mode 100644 index 00000000..c2c4c087 --- /dev/null +++ b/src/QtTextReader.cpp @@ -0,0 +1,262 @@ +/** + * @file + * @brief Source file for QtTextReader class + * @author Jonathan Thomas + * + * @section LICENSE + * + * Copyright (c) 2008-2014 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 "../include/QtTextReader.h" +#include +#include + +using namespace openshot; + +/// Default constructor (blank text) +QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font("Arial"), size(10.0), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) { + + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + Open(); + Close(); +} + +QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string text, string font, double size, string text_color, string background_color) +: width(width), height(height), x_offset(x_offset), y_offset(y_offset), text(text), font(font), size(size), text_color(text_color), background_color(background_color), is_open(false), gravity(gravity) +{ + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + Open(); + Close(); +} + +// Open reader +void QtTextReader::Open() +{ + // Open reader if not already open + if (!is_open) + { + // create image + image = std::shared_ptr(new QImage(width, height, QImage::Format_RGBA8888)); + image->fill(QColor(background_color.c_str())); + //start painting + QPainter painter; + if(!painter.begin(image.get())) + return; + + //set background + painter.setBackground(QBrush(background_color.c_str())); + + //set font color + painter.setPen(QPen(text_color.c_str())); + + //set font + painter.setFont(QFont(font.c_str(), size)); + + // Set gravity (map between OpenShot and Qt) + int align_flag = 0; + switch (gravity) + { + case GRAVITY_TOP_LEFT: + align_flag = Qt::AlignLeft | Qt::AlignTop; + break; + case GRAVITY_TOP: + align_flag = Qt::AlignTop; + break; + case GRAVITY_TOP_RIGHT: + align_flag = Qt::AlignRight | Qt::AlignTop; + break; + case GRAVITY_LEFT: + align_flag = Qt::AlignLeft; + break; + case GRAVITY_CENTER: + align_flag = Qt::AlignCenter; + break; + case GRAVITY_RIGHT: + align_flag = Qt::AlignRight; + break; + case GRAVITY_BOTTOM_LEFT: + align_flag = Qt::AlignLeft | Qt::AlignBottom; + break; + case GRAVITY_BOTTOM: + align_flag = Qt::AlignBottom; + break; + case GRAVITY_BOTTOM_RIGHT: + align_flag = Qt::AlignRight | Qt::AlignBottom; + break; + } + + //draw text + painter.drawText(x_offset, y_offset, width, height, align_flag, text.c_str()); + + //end painting + painter.end(); + + // Update image properties + info.has_audio = false; + info.has_video = true; + info.file_size = 0; + info.vcodec = "Constant image uniform color"; + info.width = width; + info.height = height; + info.pixel_ratio.num = 1; + info.pixel_ratio.den = 1; + info.duration = 60 * 60 * 24; // 24 hour duration + info.fps.num = 30; + info.fps.den = 1; + info.video_timebase.num = 1; + info.video_timebase.den = 30; + info.video_length = round(info.duration * info.fps.ToDouble()); + + // Calculate the DAR (display aspect ratio) + Fraction size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den); + + // Reduce size fraction + size.Reduce(); + + // Set the ratio based on the reduced fraction + info.display_ratio.num = size.num; + info.display_ratio.den = size.den; + + // Mark as "open" + is_open = true; + } +} + +// Close reader +void QtTextReader::Close() +{ + // Close all objects, if reader is 'open' + if (is_open) + { + // Mark as "closed" + is_open = false; + } +} + +// Get an openshot::Frame object for a specific frame number of this reader. +std::shared_ptr QtTextReader::GetFrame(int64_t requested_frame) +{ + if (image) + { + // Create or get frame object + std::shared_ptr image_frame(new Frame(requested_frame, image->size().width(), image->size().height(), background_color, 0, 2)); + + // Add Image data to frame + image_frame->AddImage(image); + + // return frame object + return image_frame; + } else { + // return empty frame + std::shared_ptr image_frame(new Frame(1, 640, 480, background_color, 0, 2)); + + // return frame object + return image_frame; + } + +} + +// Generate JSON string of this object +string QtTextReader::Json() { + + // Return formatted string + return JsonValue().toStyledString(); +} + +// Generate Json::JsonValue for this object +Json::Value QtTextReader::JsonValue() { + + // Create root json object + Json::Value root = ReaderBase::JsonValue(); // get parent properties + root["type"] = "QtTextReader"; + root["width"] = width; + root["height"] = height; + root["x_offset"] = x_offset; + root["y_offset"] = y_offset; + root["text"] = text; + root["font"] = font; + root["size"] = size; + root["text_color"] = text_color; + root["background_color"] = background_color; + root["gravity"] = gravity; + + // return JsonValue + return root; +} + +// Load JSON string into this object +void QtTextReader::SetJson(string value) { + + // Parse JSON string into JSON objects + Json::Value root; + Json::Reader reader; + bool success = reader.parse( value, root ); + if (!success) + // Raise exception + throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + + try + { + // Set all values that match + SetJsonValue(root); + } + catch (exception e) + { + // Error parsing JSON (or missing keys) + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + } +} + +// Load Json::JsonValue into this object +void QtTextReader::SetJsonValue(Json::Value root) { + + // Set parent data + ReaderBase::SetJsonValue(root); + + // Set data from Json (if key is found) + if (!root["width"].isNull()) + width = root["width"].asInt(); + if (!root["height"].isNull()) + height = root["height"].asInt(); + if (!root["x_offset"].isNull()) + x_offset = root["x_offset"].asInt(); + if (!root["y_offset"].isNull()) + y_offset = root["y_offset"].asInt(); + if (!root["text"].isNull()) + text = root["text"].asString(); + if (!root["font"].isNull()) + font = root["font"].asString(); + if (!root["size"].isNull()) + size = root["size"].asDouble(); + if (!root["text_color"].isNull()) + text_color = root["text_color"].asString(); + if (!root["background_color"].isNull()) + background_color = root["background_color"].asString(); + if (!root["gravity"].isNull()) + gravity = (GravityType) root["gravity"].asInt(); + + // Re-Open path, and re-init everything (if needed) + if (is_open) + { + Close(); + Open(); + } +} From ac9ea27cce83375241650733fbb61494047937ea Mon Sep 17 00:00:00 2001 From: jediserg Date: Sat, 6 Jul 2019 14:50:50 -0700 Subject: [PATCH 02/50] --add QtHtmlReader --- include/OpenShot.h | 2 + include/QtHtmlReader.h | 143 ++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/QtHtmlReader.cpp | 227 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 373 insertions(+) create mode 100644 include/QtHtmlReader.h create mode 100644 src/QtHtmlReader.cpp diff --git a/include/OpenShot.h b/include/OpenShot.h index e4b60f3e..1fdc0652 100644 --- a/include/OpenShot.h +++ b/include/OpenShot.h @@ -128,6 +128,8 @@ #include "ImageWriter.h" #include "TextReader.h" #endif +#include "QtTextReader.h" +#include "QtHtmlReader.h" #include "KeyFrame.h" #include "PlayerBase.h" #include "Point.h" diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h new file mode 100644 index 00000000..88b55ad7 --- /dev/null +++ b/include/QtHtmlReader.h @@ -0,0 +1,143 @@ +/** + * @file + * @brief Header file for QtHtmlReader class + * @author Jonathan Thomas + * + * @section LICENSE + * + * Copyright (c) 2008-2014 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 . + */ + +#ifndef OPENSHOT_QT_TEXT_READER_H +#define OPENSHOT_QT_TEXT_READER_H + +#include "ReaderBase.h" + +#include +#include +#include +#include +#include +#include +#include "CacheMemory.h" +#include "Enums.h" +#include "Exceptions.h" + +using namespace std; + +class QImage; + +namespace openshot +{ + + /** + * @brief This class uses the ImageMagick++ libraries, to create frames with "Text", and return + * openshot::Frame objects. + * + * All system fonts are supported, including many different font properties, such as size, color, + * alignment, padding, etc... + * + * @code + * // Create a reader to generate an openshot::Frame containing text + * QtHtmlReader r(720, // width + * 480, // height + * 5, // x_offset + * 5, // y_offset + * GRAVITY_CENTER, // gravity + * "Check out this Text!", // text + * "Arial", // font + * 15.0, // size + * "#fff000", // text_color + * "#000000" // background_color + * ); + * r.Open(); // Open the reader + * + * // Get frame number 1 from the video (in fact, any frame # you request will return the same frame) + * std::shared_ptr f = r.GetFrame(1); + * + * // Now that we have an openshot::Frame object, lets have some fun! + * f->Display(); // Display the frame on the screen + * + * // Close the reader + * r.Close(); + * @endcode + */ + class QtHtmlReader : public ReaderBase + { + private: + int width; + int height; + int x_offset; + int y_offset; + string html; + string background_color; + std::shared_ptr image; + bool is_open; + GravityType gravity; + public: + + /// Default constructor (blank text) + QtHtmlReader(); + + /// @brief Constructor for QtHtmlReader with all parameters. + /// @param width The width of the requested openshot::Frame (not the size of the text) + /// @param height The height of the requested openshot::Frame (not the size of the text) + /// @param x_offset The number of pixels to offset the text on the X axis (horizontal) + /// @param y_offset The number of pixels to offset the text on the Y axis (vertical) + /// @param gravity The alignment / gravity of the text + /// @param text The text you want to generate / display + /// @param font The font of the text + /// @param size The size of the text + /// @param text_color The color of the text + /// @param background_color The background color of the text (also supports Transparent) + QtHtmlReader(int width, int height, int x_offset, int y_offset, string html, string background_color); + + /// Close Reader + void Close(); + + /// Get the cache object used by this reader (always returns NULL for this object) + CacheMemory* GetCache() { return NULL; }; + + /// Get an openshot::Frame object for a specific frame number of this reader. All numbers + /// return the same Frame, since they all share the same image data. + /// + /// @returns The requested frame (containing the image) + /// @param requested_frame The frame number that is requested. + std::shared_ptr GetFrame(int64_t requested_frame); + + /// Determine if reader is open or closed + bool IsOpen() { return is_open; }; + + /// Return the type name of the class + string Name() { return "QtHtmlReader"; }; + + /// Get and Set JSON methods + string Json(); ///< Generate JSON string of this object + void SetJson(string value); ///< Load JSON string into this object + Json::Value JsonValue(); ///< Generate Json::JsonValue for this object + void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object + + /// Open Reader - which is called by the constructor automatically + void Open(); + }; + +} + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7df1b69b..bbad89ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -216,6 +216,7 @@ SET ( OPENSHOT_SOURCE_FILES QtPlayer.cpp Timeline.cpp QtTextReader.cpp + QtHtmlReader.cpp # Qt Video Player ${QT_PLAYER_FILES} diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp new file mode 100644 index 00000000..20de0466 --- /dev/null +++ b/src/QtHtmlReader.cpp @@ -0,0 +1,227 @@ +/** + * @file + * @brief Source file for QtHtmlReader class + * @author Jonathan Thomas + * + * @section LICENSE + * + * Copyright (c) 2008-2014 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 "../include/QtHtmlReader.h" +#include +#include +#include +#include + +using namespace openshot; + +/// Default constructor (blank text) +QtHtmlReader::QtHtmlReader() : width(1024), height(768), x_offset(0), y_offset(0), html(""), background_color("#000000"), is_open(false) { + + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + Open(); + Close(); +} + +QtHtmlReader::QtHtmlReader(int width, int height, int x_offset, int y_offset, string html, string background_color) +: width(width), height(height), x_offset(x_offset), y_offset(y_offset), html(html), background_color(background_color), is_open(false) +{ + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + Open(); + Close(); +} + +// Open reader +void QtHtmlReader::Open() +{ + // Open reader if not already open + if (!is_open) + { + /*bool hasGuiApp = (qobject_cast(QCoreApplication::instance())!=0) || (qobject_cast(QCoreApplication::instance())!=0); + if(!hasGuiApp){ + static char appname[] = {"appname"}; + static char* argv[1] = {appname}; + + static int argc = 1; + static QGuiApplication app(argc, argv); + }*/ + // create image + image = std::shared_ptr(new QImage(width, height, QImage::Format_RGBA8888)); + image->fill(QColor(background_color.c_str())); + //start painting + QPainter painter; + if(!painter.begin(image.get())) + return; + + //set background + painter.setBackground(QBrush(background_color.c_str())); + + //draw text + QTextDocument text_document; + text_document.setPageSize(QSizeF(width, height)); + text_document.setHtml(html.c_str()); + painter.translate(x_offset, y_offset); + text_document.drawContents(&painter); + + //end painting + painter.end(); + + // Update image properties + info.has_audio = false; + info.has_video = true; + info.file_size = 0; + info.vcodec = "Constant image uniform color"; + info.width = width; + info.height = height; + info.pixel_ratio.num = 1; + info.pixel_ratio.den = 1; + info.duration = 60 * 60 * 24; // 24 hour duration + info.fps.num = 30; + info.fps.den = 1; + info.video_timebase.num = 1; + info.video_timebase.den = 30; + info.video_length = round(info.duration * info.fps.ToDouble()); + + // Calculate the DAR (display aspect ratio) + Fraction size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den); + + // Reduce size fraction + size.Reduce(); + + // Set the ratio based on the reduced fraction + info.display_ratio.num = size.num; + info.display_ratio.den = size.den; + + // Mark as "open" + is_open = true; + } +} + +// Close reader +void QtHtmlReader::Close() +{ + // Close all objects, if reader is 'open' + if (is_open) + { + // Mark as "closed" + is_open = false; + } +} + +// Get an openshot::Frame object for a specific frame number of this reader. +std::shared_ptr QtHtmlReader::GetFrame(int64_t requested_frame) +{ + if (image) + { + // Create or get frame object + std::shared_ptr image_frame(new Frame(requested_frame, image->size().width(), image->size().height(), background_color, 0, 2)); + + // Add Image data to frame + image_frame->AddImage(image); + + // return frame object + return image_frame; + } else { + // return empty frame + std::shared_ptr image_frame(new Frame(1, 640, 480, background_color, 0, 2)); + + // return frame object + return image_frame; + } + +} + +// Generate JSON string of this object +string QtHtmlReader::Json() { + + // Return formatted string + return JsonValue().toStyledString(); +} + +// Generate Json::JsonValue for this object +Json::Value QtHtmlReader::JsonValue() { + + // Create root json object + Json::Value root = ReaderBase::JsonValue(); // get parent properties + root["type"] = "QtHtmlReader"; + root["width"] = width; + root["height"] = height; + root["x_offset"] = x_offset; + root["y_offset"] = y_offset; + root["html"] = html; + root["background_color"] = background_color; + + // return JsonValue + return root; +} + +// Load JSON string into this object +void QtHtmlReader::SetJson(string value) { + + // Parse JSON string into JSON objects + Json::Value root; + Json::Reader reader; + bool success = reader.parse( value, root ); + if (!success) + // Raise exception + throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + + try + { + // Set all values that match + SetJsonValue(root); + } + catch (exception e) + { + // Error parsing JSON (or missing keys) + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + } +} + +// Load Json::JsonValue into this object +void QtHtmlReader::SetJsonValue(Json::Value root) { + + // Set parent data + ReaderBase::SetJsonValue(root); + + // Set data from Json (if key is found) + if (!root["width"].isNull()) + width = root["width"].asInt(); + if (!root["height"].isNull()) + height = root["height"].asInt(); + if (!root["x_offset"].isNull()) + x_offset = root["x_offset"].asInt(); + if (!root["y_offset"].isNull()) + y_offset = root["y_offset"].asInt(); + if (!root["html"].isNull()) + html = root["html"].asString(); + + if (!root["background_color"].isNull()) + background_color = root["background_color"].asString(); + + + // Re-Open path, and re-init everything (if needed) + if (is_open) + { + Close(); + Open(); + } +} From bf4323f3544b10df9c474e530b393cb1ffb525e2 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Fri, 12 Jul 2019 15:14:38 +1000 Subject: [PATCH 03/50] Fixed missing include and Qt gravity --- include/OpenShot.h | 1 + src/QtTextReader.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/OpenShot.h b/include/OpenShot.h index fb53164c..fb4f4673 100644 --- a/include/OpenShot.h +++ b/include/OpenShot.h @@ -136,6 +136,7 @@ #include "Point.h" #include "Profiles.h" #include "QtImageReader.h" +#include "QtTextReader.h" #include "Timeline.h" #include "Settings.h" diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index c2c4c087..0089874a 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -78,25 +78,25 @@ void QtTextReader::Open() align_flag = Qt::AlignLeft | Qt::AlignTop; break; case GRAVITY_TOP: - align_flag = Qt::AlignTop; + align_flag = Qt::AlignHCenter | Qt::AlignTop; break; case GRAVITY_TOP_RIGHT: align_flag = Qt::AlignRight | Qt::AlignTop; break; case GRAVITY_LEFT: - align_flag = Qt::AlignLeft; + align_flag = Qt::AlignVCenter | Qt::AlignLeft; break; case GRAVITY_CENTER: align_flag = Qt::AlignCenter; break; case GRAVITY_RIGHT: - align_flag = Qt::AlignRight; + align_flag = Qt::AlignVCenter | Qt::AlignRight; break; case GRAVITY_BOTTOM_LEFT: align_flag = Qt::AlignLeft | Qt::AlignBottom; break; case GRAVITY_BOTTOM: - align_flag = Qt::AlignBottom; + align_flag = Qt::AlignHCenter | Qt::AlignBottom; break; case GRAVITY_BOTTOM_RIGHT: align_flag = Qt::AlignRight | Qt::AlignBottom; From 40521c9d722314f902c54d0d8e588bdc27b36606 Mon Sep 17 00:00:00 2001 From: Sergei Kolesov Date: Mon, 22 Jul 2019 05:52:24 -0700 Subject: [PATCH 04/50] --add gravity to QtHtmlReader --- include/QtHtmlReader.h | 7 ++----- src/QtHtmlReader.cpp | 32 ++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h index 88b55ad7..cdf494ce 100644 --- a/include/QtHtmlReader.h +++ b/include/QtHtmlReader.h @@ -102,12 +102,9 @@ namespace openshot /// @param x_offset The number of pixels to offset the text on the X axis (horizontal) /// @param y_offset The number of pixels to offset the text on the Y axis (vertical) /// @param gravity The alignment / gravity of the text - /// @param text The text you want to generate / display - /// @param font The font of the text - /// @param size The size of the text - /// @param text_color The color of the text + /// @param html The text you want to generate / display /// @param background_color The background color of the text (also supports Transparent) - QtHtmlReader(int width, int height, int x_offset, int y_offset, string html, string background_color); + QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string html, string background_color); /// Close Reader void Close(); diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 20de0466..3100e987 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -34,15 +34,15 @@ using namespace openshot; /// Default constructor (blank text) -QtHtmlReader::QtHtmlReader() : width(1024), height(768), x_offset(0), y_offset(0), html(""), background_color("#000000"), is_open(false) { +QtHtmlReader::QtHtmlReader() : width(1024), height(768), x_offset(0), y_offset(0), html(""), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER){ // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); Close(); } -QtHtmlReader::QtHtmlReader(int width, int height, int x_offset, int y_offset, string html, string background_color) -: width(width), height(height), x_offset(x_offset), y_offset(y_offset), html(html), background_color(background_color), is_open(false) +QtHtmlReader::QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string html, string background_color) +: width(width), height(height), x_offset(x_offset), y_offset(y_offset), gravity(gravity), html(html), background_color(background_color), is_open(false) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); @@ -76,11 +76,26 @@ void QtHtmlReader::Open() //draw text QTextDocument text_document; - text_document.setPageSize(QSizeF(width, height)); + text_document.setTextWidth(width); text_document.setHtml(html.c_str()); - painter.translate(x_offset, y_offset); - text_document.drawContents(&painter); + + int td_height = text_document.documentLayout()->documentSize().height(); + + if(gravity == GRAVITY_TOP_LEFT || gravity == GRAVITY_TOP || gravity == GRAVITY_TOP_RIGHT) + painter.translate(x_offset, y_offset); + else if(gravity == GRAVITY_LEFT || gravity == GRAVITY_CENTER || gravity == GRAVITY_RIGHT) + painter.translate(x_offset, (height - td_height) / 2 + y_offset); + else if(gravity == GRAVITY_BOTTOM_LEFT || gravity == GRAVITY_BOTTOM_RIGHT || gravity == GRAVITY_BOTTOM) + painter.translate(x_offset, height - td_height + y_offset); + + if(gravity == GRAVITY_TOP_LEFT || gravity == GRAVITY_LEFT || gravity == GRAVITY_BOTTOM_LEFT) + text_document.setDefaultTextOption(QTextOption(Qt::AlignLeft)); + else if(gravity == GRAVITY_CENTER || gravity == GRAVITY_TOP || gravity == GRAVITY_BOTTOM) + text_document.setDefaultTextOption(QTextOption(Qt::AlignHCenter)); + else if(gravity == GRAVITY_TOP_RIGHT || gravity == GRAVITY_RIGHT|| gravity == GRAVITY_BOTTOM_RIGHT) + text_document.setDefaultTextOption(QTextOption(Qt::AlignRight)); + text_document.drawContents(&painter); //end painting painter.end(); @@ -168,6 +183,7 @@ Json::Value QtHtmlReader::JsonValue() { root["y_offset"] = y_offset; root["html"] = html; root["background_color"] = background_color; + root["gravity"] = gravity; // return JsonValue return root; @@ -216,6 +232,10 @@ void QtHtmlReader::SetJsonValue(Json::Value root) { if (!root["background_color"].isNull()) background_color = root["background_color"].asString(); + + if (!root["gravity"].isNull()) + gravity = (GravityType) root["gravity"].asInt(); + // Re-Open path, and re-init everything (if needed) From e9ba82dd5b6bc15fd667f02d42a73f17d69dcbd8 Mon Sep 17 00:00:00 2001 From: jediserg Date: Sat, 27 Jul 2019 18:13:45 -0700 Subject: [PATCH 05/50] --add missing include and header guard macro --- include/QtHtmlReader.h | 4 ++-- src/QtHtmlReader.cpp | 9 +-------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h index cdf494ce..b3e169b9 100644 --- a/include/QtHtmlReader.h +++ b/include/QtHtmlReader.h @@ -25,8 +25,8 @@ * along with OpenShot Library. If not, see . */ -#ifndef OPENSHOT_QT_TEXT_READER_H -#define OPENSHOT_QT_TEXT_READER_H +#ifndef OPENSHOT_QT_HTML_READER_H +#define OPENSHOT_QT_HTML_READER_H #include "ReaderBase.h" diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 3100e987..e5b01cf9 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -30,6 +30,7 @@ #include #include #include +#include using namespace openshot; @@ -55,14 +56,6 @@ void QtHtmlReader::Open() // Open reader if not already open if (!is_open) { - /*bool hasGuiApp = (qobject_cast(QCoreApplication::instance())!=0) || (qobject_cast(QCoreApplication::instance())!=0); - if(!hasGuiApp){ - static char appname[] = {"appname"}; - static char* argv[1] = {appname}; - - static int argc = 1; - static QGuiApplication app(argc, argv); - }*/ // create image image = std::shared_ptr(new QImage(width, height, QImage::Format_RGBA8888)); image->fill(QColor(background_color.c_str())); From 160df3ac40e9098942e1d2b9c7b0bd6757f4be05 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 2 Aug 2019 07:14:11 -0400 Subject: [PATCH 06/50] Python install path: remove site-packages detection The path `${CMAKE_INSTALL_PREFIX}/lib/pythonM.N/site-packages` is not Debian-specific, and will exist on too many systems where it should _not_ be assumed to be the correct install path. (This is causing Fedora and other `lib64`-using distros to install the bindings into `/usr/lib/`, when they were previously being installed into the correct `/usr/lib64/` location.) --- src/bindings/python/CMakeLists.txt | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index 9afabd41..80281d7e 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -72,26 +72,21 @@ if (PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) ${PYTHON_LIBRARIES} openshot) ### Check if the following Debian-friendly python module path exists - SET(PYTHON_MODULE_PATH "${CMAKE_INSTALL_PREFIX}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages") + SET(PYTHON_MODULE_PATH "${CMAKE_INSTALL_PREFIX}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/dist-packages") if (NOT EXISTS ${PYTHON_MODULE_PATH}) - ### Check if another Debian-friendly python module path exists - SET(PYTHON_MODULE_PATH "${CMAKE_INSTALL_PREFIX}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/dist-packages") - if (NOT EXISTS ${PYTHON_MODULE_PATH}) - - ### Calculate the python module path (using distutils) - execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "\ + ### Calculate the python module path (using distutils) + execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "\ from distutils.sysconfig import get_python_lib; \ print( get_python_lib( plat_specific=True, prefix='${CMAKE_INSTALL_PREFIX}' ) )" - OUTPUT_VARIABLE _ABS_PYTHON_MODULE_PATH - OUTPUT_STRIP_TRAILING_WHITESPACE ) + OUTPUT_VARIABLE _ABS_PYTHON_MODULE_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE ) - GET_FILENAME_COMPONENT(_ABS_PYTHON_MODULE_PATH - "${_ABS_PYTHON_MODULE_PATH}" ABSOLUTE) - FILE(RELATIVE_PATH _REL_PYTHON_MODULE_PATH - ${CMAKE_INSTALL_PREFIX} ${_ABS_PYTHON_MODULE_PATH}) - SET(PYTHON_MODULE_PATH ${_ABS_PYTHON_MODULE_PATH}) - endif() + GET_FILENAME_COMPONENT(_ABS_PYTHON_MODULE_PATH + "${_ABS_PYTHON_MODULE_PATH}" ABSOLUTE) + FILE(RELATIVE_PATH _REL_PYTHON_MODULE_PATH + ${CMAKE_INSTALL_PREFIX} ${_ABS_PYTHON_MODULE_PATH}) + SET(PYTHON_MODULE_PATH ${_ABS_PYTHON_MODULE_PATH}) endif() message("PYTHON_MODULE_PATH: ${PYTHON_MODULE_PATH}") From dbd80926b2437b37c04d2ea4f7c74843310d26fd Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Sun, 11 Aug 2019 22:06:34 +1000 Subject: [PATCH 07/50] General tidy up and code quality, consistency update --- include/QtHtmlReader.h | 14 +++++--------- include/QtTextReader.h | 4 ++-- src/QtHtmlReader.cpp | 29 ++++++++++++++++------------- src/QtTextReader.cpp | 24 ++++++++++++------------ 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h index b3e169b9..ef61e362 100644 --- a/include/QtHtmlReader.h +++ b/include/QtHtmlReader.h @@ -5,7 +5,7 @@ * * @section LICENSE * - * Copyright (c) 2008-2014 OpenShot Studios, LLC + * 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 @@ -48,11 +48,10 @@ namespace openshot { /** - * @brief This class uses the ImageMagick++ libraries, to create frames with "Text", and return + * @brief This class uses Qt libraries, to create frames with rendered HTML, and return * openshot::Frame objects. * - * All system fonts are supported, including many different font properties, such as size, color, - * alignment, padding, etc... + * Supports HTML/CSS subset available via Qt libraries, see: https://doc.qt.io/qt-5/richtext-html-subset.html * * @code * // Create a reader to generate an openshot::Frame containing text @@ -61,10 +60,7 @@ namespace openshot * 5, // x_offset * 5, // y_offset * GRAVITY_CENTER, // gravity - * "Check out this Text!", // text - * "Arial", // font - * 15.0, // size - * "#fff000", // text_color + * "Check out this Text!", // html * "#000000" // background_color * ); * r.Open(); // Open the reader @@ -102,7 +98,7 @@ namespace openshot /// @param x_offset The number of pixels to offset the text on the X axis (horizontal) /// @param y_offset The number of pixels to offset the text on the Y axis (vertical) /// @param gravity The alignment / gravity of the text - /// @param html The text you want to generate / display + /// @param html The html you want to render / display /// @param background_color The background color of the text (also supports Transparent) QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string html, string background_color); diff --git a/include/QtTextReader.h b/include/QtTextReader.h index 60023a87..10886cbf 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -5,7 +5,7 @@ * * @section LICENSE * - * Copyright (c) 2008-2014 OpenShot Studios, LLC + * 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 @@ -48,7 +48,7 @@ namespace openshot { /** - * @brief This class uses the ImageMagick++ libraries, to create frames with "Text", and return + * @brief This class uses Qt libraries, to create frames with "Text", and return * openshot::Frame objects. * * All system fonts are supported, including many different font properties, such as size, color, diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index e5b01cf9..49fed776 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -5,7 +5,7 @@ * * @section LICENSE * - * Copyright (c) 2008-2014 OpenShot Studios, LLC + * 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 @@ -35,8 +35,8 @@ using namespace openshot; /// Default constructor (blank text) -QtHtmlReader::QtHtmlReader() : width(1024), height(768), x_offset(0), y_offset(0), html(""), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER){ - +QtHtmlReader::QtHtmlReader() : width(1024), height(768), x_offset(0), y_offset(0), html(""), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) +{ // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); Close(); @@ -59,10 +59,12 @@ void QtHtmlReader::Open() // create image image = std::shared_ptr(new QImage(width, height, QImage::Format_RGBA8888)); image->fill(QColor(background_color.c_str())); + //start painting QPainter painter; - if(!painter.begin(image.get())) + if (!painter.begin(image.get())) { return; + } //set background painter.setBackground(QBrush(background_color.c_str())); @@ -74,22 +76,25 @@ void QtHtmlReader::Open() int td_height = text_document.documentLayout()->documentSize().height(); - if(gravity == GRAVITY_TOP_LEFT || gravity == GRAVITY_TOP || gravity == GRAVITY_TOP_RIGHT) + if (gravity == GRAVITY_TOP_LEFT || gravity == GRAVITY_TOP || gravity == GRAVITY_TOP_RIGHT) { painter.translate(x_offset, y_offset); - else if(gravity == GRAVITY_LEFT || gravity == GRAVITY_CENTER || gravity == GRAVITY_RIGHT) + } else if (gravity == GRAVITY_LEFT || gravity == GRAVITY_CENTER || gravity == GRAVITY_RIGHT) { painter.translate(x_offset, (height - td_height) / 2 + y_offset); - else if(gravity == GRAVITY_BOTTOM_LEFT || gravity == GRAVITY_BOTTOM_RIGHT || gravity == GRAVITY_BOTTOM) + } else if (gravity == GRAVITY_BOTTOM_LEFT || gravity == GRAVITY_BOTTOM_RIGHT || gravity == GRAVITY_BOTTOM) { painter.translate(x_offset, height - td_height + y_offset); + } - if(gravity == GRAVITY_TOP_LEFT || gravity == GRAVITY_LEFT || gravity == GRAVITY_BOTTOM_LEFT) + if (gravity == GRAVITY_TOP_LEFT || gravity == GRAVITY_LEFT || gravity == GRAVITY_BOTTOM_LEFT) { text_document.setDefaultTextOption(QTextOption(Qt::AlignLeft)); - else if(gravity == GRAVITY_CENTER || gravity == GRAVITY_TOP || gravity == GRAVITY_BOTTOM) + } else if (gravity == GRAVITY_CENTER || gravity == GRAVITY_TOP || gravity == GRAVITY_BOTTOM) { text_document.setDefaultTextOption(QTextOption(Qt::AlignHCenter)); - else if(gravity == GRAVITY_TOP_RIGHT || gravity == GRAVITY_RIGHT|| gravity == GRAVITY_BOTTOM_RIGHT) + } else if (gravity == GRAVITY_TOP_RIGHT || gravity == GRAVITY_RIGHT|| gravity == GRAVITY_BOTTOM_RIGHT) { text_document.setDefaultTextOption(QTextOption(Qt::AlignRight)); + } + // Draw image text_document.drawContents(&painter); - //end painting + painter.end(); // Update image properties @@ -229,8 +234,6 @@ void QtHtmlReader::SetJsonValue(Json::Value root) { if (!root["gravity"].isNull()) gravity = (GravityType) root["gravity"].asInt(); - - // Re-Open path, and re-init everything (if needed) if (is_open) { diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index 0089874a..d078b496 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -5,7 +5,7 @@ * * @section LICENSE * - * Copyright (c) 2008-2014 OpenShot Studios, LLC + * 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 @@ -32,8 +32,8 @@ using namespace openshot; /// Default constructor (blank text) -QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font("Arial"), size(10.0), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) { - +QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font("Arial"), size(10.0), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) +{ // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); Close(); @@ -56,18 +56,19 @@ void QtTextReader::Open() // create image image = std::shared_ptr(new QImage(width, height, QImage::Format_RGBA8888)); image->fill(QColor(background_color.c_str())); - //start painting - QPainter painter; - if(!painter.begin(image.get())) - return; - //set background + QPainter painter; + if (!painter.begin(image.get())) { + return; + } + + // set background painter.setBackground(QBrush(background_color.c_str())); - //set font color + // set font color painter.setPen(QPen(text_color.c_str())); - //set font + // set font painter.setFont(QFont(font.c_str(), size)); // Set gravity (map between OpenShot and Qt) @@ -103,10 +104,9 @@ void QtTextReader::Open() break; } - //draw text + // Draw image painter.drawText(x_offset, y_offset, width, height, align_flag, text.c_str()); - //end painting painter.end(); // Update image properties From 3681121d81d625e1267708c51152f86cc6d530a0 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Sun, 11 Aug 2019 22:54:49 +1000 Subject: [PATCH 08/50] Remove std namespace usage --- include/QtHtmlReader.h | 20 +++++++++----------- include/QtTextReader.h | 22 ++++++++++------------ src/QtHtmlReader.cpp | 14 +++++++++----- src/QtTextReader.cpp | 14 +++++++++----- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h index ef61e362..491164cb 100644 --- a/include/QtHtmlReader.h +++ b/include/QtHtmlReader.h @@ -40,8 +40,6 @@ #include "Enums.h" #include "Exceptions.h" -using namespace std; - class QImage; namespace openshot @@ -82,11 +80,11 @@ namespace openshot int height; int x_offset; int y_offset; - string html; - string background_color; + std::string html; + std::string background_color; std::shared_ptr image; bool is_open; - GravityType gravity; + openshot::GravityType gravity; public: /// Default constructor (blank text) @@ -100,30 +98,30 @@ namespace openshot /// @param gravity The alignment / gravity of the text /// @param html The html you want to render / display /// @param background_color The background color of the text (also supports Transparent) - QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string html, string background_color); + QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string html, std::string background_color); /// Close Reader void Close(); /// Get the cache object used by this reader (always returns NULL for this object) - CacheMemory* GetCache() { return NULL; }; + openshot::CacheMemory* GetCache() { return NULL; }; /// Get an openshot::Frame object for a specific frame number of this reader. All numbers /// return the same Frame, since they all share the same image data. /// /// @returns The requested frame (containing the image) /// @param requested_frame The frame number that is requested. - std::shared_ptr GetFrame(int64_t requested_frame); + std::shared_ptr GetFrame(int64_t requested_frame); /// Determine if reader is open or closed bool IsOpen() { return is_open; }; /// Return the type name of the class - string Name() { return "QtHtmlReader"; }; + std::string Name() { return "QtHtmlReader"; }; /// Get and Set JSON methods - string Json(); ///< Generate JSON string of this object - void SetJson(string value); ///< Load JSON string into this object + std::string Json(); ///< Generate JSON string of this object + void SetJson(std::string value); ///< Load JSON string into this object Json::Value JsonValue(); ///< Generate Json::JsonValue for this object void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object diff --git a/include/QtTextReader.h b/include/QtTextReader.h index 10886cbf..3884113e 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -40,8 +40,6 @@ #include "Enums.h" #include "Exceptions.h" -using namespace std; - class QImage; namespace openshot @@ -86,14 +84,14 @@ namespace openshot int height; int x_offset; int y_offset; - string text; - string font; + std::string text; + std::string font; double size; - string text_color; - string background_color; + std::string text_color; + std::string background_color; std::shared_ptr image; bool is_open; - GravityType gravity; + openshot::GravityType gravity; public: @@ -111,29 +109,29 @@ namespace openshot /// @param size The size of the text /// @param text_color The color of the text /// @param background_color The background color of the text (also supports Transparent) - QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string text, string font, double size, string text_color, string background_color); + QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double size, std::string text_color, std::string background_color); /// Close Reader void Close(); /// Get the cache object used by this reader (always returns NULL for this object) - CacheMemory* GetCache() { return NULL; }; + openshot::CacheMemory* GetCache() { return NULL; }; /// Get an openshot::Frame object for a specific frame number of this reader. All numbers /// return the same Frame, since they all share the same image data. /// /// @returns The requested frame (containing the image) /// @param requested_frame The frame number that is requested. - std::shared_ptr GetFrame(int64_t requested_frame); + std::shared_ptr GetFrame(int64_t requested_frame); /// Determine if reader is open or closed bool IsOpen() { return is_open; }; /// Return the type name of the class - string Name() { return "QtTextReader"; }; + std::string Name() { return "QtTextReader"; }; /// Get and Set JSON methods - string Json(); ///< Generate JSON string of this object + std::string Json(); ///< Generate JSON string of this object void SetJson(string value); ///< Load JSON string into this object Json::Value JsonValue(); ///< Generate Json::JsonValue for this object void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 49fed776..04dcfe66 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -42,7 +42,7 @@ QtHtmlReader::QtHtmlReader() : width(1024), height(768), x_offset(0), y_offset(0 Close(); } -QtHtmlReader::QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string html, string background_color) +QtHtmlReader::QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string html, std::string background_color) : width(width), height(height), x_offset(x_offset), y_offset(y_offset), gravity(gravity), html(html), background_color(background_color), is_open(false) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) @@ -163,7 +163,7 @@ std::shared_ptr QtHtmlReader::GetFrame(int64_t requested_frame) } // Generate JSON string of this object -string QtHtmlReader::Json() { +std::string QtHtmlReader::Json() { // Return formatted string return JsonValue().toStyledString(); @@ -188,12 +188,16 @@ Json::Value QtHtmlReader::JsonValue() { } // Load JSON string into this object -void QtHtmlReader::SetJson(string value) { +void QtHtmlReader::SetJson(std::string value) { // Parse JSON string into JSON objects Json::Value root; - Json::Reader reader; - bool success = reader.parse( value, root ); + Json::CharReaderBuilder rbuilder; + Json::CharReader* reader(rbuilder.newCharReader()); + + std::string errors; + bool success = reader->parse( value.c_str(), + value.c_str() + value.size(), &root, &errors ); if (!success) // Raise exception throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index d078b496..3269991e 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -39,7 +39,7 @@ QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0 Close(); } -QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string text, string font, double size, string text_color, string background_color) +QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double size, std::string text_color, std::string background_color) : width(width), height(height), x_offset(x_offset), y_offset(y_offset), text(text), font(font), size(size), text_color(text_color), background_color(background_color), is_open(false), gravity(gravity) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) @@ -175,7 +175,7 @@ std::shared_ptr QtTextReader::GetFrame(int64_t requested_frame) } // Generate JSON string of this object -string QtTextReader::Json() { +std::string QtTextReader::Json() { // Return formatted string return JsonValue().toStyledString(); @@ -203,12 +203,16 @@ Json::Value QtTextReader::JsonValue() { } // Load JSON string into this object -void QtTextReader::SetJson(string value) { +void QtTextReader::SetJson(std::string value) { // Parse JSON string into JSON objects Json::Value root; - Json::Reader reader; - bool success = reader.parse( value, root ); + Json::CharReaderBuilder rbuilder; + Json::CharReader* reader(rbuilder.newCharReader()); + + std::string errors; + bool success = reader->parse( value.c_str(), + value.c_str() + value.size(), &root, &errors ); if (!success) // Raise exception throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); From 482ad6b14c66e5c07e5aaffe88a322999c5c0cc2 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Sun, 11 Aug 2019 22:58:15 +1000 Subject: [PATCH 09/50] Tidy and remove duplicate include --- include/OpenShot.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/OpenShot.h b/include/OpenShot.h index 3c9aac9a..35cba101 100644 --- a/include/OpenShot.h +++ b/include/OpenShot.h @@ -131,12 +131,11 @@ #include "ImageWriter.h" #include "TextReader.h" #endif -#include "QtTextReader.h" -#include "QtHtmlReader.h" #include "KeyFrame.h" #include "PlayerBase.h" #include "Point.h" #include "Profiles.h" +#include "QtHtmlReader.h" #include "QtImageReader.h" #include "QtTextReader.h" #include "Timeline.h" From b90a83dd4c7b9e747f40307ed75c7de65ce70f1d Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 12 Aug 2019 09:39:26 -0400 Subject: [PATCH 10/50] Fix documentation-comment formatting, for Doxygen --- include/QtHtmlReader.h | 5 ++++- include/QtTextReader.h | 5 ++++- src/QtHtmlReader.cpp | 5 ++++- src/QtTextReader.cpp | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h index 491164cb..ef9ad570 100644 --- a/include/QtHtmlReader.h +++ b/include/QtHtmlReader.h @@ -3,7 +3,10 @@ * @brief Header file for QtHtmlReader class * @author Jonathan Thomas * - * @section LICENSE + * @ref License + */ + +/* LICENSE * * Copyright (c) 2008-2019 OpenShot Studios, LLC * . This file is part of diff --git a/include/QtTextReader.h b/include/QtTextReader.h index 3884113e..741fe74c 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -3,7 +3,10 @@ * @brief Header file for QtTextReader class * @author Jonathan Thomas * - * @section LICENSE + * @ref License + */ + +/* LICENSE * * Copyright (c) 2008-2019 OpenShot Studios, LLC * . This file is part of diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 04dcfe66..c81508db 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -3,7 +3,10 @@ * @brief Source file for QtHtmlReader class * @author Jonathan Thomas * - * @section LICENSE + * @ref License + */ + +/* LICENSE * * Copyright (c) 2008-2019 OpenShot Studios, LLC * . This file is part of diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index 3269991e..7527894d 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -3,7 +3,10 @@ * @brief Source file for QtTextReader class * @author Jonathan Thomas * - * @section LICENSE + * @ref License + */ + +/* LICENSE * * Copyright (c) 2008-2019 OpenShot Studios, LLC * . This file is part of From 140b5fdad3e0a6bcb3d7c2d58a8478ca5ed8c153 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 12 Aug 2019 08:58:24 -0400 Subject: [PATCH 11/50] Add src/examples/ExampleHtml.cpp test program --- src/CMakeLists.txt | 5 +- src/examples/ExampleHtml.cpp | 89 ++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/examples/ExampleHtml.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 55a13484..1daacf1b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -371,13 +371,16 @@ ENDIF(WIN32) target_link_libraries(openshot ${REQUIRED_LIBRARIES}) -############### CLI EXECUTABLE ################ +############### CLI EXECUTABLES ################ # Create test executable add_executable(openshot-example examples/Example.cpp) # Link test executable to the new library target_link_libraries(openshot-example openshot) +add_executable(openshot-html-test examples/ExampleHtml.cpp) +target_link_libraries(openshot-html-test openshot) + ############### PLAYER EXECUTABLE ################ # Create test executable add_executable(openshot-player Qt/demo/main.cpp) diff --git a/src/examples/ExampleHtml.cpp b/src/examples/ExampleHtml.cpp new file mode 100644 index 00000000..0148b6f7 --- /dev/null +++ b/src/examples/ExampleHtml.cpp @@ -0,0 +1,89 @@ +/** + * @file + * @brief Source file for Example Executable (example app for libopenshot) + * @author Jonathan Thomas + * + * @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 +#include +#include +#include "../../include/OpenShot.h" +//#include "../../include/CrashHandler.h" + +using namespace openshot; + +int main(int argc, char* argv[]) { + + // Create a reader to generate an openshot::Frame containing text + QtHtmlReader r(720, // width + 480, // height + 5, // x_offset + 5, // y_offset + GRAVITY_CENTER, // gravity + "Check out this Text!", // html + "#000000" // background_color + ); + r.Open(); // Open the reader + + // XXX: Not implemented + // r.DisplayInfo(); + + /* WRITER ---------------- */ + FFmpegWriter w9("/var/tmp/metadata.mp4"); + + // Set options + //w9.SetAudioOptions(true, "libmp3lame", r.info.sample_rate, r9.info.channels, r9.info.channel_layout, 128000); + w9.SetVideoOptions(true, "libx264", Fraction{30000, 1000}, 720, 480, Fraction(1,1), false, false, 3000000); + + w9.info.metadata["title"] = "testtest"; + w9.info.metadata["artist"] = "aaa"; + w9.info.metadata["album"] = "bbb"; + w9.info.metadata["year"] = "2015"; + w9.info.metadata["description"] = "ddd"; + w9.info.metadata["comment"] = "eee"; + w9.info.metadata["comment"] = "comment"; + w9.info.metadata["copyright"] = "copyright OpenShot!"; + + // Open writer + w9.Open(); + + for (long int frame = 1; frame <= 30; frame++) + { + std::shared_ptr f = r.GetFrame(1); // Same frame every time + w9.WriteFrame(f); + } + + // Close writer & reader + w9.Close(); + + // Close timeline + r.Close(); + + cout << "Completed successfully!" << endl; + + return 0; +} From b2942f412598bbc2d753b3ea39431bdabe533f40 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 12 Aug 2019 11:54:13 -0400 Subject: [PATCH 12/50] ExampleHtml.cpp updates --- src/examples/ExampleHtml.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/examples/ExampleHtml.cpp b/src/examples/ExampleHtml.cpp index 0148b6f7..feb1f153 100644 --- a/src/examples/ExampleHtml.cpp +++ b/src/examples/ExampleHtml.cpp @@ -33,6 +33,7 @@ #include #include "../../include/OpenShot.h" //#include "../../include/CrashHandler.h" +#include using namespace openshot; @@ -49,8 +50,7 @@ int main(int argc, char* argv[]) { ); r.Open(); // Open the reader - // XXX: Not implemented - // r.DisplayInfo(); + r.DisplayInfo(); /* WRITER ---------------- */ FFmpegWriter w9("/var/tmp/metadata.mp4"); From c7457e51d19f8aa231c7dda36653af06c2eee20d Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 12 Aug 2019 11:55:30 -0400 Subject: [PATCH 13/50] Build example executables correctly --- src/CMakeLists.txt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1daacf1b..126ea7df 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 @@ -259,7 +259,7 @@ SET ( OPENSHOT_SOURCE_FILES Timeline.cpp QtTextReader.cpp QtHtmlReader.cpp - + # Qt Video Player ${QT_PLAYER_FILES} @@ -309,6 +309,9 @@ set_target_properties(openshot INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" ) +# Linked executables will need this propagated to them +target_compile_options(openshot PUBLIC ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS} ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS} ${Qt5Multimedia_EXECUTABLE_COMPILE_FLAGS} ${Qt5MultimediaWidgets_EXECUTABLE_COMPILE_FLAGS}) + ############### LINK LIBRARY ################# SET ( REQUIRED_LIBRARIES ${LIBOPENSHOT_AUDIO_LIBRARIES} @@ -379,7 +382,10 @@ add_executable(openshot-example examples/Example.cpp) target_link_libraries(openshot-example openshot) add_executable(openshot-html-test examples/ExampleHtml.cpp) -target_link_libraries(openshot-html-test openshot) +target_link_libraries(openshot-html-test openshot Qt5::Gui) + +add_executable(openshot-text-test examples/ExampleText.cpp) +target_link_libraries(openshot-text-test openshot Qt5::Gui) ############### PLAYER EXECUTABLE ################ # Create test executable From 745225ad6257e6e8fc1f02f2407af717a4a9a497 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Tue, 13 Aug 2019 21:18:55 +1000 Subject: [PATCH 14/50] Rename variable to font_size. Add docs for QApplication --- include/QtHtmlReader.h | 3 +++ include/QtTextReader.h | 11 +++++++---- src/QtTextReader.cpp | 22 +++++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h index ef9ad570..3c6b7528 100644 --- a/include/QtHtmlReader.h +++ b/include/QtHtmlReader.h @@ -55,6 +55,9 @@ namespace openshot * Supports HTML/CSS subset available via Qt libraries, see: https://doc.qt.io/qt-5/richtext-html-subset.html * * @code + * // Any application using this class must instantiate either QGuiApplication or QApplication + * QApplication a(argc, argv); + * * // Create a reader to generate an openshot::Frame containing text * QtHtmlReader r(720, // width * 480, // height diff --git a/include/QtTextReader.h b/include/QtTextReader.h index 741fe74c..316825b7 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -56,6 +56,9 @@ namespace openshot * alignment, padding, etc... * * @code + * // Any application using this class must instantiate either QGuiApplication or QApplication + * QApplication a(argc, argv); + * * // Create a reader to generate an openshot::Frame containing text * QtTextReader r(720, // width * 480, // height @@ -64,7 +67,7 @@ namespace openshot * GRAVITY_CENTER, // gravity * "Check out this Text!", // text * "Arial", // font - * 15.0, // size + * 15.0, // font size * "#fff000", // text_color * "#000000" // background_color * ); @@ -89,7 +92,7 @@ namespace openshot int y_offset; std::string text; std::string font; - double size; + double font_size; std::string text_color; std::string background_color; std::shared_ptr image; @@ -109,10 +112,10 @@ namespace openshot /// @param gravity The alignment / gravity of the text /// @param text The text you want to generate / display /// @param font The font of the text - /// @param size The size of the text + /// @param font_size The size of the text /// @param text_color The color of the text /// @param background_color The background color of the text (also supports Transparent) - QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double size, std::string text_color, std::string background_color); + QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, std::string text_color, std::string background_color); /// Close Reader void Close(); diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index 7527894d..a287bc43 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -35,15 +35,15 @@ using namespace openshot; /// Default constructor (blank text) -QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font("Arial"), size(10.0), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) +QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font("Arial"), font_size(10.0), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); Close(); } -QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double size, std::string text_color, std::string background_color) -: width(width), height(height), x_offset(x_offset), y_offset(y_offset), text(text), font(font), size(size), text_color(text_color), background_color(background_color), is_open(false), gravity(gravity) +QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, std::string text_color, std::string background_color) +: width(width), height(height), x_offset(x_offset), y_offset(y_offset), text(text), font(font), font_size(font_size), text_color(text_color), background_color(background_color), is_open(false), gravity(gravity) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); @@ -72,7 +72,7 @@ void QtTextReader::Open() painter.setPen(QPen(text_color.c_str())); // set font - painter.setFont(QFont(font.c_str(), size)); + painter.setFont(QFont(font.c_str(), font_size)); // Set gravity (map between OpenShot and Qt) int align_flag = 0; @@ -129,14 +129,14 @@ void QtTextReader::Open() info.video_length = round(info.duration * info.fps.ToDouble()); // Calculate the DAR (display aspect ratio) - Fraction size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den); + Fraction font_size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den); // Reduce size fraction - size.Reduce(); + font_size.Reduce(); // Set the ratio based on the reduced fraction - info.display_ratio.num = size.num; - info.display_ratio.den = size.den; + info.display_ratio.num = font_size.num; + info.display_ratio.den = font_size.den; // Mark as "open" is_open = true; @@ -196,7 +196,7 @@ Json::Value QtTextReader::JsonValue() { root["y_offset"] = y_offset; root["text"] = text; root["font"] = font; - root["size"] = size; + root["font_size"] = font_size; root["text_color"] = text_color; root["background_color"] = background_color; root["gravity"] = gravity; @@ -251,8 +251,8 @@ void QtTextReader::SetJsonValue(Json::Value root) { text = root["text"].asString(); if (!root["font"].isNull()) font = root["font"].asString(); - if (!root["size"].isNull()) - size = root["size"].asDouble(); + if (!root["font_size"].isNull()) + font_size = root["font_size"].asDouble(); if (!root["text_color"].isNull()) text_color = root["text_color"].asString(); if (!root["background_color"].isNull()) From c8f2c08d344dd402ee55476bf3417c2b97f1a7d5 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Tue, 13 Aug 2019 21:24:42 +1000 Subject: [PATCH 15/50] Add authors to docs --- include/QtHtmlReader.h | 2 ++ include/QtTextReader.h | 2 ++ src/QtHtmlReader.cpp | 2 ++ src/QtTextReader.cpp | 2 ++ 4 files changed, 8 insertions(+) diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h index 3c6b7528..456b5f1d 100644 --- a/include/QtHtmlReader.h +++ b/include/QtHtmlReader.h @@ -2,6 +2,8 @@ * @file * @brief Header file for QtHtmlReader class * @author Jonathan Thomas + * @author Sergei Kolesov (jediserg) + * @author Jeff Shillitto (jeffski) * * @ref License */ diff --git a/include/QtTextReader.h b/include/QtTextReader.h index 316825b7..85187afe 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -2,6 +2,8 @@ * @file * @brief Header file for QtTextReader class * @author Jonathan Thomas + * @author Sergei Kolesov (jediserg) + * @author Jeff Shillitto (jeffski) * * @ref License */ diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index c81508db..9bda8a18 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -2,6 +2,8 @@ * @file * @brief Source file for QtHtmlReader class * @author Jonathan Thomas + * @author Sergei Kolesov (jediserg) + * @author Jeff Shillitto (jeffski) * * @ref License */ diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index a287bc43..4205eb81 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -2,6 +2,8 @@ * @file * @brief Source file for QtTextReader class * @author Jonathan Thomas + * @author Sergei Kolesov (jediserg) + * @author Jeff Shillitto (jeffski) * * @ref License */ From 78f370ee14eb2f1b78b96dc597b2942f823798ea Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Tue, 13 Aug 2019 22:11:55 +1000 Subject: [PATCH 16/50] Add ability to apply style sheet/css to format HTML --- include/QtHtmlReader.h | 4 +++- src/QtHtmlReader.cpp | 12 +++++++----- src/examples/ExampleHtml.cpp | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h index 456b5f1d..01defa8c 100644 --- a/include/QtHtmlReader.h +++ b/include/QtHtmlReader.h @@ -67,6 +67,7 @@ namespace openshot * 5, // y_offset * GRAVITY_CENTER, // gravity * "Check out this Text!", // html + * "b { color: #ff0000 }", // css * "#000000" // background_color * ); * r.Open(); // Open the reader @@ -89,6 +90,7 @@ namespace openshot int x_offset; int y_offset; std::string html; + std::string css; std::string background_color; std::shared_ptr image; bool is_open; @@ -106,7 +108,7 @@ namespace openshot /// @param gravity The alignment / gravity of the text /// @param html The html you want to render / display /// @param background_color The background color of the text (also supports Transparent) - QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string html, std::string background_color); + QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string html, std::string css, std::string background_color); /// Close Reader void Close(); diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 9bda8a18..d73554cb 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -40,15 +40,15 @@ using namespace openshot; /// Default constructor (blank text) -QtHtmlReader::QtHtmlReader() : width(1024), height(768), x_offset(0), y_offset(0), html(""), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) +QtHtmlReader::QtHtmlReader() : width(1024), height(768), x_offset(0), y_offset(0), html(""), css(""), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); Close(); } -QtHtmlReader::QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string html, std::string background_color) -: width(width), height(height), x_offset(x_offset), y_offset(y_offset), gravity(gravity), html(html), background_color(background_color), is_open(false) +QtHtmlReader::QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string html, std::string css, std::string background_color) +: width(width), height(height), x_offset(x_offset), y_offset(y_offset), gravity(gravity), html(html), css(css), background_color(background_color), is_open(false) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); @@ -77,6 +77,7 @@ void QtHtmlReader::Open() //draw text QTextDocument text_document; text_document.setTextWidth(width); + text_document.setDefaultStyleSheet(css.c_str()); text_document.setHtml(html.c_str()); int td_height = text_document.documentLayout()->documentSize().height(); @@ -185,6 +186,7 @@ Json::Value QtHtmlReader::JsonValue() { root["x_offset"] = x_offset; root["y_offset"] = y_offset; root["html"] = html; + root["css"] = css; root["background_color"] = background_color; root["gravity"] = gravity; @@ -236,10 +238,10 @@ void QtHtmlReader::SetJsonValue(Json::Value root) { y_offset = root["y_offset"].asInt(); if (!root["html"].isNull()) html = root["html"].asString(); - + if (!root["css"].isNull()) + css = root["css"].asString(); if (!root["background_color"].isNull()) background_color = root["background_color"].asString(); - if (!root["gravity"].isNull()) gravity = (GravityType) root["gravity"].asInt(); diff --git a/src/examples/ExampleHtml.cpp b/src/examples/ExampleHtml.cpp index 0148b6f7..3f466df0 100644 --- a/src/examples/ExampleHtml.cpp +++ b/src/examples/ExampleHtml.cpp @@ -45,6 +45,7 @@ int main(int argc, char* argv[]) { 5, // y_offset GRAVITY_CENTER, // gravity "Check out this Text!", // html + "b { color: #ff0000; }", "#000000" // background_color ); r.Open(); // Open the reader From ada13ddebd80d135f41be2a7d517ef57004b3356 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Tue, 13 Aug 2019 22:17:49 +1000 Subject: [PATCH 17/50] Disable undo/redo stack --- src/QtHtmlReader.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index d73554cb..0d71c658 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -76,6 +76,11 @@ void QtHtmlReader::Open() //draw text QTextDocument text_document; + + //disable redo/undo stack as not needed + text_document.setUndoRedoEnabled(false); + + //create the HTML/CSS document text_document.setTextWidth(width); text_document.setDefaultStyleSheet(css.c_str()); text_document.setHtml(html.c_str()); From 8ab535fc9631de823d7370bae7458c770c8a01d1 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 13 Aug 2019 17:21:15 -0400 Subject: [PATCH 18/50] Update ExampleHtml.cpp for QGuiApplication --- src/examples/ExampleHtml.cpp | 53 ++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/examples/ExampleHtml.cpp b/src/examples/ExampleHtml.cpp index 155c98b5..96e98e2a 100644 --- a/src/examples/ExampleHtml.cpp +++ b/src/examples/ExampleHtml.cpp @@ -34,24 +34,28 @@ #include "../../include/OpenShot.h" //#include "../../include/CrashHandler.h" #include +#include using namespace openshot; int main(int argc, char* argv[]) { - // Create a reader to generate an openshot::Frame containing text - QtHtmlReader r(720, // width - 480, // height - 5, // x_offset - 5, // y_offset - GRAVITY_CENTER, // gravity - "Check out this Text!", // html - "b { color: #ff0000; }", - "#000000" // background_color - ); - r.Open(); // Open the reader + QGuiApplication app(argc, argv); - r.DisplayInfo(); + // Create a reader to generate an openshot::Frame containing text + QtHtmlReader r(720, // width + 480, // height + 5, // x_offset + 5, // y_offset + GRAVITY_CENTER, // gravity + "Check out this Text!", // html + "b { color: #ff0000; }", + "#000000" // background_color + ); + + r.Open(); // Open the reader + + r.DisplayInfo(); /* WRITER ---------------- */ FFmpegWriter w9("/var/tmp/metadata.mp4"); @@ -61,30 +65,31 @@ int main(int argc, char* argv[]) { w9.SetVideoOptions(true, "libx264", Fraction{30000, 1000}, 720, 480, Fraction(1,1), false, false, 3000000); w9.info.metadata["title"] = "testtest"; - w9.info.metadata["artist"] = "aaa"; - w9.info.metadata["album"] = "bbb"; - w9.info.metadata["year"] = "2015"; - w9.info.metadata["description"] = "ddd"; - w9.info.metadata["comment"] = "eee"; - w9.info.metadata["comment"] = "comment"; + w9.info.metadata["artist"] = "aaa"; + w9.info.metadata["album"] = "bbb"; + w9.info.metadata["year"] = "2015"; + w9.info.metadata["description"] = "ddd"; + w9.info.metadata["comment"] = "eee"; + w9.info.metadata["comment"] = "comment"; w9.info.metadata["copyright"] = "copyright OpenShot!"; // Open writer w9.Open(); - for (long int frame = 1; frame <= 30; frame++) + for (long int frame = 1; frame <= 30; ++frame) { - std::shared_ptr f = r.GetFrame(1); // Same frame every time + std::shared_ptr f = r.GetFrame(frame); // Same frame every time w9.WriteFrame(f); } // Close writer & reader w9.Close(); - - // Close timeline r.Close(); - cout << "Completed successfully!" << endl; + // Set a timer with 0 timeout to terminate immediately after + // processing events + QTimer::singleShot(0, &app, SLOT(quit())); - return 0; + // Run QGuiApplication to completion + return app.exec(); } From acc27064841ecfc91f06859d2def3eae52c1957f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 13 Aug 2019 17:25:20 -0400 Subject: [PATCH 19/50] Remove nonexistent example from cmake build --- src/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 126ea7df..b24d590e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -384,9 +384,6 @@ target_link_libraries(openshot-example openshot) add_executable(openshot-html-test examples/ExampleHtml.cpp) target_link_libraries(openshot-html-test openshot Qt5::Gui) -add_executable(openshot-text-test examples/ExampleText.cpp) -target_link_libraries(openshot-text-test openshot Qt5::Gui) - ############### PLAYER EXECUTABLE ################ # Create test executable add_executable(openshot-player Qt/demo/main.cpp) From 3b4580ab7c413a04f9ca53614dbd670e14ff5bd8 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Wed, 14 Aug 2019 22:15:05 +1000 Subject: [PATCH 20/50] Update documentation with css parameter and valid color values --- include/QtHtmlReader.h | 5 +++-- include/QtTextReader.h | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/QtHtmlReader.h b/include/QtHtmlReader.h index 01defa8c..ca5f45c4 100644 --- a/include/QtHtmlReader.h +++ b/include/QtHtmlReader.h @@ -106,8 +106,9 @@ namespace openshot /// @param x_offset The number of pixels to offset the text on the X axis (horizontal) /// @param y_offset The number of pixels to offset the text on the Y axis (vertical) /// @param gravity The alignment / gravity of the text - /// @param html The html you want to render / display - /// @param background_color The background color of the text (also supports Transparent) + /// @param html The HTML you want to render / display + /// @param css The CSS you want to apply to style the HTML + /// @param background_color The background color of the frame image (valid values are a color string in #RRGGBB or #AARRGGBB notation, a CSS color name, or 'transparent') QtHtmlReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string html, std::string css, std::string background_color); /// Close Reader diff --git a/include/QtTextReader.h b/include/QtTextReader.h index 85187afe..a3fa014c 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -115,8 +115,8 @@ namespace openshot /// @param text The text you want to generate / display /// @param font The font of the text /// @param font_size The size of the text - /// @param text_color The color of the text - /// @param background_color The background color of the text (also supports Transparent) + /// @param text_color The color of the text (valid values are a color string in #RRGGBB or #AARRGGBB notation or a CSS color name) + /// @param background_color The background color of the frame image (valid values are a color string in #RRGGBB or #AARRGGBB notation, a CSS color name, or 'transparent') QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, std::string text_color, std::string background_color); /// Close Reader From 5a08afdb3f138ae7f1b175ac5e59f6d2f32d99c6 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Wed, 14 Aug 2019 22:18:26 +1000 Subject: [PATCH 21/50] Set info.vcodec to QImage --- src/QtHtmlReader.cpp | 2 +- src/QtTextReader.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 0d71c658..7a1bf584 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -112,7 +112,7 @@ void QtHtmlReader::Open() info.has_audio = false; info.has_video = true; info.file_size = 0; - info.vcodec = "Constant image uniform color"; + info.vcodec = "QImage"; info.width = width; info.height = height; info.pixel_ratio.num = 1; diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index 4205eb81..b11a3b55 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -118,7 +118,7 @@ void QtTextReader::Open() info.has_audio = false; info.has_video = true; info.file_size = 0; - info.vcodec = "Constant image uniform color"; + info.vcodec = "QImage"; info.width = width; info.height = height; info.pixel_ratio.num = 1; From 0ee9ed8e3a08985e60751be4d7515f79ae8a17dc Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Wed, 14 Aug 2019 22:38:41 +1000 Subject: [PATCH 22/50] Delete image on close --- src/QtHtmlReader.cpp | 6 ++++++ src/QtTextReader.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 7a1bf584..9d22feda 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -147,6 +147,12 @@ void QtHtmlReader::Close() { // Mark as "closed" is_open = false; + + // Delete the image + image.reset(); + + info.vcodec = ""; + info.acodec = ""; } } diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index b11a3b55..de5d4542 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -153,6 +153,12 @@ void QtTextReader::Close() { // Mark as "closed" is_open = false; + + // Delete the image + image.reset(); + + info.vcodec = ""; + info.acodec = ""; } } From 74c9869c96844721ec3e2c7bf9aa85f51bc1456f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 14 Aug 2019 10:21:57 -0400 Subject: [PATCH 23/50] Python & Ruby bindings for new Readers --- src/bindings/python/openshot.i | 8 ++++++-- src/bindings/ruby/openshot.i | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/bindings/python/openshot.i b/src/bindings/python/openshot.i index 512224ef..34aada1b 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 @@ -83,8 +83,10 @@ #include "../../../include/PlayerBase.h" #include "../../../include/Point.h" #include "../../../include/Profiles.h" +#include "../../../include/QtHtmlReader.h" #include "../../../include/QtImageReader.h" #include "../../../include/QtPlayer.h" +#include "../../../include/QtTextReader.h" #include "../../../include/KeyFrame.h" #include "../../../include/RendererBase.h" #include "../../../include/Settings.h" @@ -151,8 +153,10 @@ %include "../../../include/PlayerBase.h" %include "../../../include/Point.h" %include "../../../include/Profiles.h" +%include "../../../include/QtHtmlReader.h" %include "../../../include/QtImageReader.h" %include "../../../include/QtPlayer.h" +%include "../../../include/QtTextReader.h" %include "../../../include/KeyFrame.h" %include "../../../include/RendererBase.h" %include "../../../include/Settings.h" diff --git a/src/bindings/ruby/openshot.i b/src/bindings/ruby/openshot.i index 1f3e0d99..9b16aee2 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 @@ -95,8 +95,10 @@ namespace std { #include "../../../include/PlayerBase.h" #include "../../../include/Point.h" #include "../../../include/Profiles.h" +#include "../../../include/QtHtmlReader.h" #include "../../../include/QtImageReader.h" #include "../../../include/QtPlayer.h" +#include "../../../include/QtTextReader.h" #include "../../../include/KeyFrame.h" #include "../../../include/RendererBase.h" #include "../../../include/Settings.h" @@ -182,8 +184,10 @@ namespace std { %include "../../../include/PlayerBase.h" %include "../../../include/Point.h" %include "../../../include/Profiles.h" +%include "../../../include/QtHtmlReader.h" %include "../../../include/QtImageReader.h" %include "../../../include/QtPlayer.h" +%include "../../../include/QtTextReader.h" %include "../../../include/KeyFrame.h" %include "../../../include/RendererBase.h" %include "../../../include/Settings.h" From 0d067b33a316c61ce9ba403545e5af15c32bb1b3 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 14 Aug 2019 10:22:29 -0400 Subject: [PATCH 24/50] new ExampleHtml.py and updated ExampleHtml.cpp --- src/examples/ExampleHtml.cpp | 3 +- src/examples/ExampleHtml.py | 88 ++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100755 src/examples/ExampleHtml.py diff --git a/src/examples/ExampleHtml.cpp b/src/examples/ExampleHtml.cpp index 96e98e2a..26ec42be 100644 --- a/src/examples/ExampleHtml.cpp +++ b/src/examples/ExampleHtml.cpp @@ -1,7 +1,8 @@ /** * @file - * @brief Source file for Example Executable (example app for libopenshot) + * @brief Source file for QtHtmlReader Example (example app for libopenshot) * @author Jonathan Thomas + * @author FeRD (Frank Dana) * * @ref License */ diff --git a/src/examples/ExampleHtml.py b/src/examples/ExampleHtml.py new file mode 100755 index 00000000..116df0ca --- /dev/null +++ b/src/examples/ExampleHtml.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 + +""" + @file + @brief Python source file for QtHtmlReader 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 +from PyQt5.QtCore import QTimer +from PyQt5.QtGui import QGuiApplication +import openshot + +app = QGuiApplication(sys.argv) + +html_code = "Check out this Text!" + +# Create a QtHtmlReader +r = openshot.QtHtmlReader(720, + 480, + 5, + 5, + openshot.GRAVITY_CENTER, + html_code, + "b { color: #ff0000; }", + "#000000" + ) + +r.Open() # Open the reader + +r.DisplayInfo() # Display metadata + +# Set up Writer +w = openshot.FFmpegWriter("/var/tmp/pyHtmlExample.mp4") + +w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 720, 480, + 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 i in range(30): + f = r.GetFrame(i) + w.WriteFrame(f) + +# Close out Reader & Writer +w.Close() +r.Close() + +# Set a timer to terminate the app as soon as the event queue empties +QTimer.singleShot(0, app.quit) + +# Run QGuiApplication to completion +sys.exit(app.exec()) From bcaa9ace988591c395f1a0a78a60db6aa72ebbc8 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 14 Aug 2019 11:40:29 -0400 Subject: [PATCH 25/50] QtText/QtHtmlReader: Don't leak memory in SetJson --- src/QtHtmlReader.cpp | 8 +++++--- src/QtTextReader.cpp | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 9d22feda..0627d55b 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -84,9 +84,9 @@ void QtHtmlReader::Open() text_document.setTextWidth(width); text_document.setDefaultStyleSheet(css.c_str()); text_document.setHtml(html.c_str()); - + int td_height = text_document.documentLayout()->documentSize().height(); - + if (gravity == GRAVITY_TOP_LEFT || gravity == GRAVITY_TOP || gravity == GRAVITY_TOP_RIGHT) { painter.translate(x_offset, y_offset); } else if (gravity == GRAVITY_LEFT || gravity == GRAVITY_CENTER || gravity == GRAVITY_RIGHT) { @@ -94,7 +94,7 @@ void QtHtmlReader::Open() } else if (gravity == GRAVITY_BOTTOM_LEFT || gravity == GRAVITY_BOTTOM_RIGHT || gravity == GRAVITY_BOTTOM) { painter.translate(x_offset, height - td_height + y_offset); } - + if (gravity == GRAVITY_TOP_LEFT || gravity == GRAVITY_LEFT || gravity == GRAVITY_BOTTOM_LEFT) { text_document.setDefaultTextOption(QTextOption(Qt::AlignLeft)); } else if (gravity == GRAVITY_CENTER || gravity == GRAVITY_TOP || gravity == GRAVITY_BOTTOM) { @@ -216,6 +216,8 @@ void QtHtmlReader::SetJson(std::string value) { std::string errors; bool success = reader->parse( value.c_str(), value.c_str() + value.size(), &root, &errors ); + delete reader; + if (!success) // Raise exception throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index de5d4542..0c45ea4e 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -224,6 +224,8 @@ void QtTextReader::SetJson(std::string value) { std::string errors; bool success = reader->parse( value.c_str(), value.c_str() + value.size(), &root, &errors ); + delete reader; + if (!success) // Raise exception throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); From 74869ffa70de4fa631d94076ed987e1df8a8f2a8 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 14 Aug 2019 12:18:49 -0400 Subject: [PATCH 26/50] ExampleHtml.cpp cleanup * Change writer var from 'w9' to 'w' * More descriptive output filename * Write output file to current directory * More readable formatting --- src/examples/ExampleHtml.cpp | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/examples/ExampleHtml.cpp b/src/examples/ExampleHtml.cpp index 26ec42be..298d52b4 100644 --- a/src/examples/ExampleHtml.cpp +++ b/src/examples/ExampleHtml.cpp @@ -43,13 +43,15 @@ int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); + std::string html_code = "Check out this Text!"; + // Create a reader to generate an openshot::Frame containing text QtHtmlReader r(720, // width 480, // height 5, // x_offset 5, // y_offset GRAVITY_CENTER, // gravity - "Check out this Text!", // html + html_code, // html "b { color: #ff0000; }", "#000000" // background_color ); @@ -59,32 +61,32 @@ int main(int argc, char* argv[]) { r.DisplayInfo(); /* WRITER ---------------- */ - FFmpegWriter w9("/var/tmp/metadata.mp4"); + FFmpegWriter w("cppHtmlExample.mp4"); // Set options - //w9.SetAudioOptions(true, "libmp3lame", r.info.sample_rate, r9.info.channels, r9.info.channel_layout, 128000); - w9.SetVideoOptions(true, "libx264", Fraction{30000, 1000}, 720, 480, Fraction(1,1), false, false, 3000000); + //w.SetAudioOptions(true, "libmp3lame", r.info.sample_rate, r.info.channels, r.info.channel_layout, 128000); + w.SetVideoOptions(true, "libx264", Fraction(30000, 1000), 720, 480, Fraction(1, 1), false, false, 3000000); - w9.info.metadata["title"] = "testtest"; - w9.info.metadata["artist"] = "aaa"; - w9.info.metadata["album"] = "bbb"; - w9.info.metadata["year"] = "2015"; - w9.info.metadata["description"] = "ddd"; - w9.info.metadata["comment"] = "eee"; - w9.info.metadata["comment"] = "comment"; - w9.info.metadata["copyright"] = "copyright OpenShot!"; + 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 writer - w9.Open(); + w.Open(); for (long int frame = 1; frame <= 30; ++frame) { std::shared_ptr f = r.GetFrame(frame); // Same frame every time - w9.WriteFrame(f); + w.WriteFrame(f); } // Close writer & reader - w9.Close(); + w.Close(); r.Close(); // Set a timer with 0 timeout to terminate immediately after From 0048294528573d5e3b2357c22874dd00717181f5 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 14 Aug 2019 12:19:54 -0400 Subject: [PATCH 27/50] ExampleHtml.py cleanup * Remove semicolons from cut-and-paste C++ code * Write output file to current directory * More readable formatting --- src/examples/ExampleHtml.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/examples/ExampleHtml.py b/src/examples/ExampleHtml.py index 116df0ca..610176f5 100755 --- a/src/examples/ExampleHtml.py +++ b/src/examples/ExampleHtml.py @@ -55,26 +55,26 @@ r.Open() # Open the reader r.DisplayInfo() # Display metadata # Set up Writer -w = openshot.FFmpegWriter("/var/tmp/pyHtmlExample.mp4") +w = openshot.FFmpegWriter("pyHtmlExample.mp4") w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 720, 480, 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!"; +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 i in range(30): - f = r.GetFrame(i) +for frame in range(30): + f = r.GetFrame(frame) w.WriteFrame(f) # Close out Reader & Writer From 7c48bec484b48d27898deb1664a647e482482f3f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 25 Aug 2019 23:54:28 -0400 Subject: [PATCH 28/50] HTML examples: Code updates - Use same `html_code` and `css_code` - Sync up offsets and gravity (BOTTOM_RIGHT) - Create 1280x720 frames - Generate 100 frames of output video --- src/examples/ExampleHtml.cpp | 31 ++++++++++++++++++------------- src/examples/ExampleHtml.py | 25 +++++++++++++++---------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/examples/ExampleHtml.cpp b/src/examples/ExampleHtml.cpp index 298d52b4..f315e252 100644 --- a/src/examples/ExampleHtml.cpp +++ b/src/examples/ExampleHtml.cpp @@ -43,18 +43,23 @@ int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); - std::string html_code = "Check out this Text!"; + std::string html_code = R"html(

Check out this HTML!

)html"; - // Create a reader to generate an openshot::Frame containing text - QtHtmlReader r(720, // width - 480, // height - 5, // x_offset - 5, // y_offset - GRAVITY_CENTER, // gravity - html_code, // html - "b { color: #ff0000; }", - "#000000" // background_color - ); + std::string css_code = R"css( + * {font-family:sans-serif; font-size:18pt; color:#ffffff;} + #red {color: #ff0000;} + )css"; + +// Create a reader to generate an openshot::Frame containing text +QtHtmlReader r(1280, // width + 720, // height + -16, // x_offset + -16, // y_offset + GRAVITY_BOTTOM_RIGHT, // gravity + html_code, // html + css_code, // css + "#000000" // background_color + ); r.Open(); // Open the reader @@ -65,7 +70,7 @@ int main(int argc, char* argv[]) { // Set options //w.SetAudioOptions(true, "libmp3lame", r.info.sample_rate, r.info.channels, r.info.channel_layout, 128000); - w.SetVideoOptions(true, "libx264", Fraction(30000, 1000), 720, 480, Fraction(1, 1), false, false, 3000000); + w.SetVideoOptions(true, "libx264", Fraction(30000, 1000), 1280, 720, Fraction(1, 1), false, false, 3000000); w.info.metadata["title"] = "testtest"; w.info.metadata["artist"] = "aaa"; @@ -79,7 +84,7 @@ int main(int argc, char* argv[]) { // Open writer w.Open(); - for (long int frame = 1; frame <= 30; ++frame) + for (long int frame = 1; frame <= 100; ++frame) { std::shared_ptr f = r.GetFrame(frame); // Same frame every time w.WriteFrame(f); diff --git a/src/examples/ExampleHtml.py b/src/examples/ExampleHtml.py index 610176f5..1938f2fe 100755 --- a/src/examples/ExampleHtml.py +++ b/src/examples/ExampleHtml.py @@ -37,17 +37,22 @@ import openshot app = QGuiApplication(sys.argv) -html_code = "Check out this Text!" +html_code = """

Check out this HTML!

""" + +css_code = """ + * {font-family:sans-serif; font-size:18pt; color:#ffffff;} + #red {color: #ff0000;} +""" # Create a QtHtmlReader -r = openshot.QtHtmlReader(720, - 480, - 5, - 5, - openshot.GRAVITY_CENTER, +r = openshot.QtHtmlReader(1280, # width + 720, # height + -16, # x offset + -16, # y offset + openshot.GRAVITY_BOTTOM_RIGHT, html_code, - "b { color: #ff0000; }", - "#000000" + css_code, + "#000000" # background color ) r.Open() # Open the reader @@ -57,7 +62,7 @@ r.DisplayInfo() # Display metadata # Set up Writer w = openshot.FFmpegWriter("pyHtmlExample.mp4") -w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 720, 480, +w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720, openshot.Fraction(1, 1), False, False, 3000000) w.info.metadata["title"] = "testtest" @@ -73,7 +78,7 @@ w.info.metadata["copyright"] = "copyright OpenShot!" w.Open() # Grab 30 frames from Reader and encode to Writer -for frame in range(30): +for frame in range(100): f = r.GetFrame(frame) w.WriteFrame(f) From f981e38664da9bfc5b579338538016448fa3b6d7 Mon Sep 17 00:00:00 2001 From: Mario Hros Date: Fri, 23 Aug 2019 19:46:05 +0200 Subject: [PATCH 29/50] support for HEVC HW VAAPI encoding --- src/FFmpegWriter.cpp | 169 +++++++++++++++++++++++++++++++------------ 1 file changed, 123 insertions(+), 46 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 94d03e76..3b82358a 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -172,59 +172,50 @@ 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 ( (strcmp(codec.c_str(),"h264_vaapi") == 0)) { +#if defined(__linux__) + if (strstr(codec.c_str(), "_vaapi") != NULL) { new_codec = avcodec_find_encoder_by_name(codec.c_str()); hw_en_on = 1; hw_en_supported = 1; hw_en_av_pix_fmt = AV_PIX_FMT_VAAPI; hw_en_av_device_type = AV_HWDEVICE_TYPE_VAAPI; - } - else { - if ( (strcmp(codec.c_str(),"h264_nvenc") == 0)) { - new_codec = avcodec_find_encoder_by_name(codec.c_str()); - hw_en_on = 1; - hw_en_supported = 1; - hw_en_av_pix_fmt = AV_PIX_FMT_CUDA; - hw_en_av_device_type = AV_HWDEVICE_TYPE_CUDA; - } - else { - new_codec = avcodec_find_encoder_by_name(codec.c_str()); - hw_en_on = 0; - hw_en_supported = 0; - } + } else if (strstr(codec.c_str(), "_nvenc") != NULL) { + new_codec = avcodec_find_encoder_by_name(codec.c_str()); + hw_en_on = 1; + hw_en_supported = 1; + hw_en_av_pix_fmt = AV_PIX_FMT_CUDA; + hw_en_av_device_type = AV_HWDEVICE_TYPE_CUDA; + } else { + new_codec = avcodec_find_encoder_by_name(codec.c_str()); + hw_en_on = 0; + hw_en_supported = 0; } #elif defined(_WIN32) - if ( (strcmp(codec.c_str(),"h264_dxva2") == 0)) { + if (strstr(codec.c_str(), "_dxva2") != NULL) { new_codec = avcodec_find_encoder_by_name(codec.c_str()); hw_en_on = 1; hw_en_supported = 1; hw_en_av_pix_fmt = AV_PIX_FMT_DXVA2_VLD; hw_en_av_device_type = AV_HWDEVICE_TYPE_DXVA2; - } - else { - if ( (strcmp(codec.c_str(),"h264_nvenc") == 0)) { - new_codec = avcodec_find_encoder_by_name(codec.c_str()); - hw_en_on = 1; - hw_en_supported = 1; - hw_en_av_pix_fmt = AV_PIX_FMT_CUDA; - hw_en_av_device_type = AV_HWDEVICE_TYPE_CUDA; - } - else { - new_codec = avcodec_find_encoder_by_name(codec.c_str()); - hw_en_on = 0; - hw_en_supported = 0; - } + } else if (strstr(codec.c_str(), "_nvenc") != NULL) { + new_codec = avcodec_find_encoder_by_name(codec.c_str()); + hw_en_on = 1; + hw_en_supported = 1; + hw_en_av_pix_fmt = AV_PIX_FMT_CUDA; + hw_en_av_device_type = AV_HWDEVICE_TYPE_CUDA; + } else { + new_codec = avcodec_find_encoder_by_name(codec.c_str()); + hw_en_on = 0; + hw_en_supported = 0; } #elif defined(__APPLE__) - if ( (strcmp(codec.c_str(),"h264_videotoolbox") == 0)) { + if (strstr(codec.c_str(), "_videotoolbox") != NULL) { new_codec = avcodec_find_encoder_by_name(codec.c_str()); hw_en_on = 1; hw_en_supported = 1; hw_en_av_pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX; hw_en_av_device_type = AV_HWDEVICE_TYPE_VIDEOTOOLBOX; - } - else { + } else { new_codec = avcodec_find_encoder_by_name(codec.c_str()); hw_en_on = 0; hw_en_supported = 0; @@ -350,7 +341,7 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value) { // Was option found? if (option || (name == "g" || name == "qmin" || name == "qmax" || name == "max_b_frames" || name == "mb_decision" || name == "level" || name == "profile" || name == "slices" || name == "rc_min_rate" || name == "rc_max_rate" || - name == "crf")) { + name == "crf" || name == "cqp")) { // Check for specific named options if (name == "g") // Set gop_size @@ -396,7 +387,57 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value) { // Buffer size convert >> c->rc_buffer_size; - else if (name == "crf") { + else if (name == "cqp") { + // encode quality and special settings like lossless + // This might be better in an extra methods as more options + // and way to set quality are possible + #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) + #if IS_FFMPEG_3_2 + if (hw_en_on) { + av_opt_set_int(c->priv_data, "qp", min(stoi(value),63), 0); // 0-63 + } else + #endif + { + switch (c->codec_id) { + #if (LIBAVCODEC_VERSION_MAJOR >= 58) + case AV_CODEC_ID_AV1 : + c->bit_rate = 0; + av_opt_set_int(c->priv_data, "qp", min(stoi(value),63), 0); // 0-63 + break; + #endif + case AV_CODEC_ID_VP8 : + c->bit_rate = 10000000; + av_opt_set_int(c->priv_data, "qp", max(min(stoi(value), 63), 4), 0); // 4-63 + break; + case AV_CODEC_ID_VP9 : + c->bit_rate = 0; // Must be zero! + av_opt_set_int(c->priv_data, "qp", min(stoi(value), 63), 0); // 0-63 + if (stoi(value) == 0) { + av_opt_set(c->priv_data, "preset", "veryslow", 0); + av_opt_set_int(c->priv_data, "lossless", 1, 0); + } + break; + case AV_CODEC_ID_H264 : + av_opt_set_int(c->priv_data, "qp", min(stoi(value), 51), 0); // 0-51 + if (stoi(value) == 0) { + av_opt_set(c->priv_data, "preset", "veryslow", 0); + } + break; + case AV_CODEC_ID_H265 : + av_opt_set_int(c->priv_data, "qp", min(stoi(value), 51), 0); // 0-51 + if (stoi(value) == 0) { + av_opt_set(c->priv_data, "preset", "veryslow", 0); + av_opt_set_int(c->priv_data, "lossless", 1, 0); + } + break; + default: + // For all other codecs assume a range of 0-63 + av_opt_set_int(c->priv_data, "qp", min(stoi(value), 63), 0); // 0-63 + c->bit_rate = 0; + } + } + #endif + } else if (name == "crf") { // encode quality and special settings like lossless // This might be better in an extra methods as more options // and way to set quality are possible @@ -480,7 +521,7 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value) { // write selfcontained fragmented file, minimum length of the fragment 8 sec; only for MOV, MP4 av_dict_set(&mux_dict, "movflags", "frag_keyframe", 0); av_dict_set(&mux_dict, "min_frag_duration", "8000000", 0); - } + } } else { throw InvalidOptions("The option is not valid for this codec.", path); } @@ -543,6 +584,7 @@ void FFmpegWriter::WriteHeader() { // Write the stream header if (avformat_write_header(oc, &dict) != 0) { + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::WriteHeader (avformat_write_header)"); throw InvalidFile("Could not write header to file.", path); }; @@ -1241,7 +1283,7 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) { // Open the codec if (avcodec_open2(audio_codec, codec, &opts) < 0) - throw InvalidCodec("Could not open codec", path); + throw InvalidCodec("Could not open audio codec", path); AV_COPY_PARAMS_FROM_CONTEXT(st, audio_codec); // Free options @@ -1330,7 +1372,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { #elif defined(__APPLE__) if( adapter_ptr != NULL ) { #endif - ZmqLogger::Instance()->AppendDebugMethod("Encode Device present using device"); + ZmqLogger::Instance()->AppendDebugMethod("Encode Device present using device", "adapter", adapter_num); } else { adapter_ptr = NULL; // use default @@ -1361,23 +1403,58 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { #if IS_FFMPEG_3_2 if (hw_en_on && hw_en_supported) { - video_codec->max_b_frames = 0; // At least this GPU doesn't support b-frames video_codec->pix_fmt = hw_en_av_pix_fmt; - video_codec->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED; - av_opt_set(video_codec->priv_data,"preset","slow",0); - av_opt_set(video_codec->priv_data,"tune","zerolatency",0); - av_opt_set(video_codec->priv_data, "vprofile", "baseline", AV_OPT_SEARCH_CHILDREN); + + // for the list of possible options, see the list of codec-specific options: + // e.g. ffmpeg -h encoder=h264_vaapi or ffmpeg -h encoder=hevc_vaapi + // and "man ffmpeg-codecs" + + // For VAAPI, it is safer to explicitly set rc_mode instead of relying on auto-selection + // which is ffmpeg version-specific. + if (hw_en_av_pix_fmt == AV_PIX_FMT_VAAPI) { + int64_t qp; + if (av_opt_get_int(video_codec->priv_data, "qp", 0, &qp) != 0 || qp == 0) { + // unless "qp" was set for CQP, switch to VBR RC mode + av_opt_set(video_codec->priv_data, "rc_mode", "VBR", 0); + + // In the current state (ffmpeg-4.2-4 libva-mesa-driver-19.1.5-1) to use VBR, + // one has to specify both bit_rate and maxrate, otherwise a small low quality file is generated on Intel iGPU). + video_codec->rc_max_rate = video_codec->bit_rate; + } + } + + switch (video_codec->codec_id) { + case AV_CODEC_ID_H264: + video_codec->max_b_frames = 0; // At least this GPU doesn't support b-frames + video_codec->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED; + av_opt_set(video_codec->priv_data, "preset", "slow", 0); + av_opt_set(video_codec->priv_data, "tune", "zerolatency", 0); + av_opt_set(video_codec->priv_data, "vprofile", "baseline", AV_OPT_SEARCH_CHILDREN); + break; + case AV_CODEC_ID_HEVC: + // tested to work with defaults + break; + case AV_CODEC_ID_VP9: + // tested to work with defaults + break; + default: + ZmqLogger::Instance()->AppendDebugMethod("No codec-specific options defined for this codec. HW encoding may fail", + "codec_id", video_codec->codec_id); + break; + } + // set hw_frames_ctx for encoder's AVCodecContext int err; if ((err = set_hwframe_ctx(video_codec, hw_device_ctx, info.width, info.height)) < 0) { - fprintf(stderr, "Failed to set hwframe context.\n"); + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context", + "width", info.width, "height", info.height, av_err2str(err), -1); } } #endif /* open the codec */ if (avcodec_open2(video_codec, codec, &opts) < 0) - throw InvalidCodec("Could not open codec", path); + throw InvalidCodec("Could not open video codec", path); AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec); // Free options From 562171238851018573b39646b32ed25e703f2770 Mon Sep 17 00:00:00 2001 From: SuslikV Date: Sat, 24 Aug 2019 10:48:23 +0300 Subject: [PATCH 30/50] Fix return type mismatch --- include/PlayerBase.h | 2 +- include/QtPlayer.h | 2 +- src/QtPlayer.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/PlayerBase.h b/include/PlayerBase.h index f017c3f2..3438fdab 100644 --- a/include/PlayerBase.h +++ b/include/PlayerBase.h @@ -81,7 +81,7 @@ namespace openshot virtual void Pause() = 0; /// Get the current frame number being played - virtual int Position() = 0; + virtual int64_t Position() = 0; /// Seek to a specific frame in the player virtual void Seek(int64_t new_frame) = 0; diff --git a/include/QtPlayer.h b/include/QtPlayer.h index 5d0beba6..3339dbf5 100644 --- a/include/QtPlayer.h +++ b/include/QtPlayer.h @@ -81,7 +81,7 @@ namespace openshot void Pause(); /// Get the current frame number being played - int Position(); + int64_t Position(); /// Seek to a specific frame in the player void Seek(int64_t new_frame); diff --git a/src/QtPlayer.cpp b/src/QtPlayer.cpp index c53de79d..05204a6c 100644 --- a/src/QtPlayer.cpp +++ b/src/QtPlayer.cpp @@ -127,7 +127,7 @@ void QtPlayer::Pause() Speed(0); } -int QtPlayer::Position() +int64_t QtPlayer::Position() { return p->video_position; } From 8cb87c062fa5d30e082de2861680f029426b38c5 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 27 Aug 2019 22:07:20 -0400 Subject: [PATCH 31/50] 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 b8bb1a88f88b5a9708499eeb87c0fb74635578e6 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 7 Sep 2019 17:06:04 -0400 Subject: [PATCH 32/50] A more Pythonic openshot.Fraction Extend openshot::Fraction in the Python wrapper, to permit: ```py f = openshot.Fraction(16, 9) float(f) # returns 1.777777777 int(f) # returns 2 print(f) # outputs "16:9" dict(f.GetMap()) # in Python dict form --- src/bindings/python/openshot.i | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/bindings/python/openshot.i b/src/bindings/python/openshot.i index 512224ef..329ec28f 100644 --- a/src/bindings/python/openshot.i +++ b/src/bindings/python/openshot.i @@ -120,6 +120,34 @@ } } +/* Instantiate the required template specializations */ +%template() std::map; + +/* Make openshot.Fraction more Pythonic */ +%extend openshot::Fraction { +%{ + #include + #include +%} + double __float__() { + return $self->ToDouble(); + } + int __int__() { + return $self->ToInt(); + } + std::map GetMap() { + std::map map1; + map1.insert({"num", $self->num}); + map1.insert({"den", $self->den}); + return map1; + } + std::string __repr__() { + std::ostringstream result; + result << $self->num << ":" << $self->den; + return result.str(); + } +} + %include "OpenShotVersion.h" %include "../../../include/ReaderBase.h" %include "../../../include/WriterBase.h" From c8b5300df3def39db056ea0aef7538d622dc3686 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Fri, 20 Sep 2019 21:25:09 +1000 Subject: [PATCH 33/50] Allow font bold and italic properties to be set --- include/QtTextReader.h | 6 +++++- src/QtTextReader.cpp | 11 +++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/QtTextReader.h b/include/QtTextReader.h index a3fa014c..ee35dc28 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -95,6 +95,8 @@ namespace openshot std::string text; std::string font; double font_size; + bool is_bold; + bool is_italic; std::string text_color; std::string background_color; std::shared_ptr image; @@ -115,9 +117,11 @@ namespace openshot /// @param text The text you want to generate / display /// @param font The font of the text /// @param font_size The size of the text + /// @param is_bold Set to true to make text bold + /// @param is_italic Set to true to make text italic /// @param text_color The color of the text (valid values are a color string in #RRGGBB or #AARRGGBB notation or a CSS color name) /// @param background_color The background color of the frame image (valid values are a color string in #RRGGBB or #AARRGGBB notation, a CSS color name, or 'transparent') - QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, std::string text_color, std::string background_color); + QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, bool is_bold, bool is_italic, std::string text_color, std::string background_color); /// Close Reader void Close(); diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index 0c45ea4e..d56ca1af 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -37,15 +37,15 @@ using namespace openshot; /// Default constructor (blank text) -QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font("Arial"), font_size(10.0), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) +QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font("Arial"), font_size(10.0), is_bold(false), is_italic(false), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); Close(); } -QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, std::string text_color, std::string background_color) -: width(width), height(height), x_offset(x_offset), y_offset(y_offset), text(text), font(font), font_size(font_size), text_color(text_color), background_color(background_color), is_open(false), gravity(gravity) +QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, bool is_bold, bool is_italic, std::string text_color, std::string background_color) +: width(width), height(height), x_offset(x_offset), y_offset(y_offset), text(text), font(font), font_size(font_size), is_bold(is_bold), is_italic(is_italic), text_color(text_color), background_color(background_color), is_open(false), gravity(gravity) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); @@ -74,7 +74,10 @@ void QtTextReader::Open() painter.setPen(QPen(text_color.c_str())); // set font - painter.setFont(QFont(font.c_str(), font_size)); + QFont qFont(font.c_str(), font_size); + qFont.setBold(is_bold); + qFont.setItalic(is_italic); + painter.setFont(qFont); // Set gravity (map between OpenShot and Qt) int align_flag = 0; From 738dd62132ab209616dab497b6a4af374f89bf10 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Fri, 20 Sep 2019 22:10:07 +1000 Subject: [PATCH 34/50] Enable background fill color to be set behind text --- include/QtTextReader.h | 5 +++++ src/QtTextReader.cpp | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/QtTextReader.h b/include/QtTextReader.h index ee35dc28..c9f82f70 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -99,6 +99,7 @@ namespace openshot bool is_italic; std::string text_color; std::string background_color; + std::string text_background_color; std::shared_ptr image; bool is_open; openshot::GravityType gravity; @@ -123,6 +124,10 @@ namespace openshot /// @param background_color The background color of the frame image (valid values are a color string in #RRGGBB or #AARRGGBB notation, a CSS color name, or 'transparent') QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, bool is_bold, bool is_italic, std::string text_color, std::string background_color); + /// Draw a box under rendered text using the specified color. + /// @param text_background_color The background color behind the text (valid values are a color string in #RRGGBB or #AARRGGBB notation or a CSS color name) + void SetTextBackgroundColor(std::string color); + /// Close Reader void Close(); diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index d56ca1af..d17a486a 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -52,6 +52,14 @@ QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, Gr Close(); } +void QtTextReader::SetTextBackgroundColor(string color) { + text_background_color = color; + + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) plus the text background color + Open(); + Close(); +} + // Open reader void QtTextReader::Open() { @@ -68,7 +76,10 @@ void QtTextReader::Open() } // set background - painter.setBackground(QBrush(background_color.c_str())); + if (!text_background_color.empty()) { + painter.setBackgroundMode(Qt::OpaqueMode); + painter.setBackground(QBrush(text_background_color.c_str())); + } // set font color painter.setPen(QPen(text_color.c_str())); @@ -210,6 +221,7 @@ Json::Value QtTextReader::JsonValue() { root["font_size"] = font_size; root["text_color"] = text_color; root["background_color"] = background_color; + root["text_background_color"] = text_background_color; root["gravity"] = gravity; // return JsonValue @@ -270,6 +282,8 @@ void QtTextReader::SetJsonValue(Json::Value root) { text_color = root["text_color"].asString(); if (!root["background_color"].isNull()) background_color = root["background_color"].asString(); + if (!root["text_background_color"].isNull()) + text_background_color = root["text_background_color"].asString(); if (!root["gravity"].isNull()) gravity = (GravityType) root["gravity"].asInt(); From 0cae5da6fad9b8a12e039af7775b5a1e99404b2a Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Fri, 20 Sep 2019 22:38:31 +1000 Subject: [PATCH 35/50] Correct parameter documentation --- include/QtTextReader.h | 2 +- include/TextReader.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/QtTextReader.h b/include/QtTextReader.h index c9f82f70..2e0b6840 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -125,7 +125,7 @@ namespace openshot QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, bool is_bold, bool is_italic, std::string text_color, std::string background_color); /// Draw a box under rendered text using the specified color. - /// @param text_background_color The background color behind the text (valid values are a color string in #RRGGBB or #AARRGGBB notation or a CSS color name) + /// @param color The background color behind the text (valid values are a color string in #RRGGBB or #AARRGGBB notation or a CSS color name) void SetTextBackgroundColor(std::string color); /// Close Reader diff --git a/include/TextReader.h b/include/TextReader.h index 7b276f7f..0995357d 100644 --- a/include/TextReader.h +++ b/include/TextReader.h @@ -121,7 +121,7 @@ namespace openshot TextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string text, string font, double size, string text_color, string background_color); /// Draw a box under rendered text using the specified color. - /// @param text_background_color The background color behind the text + /// @param color The background color behind the text void SetTextBackgroundColor(string color); /// Close Reader From 33f16d3a55c555e035c4f7ded95a7e8fecf1c7c6 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Sat, 21 Sep 2019 21:11:29 +1000 Subject: [PATCH 36/50] Use QFont instead of setting parameters --- include/QtTextReader.h | 7 ++----- src/QtTextReader.cpp | 18 ++++++------------ 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/include/QtTextReader.h b/include/QtTextReader.h index 2e0b6840..3bcb2236 100644 --- a/include/QtTextReader.h +++ b/include/QtTextReader.h @@ -93,10 +93,7 @@ namespace openshot int x_offset; int y_offset; std::string text; - std::string font; - double font_size; - bool is_bold; - bool is_italic; + QFont font; std::string text_color; std::string background_color; std::string text_background_color; @@ -122,7 +119,7 @@ namespace openshot /// @param is_italic Set to true to make text italic /// @param text_color The color of the text (valid values are a color string in #RRGGBB or #AARRGGBB notation or a CSS color name) /// @param background_color The background color of the frame image (valid values are a color string in #RRGGBB or #AARRGGBB notation, a CSS color name, or 'transparent') - QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, bool is_bold, bool is_italic, std::string text_color, std::string background_color); + QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, QFont font, std::string text_color, std::string background_color); /// Draw a box under rendered text using the specified color. /// @param color The background color behind the text (valid values are a color string in #RRGGBB or #AARRGGBB notation or a CSS color name) diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index d17a486a..e32835cf 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -37,15 +37,15 @@ using namespace openshot; /// Default constructor (blank text) -QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font("Arial"), font_size(10.0), is_bold(false), is_italic(false), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) +QtTextReader::QtTextReader() : width(1024), height(768), x_offset(0), y_offset(0), text(""), font(QFont("Arial", 10)), text_color("#ffffff"), background_color("#000000"), is_open(false), gravity(GRAVITY_CENTER) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); Close(); } -QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, std::string font, double font_size, bool is_bold, bool is_italic, std::string text_color, std::string background_color) -: width(width), height(height), x_offset(x_offset), y_offset(y_offset), text(text), font(font), font_size(font_size), is_bold(is_bold), is_italic(is_italic), text_color(text_color), background_color(background_color), is_open(false), gravity(gravity) +QtTextReader::QtTextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, std::string text, QFont font, std::string text_color, std::string background_color) +: width(width), height(height), x_offset(x_offset), y_offset(y_offset), text(text), font(font), text_color(text_color), background_color(background_color), is_open(false), gravity(gravity) { // Open and Close the reader, to populate it's attributes (such as height, width, etc...) Open(); @@ -85,10 +85,7 @@ void QtTextReader::Open() painter.setPen(QPen(text_color.c_str())); // set font - QFont qFont(font.c_str(), font_size); - qFont.setBold(is_bold); - qFont.setItalic(is_italic); - painter.setFont(qFont); + painter.setFont(font); // Set gravity (map between OpenShot and Qt) int align_flag = 0; @@ -217,8 +214,7 @@ Json::Value QtTextReader::JsonValue() { root["x_offset"] = x_offset; root["y_offset"] = y_offset; root["text"] = text; - root["font"] = font; - root["font_size"] = font_size; + root["font"] = font.toString().toStdString(); root["text_color"] = text_color; root["background_color"] = background_color; root["text_background_color"] = text_background_color; @@ -275,9 +271,7 @@ void QtTextReader::SetJsonValue(Json::Value root) { if (!root["text"].isNull()) text = root["text"].asString(); if (!root["font"].isNull()) - font = root["font"].asString(); - if (!root["font_size"].isNull()) - font_size = root["font_size"].asDouble(); + font.fromString(QString::fromStdString(root["font"].asString())); if (!root["text_color"].isNull()) text_color = root["text_color"].asString(); if (!root["background_color"].isNull()) From 5bf38934989d8bdcc4fdf415eba7d0569f813172 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 24 Sep 2019 23:21:14 -0400 Subject: [PATCH 37/50] FindFFmpeg.cmake: create targets --- cmake/Modules/FindFFmpeg.cmake | 313 +++++++++++++++++++++------------ 1 file changed, 196 insertions(+), 117 deletions(-) diff --git a/cmake/Modules/FindFFmpeg.cmake b/cmake/Modules/FindFFmpeg.cmake index c4eb7ca3..4c81e95b 100644 --- a/cmake/Modules/FindFFmpeg.cmake +++ b/cmake/Modules/FindFFmpeg.cmake @@ -1,55 +1,93 @@ # vim: ts=2 sw=2 -# - Try to find the required ffmpeg components(default: AVFORMAT, AVUTIL, AVCODEC) -# -# Once done this will define -# FFMPEG_FOUND - System has the all required components. -# FFMPEG_INCLUDE_DIRS - Include directory necessary for using the required components headers. -# FFMPEG_LIBRARIES - Link these to use the required ffmpeg components. -# FFMPEG_DEFINITIONS - Compiler switches required for using the required ffmpeg components. -# -# For each of the components it will additionally set. -# - AVCODEC -# - AVDEVICE -# - AVFORMAT -# - AVFILTER -# - AVUTIL -# - POSTPROC -# - SWSCALE -# - SWRESAMPLE -# - AVRESAMPLE -# the following variables will be defined -# _FOUND - System has -# _INCLUDE_DIRS - Include directory necessary for using the headers -# _LIBRARIES - Link these to use -# _DEFINITIONS - Compiler switches required for using -# _VERSION - The components version -# -# Copyright (c) 2006, Matthias Kretz, -# Copyright (c) 2008, Alexander Neundorf, -# Copyright (c) 2011, Michael Jansen, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +#[=======================================================================[.rst: +FindFFmpeg +---------- +Try to find the requested ffmpeg components(default: avformat, avutil, avcodec) +IMPORTED targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` targets ``FFmpeg:`` for +each found component (see below). + +Components +^^^^^^^^^^ + +The module recognizes the following components: + +:: + + avcodec - target FFmpeg::avcodec + avdevice - target FFmpeg::avdevice + avformat - target FFmpeg::avformat + avfilter - target FFmpeg::avfilter + avutil - target FFmpeg::avutil + postproc - target FFmpeg::postproc + swscale - target FFmpeg::swscale + swresample - target FFmpeg::swresample + avresample - target FFmpeg::avresample + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +:: + + FFMPEG_FOUND - System has the all required components. + FFMPEG_INCLUDE_DIRS - Include directory necessary for using the required components headers. + FFMPEG_LIBRARIES - Link these to use the required ffmpeg components. + FFMPEG_DEFINITIONS - Compiler switches required for using the required ffmpeg components. + +For each component, ``_FOUND`` will be set if the component is available. + +For each ``_FOUND``, the following variables will be defined: + +:: + + _INCLUDE_DIRS - Include directory necessary for using the headers + _LIBRARIES - Link these to use + _DEFINITIONS - Compiler switches required for using + _VERSION - The components version + +Backwards compatibility +^^^^^^^^^^^^^^^^^^^^^^^ + +For compatibility with previous versions of this module, uppercase names +for FFmpeg and for all components are also recognized, and all-uppercase +versions of the cache variables are also created. + +Copyright (c) 2006, Matthias Kretz, +Copyright (c) 2008, Alexander Neundorf, +Copyright (c) 2011, Michael Jansen, +Copyright (c) 2019, FeRD (Frank Dana) + +Redistribution and use is allowed according to the terms of the BSD license. +For details see the accompanying COPYING-CMAKE-SCRIPTS file. +#]=======================================================================] include(FindPackageHandleStandardArgs) # The default components were taken from a survey over other FindFFMPEG.cmake files if (NOT FFmpeg_FIND_COMPONENTS) - set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL) + set(FFmpeg_FIND_COMPONENTS avcodec avformat avutil) endif () +set(FFmpeg_ALL_COMPONENTS avcodec avdevice avformat avfilter avutil postproc swscale swresample avresample) + # ### Macro: set_component_found # # Marks the given component as found if both *_LIBRARIES AND *_INCLUDE_DIRS is present. # macro(set_component_found _component ) - if (${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS) - # message(STATUS " - ${_component} found.") - set(${_component}_FOUND TRUE) - else () - # message(STATUS " - ${_component} not found.") - endif () + if (${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS) + # message(STATUS "FFmpeg - ${_component} found.") + set(${_component}_FOUND TRUE) + else () + if (NOT FFmpeg_FIND_QUIETLY AND NOT FFMPEG_FIND_QUIETLY) + message(STATUS "FFmpeg - ${_component} not found.") + endif () + endif () endmacro() # @@ -60,102 +98,143 @@ endmacro() # macro(find_component _component _pkgconfig _library _header) - if (NOT WIN32) - # use pkg-config to get the directories and then use these values - # in the FIND_PATH() and FIND_LIBRARY() calls - find_package(PkgConfig) - if (PKG_CONFIG_FOUND) - pkg_check_modules(PC_${_component} ${_pkgconfig}) - endif () - endif (NOT WIN32) + if (NOT WIN32) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + find_package(PkgConfig) + if (PKG_CONFIG_FOUND) + pkg_check_modules(PC_${_component} ${_pkgconfig}) + endif () + endif (NOT WIN32) - find_path(${_component}_INCLUDE_DIRS ${_header} - HINTS - /opt/ - /opt/include/ - ${PC_LIB${_component}_INCLUDEDIR} - ${PC_LIB${_component}_INCLUDE_DIRS} - $ENV{FFMPEGDIR}/include/ - $ENV{FFMPEGDIR}/include/ffmpeg/ - PATH_SUFFIXES - ffmpeg - ) + find_path(${_component}_INCLUDE_DIRS ${_header} + HINTS + /opt/ + /opt/include/ + ${PC_${_component}_INCLUDEDIR} + ${PC_${_component}_INCLUDE_DIRS} + $ENV{FFMPEGDIR}/include/ + $ENV{FFMPEGDIR}/include/ffmpeg/ + PATH_SUFFIXES + ffmpeg + ) - find_library(${_component}_LIBRARIES NAMES ${_library} - HINTS - ${PC_LIB${_component}_LIBDIR} - ${PC_LIB${_component}_LIBRARY_DIRS} - $ENV{FFMPEGDIR}/lib/ - $ENV{FFMPEGDIR}/lib/ffmpeg/ - $ENV{FFMPEGDIR}/bin/ - ) + find_library(${_component}_LIBRARIES NAMES ${_library} + HINTS + ${PC_${_component}_LIBDIR} + ${PC_${_component}_LIBRARY_DIRS} + $ENV{FFMPEGDIR}/lib/ + $ENV{FFMPEGDIR}/lib/ffmpeg/ + $ENV{FFMPEGDIR}/bin/ + ) - set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.") - set(${_component}_VERSION ${PC_${_component}_VERSION} CACHE STRING "The ${_component} version number.") + set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.") + set(${_component}_VERSION ${PC_${_component}_VERSION} CACHE STRING "The ${_component} version number.") - set_component_found(${_component}) + set_component_found(${_component}) - mark_as_advanced( - ${_component}_INCLUDE_DIRS - ${_component}_LIBRARIES - ${_component}_DEFINITIONS - ${_component}_VERSION) + mark_as_advanced( + ${_component}_INCLUDE_DIRS + ${_component}_LIBRARIES + ${_component}_DEFINITIONS + ${_component}_VERSION) endmacro() # Check for cached results. If there are skip the costly part. -if (NOT FFMPEG_LIBRARIES) +if (NOT FFmpeg_LIBRARIES) - # Check for all possible component. - find_component(AVCODEC libavcodec avcodec libavcodec/avcodec.h) - find_component(AVFORMAT libavformat avformat libavformat/avformat.h) - find_component(AVDEVICE libavdevice avdevice libavdevice/avdevice.h) - find_component(AVUTIL libavutil avutil libavutil/avutil.h) - find_component(AVFILTER libavfilter avfilter libavfilter/avfilter.h) - find_component(SWSCALE libswscale swscale libswscale/swscale.h) - find_component(POSTPROC libpostproc postproc libpostproc/postprocess.h) - find_component(SWRESAMPLE libswresample swresample libswresample/swresample.h) - find_component(AVRESAMPLE libavresample avresample libavresample/avresample.h) + # Check for all possible component. + find_component(avcodec libavcodec avcodec libavcodec/avcodec.h) + find_component(avdevice libavdevice avdevice libavdevice/avdevice.h) + find_component(avformat libavformat avformat libavformat/avformat.h) + find_component(avfilter libavfilter avfilter libavfilter/avfilter.h) + find_component(avutil libavutil avutil libavutil/avutil.h) + find_component(postproc libpostproc postproc libpostproc/postprocess.h) + find_component(swscale libswscale swscale libswscale/swscale.h) + find_component(swresample libswresample swresample libswresample/swresample.h) + find_component(avresample libavresample avresample libavresample/avresample.h) +else() + # Just set the noncached _FOUND vars for the components. + foreach(_component ${FFmpeg_ALL_COMPONENTS}) + set_component_found(${_component}) + endforeach () +endif() - # Check if the required components were found and add their stuff to the FFMPEG_* vars. - foreach (_component ${FFmpeg_FIND_COMPONENTS}) - if (${_component}_FOUND) - # message(STATUS "Required component ${_component} present.") - set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${${_component}_LIBRARIES}) - set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} ${${_component}_DEFINITIONS}) - list(APPEND FFMPEG_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS}) - else () - # message(STATUS "Required component ${_component} missing.") - endif () - endforeach () - - # Build the include path with duplicates removed. - if (FFMPEG_INCLUDE_DIRS) - list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS) - endif () - - # cache the vars. - set(FFMPEG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIRS} CACHE STRING "The FFmpeg include directories." FORCE) - set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} CACHE STRING "The FFmpeg libraries." FORCE) - set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} CACHE STRING "The FFmpeg cflags." FORCE) - - mark_as_advanced(FFMPEG_INCLUDE_DIRS - FFMPEG_LIBRARIES - FFMPEG_DEFINITIONS) - -endif () - -# Now set the noncached _FOUND vars for the components. -foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE SWRESAMPLE AVRESAMPLE) - set_component_found(${_component}) +# Check if the requested components were found and add their stuff to the FFmpeg_* vars. +foreach (_component ${FFmpeg_FIND_COMPONENTS}) + string(TOLOWER "${_component}" _component) + if (${_component}_FOUND) + # message(STATUS "Requested component ${_component} present.") + set(FFmpeg_LIBRARIES ${FFmpeg_LIBRARIES} ${${_component}_LIBRARIES}) + set(FFmpeg_DEFINITIONS ${FFmpeg_DEFINITIONS} ${${_component}_DEFINITIONS}) + list(APPEND FFmpeg_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS}) + else () + # message(STATUS "Requested component ${_component} missing.") + endif () endforeach () +# Build the include path with duplicates removed. +if (FFmpeg_INCLUDE_DIRS) + list(REMOVE_DUPLICATES FFmpeg_INCLUDE_DIRS) +endif () + +# cache the vars. +set(FFmpeg_INCLUDE_DIRS ${FFmpeg_INCLUDE_DIRS} CACHE STRING "The FFmpeg include directories." FORCE) +set(FFmpeg_LIBRARIES ${FFmpeg_LIBRARIES} CACHE STRING "The FFmpeg libraries." FORCE) +set(FFmpeg_DEFINITIONS ${FFmpeg_DEFINITIONS} CACHE STRING "The FFmpeg cflags." FORCE) + +mark_as_advanced(FFmpeg_INCLUDE_DIRS + FFmpeg_LIBRARIES + FFmpeg_DEFINITIONS) + +# Backwards compatibility +foreach(_suffix INCLUDE_DIRS LIBRARIES DEFINITIONS) + get_property(_help CACHE FFmpeg_${_suffix} PROPERTY HELPSTRING) + set(FFMPEG_${_suffix} ${FFmpeg_${_suffix}} CACHE STRING "${_help}" FORCE) + mark_as_advanced(FFMPEG_${_suffix}) +endforeach() +foreach(_component ${FFmpeg_ALL_COMPONENTS}) + if(${_component}_FOUND) + string(TOUPPER "${_component}" _uc_component) + set(${_uc_component}_FOUND TRUE) + foreach(_suffix INCLUDE_DIRS LIBRARIES DEFINITIONS VERSION) + get_property(_help CACHE ${_component}_${_suffix} PROPERTY HELPSTRING) + set(${_uc_component}_${_suffix} ${${_component}_${_suffix}} CACHE STRING "${_help}" FORCE) + mark_as_advanced(${_uc_component}_${_suffix}) + endforeach() + endif() +endforeach() + # Compile the list of required vars -set(_FFmpeg_REQUIRED_VARS FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIRS) +set(_FFmpeg_REQUIRED_VARS FFmpeg_LIBRARIES FFmpeg_INCLUDE_DIRS) foreach (_component ${FFmpeg_FIND_COMPONENTS}) - list(APPEND _FFmpeg_REQUIRED_VARS ${_component}_LIBRARIES ${_component}_INCLUDE_DIRS) + list(APPEND _FFmpeg_REQUIRED_VARS ${_component}_LIBRARIES ${_component}_INCLUDE_DIRS) endforeach () # Give a nice error message if some of the required vars are missing. find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${_FFmpeg_REQUIRED_VARS}) + +# Export targets for each found component +foreach (_component ${FFmpeg_ALL_COMPONENTS}) + + if(${_component}_FOUND) + # message(STATUS "Creating IMPORTED target FFmpeg::${_component}") + + if(NOT TARGET FFmpeg::${_component}) + add_library(FFmpeg::${_component} UNKNOWN IMPORTED) + + set_target_properties(FFmpeg::${_component} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${${_component}_INCLUDE_DIRS}") + + set_property(TARGET FFmpeg::${_component} APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS "${${_component}_DEFINITIONS}") + + set_property(TARGET FFmpeg::${_component} APPEND PROPERTY + IMPORTED_LOCATION "${${_component}_LIBRARIES}") + endif() + + endif() + +endforeach() From 6502c2a6b2ddd710b007a531887154795940c707 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 2 Oct 2019 09:29:15 -0400 Subject: [PATCH 38/50] CMake: Link with FFmpeg:: targets --- src/CMakeLists.txt | 39 ++++++++++++++++++++++++--------------- tests/CMakeLists.txt | 14 -------------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4045b7d0..5776f40f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -84,19 +84,19 @@ IF (ImageMagick_FOUND) ENDIF (ImageMagick_FOUND) -################### FFMPEG ##################### -# Find FFmpeg libraries (used for video encoding / decoding) -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() -endforeach() -list(REMOVE_DUPLICATES FF_INCLUDES) -include_directories(${FF_INCLUDES}) +# ################### FFMPEG ##################### +# # Find FFmpeg libraries (used for video encoding / decoding) +# 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() +# endforeach() +# list(REMOVE_DUPLICATES FF_INCLUDES) +# include_directories(${FF_INCLUDES}) ################# LIBOPENSHOT-AUDIO ################### # Find JUCE-based openshot Audio libraries @@ -273,10 +273,19 @@ set_target_properties(openshot INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" ) +################### FFMPEG ##################### +# Find FFmpeg libraries (used for video encoding / decoding) +FIND_PACKAGE(FFmpeg REQUIRED) + +foreach(ff_comp avcodec avdevice avformat avfilter avutil postproc swscale swresample avresample) + if(TARGET FFmpeg::${ff_comp}) + target_link_libraries(openshot PUBLIC FFmpeg::${ff_comp}) + endif() +endforeach() + ############### LINK LIBRARY ################# SET ( REQUIRED_LIBRARIES ${LIBOPENSHOT_AUDIO_LIBRARIES} - ${FF_LIBRARIES} ${QT_LIBRARIES} ${PROFILER} ${JSONCPP_LIBRARY} @@ -305,7 +314,7 @@ IF (WIN32) ENDIF(WIN32) # Link all referenced libraries -target_link_libraries(openshot ${REQUIRED_LIBRARIES}) +target_link_libraries(openshot PUBLIC ${REQUIRED_LIBRARIES}) ############### CLI EXECUTABLE ################ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ab44fa31..3c0cba7e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -77,20 +77,6 @@ IF (ImageMagick_FOUND) ENDIF (ImageMagick_FOUND) -################### FFMPEG ##################### -# Find FFmpeg libraries (used for video encoding / decoding) -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() -endforeach() -list(REMOVE_DUPLICATES FF_INCLUDES) -include_directories(${FF_INCLUDES}) - ################# LIBOPENSHOT-AUDIO ################### # Find JUCE-based openshot Audio libraries FIND_PACKAGE(OpenShotAudio 0.1.8 REQUIRED) From 655b137ee20eeafcf082079cc25822e40dc13715 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 2 Oct 2019 09:30:06 -0400 Subject: [PATCH 39/50] Bindings: Pick up include dirs from targets --- src/bindings/python/CMakeLists.txt | 9 ++++++++- src/bindings/ruby/CMakeLists.txt | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index 9afabd41..90053270 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -56,6 +56,13 @@ if (PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) separate_arguments(sw_flags UNIX_COMMAND ${SWIG_CXX_FLAGS}) set_property(SOURCE openshot.i PROPERTY GENERATED_COMPILE_OPTIONS ${sw_flags}) + ### Take include dirs from target, automatically if possible + if (CMAKE_VERSION VERSION_GREATER 3.13) + set_property(SOURCE openshot.i PROPERTY USE_TARGET_INCLUDE_DIRECTORIES True) + else () + set_property(SOURCE openshot.i PROPERTY INCLUDE_DIRECTORIES $) + endif () + ### Add the SWIG interface file (which defines all the SWIG methods) if (CMAKE_VERSION VERSION_LESS 3.8.0) swig_add_module(pyopenshot python openshot.i) @@ -69,7 +76,7 @@ if (PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) ### Link the new python wrapper library with libopenshot target_link_libraries(${SWIG_MODULE_pyopenshot_REAL_NAME} - ${PYTHON_LIBRARIES} openshot) + PUBLIC ${PYTHON_LIBRARIES} openshot) ### Check if the following Debian-friendly python module path exists SET(PYTHON_MODULE_PATH "${CMAKE_INSTALL_PREFIX}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages") diff --git a/src/bindings/ruby/CMakeLists.txt b/src/bindings/ruby/CMakeLists.txt index 4b962e73..5208abc1 100644 --- a/src/bindings/ruby/CMakeLists.txt +++ b/src/bindings/ruby/CMakeLists.txt @@ -57,6 +57,13 @@ IF (RUBY_FOUND) separate_arguments(sw_flags UNIX_COMMAND ${SWIG_CXX_FLAGS}) set_property(SOURCE openshot.i PROPERTY GENERATED_COMPILE_OPTIONS ${sw_flags}) + ### Take include dirs from target, automatically if possible + if (CMAKE_VERSION VERSION_GREATER 3.13) + set_property(SOURCE openshot.i PROPERTY USE_TARGET_INCLUDE_DIRECTORIES True) + else () + set_property(SOURCE openshot.i PROPERTY INCLUDE_DIRECTORIES $) + endif () + ### Add the SWIG interface file (which defines all the SWIG methods) if (CMAKE_VERSION VERSION_LESS 3.8.0) swig_add_module(rbopenshot ruby openshot.i) From beab9527026c1ab8cb3bb62cad0e21cdd8ebbf5e Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 3 Oct 2019 04:17:13 -0400 Subject: [PATCH 40/50] FindFFmpeg: Default to all components, if not specified --- cmake/Modules/FindFFmpeg.cmake | 75 +++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/cmake/Modules/FindFFmpeg.cmake b/cmake/Modules/FindFFmpeg.cmake index 4c81e95b..b2409e05 100644 --- a/cmake/Modules/FindFFmpeg.cmake +++ b/cmake/Modules/FindFFmpeg.cmake @@ -67,12 +67,16 @@ For details see the accompanying COPYING-CMAKE-SCRIPTS file. #]=======================================================================] include(FindPackageHandleStandardArgs) -# The default components were taken from a survey over other FindFFMPEG.cmake files +set(FFmpeg_ALL_COMPONENTS avcodec avdevice avformat avfilter avutil postproc swscale swresample avresample) + +# Default to all components, if not specified +if (FFMPEG_FIND_COMPONENTS AND NOT FFmpeg_FIND_COMPONENTS) + set(FFmpeg_FIND_COMPONENTS ${FFMPEG_FIND_COMPONENTS}) +endif () if (NOT FFmpeg_FIND_COMPONENTS) - set(FFmpeg_FIND_COMPONENTS avcodec avformat avutil) + set(FFmpeg_FIND_COMPONENTS ${FFmpeg_ALL_COMPONENTS}) endif () -set(FFmpeg_ALL_COMPONENTS avcodec avdevice avformat avfilter avutil postproc swscale swresample avresample) # ### Macro: set_component_found @@ -81,12 +85,12 @@ set(FFmpeg_ALL_COMPONENTS avcodec avdevice avformat avfilter avutil postproc sws # macro(set_component_found _component ) if (${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS) - # message(STATUS "FFmpeg - ${_component} found.") + # message(STATUS "FFmpeg - ${_component} found.") set(${_component}_FOUND TRUE) else () - if (NOT FFmpeg_FIND_QUIETLY AND NOT FFMPEG_FIND_QUIETLY) - message(STATUS "FFmpeg - ${_component} not found.") - endif () + if (NOT FFmpeg_FIND_QUIETLY AND NOT FFMPEG_FIND_QUIETLY) + message(STATUS "FFmpeg - ${_component} not found.") + endif () endif () endmacro() @@ -108,25 +112,25 @@ macro(find_component _component _pkgconfig _library _header) endif (NOT WIN32) find_path(${_component}_INCLUDE_DIRS ${_header} - HINTS - /opt/ - /opt/include/ - ${PC_${_component}_INCLUDEDIR} - ${PC_${_component}_INCLUDE_DIRS} - $ENV{FFMPEGDIR}/include/ - $ENV{FFMPEGDIR}/include/ffmpeg/ - PATH_SUFFIXES - ffmpeg - ) + HINTS + /opt/ + /opt/include/ + ${PC_${_component}_INCLUDEDIR} + ${PC_${_component}_INCLUDE_DIRS} + $ENV{FFMPEGDIR}/include/ + $ENV{FFMPEGDIR}/include/ffmpeg/ + PATH_SUFFIXES + ffmpeg + ) find_library(${_component}_LIBRARIES NAMES ${_library} - HINTS - ${PC_${_component}_LIBDIR} - ${PC_${_component}_LIBRARY_DIRS} - $ENV{FFMPEGDIR}/lib/ - $ENV{FFMPEGDIR}/lib/ffmpeg/ - $ENV{FFMPEGDIR}/bin/ - ) + HINTS + ${PC_${_component}_LIBDIR} + ${PC_${_component}_LIBRARY_DIRS} + $ENV{FFMPEGDIR}/lib/ + $ENV{FFMPEGDIR}/lib/ffmpeg/ + $ENV{FFMPEGDIR}/bin/ + ) set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.") set(${_component}_VERSION ${PC_${_component}_VERSION} CACHE STRING "The ${_component} version number.") @@ -134,10 +138,11 @@ macro(find_component _component _pkgconfig _library _header) set_component_found(${_component}) mark_as_advanced( - ${_component}_INCLUDE_DIRS - ${_component}_LIBRARIES - ${_component}_DEFINITIONS - ${_component}_VERSION) + ${_component}_INCLUDE_DIRS + ${_component}_LIBRARIES + ${_component}_DEFINITIONS + ${_component}_VERSION + ) endmacro() @@ -166,12 +171,12 @@ endif() foreach (_component ${FFmpeg_FIND_COMPONENTS}) string(TOLOWER "${_component}" _component) if (${_component}_FOUND) - # message(STATUS "Requested component ${_component} present.") + # message(STATUS "Requested component ${_component} present.") set(FFmpeg_LIBRARIES ${FFmpeg_LIBRARIES} ${${_component}_LIBRARIES}) set(FFmpeg_DEFINITIONS ${FFmpeg_DEFINITIONS} ${${_component}_DEFINITIONS}) list(APPEND FFmpeg_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS}) else () - # message(STATUS "Requested component ${_component} missing.") + # message(STATUS "Requested component ${_component} missing.") endif () endforeach () @@ -186,8 +191,8 @@ set(FFmpeg_LIBRARIES ${FFmpeg_LIBRARIES} CACHE STRING "The FFmpeg librarie set(FFmpeg_DEFINITIONS ${FFmpeg_DEFINITIONS} CACHE STRING "The FFmpeg cflags." FORCE) mark_as_advanced(FFmpeg_INCLUDE_DIRS - FFmpeg_LIBRARIES - FFmpeg_DEFINITIONS) + FFmpeg_LIBRARIES + FFmpeg_DEFINITIONS) # Backwards compatibility foreach(_suffix INCLUDE_DIRS LIBRARIES DEFINITIONS) @@ -210,7 +215,9 @@ endforeach() # Compile the list of required vars set(_FFmpeg_REQUIRED_VARS FFmpeg_LIBRARIES FFmpeg_INCLUDE_DIRS) foreach (_component ${FFmpeg_FIND_COMPONENTS}) - list(APPEND _FFmpeg_REQUIRED_VARS ${_component}_LIBRARIES ${_component}_INCLUDE_DIRS) + list(APPEND _FFmpeg_REQUIRED_VARS + ${_component}_LIBRARIES + ${_component}_INCLUDE_DIRS) endforeach () # Give a nice error message if some of the required vars are missing. @@ -220,7 +227,7 @@ find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${_FFmpeg_REQUIRED_VARS}) foreach (_component ${FFmpeg_ALL_COMPONENTS}) if(${_component}_FOUND) - # message(STATUS "Creating IMPORTED target FFmpeg::${_component}") + # message(STATUS "Creating IMPORTED target FFmpeg::${_component}") if(NOT TARGET FFmpeg::${_component}) add_library(FFmpeg::${_component} UNKNOWN IMPORTED) From 798dcafb651da947b88a528e97bb40ceb2eb3407 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 8 Oct 2019 09:48:04 -0400 Subject: [PATCH 41/50] CMake: Set required FFMpeg libs --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5776f40f..5e6c631b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -275,7 +275,7 @@ set_target_properties(openshot ################### FFMPEG ##################### # Find FFmpeg libraries (used for video encoding / decoding) -FIND_PACKAGE(FFmpeg REQUIRED) +FIND_PACKAGE(FFmpeg REQUIRED COMPONENTS avcodec avdevice avformat avutil swscale) foreach(ff_comp avcodec avdevice avformat avfilter avutil postproc swscale swresample avresample) if(TARGET FFmpeg::${ff_comp}) From 56e8d8aa2b7a228ec45c16bcd6d45a2ab3a0bdb6 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 25 Oct 2019 02:06:29 -0400 Subject: [PATCH 42/50] Remove old commented-out code --- src/CMakeLists.txt | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9122f9bf..732d20e8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,9 +29,6 @@ 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 @@ -84,20 +81,6 @@ IF (ImageMagick_FOUND) ENDIF (ImageMagick_FOUND) -# ################### FFMPEG ##################### -# # Find FFmpeg libraries (used for video encoding / decoding) -# 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() -# endforeach() -# list(REMOVE_DUPLICATES FF_INCLUDES) -# include_directories(${FF_INCLUDES}) - ################# LIBOPENSHOT-AUDIO ################### # Find JUCE-based openshot Audio libraries FIND_PACKAGE(OpenShotAudio 0.1.8 REQUIRED) From 645946458b01adac7e6e234fb158459051c76a4f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 26 Oct 2019 07:22:01 -0400 Subject: [PATCH 43/50] DISABLE_TESTS covers entire tests/ dir --- CMakeLists.txt | 5 +-- tests/CMakeLists.txt | 86 ++++++++++++++++++++++---------------------- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0809c04d..6eb63c68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,5 +115,6 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html/ endif() ############# PROCESS tests/ DIRECTORY ############## -add_subdirectory(tests) - +if(NOT DISABLE_TESTS) + add_subdirectory(tests) +endif() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0bfd56d8..e15601eb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -160,52 +160,50 @@ else() include_directories("../thirdparty/jsoncpp") endif(USE_SYSTEM_JSONCPP) -IF (NOT DISABLE_TESTS) - ############### SET TEST SOURCE FILES ################# - SET ( OPENSHOT_TEST_FILES - Cache_Tests.cpp - Clip_Tests.cpp - Color_Tests.cpp - Coordinate_Tests.cpp - ReaderBase_Tests.cpp - ImageWriter_Tests.cpp - FFmpegReader_Tests.cpp - FFmpegWriter_Tests.cpp - Fraction_Tests.cpp - FrameMapper_Tests.cpp - KeyFrame_Tests.cpp - Point_Tests.cpp - Settings_Tests.cpp - Timeline_Tests.cpp ) +############### SET TEST SOURCE FILES ################# +SET ( OPENSHOT_TEST_FILES + Cache_Tests.cpp + Clip_Tests.cpp + Color_Tests.cpp + Coordinate_Tests.cpp + ReaderBase_Tests.cpp + ImageWriter_Tests.cpp + FFmpegReader_Tests.cpp + FFmpegWriter_Tests.cpp + Fraction_Tests.cpp + FrameMapper_Tests.cpp + KeyFrame_Tests.cpp + Point_Tests.cpp + Settings_Tests.cpp + Timeline_Tests.cpp ) - ################ 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} ) +################ 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} ) - # Link libraries to the new executable - target_link_libraries(openshot-test openshot ${UNITTEST++_LIBRARY}) +# Link libraries to the new executable +target_link_libraries(openshot-test openshot ${UNITTEST++_LIBRARY}) - ##### 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) - list(APPEND OS_TEST_CMDS "'make os_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) +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}") +# 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}") From 001cf00b8041ca2ba669db622d25ae84bb21b8aa Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 26 Oct 2019 08:29:19 -0400 Subject: [PATCH 44/50] Bump CMake min-version to 3.2, display --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0809c04d..f5ab4115 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ # along with OpenShot Library. If not, see . ################################################################################ -cmake_minimum_required(VERSION 3.1...3.14 FATAL_ERROR) +cmake_minimum_required(VERSION 3.2...3.14 FATAL_ERROR) message("\ ----------------------------------------------------------------- @@ -56,7 +56,7 @@ STRING(REGEX REPLACE "\-.*$" "" VERSION_NUM "${PROJECT_VERSION_FULL}") PROJECT(libopenshot LANGUAGES C CXX VERSION ${VERSION_NUM}) message(" -Generating build files for OpenShot +Generating build files for OpenShot with CMake ${CMAKE_VERSION} Building ${PROJECT_NAME} (version ${PROJECT_VERSION}) SO/API/ABI Version: ${PROJECT_SO_VERSION} ") From b6da6b9659cac60c6990119893aed04a3b62346d Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 27 Oct 2019 03:54:36 -0400 Subject: [PATCH 45/50] add DONT_SET_USING_JUCE_NAMESPACE to tests --- tests/Cache_Tests.cpp | 5 +++-- tests/Clip_Tests.cpp | 2 ++ tests/Color_Tests.cpp | 2 ++ tests/Coordinate_Tests.cpp | 2 ++ tests/FFmpegReader_Tests.cpp | 3 ++- tests/FFmpegWriter_Tests.cpp | 2 ++ tests/Fraction_Tests.cpp | 2 ++ tests/FrameMapper_Tests.cpp | 2 ++ tests/ImageWriter_Tests.cpp | 2 ++ tests/KeyFrame_Tests.cpp | 4 +++- tests/Point_Tests.cpp | 2 ++ tests/ReaderBase_Tests.cpp | 2 ++ tests/Settings_Tests.cpp | 2 ++ tests/Timeline_Tests.cpp | 2 ++ 14 files changed, 30 insertions(+), 4 deletions(-) diff --git a/tests/Cache_Tests.cpp b/tests/Cache_Tests.cpp index 7e42c741..ea5b45ce 100644 --- a/tests/Cache_Tests.cpp +++ b/tests/Cache_Tests.cpp @@ -29,10 +29,11 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" #include "../include/Json.h" -using namespace std; using namespace openshot; TEST(Cache_Default_Constructor) @@ -461,4 +462,4 @@ TEST(CacheMemory_JSON) CHECK_EQUAL(1, c.JsonValue()["ranges"].size()); CHECK_EQUAL("5", c.JsonValue()["version"].asString()); -} \ No newline at end of file +} diff --git a/tests/Clip_Tests.cpp b/tests/Clip_Tests.cpp index 5789780b..711fef03 100644 --- a/tests/Clip_Tests.cpp +++ b/tests/Clip_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/Color_Tests.cpp b/tests/Color_Tests.cpp index 86b3a458..210cca59 100644 --- a/tests/Color_Tests.cpp +++ b/tests/Color_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/Coordinate_Tests.cpp b/tests/Coordinate_Tests.cpp index ec8c29a1..a666ce8c 100644 --- a/tests/Coordinate_Tests.cpp +++ b/tests/Coordinate_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/FFmpegReader_Tests.cpp b/tests/FFmpegReader_Tests.cpp index 4b808d83..0a8620c9 100644 --- a/tests/FFmpegReader_Tests.cpp +++ b/tests/FFmpegReader_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; @@ -219,4 +221,3 @@ TEST(FFmpegReader_Multiple_Open_and_Close) // Close reader r.Close(); } - diff --git a/tests/FFmpegWriter_Tests.cpp b/tests/FFmpegWriter_Tests.cpp index 1cab8043..21940b1b 100644 --- a/tests/FFmpegWriter_Tests.cpp +++ b/tests/FFmpegWriter_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/Fraction_Tests.cpp b/tests/Fraction_Tests.cpp index 72bd6407..8f4f5f83 100644 --- a/tests/Fraction_Tests.cpp +++ b/tests/Fraction_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/FrameMapper_Tests.cpp b/tests/FrameMapper_Tests.cpp index f400d830..921f3a15 100644 --- a/tests/FrameMapper_Tests.cpp +++ b/tests/FrameMapper_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/ImageWriter_Tests.cpp b/tests/ImageWriter_Tests.cpp index 49202e96..bdf73a07 100644 --- a/tests/ImageWriter_Tests.cpp +++ b/tests/ImageWriter_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/KeyFrame_Tests.cpp b/tests/KeyFrame_Tests.cpp index 3d790739..3c94fa22 100644 --- a/tests/KeyFrame_Tests.cpp +++ b/tests/KeyFrame_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; @@ -396,4 +398,4 @@ TEST(Keyframe_Large_Number_Values) CHECK_EQUAL(kf.GetLength(), large_value + 1); CHECK_CLOSE(kf.GetPoint(0).co.Y, 1.0, 0.01); CHECK_CLOSE(kf.GetPoint(1).co.Y, 100.0, 0.01); -} \ No newline at end of file +} diff --git a/tests/Point_Tests.cpp b/tests/Point_Tests.cpp index ed560a9d..dfe35d2a 100644 --- a/tests/Point_Tests.cpp +++ b/tests/Point_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/ReaderBase_Tests.cpp b/tests/ReaderBase_Tests.cpp index 9f56cf6d..8ac28321 100644 --- a/tests/ReaderBase_Tests.cpp +++ b/tests/ReaderBase_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/Settings_Tests.cpp b/tests/Settings_Tests.cpp index cf7b8a00..b63b56a8 100644 --- a/tests/Settings_Tests.cpp +++ b/tests/Settings_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; diff --git a/tests/Timeline_Tests.cpp b/tests/Timeline_Tests.cpp index 77a3bcbc..946693a1 100644 --- a/tests/Timeline_Tests.cpp +++ b/tests/Timeline_Tests.cpp @@ -29,6 +29,8 @@ */ #include "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 #include "../include/OpenShot.h" using namespace std; From bcc62f900c6ae40303abab04d1b4377c06adbd22 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 27 Oct 2019 03:56:13 -0400 Subject: [PATCH 46/50] Fix juce:: prefixing --- include/AudioBufferSource.h | 16 ++++++++-------- include/AudioReaderSource.h | 14 +++++++------- include/AudioResampler.h | 14 +++++++------- include/CacheBase.h | 2 +- include/Clip.h | 8 ++++---- include/Frame.h | 4 ++-- include/ReaderBase.h | 4 ++-- include/ZmqLogger.h | 2 +- src/AudioBufferSource.cpp | 12 ++++++------ src/AudioReaderSource.cpp | 12 ++++++------ src/AudioResampler.cpp | 10 +++++----- src/Clip.cpp | 12 ++++++------ src/Frame.cpp | 32 ++++++++++++++++---------------- 13 files changed, 71 insertions(+), 71 deletions(-) diff --git a/include/AudioBufferSource.h b/include/AudioBufferSource.h index 4addb37d..d1eba986 100644 --- a/include/AudioBufferSource.h +++ b/include/AudioBufferSource.h @@ -54,25 +54,25 @@ namespace openshot * The JUCE library cannot play audio directly from an AudioSampleBuffer, so this class exposes * an AudioSampleBuffer as a AudioSource, so that JUCE can play the audio. */ - class AudioBufferSource : public PositionableAudioSource + class AudioBufferSource : public juce::PositionableAudioSource { private: int position; int start; bool repeat; - AudioSampleBuffer *buffer; + juce::AudioSampleBuffer *buffer; public: /// @brief Default constructor /// @param audio_buffer This buffer contains the samples you want to play through JUCE. - AudioBufferSource(AudioSampleBuffer *audio_buffer); + AudioBufferSource(juce::AudioSampleBuffer *audio_buffer); /// Destructor ~AudioBufferSource(); /// @brief Get the next block of audio samples /// @param info This struct informs us of which samples are needed next. - void getNextAudioBlock (const AudioSourceChannelInfo& info); + void getNextAudioBlock (const juce::AudioSourceChannelInfo& info); /// Prepare to play this audio source void prepareToPlay(int, double); @@ -82,13 +82,13 @@ namespace openshot /// @brief Set the next read position of this source /// @param newPosition The sample # to start reading from - void setNextReadPosition (int64 newPosition); + void setNextReadPosition (juce::int64 newPosition); /// Get the next read position of this source - int64 getNextReadPosition() const; + juce::int64 getNextReadPosition() const; /// Get the total length (in samples) of this audio source - int64 getTotalLength() const; + juce::int64 getTotalLength() const; /// Determines if this audio source should repeat when it reaches the end bool isLooping() const; @@ -98,7 +98,7 @@ namespace openshot void setLooping (bool shouldLoop); /// Update the internal buffer used by this source - void setBuffer (AudioSampleBuffer *audio_buffer); + void setBuffer (juce::AudioSampleBuffer *audio_buffer); }; } diff --git a/include/AudioReaderSource.h b/include/AudioReaderSource.h index 679aed61..6e2f541e 100644 --- a/include/AudioReaderSource.h +++ b/include/AudioReaderSource.h @@ -54,13 +54,13 @@ namespace openshot * * This allows any reader to play audio through JUCE (our audio framework). */ - class AudioReaderSource : public PositionableAudioSource + class AudioReaderSource : public juce::PositionableAudioSource { private: int position; /// The position of the audio source (index of buffer) bool repeat; /// Repeat the audio source when finished int size; /// The size of the internal buffer - AudioSampleBuffer *buffer; /// The audio sample buffer + juce::AudioSampleBuffer *buffer; /// The audio sample buffer int speed; /// The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...) ReaderBase *reader; /// The reader to pull samples from @@ -90,7 +90,7 @@ namespace openshot /// @brief Get the next block of audio samples /// @param info This struct informs us of which samples are needed next. - void getNextAudioBlock (const AudioSourceChannelInfo& info); + void getNextAudioBlock (const juce::AudioSourceChannelInfo& info); /// Prepare to play this audio source void prepareToPlay(int, double); @@ -100,13 +100,13 @@ namespace openshot /// @brief Set the next read position of this source /// @param newPosition The sample # to start reading from - void setNextReadPosition (int64 newPosition); + void setNextReadPosition (juce::int64 newPosition); /// Get the next read position of this source - int64 getNextReadPosition() const; + juce::int64 getNextReadPosition() const; /// Get the total length (in samples) of this audio source - int64 getTotalLength() const; + juce::int64 getTotalLength() const; /// Determines if this audio source should repeat when it reaches the end bool isLooping() const; @@ -116,7 +116,7 @@ namespace openshot void setLooping (bool shouldLoop); /// Update the internal buffer used by this source - void setBuffer (AudioSampleBuffer *audio_buffer); + void setBuffer (juce::AudioSampleBuffer *audio_buffer); const ReaderInfo & getReaderInfo() const { return reader->info; } diff --git a/include/AudioResampler.h b/include/AudioResampler.h index 85a44b1f..de3cae41 100644 --- a/include/AudioResampler.h +++ b/include/AudioResampler.h @@ -55,11 +55,11 @@ namespace openshot { */ class AudioResampler { private: - AudioSampleBuffer *buffer; - AudioSampleBuffer *resampled_buffer; + juce::AudioSampleBuffer *buffer; + juce::AudioSampleBuffer *resampled_buffer; AudioBufferSource *buffer_source; - ResamplingAudioSource *resample_source; - AudioSourceChannelInfo resample_callback_buffer; + juce::ResamplingAudioSource *resample_source; + juce::AudioSourceChannelInfo resample_callback_buffer; int num_of_samples; int new_num_of_samples; @@ -78,15 +78,15 @@ namespace openshot { /// @param new_buffer The buffer of audio samples needing to be resampled /// @param sample_rate The original sample rate of the buffered samples /// @param new_sample_rate The requested sample rate you need - void SetBuffer(AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate); + void SetBuffer(juce::AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate); /// @brief Sets the audio buffer and key settings /// @param new_buffer The buffer of audio samples needing to be resampled /// @param ratio The multiplier that needs to be applied to the sample rate (this is how resampling happens) - void SetBuffer(AudioSampleBuffer *new_buffer, double ratio); + void SetBuffer(juce::AudioSampleBuffer *new_buffer, double ratio); /// Get the resampled audio buffer - AudioSampleBuffer* GetResampledBuffer(); + juce::AudioSampleBuffer* GetResampledBuffer(); }; } diff --git a/include/CacheBase.h b/include/CacheBase.h index d954e411..72880dd5 100644 --- a/include/CacheBase.h +++ b/include/CacheBase.h @@ -53,7 +53,7 @@ namespace openshot { int64_t max_bytes; ///< This is the max number of bytes to cache (0 = no limit) /// Section lock for multiple threads - CriticalSection *cacheCriticalSection; + juce::CriticalSection *cacheCriticalSection; public: diff --git a/include/Clip.h b/include/Clip.h index c092c2ad..101b3697 100644 --- a/include/Clip.h +++ b/include/Clip.h @@ -103,15 +103,15 @@ namespace openshot { class Clip : public ClipBase { protected: /// Section lock for multiple threads - CriticalSection getFrameCriticalSection; + juce::CriticalSection getFrameCriticalSection; private: bool waveform; ///< Should a waveform be used instead of the clip's image - list effects; /// effects; /// apply_effects(std::shared_ptr frame); /// Get file extension - string get_file_extension(string path); + std::string get_file_extension(std::string path); /// Get a frame object or create a blank one std::shared_ptr GetOrCreateFrame(int64_t number); diff --git a/include/Frame.h b/include/Frame.h index 1048c9cf..8eb51ed2 100644 --- a/include/Frame.h +++ b/include/Frame.h @@ -119,8 +119,8 @@ namespace openshot std::shared_ptr wave_image; std::shared_ptr audio; std::shared_ptr previewApp; - CriticalSection addingImageSection; - CriticalSection addingAudioSection; + juce::CriticalSection addingImageSection; + juce::CriticalSection addingAudioSection; const unsigned char *qbuffer; Fraction pixel_ratio; int channels; diff --git a/include/ReaderBase.h b/include/ReaderBase.h index 38f448c2..8aabd336 100644 --- a/include/ReaderBase.h +++ b/include/ReaderBase.h @@ -100,8 +100,8 @@ namespace openshot { protected: /// Section lock for multiple threads - CriticalSection getFrameCriticalSection; - CriticalSection processingCriticalSection; + juce::CriticalSection getFrameCriticalSection; + juce::CriticalSection processingCriticalSection; ClipBase* parent; public: diff --git a/include/ZmqLogger.h b/include/ZmqLogger.h index 2dc1a0cb..c165299e 100644 --- a/include/ZmqLogger.h +++ b/include/ZmqLogger.h @@ -55,7 +55,7 @@ namespace openshot { */ class ZmqLogger { private: - CriticalSection loggerCriticalSection; + juce::CriticalSection loggerCriticalSection; std::string connection; // Logfile related vars diff --git a/src/AudioBufferSource.cpp b/src/AudioBufferSource.cpp index 912d2552..46b04916 100644 --- a/src/AudioBufferSource.cpp +++ b/src/AudioBufferSource.cpp @@ -34,7 +34,7 @@ using namespace std; using namespace openshot; // Default constructor -AudioBufferSource::AudioBufferSource(AudioSampleBuffer *audio_buffer) +AudioBufferSource::AudioBufferSource(juce::AudioSampleBuffer *audio_buffer) : position(0), start(0), repeat(false), buffer(audio_buffer) { } @@ -46,7 +46,7 @@ AudioBufferSource::~AudioBufferSource() }; // Get the next block of audio samples -void AudioBufferSource::getNextAudioBlock (const AudioSourceChannelInfo& info) +void AudioBufferSource::getNextAudioBlock (const juce::AudioSourceChannelInfo& info) { int buffer_samples = buffer->getNumSamples(); int buffer_channels = buffer->getNumChannels(); @@ -98,7 +98,7 @@ void AudioBufferSource::prepareToPlay(int, double) { } void AudioBufferSource::releaseResources() { } // Set the next read position of this source -void AudioBufferSource::setNextReadPosition (int64 newPosition) +void AudioBufferSource::setNextReadPosition (juce::int64 newPosition) { // set position (if the new position is in range) if (newPosition >= 0 && newPosition < buffer->getNumSamples()) @@ -106,14 +106,14 @@ void AudioBufferSource::setNextReadPosition (int64 newPosition) } // Get the next read position of this source -int64 AudioBufferSource::getNextReadPosition() const +juce::int64 AudioBufferSource::getNextReadPosition() const { // return the next read position return position; } // Get the total length (in samples) of this audio source -int64 AudioBufferSource::getTotalLength() const +juce::int64 AudioBufferSource::getTotalLength() const { // Get the length return buffer->getNumSamples(); @@ -134,7 +134,7 @@ void AudioBufferSource::setLooping (bool shouldLoop) } // Use a different AudioSampleBuffer for this source -void AudioBufferSource::setBuffer (AudioSampleBuffer *audio_buffer) +void AudioBufferSource::setBuffer (juce::AudioSampleBuffer *audio_buffer) { buffer = audio_buffer; setNextReadPosition(0); diff --git a/src/AudioReaderSource.cpp b/src/AudioReaderSource.cpp index 8195d03b..41c0b3f6 100644 --- a/src/AudioReaderSource.cpp +++ b/src/AudioReaderSource.cpp @@ -152,7 +152,7 @@ juce::AudioSampleBuffer* AudioReaderSource::reverse_buffer(juce::AudioSampleBuff ZmqLogger::Instance()->AppendDebugMethod("AudioReaderSource::reverse_buffer", "number_of_samples", number_of_samples, "channels", channels); // Reverse array (create new buffer to hold the reversed version) - AudioSampleBuffer *reversed = new juce::AudioSampleBuffer(channels, number_of_samples); + juce::AudioSampleBuffer *reversed = new juce::AudioSampleBuffer(channels, number_of_samples); reversed->clear(); for (int channel = 0; channel < channels; channel++) @@ -177,7 +177,7 @@ juce::AudioSampleBuffer* AudioReaderSource::reverse_buffer(juce::AudioSampleBuff } // Get the next block of audio samples -void AudioReaderSource::getNextAudioBlock(const AudioSourceChannelInfo& info) +void AudioReaderSource::getNextAudioBlock(const juce::AudioSourceChannelInfo& info) { int buffer_samples = buffer->getNumSamples(); int buffer_channels = buffer->getNumChannels(); @@ -248,7 +248,7 @@ void AudioReaderSource::prepareToPlay(int, double) { } void AudioReaderSource::releaseResources() { } // Set the next read position of this source -void AudioReaderSource::setNextReadPosition (int64 newPosition) +void AudioReaderSource::setNextReadPosition (juce::int64 newPosition) { // set position (if the new position is in range) if (newPosition >= 0 && newPosition < buffer->getNumSamples()) @@ -256,14 +256,14 @@ void AudioReaderSource::setNextReadPosition (int64 newPosition) } // Get the next read position of this source -int64 AudioReaderSource::getNextReadPosition() const +juce::int64 AudioReaderSource::getNextReadPosition() const { // return the next read position return position; } // Get the total length (in samples) of this audio source -int64 AudioReaderSource::getTotalLength() const +juce::int64 AudioReaderSource::getTotalLength() const { // Get the length if (reader) @@ -287,7 +287,7 @@ void AudioReaderSource::setLooping (bool shouldLoop) } // Update the internal buffer used by this source -void AudioReaderSource::setBuffer (AudioSampleBuffer *audio_buffer) +void AudioReaderSource::setBuffer (juce::AudioSampleBuffer *audio_buffer) { buffer = audio_buffer; setNextReadPosition(0); diff --git a/src/AudioResampler.cpp b/src/AudioResampler.cpp index d9c5a609..145f5d91 100644 --- a/src/AudioResampler.cpp +++ b/src/AudioResampler.cpp @@ -49,10 +49,10 @@ AudioResampler::AudioResampler() buffer_source = new AudioBufferSource(buffer); // Init resampling source - resample_source = new ResamplingAudioSource(buffer_source, false, 2); + resample_source = new juce::ResamplingAudioSource(buffer_source, false, 2); // Init resampled buffer - resampled_buffer = new AudioSampleBuffer(2, 1); + resampled_buffer = new juce::AudioSampleBuffer(2, 1); resampled_buffer->clear(); // Init callback buffer @@ -74,7 +74,7 @@ AudioResampler::~AudioResampler() } // Sets the audio buffer and updates the key settings -void AudioResampler::SetBuffer(AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate) +void AudioResampler::SetBuffer(juce::AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate) { if (sample_rate <= 0) sample_rate = 44100; @@ -89,7 +89,7 @@ void AudioResampler::SetBuffer(AudioSampleBuffer *new_buffer, double sample_rate } // Sets the audio buffer and key settings -void AudioResampler::SetBuffer(AudioSampleBuffer *new_buffer, double ratio) +void AudioResampler::SetBuffer(juce::AudioSampleBuffer *new_buffer, double ratio) { // Update buffer & buffer source buffer = new_buffer; @@ -120,7 +120,7 @@ void AudioResampler::SetBuffer(AudioSampleBuffer *new_buffer, double ratio) } // Get the resampled audio buffer -AudioSampleBuffer* AudioResampler::GetResampledBuffer() +juce::AudioSampleBuffer* AudioResampler::GetResampledBuffer() { // Resample the current frame's audio buffer (into the temp callback buffer) resample_source->getNextAudioBlock(resample_callback_buffer); diff --git a/src/Clip.cpp b/src/Clip.cpp index 7e82ff01..5252681a 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -367,7 +367,7 @@ void Clip::reverse_buffer(juce::AudioSampleBuffer* buffer) int channels = buffer->getNumChannels(); // Reverse array (create new buffer to hold the reversed version) - AudioSampleBuffer *reversed = new juce::AudioSampleBuffer(channels, number_of_samples); + juce::AudioSampleBuffer *reversed = new juce::AudioSampleBuffer(channels, number_of_samples); reversed->clear(); for (int channel = 0; channel < channels; channel++) @@ -399,7 +399,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num // Check for a valid time map curve if (time.Values.size() > 1) { - const GenericScopedLock lock(getFrameCriticalSection); + const GenericScopedLock lock(getFrameCriticalSection); // create buffer and resampler juce::AudioSampleBuffer *samples = NULL; @@ -423,7 +423,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num if (time.GetRepeatFraction(frame_number).den > 1) { // SLOWING DOWN AUDIO // Resample data, and return new buffer pointer - AudioSampleBuffer *resampled_buffer = NULL; + juce::AudioSampleBuffer *resampled_buffer = NULL; int resampled_buffer_size = 0; // SLOW DOWN audio (split audio) @@ -482,7 +482,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num delta_frame <= new_frame_number; delta_frame++) { // buffer to hold detal samples int number_of_delta_samples = GetOrCreateFrame(delta_frame)->GetAudioSamplesCount(); - AudioSampleBuffer *delta_samples = new juce::AudioSampleBuffer(channels, + juce::AudioSampleBuffer *delta_samples = new juce::AudioSampleBuffer(channels, number_of_delta_samples); delta_samples->clear(); @@ -526,7 +526,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num delta_frame >= new_frame_number; delta_frame--) { // buffer to hold delta samples int number_of_delta_samples = GetOrCreateFrame(delta_frame)->GetAudioSamplesCount(); - AudioSampleBuffer *delta_samples = new juce::AudioSampleBuffer(channels, + juce::AudioSampleBuffer *delta_samples = new juce::AudioSampleBuffer(channels, number_of_delta_samples); delta_samples->clear(); @@ -557,7 +557,7 @@ void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_num resampler->SetBuffer(samples, float(start) / float(number_of_samples)); // Resample data, and return new buffer pointer - AudioSampleBuffer *buffer = resampler->GetResampledBuffer(); + juce::AudioSampleBuffer *buffer = resampler->GetResampledBuffer(); int resampled_buffer_size = buffer->getNumSamples(); // Add the newly resized audio samples to the current frame diff --git a/src/Frame.cpp b/src/Frame.cpp index 49fb7358..d5e64c37 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -340,7 +340,7 @@ float* Frame::GetAudioSamples(int channel) float* Frame::GetPlanarAudioSamples(int new_sample_rate, AudioResampler* resampler, int* sample_count) { float *output = NULL; - AudioSampleBuffer *buffer(audio.get()); + juce::AudioSampleBuffer *buffer(audio.get()); int num_of_channels = audio->getNumChannels(); int num_of_samples = GetAudioSamplesCount(); @@ -386,7 +386,7 @@ float* Frame::GetPlanarAudioSamples(int new_sample_rate, AudioResampler* resampl float* Frame::GetInterleavedAudioSamples(int new_sample_rate, AudioResampler* resampler, int* sample_count) { float *output = NULL; - AudioSampleBuffer *buffer(audio.get()); + juce::AudioSampleBuffer *buffer(audio.get()); int num_of_channels = audio->getNumChannels(); int num_of_samples = GetAudioSamplesCount(); @@ -430,7 +430,7 @@ float* Frame::GetInterleavedAudioSamples(int new_sample_rate, AudioResampler* re // Get number of audio channels int Frame::GetAudioChannelsCount() { - const GenericScopedLock lock(addingAudioSection); + const GenericScopedLock lock(addingAudioSection); if (audio) return audio->getNumChannels(); else @@ -440,7 +440,7 @@ int Frame::GetAudioChannelsCount() // Get number of audio samples int Frame::GetAudioSamplesCount() { - const GenericScopedLock lock(addingAudioSection); + const GenericScopedLock lock(addingAudioSection); return max_audio_sample; } @@ -735,7 +735,7 @@ void Frame::AddColor(int new_width, int new_height, string new_color) color = new_color; // Create new image object, and fill with pixel data - const GenericScopedLock lock(addingImageSection); + const GenericScopedLock lock(addingImageSection); #pragma omp critical (AddImage) { image = std::shared_ptr(new QImage(new_width, new_height, QImage::Format_RGBA8888)); @@ -753,7 +753,7 @@ void Frame::AddColor(int new_width, int new_height, string new_color) void Frame::AddImage(int new_width, int new_height, int bytes_per_pixel, QImage::Format type, const unsigned char *pixels_) { // Create new buffer - const GenericScopedLock lock(addingImageSection); + const GenericScopedLock lock(addingImageSection); int buffer_size = new_width * new_height * bytes_per_pixel; qbuffer = new unsigned char[buffer_size](); @@ -784,7 +784,7 @@ void Frame::AddImage(std::shared_ptr new_image) return; // assign image data - const GenericScopedLock lock(addingImageSection); + const GenericScopedLock lock(addingImageSection); #pragma omp critical (AddImage) { image = new_image; @@ -823,7 +823,7 @@ void Frame::AddImage(std::shared_ptr new_image, bool only_odd_lines) return; // Get the frame's image - const GenericScopedLock lock(addingImageSection); + const GenericScopedLock lock(addingImageSection); #pragma omp critical (AddImage) { const unsigned char *pixels = image->bits(); @@ -851,7 +851,7 @@ void Frame::AddImage(std::shared_ptr new_image, bool only_odd_lines) // Resize audio container to hold more (or less) samples and channels void Frame::ResizeAudio(int channels, int length, int rate, ChannelLayout layout) { - const GenericScopedLock lock(addingAudioSection); + const GenericScopedLock lock(addingAudioSection); // Resize JUCE audio buffer audio->setSize(channels, length, true, true, false); @@ -864,7 +864,7 @@ void Frame::ResizeAudio(int channels, int length, int rate, ChannelLayout layout // Add audio samples to a specific channel void Frame::AddAudio(bool replaceSamples, int destChannel, int destStartSample, const float* source, int numSamples, float gainToApplyToSource = 1.0f) { - const GenericScopedLock lock(addingAudioSection); + const GenericScopedLock lock(addingAudioSection); #pragma omp critical (adding_audio) { // Clamp starting sample to 0 @@ -895,7 +895,7 @@ void Frame::AddAudio(bool replaceSamples, int destChannel, int destStartSample, // Apply gain ramp (i.e. fading volume) void Frame::ApplyGainRamp(int destChannel, int destStartSample, int numSamples, float initial_gain = 0.0f, float final_gain = 1.0f) { - const GenericScopedLock lock(addingAudioSection); + const GenericScopedLock lock(addingAudioSection); // Apply gain ramp audio->applyGainRamp(destChannel, destStartSample, numSamples, initial_gain, final_gain); @@ -970,7 +970,7 @@ void Frame::Play() if (!GetAudioSamplesCount()) return; - AudioDeviceManager deviceManager; + juce::AudioDeviceManager deviceManager; String error = deviceManager.initialise (0, /* number of input channels */ 2, /* number of output channels */ 0, /* no XML settings.. */ @@ -981,14 +981,14 @@ void Frame::Play() cout << "Error on initialise(): " << error.toStdString() << endl; } - AudioSourcePlayer audioSourcePlayer; + juce::AudioSourcePlayer audioSourcePlayer; deviceManager.addAudioCallback (&audioSourcePlayer); ScopedPointer my_source; my_source = new AudioBufferSource(audio.get()); // Create TimeSliceThread for audio buffering - TimeSliceThread my_thread("Audio buffer thread"); + juce::TimeSliceThread my_thread("Audio buffer thread"); // Start thread my_thread.startThread(); @@ -1004,7 +1004,7 @@ void Frame::Play() // Create MIXER - MixerAudioSource mixer; + juce::MixerAudioSource mixer; mixer.addInputSource(&transport1, false); audioSourcePlayer.setSource (&mixer); @@ -1047,7 +1047,7 @@ void Frame::cleanUpBuffer(void *info) // Add audio silence void Frame::AddAudioSilence(int numSamples) { - const GenericScopedLock lock(addingAudioSection); + const GenericScopedLock lock(addingAudioSection); // Resize audio container audio->setSize(channels, numSamples, false, true, false); From ed908faa467b2486e04671d5840a25437e7c1edf Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 27 Oct 2019 06:59:03 -0400 Subject: [PATCH 47/50] Add ENABLE_IWTU CMake option Add CMake handling for `-DENABLE_IWYU=1" to enable scanning with include-what-you-use (if `iwyu` binary is found in PATH), and e.g. `-DIWYU_OPTS="--max_line_length=120 --verbose=1"` to supply args. --- src/CMakeLists.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 398d6154..3e44ab89 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,6 +36,7 @@ include(FeatureSummary) ################ OPTIONS ################## # Optional build settings for libopenshot OPTION(USE_SYSTEM_JSONCPP "Use system installed JsonCpp" OFF) +option(ENABLE_IWYU "Enable 'Include What You Use' scanner" OFF) ################ WINDOWS ################## # Set some compiler options for Windows @@ -181,6 +182,21 @@ endif(USE_SYSTEM_JSONCPP) #set(PROFILER "/usr/lib/libprofiler.so.0.3.2") #set(PROFILER "/usr/lib/libtcmalloc.so.4") +if(ENABLE_IWYU) + find_program(IWYU_PATH NAMES "iwyu" + DOC "include-what-you-use source code scanner executable") + if(IWYU_PATH) + if(IWYU_OPTS) + separate_arguments(IWYU_OPTS) + list(APPEND _iwyu_cmd ${IWYU_PATH} "-Xiwyu" ${IWYU_OPTS}) + endif() + set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${_iwyu_cmd}) + else() + set(ENABLE_IWYU FALSE) + endif() +endif() +add_feature_info("IWYU (include-what-you-use)" ENABLE_IWYU "Scan all source files with 'iwyu'") + #### GET LIST OF EFFECT FILES #### FILE(GLOB EFFECT_FILES "${CMAKE_CURRENT_SOURCE_DIR}/effects/*.cpp") From 21951bea5c8cf177b0b977d2567aa67219a42fa1 Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Wed, 30 Oct 2019 09:43:31 +1100 Subject: [PATCH 48/50] Set duration to 1 hour Co-Authored-By: Frank Dana --- src/QtTextReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index e32835cf..38240c96 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -134,7 +134,7 @@ void QtTextReader::Open() info.height = height; info.pixel_ratio.num = 1; info.pixel_ratio.den = 1; - info.duration = 60 * 60 * 24; // 24 hour duration + info.duration = 60 * 60 * 1; // 1 hour duration info.fps.num = 30; info.fps.den = 1; info.video_timebase.num = 1; From 6c20fa43c21b45128c9c8c480c29b80b35a1050b Mon Sep 17 00:00:00 2001 From: Jeff Shillitto Date: Wed, 30 Oct 2019 09:44:01 +1100 Subject: [PATCH 49/50] Set HTML reader duration to 1 hour Co-Authored-By: Frank Dana --- src/QtHtmlReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 0627d55b..e3cdc602 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -117,7 +117,7 @@ void QtHtmlReader::Open() info.height = height; info.pixel_ratio.num = 1; info.pixel_ratio.den = 1; - info.duration = 60 * 60 * 24; // 24 hour duration + info.duration = 60 * 60 * 1; // 1 hour duration info.fps.num = 30; info.fps.den = 1; info.video_timebase.num = 1; From f09ac1bcc30af5728dcdbb4d34b854f57da6f308 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 30 Oct 2019 02:42:26 -0400 Subject: [PATCH 50/50] CMake: Fix IWYU invocation with unset IWYU_OPTS --- src/CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ddb56b52..8e03b733 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,7 +33,7 @@ include(FeatureSummary) ################ OPTIONS ################## # Optional build settings for libopenshot OPTION(USE_SYSTEM_JSONCPP "Use system installed JsonCpp" OFF) -option(ENABLE_IWYU "Enable 'Include What You Use' scanner" OFF) +option(ENABLE_IWYU "Enable 'Include What You Use' scanner (CMake 3.3+)" OFF) ################ WINDOWS ################## # Set some compiler options for Windows @@ -165,15 +165,20 @@ endif(USE_SYSTEM_JSONCPP) #set(PROFILER "/usr/lib/libprofiler.so.0.3.2") #set(PROFILER "/usr/lib/libtcmalloc.so.4") +if(CMAKE_VERSION VERSION_LESS 3.3) + # IWYU wasn't supported internally in 3.2 + set(ENABLE_IWYU FALSE) +endif() + if(ENABLE_IWYU) find_program(IWYU_PATH NAMES "iwyu" DOC "include-what-you-use source code scanner executable") if(IWYU_PATH) if(IWYU_OPTS) separate_arguments(IWYU_OPTS) - list(APPEND _iwyu_cmd ${IWYU_PATH} "-Xiwyu" ${IWYU_OPTS}) + list(APPEND _iwyu_opts "-Xiwyu" ${IWYU_OPTS}) endif() - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${_iwyu_cmd}) + set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${IWYU_PATH} ${_iwyu_opts}) else() set(ENABLE_IWYU FALSE) endif()