From c7f0a481ccde4f49b32bed6dcae3a69dffd0cfa5 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Thu, 6 Aug 2015 20:01:34 -0500 Subject: [PATCH] Added a new class to easily expose the JSON metadata of supported effects in libopenshot. Fixed some bugs related to metadata, and a few bugs in the Mask effect (if initialized without a reader). --- include/EffectBase.h | 7 +++-- include/EffectInfo.h | 57 ++++++++++++++++++++++++++++++++++ include/OpenShot.h | 1 + include/effects/ChromaKey.h | 3 ++ include/effects/Deinterlace.h | 3 ++ src/CMakeLists.txt | 1 + src/Clip.cpp | 1 + src/EffectBase.cpp | 16 ++++++++++ src/EffectInfo.cpp | 56 +++++++++++++++++++++++++++++++++ src/bindings/python/openshot.i | 3 ++ src/bindings/ruby/openshot.i | 3 ++ src/effects/ChromaKey.cpp | 14 +++++++-- src/effects/Deinterlace.cpp | 16 ++++++++-- src/effects/Mask.cpp | 13 ++++++-- src/effects/Negate.cpp | 3 +- src/examples/Example.cpp | 4 ++- 16 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 include/EffectInfo.h create mode 100644 src/EffectInfo.cpp diff --git a/include/EffectBase.h b/include/EffectBase.h index 413e2218..2fd84e69 100644 --- a/include/EffectBase.h +++ b/include/EffectBase.h @@ -46,8 +46,10 @@ namespace openshot * about the underlying effect. Derived classes of EffectBase should call the InitEffectInfo() method to initialize the * default values of this struct. */ - struct EffectInfo + struct EffectInfoStruct { + string class_name; ///< The class name of the effect + string short_name; ///< A short name of the effect, commonly used for icon names, etc... string name; ///< The name of the effect string description; ///< The description of this effect and what it does bool has_video; ///< Determines if this effect manipulates the image of a frame @@ -68,7 +70,7 @@ namespace openshot public: /// Information about the current effect - EffectInfo info; + EffectInfoStruct info; /// Display effect information in the standard output stream (stdout) void DisplayInfo(); @@ -93,6 +95,7 @@ namespace openshot virtual void SetJson(string value) throw(InvalidJSON) = 0; ///< Load JSON string into this object virtual Json::Value JsonValue() = 0; ///< Generate Json::JsonValue for this object virtual void SetJsonValue(Json::Value root) = 0; ///< Load Json::JsonValue into this object + Json::Value JsonInfo(); ///< Generate JSON object of meta data / info /// Get the order that this effect should be executed. int Order() { return order; } diff --git a/include/EffectInfo.h b/include/EffectInfo.h new file mode 100644 index 00000000..9dbe9828 --- /dev/null +++ b/include/EffectInfo.h @@ -0,0 +1,57 @@ +/** + * @file + * @brief Header file for the EffectInfo 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_EFFECT_INFO_H +#define OPENSHOT_EFFECT_INFO_H + +#include "Effects.h" + + +using namespace std; + +namespace openshot +{ + + /** + * @brief This class returns a listing of all effects supported by libopenshot + * + * Use this class to return a listing of all supported effects, and their + * descriptions. + */ + class EffectInfo + { + public: + + /// JSON methods + static string Json(); ///< Generate JSON string of this object + static Json::Value JsonValue(); ///< Generate Json::JsonValue for this object + + }; + +} + +#endif diff --git a/include/OpenShot.h b/include/OpenShot.h index e5edeb52..e1e9bb6d 100644 --- a/include/OpenShot.h +++ b/include/OpenShot.h @@ -112,6 +112,7 @@ #include "DummyReader.h" #include "EffectBase.h" #include "Effects.h" +#include "EffectInfo.h" #include "Enums.h" #include "Exceptions.h" #include "ReaderBase.h" diff --git a/include/effects/ChromaKey.h b/include/effects/ChromaKey.h index e437be73..7404c410 100644 --- a/include/effects/ChromaKey.h +++ b/include/effects/ChromaKey.h @@ -58,6 +58,9 @@ namespace openshot Color color; Keyframe fuzz; + /// Init effect settings + void init_effect_details(); + public: /// Blank constructor, useful when using Json to load the effect properties diff --git a/include/effects/Deinterlace.h b/include/effects/Deinterlace.h index b643a9b9..fe0f3062 100644 --- a/include/effects/Deinterlace.h +++ b/include/effects/Deinterlace.h @@ -59,6 +59,9 @@ namespace openshot private: bool isOdd; + /// Init effect settings + void init_effect_details(); + public: /// Blank constructor, useful when using Json to load the effect properties diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2014ef4c..fca7b4d7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -177,6 +177,7 @@ SET ( OPENSHOT_SOURCE_FILES WriterBase.cpp EffectBase.cpp ${EFFECT_FILES} + EffectInfo.cpp FFmpegReader.cpp FFmpegWriter.cpp Fraction.cpp diff --git a/src/Clip.cpp b/src/Clip.cpp index d05de948..74b1841f 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -714,6 +714,7 @@ void Clip::SetJsonValue(Json::Value root) { if (!root["perspective_c4_y"].isNull()) perspective_c4_y.SetJsonValue(root["perspective_c4_y"]); if (!root["effects"].isNull()) { + // Clear existing effects effects.clear(); diff --git a/src/EffectBase.cpp b/src/EffectBase.cpp index 6a76adff..6810c44e 100644 --- a/src/EffectBase.cpp +++ b/src/EffectBase.cpp @@ -109,3 +109,19 @@ void EffectBase::SetJsonValue(Json::Value root) { if (!root["order"].isNull()) Order(root["order"].asInt()); } + +// Generate Json::JsonValue for this object +Json::Value EffectBase::JsonInfo() { + + // Create root json object + Json::Value root; + root["name"] = info.name; + root["class_name"] = info.class_name; + root["short_name"] = info.short_name; + root["description"] = info.description; + root["has_video"] = info.has_video; + root["has_audio"] = info.has_audio; + + // return JsonValue + return root; +} \ No newline at end of file diff --git a/src/EffectInfo.cpp b/src/EffectInfo.cpp new file mode 100644 index 00000000..844d220c --- /dev/null +++ b/src/EffectInfo.cpp @@ -0,0 +1,56 @@ +/** + * @file + * @brief Source file for EffectInfo 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/EffectInfo.h" + + +using namespace openshot; + + +// Generate JSON string of this object +string EffectInfo::Json() { + + // Return formatted string + return JsonValue().toStyledString(); +} + +// Generate Json::JsonValue for this object +Json::Value EffectInfo::JsonValue() { + + // Create root json object + Json::Value root; + + // Append info JSON from each supported effect + root.append(ChromaKey().JsonInfo()); + root.append(Deinterlace().JsonInfo()); + root.append(Mask().JsonInfo()); + root.append(Negate().JsonInfo()); + + // return JsonValue + return root; + +} diff --git a/src/bindings/python/openshot.i b/src/bindings/python/openshot.i index 682bb92a..561cc007 100644 --- a/src/bindings/python/openshot.i +++ b/src/bindings/python/openshot.i @@ -64,6 +64,7 @@ #include "../../../include/DummyReader.h" #include "../../../include/EffectBase.h" #include "../../../include/Effects.h" +#include "../../../include/EffectInfo.h" #include "../../../include/Exceptions.h" #include "../../../include/FFmpegReader.h" #include "../../../include/FFmpegWriter.h" @@ -109,6 +110,8 @@ #endif %include "../../../include/DummyReader.h" %include "../../../include/EffectBase.h" +%include "../../../include/Effects.h" +%include "../../../include/EffectInfo.h" %include "../../../include/Exceptions.h" %include "../../../include/FFmpegReader.h" %include "../../../include/FFmpegWriter.h" diff --git a/src/bindings/ruby/openshot.i b/src/bindings/ruby/openshot.i index 12371c8c..9dd77d06 100644 --- a/src/bindings/ruby/openshot.i +++ b/src/bindings/ruby/openshot.i @@ -70,6 +70,7 @@ namespace tr1 #include "../../../include/DummyReader.h" #include "../../../include/EffectBase.h" #include "../../../include/Effects.h" +#include "../../../include/EffectInfo.h" #include "../../../include/Exceptions.h" #include "../../../include/FFmpegReader.h" #include "../../../include/FFmpegWriter.h" @@ -115,6 +116,8 @@ namespace tr1 #endif %include "../../../include/DummyReader.h" %include "../../../include/EffectBase.h" +%include "../../../include/Effects.h" +%include "../../../include/EffectInfo.h" %include "../../../include/Exceptions.h" %include "../../../include/FFmpegReader.h" %include "../../../include/FFmpegWriter.h" diff --git a/src/effects/ChromaKey.cpp b/src/effects/ChromaKey.cpp index 979cdddb..30bab95c 100644 --- a/src/effects/ChromaKey.cpp +++ b/src/effects/ChromaKey.cpp @@ -33,17 +33,28 @@ using namespace openshot; ChromaKey::ChromaKey() : fuzz(0.0) { // Init default color color = Color(); + + // Init effect properties + init_effect_details(); } // Default constructor, which takes an openshot::Color object and a 'fuzz' factor, which // is used to determine how similar colored pixels are matched. The higher the fuzz, the // more colors are matched. ChromaKey::ChromaKey(Color color, Keyframe fuzz) : color(color), fuzz(fuzz) +{ + // Init effect properties + init_effect_details(); +} + +// Init effect settings +void ChromaKey::init_effect_details() { /// Initialize the values of the EffectInfo struct. InitEffectInfo(); /// Set the effect info + info.class_name = "ChromaKey"; info.name = "Chroma Key (Greenscreen)"; info.description = "Replaces the color (or chroma) of the frame with transparency (i.e. keys out the color)."; info.has_audio = false; @@ -98,7 +109,7 @@ Json::Value ChromaKey::JsonValue() { // Create root json object Json::Value root = EffectBase::JsonValue(); // get parent properties - root["type"] = "ChromaKey"; + root["type"] = info.class_name; root["color"] = color.JsonValue(); root["fuzz"] = fuzz.JsonValue(); @@ -142,7 +153,6 @@ void ChromaKey::SetJsonValue(Json::Value root) { fuzz.SetJsonValue(root["fuzz"]); } - // Get all properties for a specific frame string ChromaKey::PropertiesJSON(int requested_frame) { diff --git a/src/effects/Deinterlace.cpp b/src/effects/Deinterlace.cpp index 08f54a96..81576522 100644 --- a/src/effects/Deinterlace.cpp +++ b/src/effects/Deinterlace.cpp @@ -30,17 +30,27 @@ using namespace openshot; /// Blank constructor, useful when using Json to load the effect properties -Deinterlace::Deinterlace() : isOdd(true) { - +Deinterlace::Deinterlace() : isOdd(true) +{ + // Init effect properties + init_effect_details(); } // Default constructor Deinterlace::Deinterlace(bool UseOddLines) : isOdd(UseOddLines) +{ + // Init effect properties + init_effect_details(); +} + +// Init effect settings +void Deinterlace::init_effect_details() { /// Initialize the values of the EffectInfo struct. InitEffectInfo(); /// Set the effect info + info.class_name = "Deinterlace"; info.name = "Deinterlace"; info.description = "Remove interlacing from a video (i.e. even or odd horizontal lines)"; info.has_audio = false; @@ -94,7 +104,7 @@ Json::Value Deinterlace::JsonValue() { // Create root json object Json::Value root = EffectBase::JsonValue(); // get parent properties - root["type"] = "Deinterlace"; + root["type"] = info.class_name; root["isOdd"] = isOdd; // return JsonValue diff --git a/src/effects/Mask.cpp b/src/effects/Mask.cpp index 52826ac9..7c7a949c 100644 --- a/src/effects/Mask.cpp +++ b/src/effects/Mask.cpp @@ -50,6 +50,7 @@ void Mask::init_effect_details() InitEffectInfo(); /// Set the effect info + info.class_name = "Mask"; info.name = "Alpha Mask / Wipe Transition"; info.description = "Uses a grayscale mask image to gradually wipe / transition between 2 images."; info.has_audio = false; @@ -115,9 +116,12 @@ tr1::shared_ptr Mask::GetFrame(tr1::shared_ptr frame, int frame_nu tr1::shared_ptr frame_image = frame->GetImage(); // Check if mask reader is open - if (!reader->IsOpen()) + if (reader && !reader->IsOpen()) #pragma omp critical (open_mask_reader) reader->Open(); + else + // No reader (bail on applying the mask) + return frame; // Get the mask image (from the mask reader) tr1::shared_ptr mask = tr1::shared_ptr(new QImage(*reader->GetFrame(frame_number)->GetImage())); @@ -162,10 +166,13 @@ Json::Value Mask::JsonValue() { // Create root json object Json::Value root = EffectBase::JsonValue(); // get parent properties - root["type"] = "Mask"; + root["type"] = info.class_name; root["brightness"] = brightness.JsonValue(); root["contrast"] = contrast.JsonValue(); - root["reader"] = reader->JsonValue(); + if (reader) + root["reader"] = reader->JsonValue(); + else + root["reader"] = Json::objectValue; root["replace_image"] = replace_image; // return JsonValue diff --git a/src/effects/Negate.cpp b/src/effects/Negate.cpp index 61690fb3..0d74d13f 100644 --- a/src/effects/Negate.cpp +++ b/src/effects/Negate.cpp @@ -36,6 +36,7 @@ Negate::Negate() InitEffectInfo(); /// Set the effect info + info.class_name = "Negate"; info.name = "Negative"; info.description = "Negates the colors, producing a negative of the image."; info.has_audio = false; @@ -65,7 +66,7 @@ Json::Value Negate::JsonValue() { // Create root json object Json::Value root = EffectBase::JsonValue(); // get parent properties - root["type"] = "Negate"; + root["type"] = info.class_name; // return JsonValue return root; diff --git a/src/examples/Example.cpp b/src/examples/Example.cpp index bd6e746c..3ca3a54f 100644 --- a/src/examples/Example.cpp +++ b/src/examples/Example.cpp @@ -30,7 +30,6 @@ #include #include "../../include/OpenShot.h" - using namespace openshot; using namespace tr1; @@ -38,6 +37,9 @@ using namespace tr1; int main(int argc, char* argv[]) { + EffectInfo::Json(); + return 0; + // FFmpegReader r110("/home/jonathan/apps/libopenshot/src/examples/piano-mono.wav"); // r110.Open(); //