From 34be0fef7953eb8b9e98a7f9deb3581a914ca12f Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 30 Oct 2019 04:00:50 -0400 Subject: [PATCH 001/148] Add labeler workflow file --- .github/workflows/label.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/label.yml diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml new file mode 100644 index 00000000..e90b599b --- /dev/null +++ b/.github/workflows/label.yml @@ -0,0 +1,19 @@ +# This workflow will triage pull requests and apply a label based on the +# paths that are modified in the pull request. +# +# To use this workflow, you will need to set up a .github/labeler.yml +# file with configuration. For more information, see: +# https://github.com/actions/labeler/blob/master/README.md + +name: Labeler +on: [pull_request] + +jobs: + label: + + runs-on: ubuntu-latest + + steps: + - uses: actions/labeler@v2 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" From 729805b914534134e1c87d0b44e2e43fabcd11a7 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 30 Oct 2019 04:03:45 -0400 Subject: [PATCH 002/148] Add labeler.yml control file for label Action --- .github/labeler.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/labeler.yml diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000..e4c991f7 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,4 @@ +# Add 'build' label to CMake changes +build: + - **/CMakeList.txt + - /cmake/**/*.cmake From c40c429581c1d51b793fd256971f546d6dd177cb Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 30 Oct 2019 04:50:24 -0400 Subject: [PATCH 003/148] Delete FindZMQ.cmake (This also serves as a test of the GitHub Actions config.) --- cmake/Modules/FindZMQ.cmake | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 cmake/Modules/FindZMQ.cmake diff --git a/cmake/Modules/FindZMQ.cmake b/cmake/Modules/FindZMQ.cmake deleted file mode 100644 index 50d27bc5..00000000 --- a/cmake/Modules/FindZMQ.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# - Try to find ZMQ -# Once done this will define -# ZMQ_FOUND - System has ZMQ -# ZMQ_INCLUDE_DIRS - The ZMQ include directories -# ZMQ_LIBRARIES - The libraries needed to use ZMQ -# ZMQ_DEFINITIONS - Compiler switches required for using ZMQ - -find_path ( ZMQ_INCLUDE_DIR zmq.h - PATHS /usr/include/ - /usr/local/include/ - $ENV{ZMQDIR}/include/ ) - -find_library ( ZMQ_LIBRARY NAMES zmq - PATHS /usr/lib/ - /usr/local/lib/ - $ENV{ZMQDIR}/lib/ ) - -set ( ZMQ_LIBRARIES ${ZMQ_LIBRARY} ) -set ( ZMQ_INCLUDE_DIRS ${ZMQ_INCLUDE_DIR} ) - -include ( FindPackageHandleStandardArgs ) -# handle the QUIETLY and REQUIRED arguments and set ZMQ_FOUND to TRUE -# if all listed variables are TRUE -find_package_handle_standard_args ( ZMQ DEFAULT_MSG ZMQ_LIBRARY ZMQ_INCLUDE_DIR ) \ No newline at end of file From cc1f82276ccf71c4cfc385b3f7b80dcbc71421c7 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 30 Oct 2019 04:53:53 -0400 Subject: [PATCH 004/148] Update labeler.yml Fix syntax errors (hopefully) --- .github/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index e4c991f7..756bf1e4 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,4 +1,4 @@ # Add 'build' label to CMake changes build: - - **/CMakeList.txt + - /**/CMakeList.txt - /cmake/**/*.cmake From b5ab66328f53cf64c19d1a1cfda69bc4c8a3b429 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 30 Oct 2019 04:58:42 -0400 Subject: [PATCH 005/148] Update CMakeLists.txt --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 566fa9da..4a9d3647 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -128,10 +128,10 @@ ENDIF (ENABLE_BLACKMAGIC) # Some platforms package the header-only cppzmq C++ bindings separately, # others (Ubuntu) bundle them in with libzmq itself find_package(cppzmq QUIET) -find_package(ZMQ REQUIRED) +find_package(ZeroMQ REQUIRED) # Include ZeroMQ headers (needed for compile) -include_directories(${ZMQ_INCLUDE_DIRS}) +include_directories(${ZeroMQ_INCLUDE_DIRS}) if (cppzmq_FOUND) include_directories(${cppzmq_INCLUDE_DIRS}) endif() From adeb452e5d47176de82c304c6aab2675bd465d3f Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Mon, 4 Nov 2019 19:56:33 +0100 Subject: [PATCH 006/148] Color-separated Saturation Signed-off-by: Markus KARG --- include/effects/Saturation.h | 5 ++- src/effects/Saturation.cpp | 75 +++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/include/effects/Saturation.h b/include/effects/Saturation.h index de3cc771..08695fd9 100644 --- a/include/effects/Saturation.h +++ b/include/effects/Saturation.h @@ -65,6 +65,9 @@ namespace openshot public: Keyframe saturation; ///< The color saturation: 0.0 = black and white, 1.0 = normal, 2.0 = double saturation + Keyframe saturation_R; ///< Red color saturation + Keyframe saturation_G; ///< Green color saturation + Keyframe saturation_B; ///< Blue color saturation /// Blank constructor, useful when using Json to load the effect properties Saturation(); @@ -72,7 +75,7 @@ namespace openshot /// Default constructor, which takes 1 curve, to adjust the color saturation over time. /// /// @param new_saturation The curve to adjust the saturation of the frame's image (0.0 = black and white, 1.0 = normal, 2.0 = double saturation) - Saturation(Keyframe new_saturation); + Saturation(Keyframe new_saturation, Keyframe new_saturation_R, Keyframe new_saturation_G, Keyframe new_saturation_B); /// @brief This method is required for all derived classes of EffectBase, and returns a /// modified openshot::Frame object diff --git a/src/effects/Saturation.cpp b/src/effects/Saturation.cpp index 06bcb02c..6762b4e7 100644 --- a/src/effects/Saturation.cpp +++ b/src/effects/Saturation.cpp @@ -33,13 +33,13 @@ using namespace openshot; /// Blank constructor, useful when using Json to load the effect properties -Saturation::Saturation() : saturation(1.0) { +Saturation::Saturation() : saturation(1.0), saturation_R(1.0), saturation_G(1.0), saturation_B(1.0) { // Init effect properties init_effect_details(); } // Default constructor -Saturation::Saturation(Keyframe new_saturation) : saturation(new_saturation) +Saturation::Saturation(Keyframe new_saturation, Keyframe new_saturation_R, Keyframe new_saturation_G, Keyframe new_saturation_B) : saturation(new_saturation), saturation_R(new_saturation_R), saturation_G(new_saturation_G), saturation_B(new_saturation_B) { // Init effect properties init_effect_details(); @@ -71,6 +71,9 @@ std::shared_ptr Saturation::GetFrame(std::shared_ptr frame, int64_ // Get keyframe values for this frame float saturation_value = saturation.GetValue(frame_number); + float saturation_value_R = saturation_R.GetValue(frame_number); + float saturation_value_G = saturation_G.GetValue(frame_number); + float saturation_value_B = saturation_B.GetValue(frame_number); // Constants used for color saturation formula double pR = .299; @@ -87,6 +90,10 @@ std::shared_ptr Saturation::GetFrame(std::shared_ptr frame, int64_ int B = pixels[byte_index + 2]; int A = pixels[byte_index + 3]; + /* + * Common saturation adjustment + */ + // Calculate the saturation multiplier double p = sqrt( (R * R * pR) + (G * G * pG) + @@ -102,6 +109,58 @@ std::shared_ptr Saturation::GetFrame(std::shared_ptr frame, int64_ G = constrain(G); B = constrain(B); + /* + * Color-separated saturation adjustment + * + * Splitting each of the three subpixels (R, G and B) into three distincs sub-subpixels (R, G and B in turn) + * which in their optical sum reproduce the original subpixel's color OR produce white light in the brightness + * of the original subpixel (dependening on the color channel's slider value). + */ + + // Three subpixels producing either R or white with brightness of R + int Rr = R; + int Gr = 0; + int Br = 0; + + // Three subpixels producing either G or white with brightness of G + int Rg = 0; + int Gg = G; + int Bg = 0; + + // Three subpixels producing either B or white with brightness of B + int Rb = 0; + int Gb = 0; + int Bb = B; + + // Compute the brightness ("saturation multiplier") of the replaced subpixels + // Actually mathematical no-ops mostly, verbosity is kept just for clarification + const double p_r = sqrt( (Rr * Rr * pR) + (Gr * Gr * pG) + (Br * Br * pB) ); + const double p_g = sqrt( (Rg * Rg * pR) + (Gg * Gg * pG) + (Bg * Bg * pB) ); + const double p_b = sqrt( (Rb * Rb * pR) + (Gb * Gb * pG) + (Bb * Bb * pB) ); + + // Adjust the saturation + Rr = p_r + (Rr - p_r) * saturation_value_R; + Gr = p_r + (Gr - p_r) * saturation_value_R; + Br = p_r + (Br - p_r) * saturation_value_R; + + Rg = p_g + (Rg - p_g) * saturation_value_G; + Gg = p_g + (Gg - p_g) * saturation_value_G; + Bg = p_g + (Bg - p_g) * saturation_value_G; + + Rb = p_b + (Rb - p_b) * saturation_value_B; + Gb = p_b + (Gb - p_b) * saturation_value_B; + Bb = p_b + (Bb - p_b) * saturation_value_B; + + // Recombine brightness of sub-subpixels (Rx, Gx and Bx) into sub-pixels (R, G and B) again + R = Rr + Rg + Rb; + G = Gr + Gg + Gb; + B = Br + Bg + Bb; + + // Constrain the value from 0 to 255 + R = constrain(R); + G = constrain(G); + B = constrain(B); + // Set all pixels to new value pixels[byte_index] = R; pixels[byte_index + 1] = G; @@ -127,6 +186,9 @@ Json::Value Saturation::JsonValue() { Json::Value root = EffectBase::JsonValue(); // get parent properties root["type"] = info.class_name; root["saturation"] = saturation.JsonValue(); + root["saturation_R"] = saturation_R.JsonValue(); + root["saturation_G"] = saturation_G.JsonValue(); + root["saturation_B"] = saturation_B.JsonValue(); // return JsonValue return root; @@ -170,6 +232,12 @@ void Saturation::SetJsonValue(Json::Value root) { // Set data from Json (if key is found) if (!root["saturation"].isNull()) saturation.SetJsonValue(root["saturation"]); + if (!root["saturation_R"].isNull()) + saturation_R.SetJsonValue(root["saturation_R"]); + if (!root["saturation_G"].isNull()) + saturation_G.SetJsonValue(root["saturation_G"]); + if (!root["saturation_B"].isNull()) + saturation_B.SetJsonValue(root["saturation_B"]); } // Get all properties for a specific frame @@ -186,6 +254,9 @@ std::string Saturation::PropertiesJSON(int64_t requested_frame) { // Keyframes root["saturation"] = add_property_json("Saturation", saturation.GetValue(requested_frame), "float", "", &saturation, 0.0, 4.0, false, requested_frame); + root["saturation_R"] = add_property_json("Saturation (Red)", saturation_R.GetValue(requested_frame), "float", "", &saturation_R, 0.0, 4.0, false, requested_frame); + root["saturation_G"] = add_property_json("Saturation (Green)", saturation_G.GetValue(requested_frame), "float", "", &saturation_G, 0.0, 4.0, false, requested_frame); + root["saturation_B"] = add_property_json("Saturation (Blue)", saturation_B.GetValue(requested_frame), "float", "", &saturation_B, 0.0, 4.0, false, requested_frame); // Return formatted string return root.toStyledString(); From ffab5705543b3739e1f4b8bcdef0460eb8947952 Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sat, 23 Nov 2019 19:10:11 +0100 Subject: [PATCH 007/148] Color-separated Saturation: Enhanced Comment See https://github.com/OpenShot/libopenshot/pull/368#discussion_r349868322. Signed-off-by: Markus KARG --- include/effects/Saturation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/effects/Saturation.h b/include/effects/Saturation.h index 08695fd9..83ee75b2 100644 --- a/include/effects/Saturation.h +++ b/include/effects/Saturation.h @@ -64,7 +64,7 @@ namespace openshot void init_effect_details(); public: - Keyframe saturation; ///< The color saturation: 0.0 = black and white, 1.0 = normal, 2.0 = double saturation + Keyframe saturation; ///< Overall color saturation: 0.0 = black and white, 1.0 = normal, 2.0 = double saturation Keyframe saturation_R; ///< Red color saturation Keyframe saturation_G; ///< Green color saturation Keyframe saturation_B; ///< Blue color saturation From 09435d3e0c0dc4cb92f231ae584e16939eb81c65 Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sat, 23 Nov 2019 19:21:14 +0100 Subject: [PATCH 008/148] Saturation: Enhanced Comment ("greyscale" vs. "black and white") Signed-off-by: Markus KARG --- include/effects/Saturation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/effects/Saturation.h b/include/effects/Saturation.h index 83ee75b2..495816f6 100644 --- a/include/effects/Saturation.h +++ b/include/effects/Saturation.h @@ -64,7 +64,7 @@ namespace openshot void init_effect_details(); public: - Keyframe saturation; ///< Overall color saturation: 0.0 = black and white, 1.0 = normal, 2.0 = double saturation + Keyframe saturation; ///< Overall color saturation: 0.0 = greyscale, 1.0 = normal, 2.0 = double saturation Keyframe saturation_R; ///< Red color saturation Keyframe saturation_G; ///< Green color saturation Keyframe saturation_B; ///< Blue color saturation @@ -74,7 +74,7 @@ namespace openshot /// Default constructor, which takes 1 curve, to adjust the color saturation over time. /// - /// @param new_saturation The curve to adjust the saturation of the frame's image (0.0 = black and white, 1.0 = normal, 2.0 = double saturation) + /// @param new_saturation The curve to adjust the saturation of the frame's image (0.0 = greyscale, 1.0 = normal, 2.0 = double saturation) Saturation(Keyframe new_saturation, Keyframe new_saturation_R, Keyframe new_saturation_G, Keyframe new_saturation_B); /// @brief This method is required for all derived classes of EffectBase, and returns a From 9474973c15fb3691eefee2e74a1e7b472342818a Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sat, 23 Nov 2019 19:33:54 +0100 Subject: [PATCH 009/148] Color-separated Saturation: Enhanced constructor parameter names See https://github.com/OpenShot/libopenshot/pull/368#discussion_r349868437. Signed-off-by: Markus KARG --- include/effects/Saturation.h | 4 ++-- src/effects/Saturation.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/effects/Saturation.h b/include/effects/Saturation.h index 495816f6..7badef0e 100644 --- a/include/effects/Saturation.h +++ b/include/effects/Saturation.h @@ -74,8 +74,8 @@ namespace openshot /// Default constructor, which takes 1 curve, to adjust the color saturation over time. /// - /// @param new_saturation The curve to adjust the saturation of the frame's image (0.0 = greyscale, 1.0 = normal, 2.0 = double saturation) - Saturation(Keyframe new_saturation, Keyframe new_saturation_R, Keyframe new_saturation_G, Keyframe new_saturation_B); + /// @param saturation The curve to adjust the saturation of the frame's image (0.0 = greyscale, 1.0 = normal, 2.0 = double saturation) + Saturation(Keyframe saturation, Keyframe saturation_R, Keyframe saturation_G, Keyframe saturation_B); /// @brief This method is required for all derived classes of EffectBase, and returns a /// modified openshot::Frame object diff --git a/src/effects/Saturation.cpp b/src/effects/Saturation.cpp index 6762b4e7..567db2d1 100644 --- a/src/effects/Saturation.cpp +++ b/src/effects/Saturation.cpp @@ -39,7 +39,7 @@ Saturation::Saturation() : saturation(1.0), saturation_R(1.0), saturation_G(1.0) } // Default constructor -Saturation::Saturation(Keyframe new_saturation, Keyframe new_saturation_R, Keyframe new_saturation_G, Keyframe new_saturation_B) : saturation(new_saturation), saturation_R(new_saturation_R), saturation_G(new_saturation_G), saturation_B(new_saturation_B) +Saturation::Saturation(Keyframe saturation, Keyframe saturation_R, Keyframe saturation_G, Keyframe saturation_B) : saturation(saturation), saturation_R(saturation_R), saturation_G(saturation_G), saturation_B(saturation_B) { // Init effect properties init_effect_details(); From 0d7468b0704df1dc985817c32c47ea9ce0a59e4d Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 24 Nov 2019 17:12:17 +0100 Subject: [PATCH 010/148] Color-separated saturation: Documented new constructor parameters Signed-off-by: Markus KARG --- include/effects/Saturation.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/effects/Saturation.h b/include/effects/Saturation.h index 7badef0e..afd1c91f 100644 --- a/include/effects/Saturation.h +++ b/include/effects/Saturation.h @@ -75,6 +75,9 @@ namespace openshot /// Default constructor, which takes 1 curve, to adjust the color saturation over time. /// /// @param saturation The curve to adjust the saturation of the frame's image (0.0 = greyscale, 1.0 = normal, 2.0 = double saturation) + /// @param saturation_R The curve to adjust red saturation of the frame's image (0.0 = greyscale, 1.0 = normal, 2.0 = double saturation) + /// @param saturation_G The curve to adjust green saturation of the frame's image (0.0 = greyscale, 1.0 = normal, 2.0 = double saturation) + /// @param saturation_B The curve to adjust blue saturation of the frame's image (0.0 = greyscale, 1.0 = normal, 2.0 = double saturation) Saturation(Keyframe saturation, Keyframe saturation_R, Keyframe saturation_G, Keyframe saturation_B); /// @brief This method is required for all derived classes of EffectBase, and returns a From 88c04944b1d073b3ece17aca3920763cff6edae0 Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 24 Nov 2019 17:15:49 +0100 Subject: [PATCH 011/148] Color-separated Saturation: Enhanced description of constructor Signed-off-by: Markus KARG --- include/effects/Saturation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/effects/Saturation.h b/include/effects/Saturation.h index afd1c91f..aba762b4 100644 --- a/include/effects/Saturation.h +++ b/include/effects/Saturation.h @@ -72,7 +72,7 @@ namespace openshot /// Blank constructor, useful when using Json to load the effect properties Saturation(); - /// Default constructor, which takes 1 curve, to adjust the color saturation over time. + /// Default constructor, which takes four curves (one common curve and one curve per color), to adjust the color saturation over time. /// /// @param saturation The curve to adjust the saturation of the frame's image (0.0 = greyscale, 1.0 = normal, 2.0 = double saturation) /// @param saturation_R The curve to adjust red saturation of the frame's image (0.0 = greyscale, 1.0 = normal, 2.0 = double saturation) From 3a987eb044e0d755b4a1ae321fd816572e246e27 Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 24 Nov 2019 17:21:43 +0100 Subject: [PATCH 012/148] Color-separated Saturation: Line Wrap Signed-off-by: Markus KARG --- src/effects/Saturation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/effects/Saturation.cpp b/src/effects/Saturation.cpp index 567db2d1..407f97af 100644 --- a/src/effects/Saturation.cpp +++ b/src/effects/Saturation.cpp @@ -39,7 +39,8 @@ Saturation::Saturation() : saturation(1.0), saturation_R(1.0), saturation_G(1.0) } // Default constructor -Saturation::Saturation(Keyframe saturation, Keyframe saturation_R, Keyframe saturation_G, Keyframe saturation_B) : saturation(saturation), saturation_R(saturation_R), saturation_G(saturation_G), saturation_B(saturation_B) +Saturation::Saturation(Keyframe saturation, Keyframe saturation_R, Keyframe saturation_G, Keyframe saturation_B) : + saturation(saturation), saturation_R(saturation_R), saturation_G(saturation_G), saturation_B(saturation_B) { // Init effect properties init_effect_details(); From c979f5b0d6655add38016ab058d26569cc49361f Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 24 Nov 2019 18:16:21 +0100 Subject: [PATCH 013/148] Color-separated Saturation: Optimized math (removed no-ops) Signed-off-by: Markus KARG --- src/effects/Saturation.cpp | 39 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/src/effects/Saturation.cpp b/src/effects/Saturation.cpp index 407f97af..560c4102 100644 --- a/src/effects/Saturation.cpp +++ b/src/effects/Saturation.cpp @@ -118,39 +118,24 @@ std::shared_ptr Saturation::GetFrame(std::shared_ptr frame, int64_ * of the original subpixel (dependening on the color channel's slider value). */ - // Three subpixels producing either R or white with brightness of R - int Rr = R; - int Gr = 0; - int Br = 0; - - // Three subpixels producing either G or white with brightness of G - int Rg = 0; - int Gg = G; - int Bg = 0; - - // Three subpixels producing either B or white with brightness of B - int Rb = 0; - int Gb = 0; - int Bb = B; - // Compute the brightness ("saturation multiplier") of the replaced subpixels // Actually mathematical no-ops mostly, verbosity is kept just for clarification - const double p_r = sqrt( (Rr * Rr * pR) + (Gr * Gr * pG) + (Br * Br * pB) ); - const double p_g = sqrt( (Rg * Rg * pR) + (Gg * Gg * pG) + (Bg * Bg * pB) ); - const double p_b = sqrt( (Rb * Rb * pR) + (Gb * Gb * pG) + (Bb * Bb * pB) ); + const double p_r = sqrt(R * R * pR); + const double p_g = sqrt(G * G * pG); + const double p_b = sqrt(B * B * pB); // Adjust the saturation - Rr = p_r + (Rr - p_r) * saturation_value_R; - Gr = p_r + (Gr - p_r) * saturation_value_R; - Br = p_r + (Br - p_r) * saturation_value_R; + const int Rr = p_r + (R - p_r) * saturation_value_R; + const int Gr = p_r + (0 - p_r) * saturation_value_R; + const int Br = p_r + (0 - p_r) * saturation_value_R; - Rg = p_g + (Rg - p_g) * saturation_value_G; - Gg = p_g + (Gg - p_g) * saturation_value_G; - Bg = p_g + (Bg - p_g) * saturation_value_G; + const int Rg = p_g + (0 - p_g) * saturation_value_G; + const int Gg = p_g + (G - p_g) * saturation_value_G; + const int Bg = p_g + (0 - p_g) * saturation_value_G; - Rb = p_b + (Rb - p_b) * saturation_value_B; - Gb = p_b + (Gb - p_b) * saturation_value_B; - Bb = p_b + (Bb - p_b) * saturation_value_B; + const int Rb = p_b + (0 - p_b) * saturation_value_B; + const int Gb = p_b + (0 - p_b) * saturation_value_B; + const int Bb = p_b + (B - p_b) * saturation_value_B; // Recombine brightness of sub-subpixels (Rx, Gx and Bx) into sub-pixels (R, G and B) again R = Rr + Rg + Rb; From e6935ae7c0bed2666c6ac7243f89c0d8812b92e5 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 1 Jan 2020 04:00:07 -0500 Subject: [PATCH 014/148] Try Codecov.io instead --- .travis.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4635f86c..87f0841d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,6 @@ addons: - doxygen - graphviz - curl - - jq packages: &ff_common # Common set of FFmpeg packages - *p_common - libfdk-aac-dev @@ -111,7 +110,6 @@ matrix: - qt5-default - libomp-dev - - name: "Coverage (Ubuntu 18.04 Bionic)" env: - BUILD_VERSION=coverage_ffmpeg3 @@ -130,10 +128,6 @@ matrix: - lcov - binutils-common # For c++filt -before_script: - - CODACY_VERSION="$(curl -Ls https://api.bintray.com/packages/codacy/Binaries/codacy-coverage-reporter/versions/_latest | jq -r .name)" - - if [ "x${TEST_TARGET}" = "xcoverage" ]; then curl -Ls -o codacy-coverage-reporter "https://dl.bintray.com/codacy/Binaries/${CODACY_VERSION}/codacy-coverage-reporter-linux"; chmod +x codacy-coverage-reporter; fi - script: - mkdir -p build; cd build; - cmake -DCMAKE_BUILD_TYPE:STRING="Debug" ${CMAKE_EXTRA_ARGS} ../ @@ -143,4 +137,4 @@ script: - cd .. after_success: - - if [ "x${TEST_TARGET}" = "xcoverage" ]; then ./codacy-coverage-reporter report -l CPP -r build/coverage.info; fi + - if [ "x$TEST_TARGET" = "xcoverage" ]; then bash <(curl -s https://codecov.io/bash) -f build/coverage.info || echo "Codecov did not collect coverage reports"; fi From f63c1e0a65c6d1031cd1a55e0dde1a75fd21830d Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 16 Feb 2020 10:00:18 -0800 Subject: [PATCH 015/148] Newer codecs --- src/FFmpegWriter.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 8d060d77..dec430d1 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -255,7 +255,7 @@ void FFmpegWriter::SetVideoOptions(bool has_video, std::string codec, Fraction f } if (bit_rate >= 1000) // bit_rate is the bitrate in b/s info.video_bit_rate = bit_rate; - if ((bit_rate >= 0) && (bit_rate < 64)) // bit_rate is the bitrate in crf + if ((bit_rate >= 0) && (bit_rate < 256)) // bit_rate is the bitrate in crf info.video_bit_rate = bit_rate; info.interlaced_frame = interlaced; @@ -341,7 +341,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va // 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 == "rc_buffer_size" || name == "crf" || name == "cqp")) { + name == "rc_buffer_size" || name == "crf" || name == "cqp" || name == "qp")) { // Check for specific named options if (name == "g") // Set gop_size @@ -462,6 +462,18 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va case AV_CODEC_ID_AV1 : c->bit_rate = 0; av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); + if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { + //av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); + av_opt_set_int(c->priv_data, "preset", 6, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + } + if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + //av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); + av_opt_set_int(c->priv_data, "speed", 7, 0); + av_opt_set_int(c->priv_data, "tile-rows", 2, 0); + av_opt_set_int(c->priv_data, "tile-columns", 4, 0); + //av_opt_set(c->priv_data, "tile-row", "", 0); + } break; #endif case AV_CODEC_ID_VP8 : @@ -503,6 +515,36 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va c->bit_rate = (int) (mbs); } } +#endif + } else if (name == "qp") { + // 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_MAJOR >= 58) + switch (c->codec_id) { + case AV_CODEC_ID_AV1 : + c->bit_rate = 0; + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); + if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); + av_opt_set_int(c->priv_data, "preset", 6, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + } + if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); + av_opt_set_int(c->priv_data, "speed", 7, 0); + av_opt_set_int(c->priv_data, "tile-rows", 2, 0); + av_opt_set_int(c->priv_data, "tile-columns", 4, 0); + //av_opt_set(c->priv_data, "tile-row", "", 0); + } + if (strstr(info.vcodec.c_str(), "aom") != NULL) { + // Hack to set tiles; libaom doesn have qp only crf + av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); + av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows + av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns + } + break; + } #endif } else { // Set AVOption From 6711c9c788eea07595b9627fb6e428f841dc557f Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 16 Feb 2020 19:16:45 -0800 Subject: [PATCH 016/148] Minor improvements --- src/FFmpegWriter.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index dec430d1..b3a0b59c 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -463,16 +463,13 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va c->bit_rate = 0; av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { - //av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); av_opt_set_int(c->priv_data, "preset", 6, 0); av_opt_set_int(c->priv_data, "forced-idr",1,0); } if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { - //av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); av_opt_set_int(c->priv_data, "speed", 7, 0); av_opt_set_int(c->priv_data, "tile-rows", 2, 0); av_opt_set_int(c->priv_data, "tile-columns", 4, 0); - //av_opt_set(c->priv_data, "tile-row", "", 0); } break; #endif @@ -524,25 +521,30 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va switch (c->codec_id) { case AV_CODEC_ID_AV1 : c->bit_rate = 0; - av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); av_opt_set_int(c->priv_data, "preset", 6, 0); av_opt_set_int(c->priv_data, "forced-idr",1,0); } - if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + // Set number of tiles to a fixed value + // TODO Let user choose number of tiles av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); av_opt_set_int(c->priv_data, "speed", 7, 0); - av_opt_set_int(c->priv_data, "tile-rows", 2, 0); - av_opt_set_int(c->priv_data, "tile-columns", 4, 0); - //av_opt_set(c->priv_data, "tile-row", "", 0); + av_opt_set_int(c->priv_data, "tile-rows", 2, 0); // number of rows + av_opt_set_int(c->priv_data, "tile-columns", 4, 0); // number of columns } - if (strstr(info.vcodec.c_str(), "aom") != NULL) { - // Hack to set tiles; libaom doesn have qp only crf + else if (strstr(info.vcodec.c_str(), "aom") != NULL) { + // Set number of tiles to a fixed value + // TODO Let user choose number of tiles + // libaom doesn't have qp only crf av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns } + else { + av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); + } break; } #endif From e03cd87373faf119057da3914af6dda1d06e9fa2 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Mon, 17 Feb 2020 10:56:00 -0800 Subject: [PATCH 017/148] Initial svt-hevc (h.265) encoder support added --- src/FFmpegWriter.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index b3a0b59c..beb19534 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -492,7 +492,14 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va } break; case AV_CODEC_ID_HEVC : - av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51 + if (strstr(info.vcodec.c_str(), "svt_hevc") != NULL) { + av_opt_set_int(c->priv_data, "preset", 7, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + av_opt_set_int(c->priv_data, "qp",std::min(std::stoi(value), 51),0); + } + else { + av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51 + } if (std::stoi(value) == 0) { av_opt_set(c->priv_data, "preset", "veryslow", 0); av_opt_set_int(c->priv_data, "lossless", 1, 0); @@ -545,6 +552,13 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va else { av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); } + case AV_CODEC_ID_HEVC : + c->bit_rate = 0; + if (strstr(info.vcodec.c_str(), "svt_hevc") != NULL) { + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),51), 0); + av_opt_set_int(c->priv_data, "preset", 7, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + } break; } #endif From ddd52460e17f37d7078ee5ac4ae3335301c9ea86 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 1 Mar 2020 16:59:06 -0800 Subject: [PATCH 018/148] Fix handling of RAWIMAGE under ffmpeg 4 --- src/FFmpegWriter.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index beb19534..cc71e11a 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -842,6 +842,9 @@ void FFmpegWriter::flush_encoders() { #if (LIBAVFORMAT_VERSION_MAJOR < 58) if (info.has_video && video_codec && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) return; +#else + if (info.has_video && video_codec && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) + return; #endif int error_code = 0; @@ -1991,10 +1994,14 @@ void FFmpegWriter::process_video_packet(std::shared_ptr frame) { bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *frame_final) { #if (LIBAVFORMAT_VERSION_MAJOR >= 58) ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags", oc->oformat->flags); + + if (video_st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && + video_st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) { #else ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE); if (oc->oformat->flags & AVFMT_RAWPICTURE) { +#endif // Raw video case. AVPacket pkt; av_init_packet(&pkt); @@ -2019,7 +2026,6 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra AV_FREE_PACKET(&pkt); } else -#endif { AVPacket pkt; From 6476f930bb601cebe7f8470776e7a4f836e46ca6 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 1 Mar 2020 17:10:39 -0800 Subject: [PATCH 019/148] Simplify fix for RAWVIDEO handling for ffmpeg 4+ --- src/FFmpegWriter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index cc71e11a..cc4b3d3a 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1995,8 +1995,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra #if (LIBAVFORMAT_VERSION_MAJOR >= 58) ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags", oc->oformat->flags); - if (video_st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && - video_st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) { + if (AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) { #else ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE); From 5764b03544b8a14f9f3669e14db4740c23c9d06e Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 4 Mar 2020 23:52:42 -0500 Subject: [PATCH 020/148] FFmpegWriter: Use std::clog for output - Eliminate fprintf(stderr...) and non-threadsafe std::cerr - Replace with thread-safe std:clog or ZeroMQ calls - Clean up some formatting & ZeroMQ logging --- include/FFmpegWriter.h | 2 -- src/FFmpegWriter.cpp | 53 +++++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/include/FFmpegWriter.h b/include/FFmpegWriter.h index 1dfb21a9..252c1c43 100644 --- a/include/FFmpegWriter.h +++ b/include/FFmpegWriter.h @@ -47,8 +47,6 @@ #include #include -#include -#include #include #include "CacheMemory.h" #include "Exceptions.h" diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index e6a1d180..dd36bed0 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -33,6 +33,8 @@ #include "../include/FFmpegWriter.h" +#include + using namespace openshot; #if HAVE_HW_ACCEL @@ -59,7 +61,7 @@ static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int6 int err = 0; if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) { - fprintf(stderr, "Failed to create HW frame context.\n"); + std::clog << "Failed to create HW frame context.\n"; return -1; } frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data); @@ -69,8 +71,8 @@ static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int6 frames_ctx->height = height; frames_ctx->initial_pool_size = 20; if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) { - fprintf(stderr, "Failed to initialize HW frame context." - "Error code: %s\n",av_err2str(err)); + std::clog << "Failed to initialize HW frame context. " << + "Error code: " << av_err2str(err) << "\n"; av_buffer_unref(&hw_frames_ref); return err; } @@ -1365,7 +1367,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { int adapter_num; // Use the hw device given in the environment variable HW_EN_DEVICE_SET or the default if not set adapter_num = openshot::Settings::Instance()->HW_EN_DEVICE_SET; - fprintf(stderr, "\n\nEncodiing Device Nr: %d\n", adapter_num); + std::clog << "Encoding Device Nr: " << adapter_num << "\n"; if (adapter_num < 3 && adapter_num >=0) { #if defined(__linux__) snprintf(adapter,sizeof(adapter),"/dev/dri/renderD%d", adapter_num+128); @@ -1392,11 +1394,11 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { } else { adapter_ptr = NULL; // use default - ZmqLogger::Instance()->AppendDebugMethod("Encode Device not present using default"); + ZmqLogger::Instance()->AppendDebugMethod("Encode Device not present, using default"); } if (av_hwdevice_ctx_create(&hw_device_ctx, hw_en_av_device_type, adapter_ptr, NULL, 0) < 0) { - ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::open_video : Codec name: ", info.vcodec.c_str(), -1, " ERROR creating\n", -1); + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::open_video ERROR creating hwdevice, Codec name:", info.vcodec.c_str(), -1); throw InvalidCodec("Could not create hwdevice", path); } } @@ -1817,10 +1819,7 @@ void FFmpegWriter::write_audio_packets(bool is_final) { pkt.flags |= AV_PKT_FLAG_KEY; /* write the compressed frame in the media file */ - int error_code = av_interleaved_write_frame(oc, &pkt); - if (error_code < 0) { - ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_audio_packets ERROR [" + (std::string) av_err2str(error_code) + "]", "error_code", error_code); - } + error_code = av_interleaved_write_frame(oc, &pkt); } if (error_code < 0) { @@ -1998,17 +1997,17 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra #if HAVE_HW_ACCEL if (hw_en_on && hw_en_supported) { if (!(hw_frame = av_frame_alloc())) { - fprintf(stderr, "Error code: av_hwframe_alloc\n"); + std::clog << "Error code: av_hwframe_alloc\n"; } if (av_hwframe_get_buffer(video_codec->hw_frames_ctx, hw_frame, 0) < 0) { - fprintf(stderr, "Error code: av_hwframe_get_buffer\n"); + std::clog << "Error code: av_hwframe_get_buffer\n"; } if (!hw_frame->hw_frames_ctx) { - fprintf(stderr, "Error hw_frames_ctx.\n"); + std::clog << "Error hw_frames_ctx.\n"; } hw_frame->format = AV_PIX_FMT_NV12; if ( av_hwframe_transfer_data(hw_frame, frame_final, 0) < 0) { - fprintf(stderr, "Error while transferring frame data to surface.\n"); + std::clog << "Error while transferring frame data to surface.\n"; } av_frame_copy_props(hw_frame, frame_final); } @@ -2031,13 +2030,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra } error_code = ret; if (ret < 0 ) { - ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet (Frame not sent)"); - if (ret == AVERROR(EAGAIN) ) { - std::cerr << "Frame EAGAIN" << "\n"; - } - if (ret == AVERROR_EOF ) { - std::cerr << "Frame AVERROR_EOF" << "\n"; - } + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet (Frame not sent) ERROR [" + (std::string) av_err2str(ret) + "]", "ret", ret); avcodec_send_frame(video_codec, NULL); } else { @@ -2060,10 +2053,10 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra // Write video packet (older than FFmpeg 3.2) error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr); if (error_code != 0) { - std::cerr << "Frame AVERROR_EOF" << "\n"; + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (std::string) av_err2str(error_code) + "]", "error_code", error_code); } if (got_packet_ptr == 0) { - std::cerr << "Frame gotpacket error" << "\n"; + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet (Frame gotpacket error)"); } #else // Write video packet (even older versions of FFmpeg) @@ -2103,9 +2096,9 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra pkt.stream_index = video_st->index; /* write the compressed frame in the media file */ - int error_code = av_interleaved_write_frame(oc, &pkt); - if (error_code < 0) { - ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (std::string) av_err2str(error_code) + "]", "error_code", error_code); + int result = av_interleaved_write_frame(oc, &pkt); + if (result < 0) { + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (std::string) av_err2str(result) + "]", "result", result); return false; } } @@ -2148,12 +2141,14 @@ void FFmpegWriter::InitScalers(int source_width, int source_height) { // Init the software scaler from FFMpeg #if HAVE_HW_ACCEL if (hw_en_on && hw_en_supported) { - img_convert_ctx = sws_getContext(source_width, source_height, PIX_FMT_RGBA, info.width, info.height, AV_PIX_FMT_NV12, scale_mode, NULL, NULL, NULL); + img_convert_ctx = sws_getContext(source_width, source_height, PIX_FMT_RGBA, + info.width, info.height, AV_PIX_FMT_NV12, scale_mode, NULL, NULL, NULL); } else #endif // HAVE_HW_ACCEL { - img_convert_ctx = sws_getContext(source_width, source_height, PIX_FMT_RGBA, info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(video_st, video_st->codec), scale_mode, - NULL, NULL, NULL); + img_convert_ctx = sws_getContext(source_width, source_height, PIX_FMT_RGBA, + info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(video_st, video_st->codec), + scale_mode, NULL, NULL, NULL); } // Add rescaler to vector From 3a88d218662e4487ca3ce5dff036600a02bfc596 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 4 Mar 2020 23:58:16 -0500 Subject: [PATCH 021/148] FFmpegWriter: Drop ancient FFmpeg code - Drop any FFmpeg version checks for versions older than 2.6 - Remove code that was only used in FFmpeg 2.4 or lower - Add human-readable version comments to checks for LIBFOO_VERSION_MAJOR. etc. --- src/FFmpegWriter.cpp | 268 ++++++++++++++++--------------------------- 1 file changed, 97 insertions(+), 171 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index dd36bed0..245b0108 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -222,10 +222,10 @@ void FFmpegWriter::SetVideoOptions(bool has_video, std::string codec, Fraction f hw_en_on = 0; hw_en_supported = 0; } - #else // is FFmpeg 3 but not linux +#else // unknown OS new_codec = avcodec_find_encoder_by_name(codec.c_str()); - #endif //__linux__ -#else // not ffmpeg 3 +#endif //__linux__/_WIN32/__APPLE__ +#else // HAVE_HW_ACCEL new_codec = avcodec_find_encoder_by_name(codec.c_str()); #endif // HAVE_HW_ACCEL if (new_codec == NULL) @@ -410,57 +410,54 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va // 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 HAVE_HW_ACCEL - if (hw_en_on) { - av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); // 0-63 - } else - #endif // HAVE_HW_ACCEL - { + #if HAVE_HW_ACCEL + if (hw_en_on) { + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); // 0-63 + } else + #endif // HAVE_HW_ACCEL + { 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", std::min(std::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", std::max(std::min(std::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", std::min(std::stoi(value), 63), 0); // 0-63 - if (std::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", std::min(std::stoi(value), 51), 0); // 0-51 - if (std::stoi(value) == 0) { - av_opt_set(c->priv_data, "preset", "veryslow", 0); - } - break; - case AV_CODEC_ID_HEVC : - av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value), 51), 0); // 0-51 - if (std::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", std::min(std::stoi(value), 63), 0); // 0-63 - c->bit_rate = 0; + #if (LIBAVCODEC_VERSION_MAJOR >= 58) + case AV_CODEC_ID_AV1 : + c->bit_rate = 0; + av_opt_set_int(c->priv_data, "qp", std::min(std::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", std::max(std::min(std::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", std::min(std::stoi(value), 63), 0); // 0-63 + if (std::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", std::min(std::stoi(value), 51), 0); // 0-51 + if (std::stoi(value) == 0) { + av_opt_set(c->priv_data, "preset", "veryslow", 0); + } + break; + case AV_CODEC_ID_HEVC : + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value), 51), 0); // 0-51 + if (std::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", std::min(std::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 -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) #if HAVE_HW_ACCEL if (hw_en_on) { double mbs = 15000000.0; @@ -478,51 +475,50 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va { 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, "crf", std::min(std::stoi(value),63), 0); - break; + case AV_CODEC_ID_AV1 : + c->bit_rate = 0; + av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); + break; #endif - case AV_CODEC_ID_VP8 : - c->bit_rate = 10000000; - av_opt_set_int(c->priv_data, "crf", std::max(std::min(std::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, "crf", std::min(std::stoi(value), 63), 0); // 0-63 - if (std::stoi(value) == 0) { - av_opt_set(c->priv_data, "preset", "veryslow", 0); - av_opt_set_int(c->priv_data, "lossless", 1, 0); + case AV_CODEC_ID_VP8 : + c->bit_rate = 10000000; + av_opt_set_int(c->priv_data, "crf", std::max(std::min(std::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, "crf", std::min(std::stoi(value), 63), 0); // 0-63 + if (std::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, "crf", std::min(std::stoi(value), 51), 0); // 0-51 + if (std::stoi(value) == 0) { + av_opt_set(c->priv_data, "preset", "veryslow", 0); + } + break; + case AV_CODEC_ID_HEVC : + av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51 + if (std::stoi(value) == 0) { + av_opt_set(c->priv_data, "preset", "veryslow", 0); + av_opt_set_int(c->priv_data, "lossless", 1, 0); + } + break; + default: + // If this codec doesn't support crf calculate a bitrate + // TODO: find better formula + double mbs = 15000000.0; + if (info.video_bit_rate > 0) { + if (info.video_bit_rate > 42) { + mbs = 380000.0; + } else { + mbs *= std::pow(0.912, info.video_bit_rate); } - break; - case AV_CODEC_ID_H264 : - av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51 - if (std::stoi(value) == 0) { - av_opt_set(c->priv_data, "preset", "veryslow", 0); - } - break; - case AV_CODEC_ID_HEVC : - av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51 - if (std::stoi(value) == 0) { - av_opt_set(c->priv_data, "preset", "veryslow", 0); - av_opt_set_int(c->priv_data, "lossless", 1, 0); - } - break; - default: - // If this codec doesn't support crf calculate a bitrate - // TODO: find better formula - double mbs = 15000000.0; - if (info.video_bit_rate > 0) { - if (info.video_bit_rate > 42) { - mbs = 380000.0; - } else { - mbs *= std::pow(0.912, info.video_bit_rate); - } - } - c->bit_rate = (int) (mbs); + } + c->bit_rate = (int) (mbs); } } -#endif } else { // Set AVOption AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c); @@ -635,15 +631,8 @@ void FFmpegWriter::WriteFrame(std::shared_ptr frame) { // Write the frames once it reaches the correct cache size if ((int)spooled_video_frames.size() == cache_size || (int)spooled_audio_frames.size() == cache_size) { - // Is writer currently writing? - if (!is_writing) - // Write frames to video file - write_queued_frames(); - - else { - // Write frames to video file - write_queued_frames(); - } + // Write frames to video file + write_queued_frames(); } // Keep track of the last frame added @@ -801,6 +790,7 @@ void FFmpegWriter::flush_encoders() { if (info.has_audio && audio_codec && AV_GET_CODEC_TYPE(audio_st) == AVMEDIA_TYPE_AUDIO && AV_GET_CODEC_ATTRIBUTES(audio_st, audio_codec)->frame_size <= 1) return; #if (LIBAVFORMAT_VERSION_MAJOR < 58) + // FFmpeg < 4.0 if (info.has_video && video_codec && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) return; #endif @@ -820,9 +810,6 @@ void FFmpegWriter::flush_encoders() { pkt.data = NULL; pkt.size = 0; - // Pointer for video buffer (if using old FFmpeg version) - uint8_t *video_outbuf = NULL; - /* encode the image */ int got_packet = 0; int error_code = 0; @@ -853,28 +840,9 @@ void FFmpegWriter::flush_encoders() { } #else // IS_FFMPEG_3_2 -#if LIBAVFORMAT_VERSION_MAJOR >= 54 // Encode video packet (older than FFmpeg 3.2) error_code = avcodec_encode_video2(video_codec, &pkt, NULL, &got_packet); -#else - // Encode video packet (even older version of FFmpeg) - int video_outbuf_size = 0; - - /* encode the image */ - int out_size = avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL); - - /* if zero size, it means the image was buffered */ - if (out_size > 0) { - if(video_codec->coded_frame->key_frame) - pkt.flags |= AV_PKT_FLAG_KEY; - pkt.data= video_outbuf; - pkt.size= out_size; - - // got data back (so encode this frame) - got_packet = 1; - } -#endif // LIBAVFORMAT_VERSION_MAJOR >= 54 #endif // IS_FFMPEG_3_2 if (error_code < 0) { @@ -903,9 +871,6 @@ void FFmpegWriter::flush_encoders() { ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::flush_encoders ERROR [" + (std::string)av_err2str(error_code) + "]", "error_code", error_code); } - // Deallocate memory (if needed) - if (video_outbuf) - av_freep(&video_outbuf); } // FLUSH AUDIO ENCODER @@ -913,12 +878,8 @@ void FFmpegWriter::flush_encoders() { for (;;) { // Increment PTS (in samples and scaled to the codec's timebase) -#if LIBAVFORMAT_VERSION_MAJOR >= 54 // for some reason, it requires me to multiply channels X 2 write_audio_count += av_rescale_q(audio_input_position / (audio_codec->channels * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)), (AVRational){1, info.sample_rate}, audio_codec->time_base); -#else - write_audio_count += av_rescale_q(audio_input_position / audio_codec->channels, (AVRational){1, info.sample_rate}, audio_codec->time_base); -#endif AVPacket pkt; av_init_packet(&pkt); @@ -1073,11 +1034,7 @@ AVStream *FFmpegWriter::add_audio_stream() { AV_FORMAT_NEW_STREAM(oc, audio_codec, codec, st) c->codec_id = codec->id; -#if LIBAVFORMAT_VERSION_MAJOR >= 53 c->codec_type = AVMEDIA_TYPE_AUDIO; -#else - c->codec_type = CODEC_TYPE_AUDIO; -#endif // Set the sample parameters c->bit_rate = info.audio_bit_rate; @@ -1131,6 +1088,7 @@ AVStream *FFmpegWriter::add_audio_stream() { // some formats want stream headers to be separate if (oc->oformat->flags & AVFMT_GLOBALHEADER) #if (LIBAVCODEC_VERSION_MAJOR >= 57) + // FFmpeg 3.0+ c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; #else c->flags |= CODEC_FLAG_GLOBAL_HEADER; @@ -1156,11 +1114,7 @@ AVStream *FFmpegWriter::add_video_stream() { AV_FORMAT_NEW_STREAM(oc, video_codec, codec, st) c->codec_id = codec->id; -#if LIBAVFORMAT_VERSION_MAJOR >= 53 c->codec_type = AVMEDIA_TYPE_VIDEO; -#else - c->codec_type = CODEC_TYPE_VIDEO; -#endif /* Init video encoder options */ if (info.video_bit_rate >= 1000) { @@ -1174,13 +1128,12 @@ AVStream *FFmpegWriter::add_video_stream() { } else { // Check if codec supports crf switch (c->codec_id) { -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) #if (LIBAVCODEC_VERSION_MAJOR >= 58) + // FFmpeg 4.0+ case AV_CODEC_ID_AV1 : #endif case AV_CODEC_ID_VP9 : case AV_CODEC_ID_HEVC : -#endif case AV_CODEC_ID_VP8 : case AV_CODEC_ID_H264 : if (info.video_bit_rate < 40) { @@ -1217,7 +1170,7 @@ AVStream *FFmpegWriter::add_video_stream() { identically 1. */ c->time_base.num = info.video_timebase.num; c->time_base.den = info.video_timebase.den; -// AVCodecContext->framerate was added in FFmpeg 2.2 +// AVCodecContext->framerate was added in FFmpeg 2.6 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0) c->framerate = av_inv_q(c->time_base); #endif @@ -1238,6 +1191,7 @@ AVStream *FFmpegWriter::add_video_stream() { // some formats want stream headers to be separate if (oc->oformat->flags & AVFMT_GLOBALHEADER) #if (LIBAVCODEC_VERSION_MAJOR >= 57) + // FFmpeg 3.0+ c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; #else c->flags |= CODEC_FLAG_GLOBAL_HEADER; @@ -1259,6 +1213,7 @@ AVStream *FFmpegWriter::add_video_stream() { c->pix_fmt = PIX_FMT_RGB24; #if (LIBAVFORMAT_VERSION_MAJOR < 58) + // FFmpeg < 4.0 if (strcmp(fmt->name, "gif") != 0) // If not GIF format, skip the encoding process // Set raw picture flag (so we don't encode this video) @@ -1272,6 +1227,7 @@ AVStream *FFmpegWriter::add_video_stream() { AV_COPY_PARAMS_FROM_CONTEXT(st, c); #if (LIBAVFORMAT_VERSION_MAJOR < 58) + // FFmpeg < 4.0 ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::add_video_stream (" + (std::string)fmt->name + " : " + (std::string)av_get_pix_fmt_name(c->pix_fmt) + ")", "c->codec_id", c->codec_id, "c->bit_rate", c->bit_rate, "c->pix_fmt", c->pix_fmt, "oc->oformat->flags", oc->oformat->flags, "AVFMT_RAWPICTURE", AVFMT_RAWPICTURE); #else ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::add_video_stream (" + (std::string)fmt->name + " : " + (std::string)av_get_pix_fmt_name(c->pix_fmt) + ")", "c->codec_id", c->codec_id, "c->bit_rate", c->bit_rate, "c->pix_fmt", c->pix_fmt, "oc->oformat->flags", oc->oformat->flags); @@ -1373,9 +1329,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { snprintf(adapter,sizeof(adapter),"/dev/dri/renderD%d", adapter_num+128); // Maybe 127 is better because the first card would be 1?! adapter_ptr = adapter; -#elif defined(_WIN32) - adapter_ptr = NULL; -#elif defined(__APPLE__) +#elif defined(_WIN32) || defined(__APPLE__) adapter_ptr = NULL; #endif } @@ -1385,9 +1339,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { // Check if it is there and writable #if defined(__linux__) if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) { -#elif defined(_WIN32) - if( adapter_ptr != NULL ) { -#elif defined(__APPLE__) +#elif defined(_WIN32) || defined(__APPLE__) if( adapter_ptr != NULL ) { #endif ZmqLogger::Instance()->AppendDebugMethod("Encode Device present using device", "adapter", adapter_num); @@ -1948,6 +1900,7 @@ void FFmpegWriter::process_video_packet(std::shared_ptr frame) { // write video frame bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *frame_final) { #if (LIBAVFORMAT_VERSION_MAJOR >= 58) + // FFmpeg 4.0+ ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags", oc->oformat->flags); #else ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE); @@ -1977,7 +1930,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra AV_FREE_PACKET(&pkt); } else -#endif +#endif // LIBAVFORMAT_VERSION_MAJOR >= 58 { AVPacket pkt; @@ -1986,9 +1939,6 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra pkt.size = 0; pkt.pts = pkt.dts = AV_NOPTS_VALUE; - // Pointer for video buffer (if using old FFmpeg version) - uint8_t *video_outbuf = NULL; - // Increment PTS (in frames and scaled to the codec's timebase) write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec->time_base); @@ -2049,7 +1999,6 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra } } #else -#if LIBAVFORMAT_VERSION_MAJOR >= 54 // Write video packet (older than FFmpeg 3.2) error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr); if (error_code != 0) { @@ -2058,25 +2007,6 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra if (got_packet_ptr == 0) { ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet (Frame gotpacket error)"); } -#else - // Write video packet (even older versions of FFmpeg) - int video_outbuf_size = 200000; - video_outbuf = (uint8_t*) av_malloc(200000); - - /* encode the image */ - int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final); - - /* if zero size, it means the image was buffered */ - if (out_size > 0) { - if(video_codec->coded_frame->key_frame) - pkt.flags |= AV_PKT_FLAG_KEY; - pkt.data= video_outbuf; - pkt.size= out_size; - - // got data back (so encode this frame) - got_packet_ptr = 1; - } -#endif // LIBAVFORMAT_VERSION_MAJOR >= 54 #endif // IS_FFMPEG_3_2 /* if zero size, it means the image was buffered */ @@ -2103,10 +2033,6 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra } } - // Deallocate memory (if needed) - if (video_outbuf) - delete[] video_outbuf; - // Deallocate packet AV_FREE_PACKET(&pkt); #if HAVE_HW_ACCEL From 92ebd15545c52622dd060d8f693209ac058cd5b6 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 5 Mar 2020 01:38:25 -0500 Subject: [PATCH 022/148] FFmpegWriter: Code reformatting --- src/FFmpegWriter.cpp | 109 +++++++++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 34 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 245b0108..e8e9542c 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -255,10 +255,14 @@ void FFmpegWriter::SetVideoOptions(bool has_video, std::string codec, Fraction f info.pixel_ratio.num = pixel_ratio.num; info.pixel_ratio.den = pixel_ratio.den; } - if (bit_rate >= 1000) // bit_rate is the bitrate in b/s + if (bit_rate >= 1000) { + // bit_rate is the bitrate in b/s info.video_bit_rate = bit_rate; - if ((bit_rate >= 0) && (bit_rate < 64)) // bit_rate is the bitrate in crf + } + if ((bit_rate >= 0) && (bit_rate < 64)) { + // bit_rate is the bitrate in crf info.video_bit_rate = bit_rate; + } info.interlaced_frame = interlaced; info.top_field_first = top_field_first; @@ -282,8 +286,10 @@ void FFmpegWriter::SetVideoOptions(bool has_video, std::string codec, Fraction f // Set video export options (overloaded function) void FFmpegWriter::SetVideoOptions(std::string codec, int width, int height, Fraction fps, int bit_rate) { // Call full signature with some default parameters - FFmpegWriter::SetVideoOptions(true, codec, fps, width, height, - openshot::Fraction(1, 1), false, true, bit_rate); + FFmpegWriter::SetVideoOptions( + true, codec, fps, width, height, + openshot::Fraction(1, 1), false, true, bit_rate + ); } @@ -326,8 +332,10 @@ void FFmpegWriter::SetAudioOptions(bool has_audio, std::string codec, int sample // Set audio export options (overloaded function) void FFmpegWriter::SetAudioOptions(std::string codec, int sample_rate, int bit_rate) { // Call full signature with some default parameters - FFmpegWriter::SetAudioOptions(true, codec, sample_rate, 2, - openshot::LAYOUT_STEREO, bit_rate); + FFmpegWriter::SetAudioOptions( + true, codec, sample_rate, 2, + openshot::LAYOUT_STEREO, bit_rate + ); } @@ -418,6 +426,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va { switch (c->codec_id) { #if (LIBAVCODEC_VERSION_MAJOR >= 58) + // FFmpeg 4.0+ case AV_CODEC_ID_AV1 : c->bit_rate = 0; av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); // 0-63 @@ -475,6 +484,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va { switch (c->codec_id) { #if (LIBAVCODEC_VERSION_MAJOR >= 58) + // FFmpeg 4.0+ case AV_CODEC_ID_AV1 : c->bit_rate = 0; av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); @@ -1570,20 +1580,25 @@ void FFmpegWriter::write_audio_packets(bool is_final) { int nb_samples = 0; // Convert audio samples - nb_samples = SWR_CONVERT(avr, // audio resample context - audio_converted->data, // output data pointers - audio_converted->linesize[0], // output plane size, in bytes. (0 if unknown) - audio_converted->nb_samples, // maximum number of samples that the output buffer can hold - audio_frame->data, // input data pointers - audio_frame->linesize[0], // input plane size, in bytes (0 if unknown) - audio_frame->nb_samples); // number of input samples to convert + nb_samples = SWR_CONVERT( + avr, // audio resample context + audio_converted->data, // output data pointers + audio_converted->linesize[0], // output plane size, in bytes. (0 if unknown) + audio_converted->nb_samples, // maximum number of samples that the output buffer can hold + audio_frame->data, // input data pointers + audio_frame->linesize[0], // input plane size, in bytes (0 if unknown) + audio_frame->nb_samples // number of input samples to convert + ); // Set remaining samples remaining_frame_samples = nb_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16); // Create a new array (to hold all resampled S16 audio samples) all_resampled_samples = (int16_t *) av_malloc( - sizeof(int16_t) * nb_samples * info.channels * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))); + sizeof(int16_t) * nb_samples * info.channels + * (av_get_bytes_per_sample(output_sample_fmt) / + av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) ) + ); // Copy audio samples over original samples memcpy(all_resampled_samples, audio_converted->data[0], nb_samples * info.channels * av_get_bytes_per_sample(output_sample_fmt)); @@ -1613,8 +1628,14 @@ void FFmpegWriter::write_audio_packets(bool is_final) { // Copy frame samples into the packet samples array if (!is_final) //TODO: Make this more sane - memcpy(samples + (audio_input_position * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))), - all_resampled_samples + samples_position, diff * av_get_bytes_per_sample(output_sample_fmt)); + memcpy( + samples + (audio_input_position + * (av_get_bytes_per_sample(output_sample_fmt) / + av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) ) + ), + all_resampled_samples + samples_position, + diff * av_get_bytes_per_sample(output_sample_fmt) + ); // Increment counters audio_input_position += diff; @@ -1631,7 +1652,14 @@ void FFmpegWriter::write_audio_packets(bool is_final) { AVFrame *frame_final = AV_ALLOCATE_FRAME(); AV_RESET_FRAME(frame_final); if (av_sample_fmt_is_planar(audio_codec->sample_fmt)) { - ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)", "in_sample_fmt", output_sample_fmt, "out_sample_fmt", audio_codec->sample_fmt, "in_sample_rate", info.sample_rate, "out_sample_rate", info.sample_rate, "in_channels", info.channels, "out_channels", info.channels); + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)", + "in_sample_fmt", output_sample_fmt, + "out_sample_fmt", audio_codec->sample_fmt, + "in_sample_rate", info.sample_rate, + "out_sample_rate", info.sample_rate, + "in_channels", info.channels, + "out_channels", info.channels + ); // setup resample context if (!avr_planar) { @@ -1654,31 +1682,38 @@ void FFmpegWriter::write_audio_packets(bool is_final) { // Create a new array final_samples_planar = (int16_t *) av_malloc( - sizeof(int16_t) * audio_frame->nb_samples * info.channels * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))); + sizeof(int16_t) * audio_frame->nb_samples * info.channels + * (av_get_bytes_per_sample(output_sample_fmt) / + av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) ) + ); // Copy audio into buffer for frame memcpy(final_samples_planar, samples, audio_frame->nb_samples * info.channels * av_get_bytes_per_sample(output_sample_fmt)); // Fill input frame with sample data - avcodec_fill_audio_frame(audio_frame, info.channels, output_sample_fmt, (uint8_t *) final_samples_planar, - audio_encoder_buffer_size, 0); + avcodec_fill_audio_frame(audio_frame, info.channels, output_sample_fmt, + (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0); // Create output frame (and allocate arrays) frame_final->nb_samples = audio_input_frame_size; - av_samples_alloc(frame_final->data, frame_final->linesize, info.channels, frame_final->nb_samples, audio_codec->sample_fmt, 0); + av_samples_alloc(frame_final->data, frame_final->linesize, info.channels, + frame_final->nb_samples, audio_codec->sample_fmt, 0); // Convert audio samples - int nb_samples = SWR_CONVERT(avr_planar, // audio resample context - frame_final->data, // output data pointers - frame_final->linesize[0], // output plane size, in bytes. (0 if unknown) - frame_final->nb_samples, // maximum number of samples that the output buffer can hold - audio_frame->data, // input data pointers - audio_frame->linesize[0], // input plane size, in bytes (0 if unknown) - audio_frame->nb_samples); // number of input samples to convert + int nb_samples = SWR_CONVERT( + avr_planar, // audio resample context + frame_final->data, // output data pointers + frame_final->linesize[0], // output plane size, in bytes. (0 if unknown) + frame_final->nb_samples, // maximum number of samples that the output buffer can hold + audio_frame->data, // input data pointers + audio_frame->linesize[0], // input plane size, in bytes (0 if unknown) + audio_frame->nb_samples // number of input samples to convert + ); // Copy audio samples over original samples if (nb_samples > 0) - memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) * info.channels); + memcpy(samples, frame_final->data[0], + nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) * info.channels); // deallocate AVFrame av_freep(&(audio_frame->data[0])); @@ -1690,7 +1725,10 @@ void FFmpegWriter::write_audio_packets(bool is_final) { } else { // Create a new array final_samples = (int16_t *) av_malloc( - sizeof(int16_t) * audio_input_position * (av_get_bytes_per_sample(audio_codec->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))); + sizeof(int16_t) * audio_input_position + * (av_get_bytes_per_sample(audio_codec->sample_fmt) / + av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) ) + ); // Copy audio into buffer for frame memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt)); @@ -1699,8 +1737,8 @@ void FFmpegWriter::write_audio_packets(bool is_final) { frame_final->nb_samples = audio_input_frame_size; // Fill the final_frame AVFrame with audio (non planar) - avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, (uint8_t *) final_samples, - audio_encoder_buffer_size, 0); + avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, + (uint8_t *) final_samples, audio_encoder_buffer_size, 0); } // Increment PTS (in samples) @@ -1872,7 +1910,10 @@ void FFmpegWriter::process_video_packet(std::shared_ptr frame) { } else #endif // HAVE_HW_ACCEL { - frame_final = allocate_avframe((AVPixelFormat)(video_st->codecpar->format), info.width, info.height, &bytes_final, NULL); + frame_final = allocate_avframe( + (AVPixelFormat)(video_st->codecpar->format), + info.width, info.height, &bytes_final, NULL + ); } #else AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt, info.width, info.height, &bytes_final, NULL); @@ -1884,7 +1925,7 @@ void FFmpegWriter::process_video_packet(std::shared_ptr frame) { // Resize & convert pixel format sws_scale(scaler, frame_source->data, frame_source->linesize, 0, - source_image_height, frame_final->data, frame_final->linesize); + source_image_height, frame_final->data, frame_final->linesize); // Add resized AVFrame to av_frames map #pragma omp critical (av_frames_section) From 527acfe77a4fa17d5b0af6a8a5d2b908c170ba03 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 22 Mar 2020 12:08:40 -0400 Subject: [PATCH 023/148] FFmpegWriter: (a/v)_codec => (a/v)_codec_ctx The audio_codec and video_codec vars have type AVCodecContext. Renaming them to reflect that makes the code easier to follow. A couple of places in FFmpegUtilities macros that also used context variables named _codec got the same fix. --- include/FFmpegUtilities.h | 8 +- include/FFmpegWriter.h | 4 +- src/FFmpegWriter.cpp | 174 +++++++++++++++++++------------------- 3 files changed, 93 insertions(+), 93 deletions(-) diff --git a/include/FFmpegUtilities.h b/include/FFmpegUtilities.h index 62d64df1..895b220d 100644 --- a/include/FFmpegUtilities.h +++ b/include/FFmpegUtilities.h @@ -40,7 +40,7 @@ #ifndef IS_FFMPEG_3_2 #define IS_FFMPEG_3_2 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101)) #endif - + #ifndef HAVE_HW_ACCEL #define HAVE_HW_ACCEL (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 107, 100)) #endif @@ -178,13 +178,13 @@ #define AV_OUTPUT_CONTEXT(output_context, path) avformat_alloc_output_context2( output_context, NULL, NULL, path) #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0) #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) av_opt_set(priv_data, name, value, 0); avcodec_parameters_from_context(av_stream->codecpar, avcodec); - #define AV_FORMAT_NEW_STREAM(oc, st_codec, av_codec, av_st) av_st = avformat_new_stream(oc, NULL);\ + #define AV_FORMAT_NEW_STREAM(oc, st_codec_ctx, av_codec, av_st) av_st = avformat_new_stream(oc, NULL);\ if (!av_st) \ throw OutOfMemory("Could not allocate memory for the video stream.", path); \ c = avcodec_alloc_context3(av_codec); \ - st_codec = c; \ + st_codec_ctx = c; \ av_st->codecpar->codec_id = av_codec->id; - #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec) avcodec_parameters_from_context(av_stream->codecpar, av_codec); + #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec_ctx) avcodec_parameters_from_context(av_stream->codecpar, av_codec_ctx); #elif IS_FFMPEG_3_2 #define AV_REGISTER_ALL av_register_all(); #define AVCODEC_REGISTER_ALL avcodec_register_all(); diff --git a/include/FFmpegWriter.h b/include/FFmpegWriter.h index 1dfb21a9..7480663f 100644 --- a/include/FFmpegWriter.h +++ b/include/FFmpegWriter.h @@ -164,8 +164,8 @@ namespace openshot { AVOutputFormat *fmt; AVFormatContext *oc; AVStream *audio_st, *video_st; - AVCodecContext *video_codec; - AVCodecContext *audio_codec; + AVCodecContext *video_codec_ctx; + AVCodecContext *audio_codec_ctx; SwsContext *img_convert_ctx; double audio_pts, video_pts; int16_t *samples; diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index e6a1d180..435c6b47 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -87,7 +87,7 @@ FFmpegWriter::FFmpegWriter(std::string path) : path(path), fmt(NULL), oc(NULL), audio_st(NULL), video_st(NULL), audio_pts(0), video_pts(0), samples(NULL), audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0), initial_audio_input_frame_size(0), img_convert_ctx(NULL), cache_size(8), num_of_rescalers(32), - rescaler_position(0), video_codec(NULL), audio_codec(NULL), is_writing(false), write_video_count(0), write_audio_count(0), + rescaler_position(0), video_codec_ctx(NULL), audio_codec_ctx(NULL), is_writing(false), write_video_count(0), write_audio_count(0), original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false), write_header(false), write_trailer(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL) { @@ -339,11 +339,11 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va if (info.has_video && stream == VIDEO_STREAM && video_st) { st = video_st; // Get codec context - c = AV_GET_CODEC_PAR_CONTEXT(st, video_codec); + c = AV_GET_CODEC_PAR_CONTEXT(st, video_codec_ctx); } else if (info.has_audio && stream == AUDIO_STREAM && audio_st) { st = audio_st; // Get codec context - c = AV_GET_CODEC_PAR_CONTEXT(st, audio_codec); + c = AV_GET_CODEC_PAR_CONTEXT(st, audio_codec_ctx); } else throw NoStreamsFound("The stream was not found. Be sure to call PrepareStreams() first.", path); @@ -796,10 +796,10 @@ void FFmpegWriter::WriteTrailer() { // Flush encoders void FFmpegWriter::flush_encoders() { - if (info.has_audio && audio_codec && AV_GET_CODEC_TYPE(audio_st) == AVMEDIA_TYPE_AUDIO && AV_GET_CODEC_ATTRIBUTES(audio_st, audio_codec)->frame_size <= 1) + if (info.has_audio && audio_codec_ctx && AV_GET_CODEC_TYPE(audio_st) == AVMEDIA_TYPE_AUDIO && AV_GET_CODEC_ATTRIBUTES(audio_st, audio_codec_ctx)->frame_size <= 1) return; #if (LIBAVFORMAT_VERSION_MAJOR < 58) - if (info.has_video && video_codec && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) + if (info.has_video && video_codec_ctx && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) return; #endif @@ -811,7 +811,7 @@ void FFmpegWriter::flush_encoders() { for (;;) { // Increment PTS (in frames and scaled to the codec's timebase) - write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec->time_base); + write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec_ctx->time_base); AVPacket pkt; av_init_packet(&pkt); @@ -829,22 +829,22 @@ void FFmpegWriter::flush_encoders() { #pragma omp critical (write_video_packet) { // Encode video packet (latest version of FFmpeg) - error_code = avcodec_send_frame(video_codec, NULL); + error_code = avcodec_send_frame(video_codec_ctx, NULL); got_packet = 0; while (error_code >= 0) { - error_code = avcodec_receive_packet(video_codec, &pkt); + error_code = avcodec_receive_packet(video_codec_ctx, &pkt); if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) { got_packet = 0; // Write packet - avcodec_flush_buffers(video_codec); + avcodec_flush_buffers(video_codec_ctx); break; } if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base); + pkt.pts = av_rescale_q(pkt.pts, video_codec_ctx->time_base, video_st->time_base); if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base); + pkt.dts = av_rescale_q(pkt.dts, video_codec_ctx->time_base, video_st->time_base); if (pkt.duration > 0) - pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base); + pkt.duration = av_rescale_q(pkt.duration, video_codec_ctx->time_base, video_st->time_base); pkt.stream_index = video_st->index; error_code = av_interleaved_write_frame(oc, &pkt); } @@ -853,18 +853,18 @@ void FFmpegWriter::flush_encoders() { #if LIBAVFORMAT_VERSION_MAJOR >= 54 // Encode video packet (older than FFmpeg 3.2) - error_code = avcodec_encode_video2(video_codec, &pkt, NULL, &got_packet); + error_code = avcodec_encode_video2(video_codec_ctx, &pkt, NULL, &got_packet); #else // Encode video packet (even older version of FFmpeg) int video_outbuf_size = 0; /* encode the image */ - int out_size = avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL); + int out_size = avcodec_encode_video(video_codec_ctx, NULL, video_outbuf_size, NULL); /* if zero size, it means the image was buffered */ if (out_size > 0) { - if(video_codec->coded_frame->key_frame) + if(video_codec_ctx->coded_frame->key_frame) pkt.flags |= AV_PKT_FLAG_KEY; pkt.data= video_outbuf; pkt.size= out_size; @@ -888,11 +888,11 @@ void FFmpegWriter::flush_encoders() { // set the timestamp if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base); + pkt.pts = av_rescale_q(pkt.pts, video_codec_ctx->time_base, video_st->time_base); if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base); + pkt.dts = av_rescale_q(pkt.dts, video_codec_ctx->time_base, video_st->time_base); if (pkt.duration > 0) - pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base); + pkt.duration = av_rescale_q(pkt.duration, video_codec_ctx->time_base, video_st->time_base); pkt.stream_index = video_st->index; // Write packet @@ -913,9 +913,9 @@ void FFmpegWriter::flush_encoders() { // Increment PTS (in samples and scaled to the codec's timebase) #if LIBAVFORMAT_VERSION_MAJOR >= 54 // for some reason, it requires me to multiply channels X 2 - write_audio_count += av_rescale_q(audio_input_position / (audio_codec->channels * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)), (AVRational){1, info.sample_rate}, audio_codec->time_base); + write_audio_count += av_rescale_q(audio_input_position / (audio_codec_ctx->channels * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)), av_make_q(1, info.sample_rate), audio_codec_ctx->time_base); #else - write_audio_count += av_rescale_q(audio_input_position / audio_codec->channels, (AVRational){1, info.sample_rate}, audio_codec->time_base); + write_audio_count += av_rescale_q(audio_input_position / audio_codec_ctx->channels, (AVRational){1, info.sample_rate}, audio_codec_ctx->time_base); #endif AVPacket pkt; @@ -927,10 +927,10 @@ void FFmpegWriter::flush_encoders() { /* encode the image */ int got_packet = 0; #if IS_FFMPEG_3_2 - avcodec_send_frame(audio_codec, NULL); + avcodec_send_frame(audio_codec_ctx, NULL); got_packet = 0; #else - error_code = avcodec_encode_audio2(audio_codec, &pkt, NULL, &got_packet); + error_code = avcodec_encode_audio2(audio_codec_ctx, &pkt, NULL, &got_packet); #endif if (error_code < 0) { ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::flush_encoders ERROR [" + (std::string)av_err2str(error_code) + "]", "error_code", error_code); @@ -946,11 +946,11 @@ void FFmpegWriter::flush_encoders() { // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase) if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base); + pkt.pts = av_rescale_q(pkt.pts, audio_codec_ctx->time_base, audio_st->time_base); if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base); + pkt.dts = av_rescale_q(pkt.dts, audio_codec_ctx->time_base, audio_st->time_base); if (pkt.duration > 0) - pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base); + pkt.duration = av_rescale_q(pkt.duration, audio_codec_ctx->time_base, audio_st->time_base); // set stream pkt.stream_index = audio_st->index; @@ -1068,7 +1068,7 @@ AVStream *FFmpegWriter::add_audio_stream() { throw InvalidCodec("A valid audio codec could not be found for this file.", path); // Create a new audio stream - AV_FORMAT_NEW_STREAM(oc, audio_codec, codec, st) + AV_FORMAT_NEW_STREAM(oc, audio_codec_ctx, codec, st) c->codec_id = codec->id; #if LIBAVFORMAT_VERSION_MAJOR >= 53 @@ -1151,7 +1151,7 @@ AVStream *FFmpegWriter::add_video_stream() { throw InvalidCodec("A valid video codec could not be found for this file.", path); // Create a new video stream - AV_FORMAT_NEW_STREAM(oc, video_codec, codec, st) + AV_FORMAT_NEW_STREAM(oc, video_codec_ctx, codec, st) c->codec_id = codec->id; #if LIBAVFORMAT_VERSION_MAJOR >= 53 @@ -1281,15 +1281,15 @@ AVStream *FFmpegWriter::add_video_stream() { // open audio codec void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) { AVCodec *codec; - AV_GET_CODEC_FROM_STREAM(st, audio_codec) + AV_GET_CODEC_FROM_STREAM(st, audio_codec_ctx) // Set number of threads equal to number of processors (not to exceed 16) - audio_codec->thread_count = std::min(FF_NUM_PROCESSORS, 16); + audio_codec_ctx->thread_count = std::min(FF_NUM_PROCESSORS, 16); // Find the audio encoder codec = avcodec_find_encoder_by_name(info.acodec.c_str()); if (!codec) - codec = avcodec_find_encoder(audio_codec->codec_id); + codec = avcodec_find_encoder(audio_codec_ctx->codec_id); if (!codec) throw InvalidCodec("Could not find codec", path); @@ -1298,16 +1298,16 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) { av_dict_set(&opts, "strict", "experimental", 0); // Open the codec - if (avcodec_open2(audio_codec, codec, &opts) < 0) + if (avcodec_open2(audio_codec_ctx, codec, &opts) < 0) throw InvalidCodec("Could not open audio codec", path); - AV_COPY_PARAMS_FROM_CONTEXT(st, audio_codec); + AV_COPY_PARAMS_FROM_CONTEXT(st, audio_codec_ctx); // Free options av_dict_free(&opts); // Calculate the size of the input frame (i..e how many samples per packet), and the output buffer // TODO: Ugly hack for PCM codecs (will be removed ASAP with new PCM support to compute the input frame size in samples - if (audio_codec->frame_size <= 1) { + if (audio_codec_ctx->frame_size <= 1) { // No frame size found... so calculate audio_input_frame_size = 50000 / info.channels; @@ -1324,7 +1324,7 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) { } } else { // Set frame size based on the codec - audio_input_frame_size = audio_codec->frame_size; + audio_input_frame_size = audio_codec_ctx->frame_size; } // Set the initial frame size (since it might change during resampling) @@ -1346,16 +1346,16 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) { av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0); } - ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::open_audio", "audio_codec->thread_count", audio_codec->thread_count, "audio_input_frame_size", audio_input_frame_size, "buffer_size", AVCODEC_MAX_AUDIO_FRAME_SIZE + MY_INPUT_BUFFER_PADDING_SIZE); + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::open_audio", "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count, "audio_input_frame_size", audio_input_frame_size, "buffer_size", AVCODEC_MAX_AUDIO_FRAME_SIZE + MY_INPUT_BUFFER_PADDING_SIZE); } // open video codec void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { AVCodec *codec; - AV_GET_CODEC_FROM_STREAM(st, video_codec) + AV_GET_CODEC_FROM_STREAM(st, video_codec_ctx) // Set number of threads equal to number of processors (not to exceed 16) - video_codec->thread_count = std::min(FF_NUM_PROCESSORS, 16); + video_codec_ctx->thread_count = std::min(FF_NUM_PROCESSORS, 16); #if HAVE_HW_ACCEL if (hw_en_on && hw_en_supported) { @@ -1410,8 +1410,8 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { throw InvalidCodec("Could not find codec", path); /* Force max_b_frames to 0 in some cases (i.e. for mjpeg image sequences */ - if (video_codec->max_b_frames && video_codec->codec_id != AV_CODEC_ID_MPEG4 && video_codec->codec_id != AV_CODEC_ID_MPEG1VIDEO && video_codec->codec_id != AV_CODEC_ID_MPEG2VIDEO) - video_codec->max_b_frames = 0; + if (video_codec_ctx->max_b_frames && video_codec_ctx->codec_id != AV_CODEC_ID_MPEG4 && video_codec_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO && video_codec_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO) + video_codec_ctx->max_b_frames = 0; // Init options AVDictionary *opts = NULL; @@ -1419,7 +1419,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { #if HAVE_HW_ACCEL if (hw_en_on && hw_en_supported) { - video_codec->pix_fmt = hw_en_av_pix_fmt; + video_codec_ctx->pix_fmt = hw_en_av_pix_fmt; // 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 @@ -1429,23 +1429,23 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { // 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) { + if (av_opt_get_int(video_codec_ctx->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); + av_opt_set(video_codec_ctx->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; + video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate; } } - switch (video_codec->codec_id) { + switch (video_codec_ctx->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); + video_codec_ctx->max_b_frames = 0; // At least this GPU doesn't support b-frames + video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED; + av_opt_set(video_codec_ctx->priv_data, "preset", "slow", 0); + av_opt_set(video_codec_ctx->priv_data, "tune", "zerolatency", 0); + av_opt_set(video_codec_ctx->priv_data, "vprofile", "baseline", AV_OPT_SEARCH_CHILDREN); break; case AV_CODEC_ID_HEVC: // tested to work with defaults @@ -1455,13 +1455,13 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { break; default: ZmqLogger::Instance()->AppendDebugMethod("No codec-specific options defined for this codec. HW encoding may fail", - "codec_id", video_codec->codec_id); + "codec_id", video_codec_ctx->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) { + if ((err = set_hwframe_ctx(video_codec_ctx, hw_device_ctx, info.width, info.height)) < 0) { 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); } @@ -1469,9 +1469,9 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { #endif // HAVE_HW_ACCEL /* open the codec */ - if (avcodec_open2(video_codec, codec, &opts) < 0) + if (avcodec_open2(video_codec_ctx, codec, &opts) < 0) throw InvalidCodec("Could not open video codec", path); - AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec); + AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec_ctx); // Free options av_dict_free(&opts); @@ -1481,7 +1481,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) { av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0); } - ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::open_video", "video_codec->thread_count", video_codec->thread_count); + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::open_video", "video_codec_ctx->thread_count", video_codec_ctx->thread_count); } @@ -1549,7 +1549,7 @@ void FFmpegWriter::write_audio_packets(bool is_final) { ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_audio_packets", "is_final", is_final, "total_frame_samples", total_frame_samples, "channel_layout_in_frame", channel_layout_in_frame, "channels_in_frame", channels_in_frame, "samples_in_frame", samples_in_frame, "LAYOUT_MONO", LAYOUT_MONO); // Keep track of the original sample format - AVSampleFormat output_sample_fmt = audio_codec->sample_fmt; + AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt; AVFrame *audio_frame = NULL; if (!is_final) { @@ -1565,7 +1565,7 @@ void FFmpegWriter::write_audio_packets(bool is_final) { } // Do not convert audio to planar format (yet). We need to keep everything interleaved at this point. - switch (audio_codec->sample_fmt) { + switch (audio_codec_ctx->sample_fmt) { case AV_SAMPLE_FMT_FLTP: { output_sample_fmt = AV_SAMPLE_FMT_FLT; break; @@ -1676,8 +1676,8 @@ void FFmpegWriter::write_audio_packets(bool is_final) { // Convert to planar (if needed by audio codec) AVFrame *frame_final = AV_ALLOCATE_FRAME(); AV_RESET_FRAME(frame_final); - if (av_sample_fmt_is_planar(audio_codec->sample_fmt)) { - ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)", "in_sample_fmt", output_sample_fmt, "out_sample_fmt", audio_codec->sample_fmt, "in_sample_rate", info.sample_rate, "out_sample_rate", info.sample_rate, "in_channels", info.channels, "out_channels", info.channels); + if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) { + ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)", "in_sample_fmt", output_sample_fmt, "out_sample_fmt", audio_codec_ctx->sample_fmt, "in_sample_rate", info.sample_rate, "out_sample_rate", info.sample_rate, "in_channels", info.channels, "out_channels", info.channels); // setup resample context if (!avr_planar) { @@ -1685,7 +1685,7 @@ void FFmpegWriter::write_audio_packets(bool is_final) { av_opt_set_int(avr_planar, "in_channel_layout", info.channel_layout, 0); av_opt_set_int(avr_planar, "out_channel_layout", info.channel_layout, 0); av_opt_set_int(avr_planar, "in_sample_fmt", output_sample_fmt, 0); - av_opt_set_int(avr_planar, "out_sample_fmt", audio_codec->sample_fmt, 0); // planar not allowed here + av_opt_set_int(avr_planar, "out_sample_fmt", audio_codec_ctx->sample_fmt, 0); // planar not allowed here av_opt_set_int(avr_planar, "in_sample_rate", info.sample_rate, 0); av_opt_set_int(avr_planar, "out_sample_rate", info.sample_rate, 0); av_opt_set_int(avr_planar, "in_channels", info.channels, 0); @@ -1711,7 +1711,7 @@ void FFmpegWriter::write_audio_packets(bool is_final) { // Create output frame (and allocate arrays) frame_final->nb_samples = audio_input_frame_size; - av_samples_alloc(frame_final->data, frame_final->linesize, info.channels, frame_final->nb_samples, audio_codec->sample_fmt, 0); + av_samples_alloc(frame_final->data, frame_final->linesize, info.channels, frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0); // Convert audio samples int nb_samples = SWR_CONVERT(avr_planar, // audio resample context @@ -1724,7 +1724,7 @@ void FFmpegWriter::write_audio_packets(bool is_final) { // Copy audio samples over original samples if (nb_samples > 0) - memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) * info.channels); + memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) * info.channels); // deallocate AVFrame av_freep(&(audio_frame->data[0])); @@ -1736,16 +1736,16 @@ void FFmpegWriter::write_audio_packets(bool is_final) { } else { // Create a new array final_samples = (int16_t *) av_malloc( - sizeof(int16_t) * audio_input_position * (av_get_bytes_per_sample(audio_codec->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))); + sizeof(int16_t) * audio_input_position * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))); // Copy audio into buffer for frame - memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt)); + memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)); // Init the nb_samples property frame_final->nb_samples = audio_input_frame_size; // Fill the final_frame AVFrame with audio (non planar) - avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, (uint8_t *) final_samples, + avcodec_fill_audio_frame(frame_final, audio_codec_ctx->channels, audio_codec_ctx->sample_fmt, (uint8_t *) final_samples, audio_encoder_buffer_size, 0); } @@ -1770,18 +1770,18 @@ void FFmpegWriter::write_audio_packets(bool is_final) { int error_code; int ret = 0; int frame_finished = 0; - error_code = ret = avcodec_send_frame(audio_codec, frame_final); + error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final); if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) { - avcodec_send_frame(audio_codec, NULL); + avcodec_send_frame(audio_codec_ctx, NULL); } else { if (ret >= 0) pkt.size = 0; - ret = avcodec_receive_packet(audio_codec, &pkt); + ret = avcodec_receive_packet(audio_codec_ctx, &pkt); if (ret >= 0) frame_finished = 1; if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) { - avcodec_flush_buffers(audio_codec); + avcodec_flush_buffers(audio_codec_ctx); ret = 0; } if (ret >= 0) { @@ -1795,7 +1795,7 @@ void FFmpegWriter::write_audio_packets(bool is_final) { got_packet_ptr = ret; #else // Encode audio (older versions of FFmpeg) - int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr); + int error_code = avcodec_encode_audio2(audio_codec_ctx, &pkt, frame_final, &got_packet_ptr); #endif /* if zero size, it means the image was buffered */ if (error_code == 0 && got_packet_ptr) { @@ -1806,11 +1806,11 @@ void FFmpegWriter::write_audio_packets(bool is_final) { // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase) if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base); + pkt.pts = av_rescale_q(pkt.pts, audio_codec_ctx->time_base, audio_st->time_base); if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base); + pkt.dts = av_rescale_q(pkt.dts, audio_codec_ctx->time_base, audio_st->time_base); if (pkt.duration > 0) - pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base); + pkt.duration = av_rescale_q(pkt.duration, audio_codec_ctx->time_base, audio_st->time_base); // set stream pkt.stream_index = audio_st->index; @@ -1924,7 +1924,7 @@ void FFmpegWriter::process_video_packet(std::shared_ptr frame) { frame_final = allocate_avframe((AVPixelFormat)(video_st->codecpar->format), info.width, info.height, &bytes_final, NULL); } #else - AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt, info.width, info.height, &bytes_final, NULL); + AVFrame *frame_final = allocate_avframe(video_codec_ctx->pix_fmt, info.width, info.height, &bytes_final, NULL); #endif // IS_FFMPEG_3_2 // Fill with data @@ -1964,7 +1964,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra pkt.size = sizeof(AVPicture); // Increment PTS (in frames and scaled to the codec's timebase) - write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec->time_base); + write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec_ctx->time_base); pkt.pts = write_video_count; /* write the compressed frame in the media file */ @@ -1991,7 +1991,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra uint8_t *video_outbuf = NULL; // Increment PTS (in frames and scaled to the codec's timebase) - write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec->time_base); + write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec_ctx->time_base); // Assign the initial AVFrame PTS from the frame counter frame_final->pts = write_video_count; @@ -2000,7 +2000,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra if (!(hw_frame = av_frame_alloc())) { fprintf(stderr, "Error code: av_hwframe_alloc\n"); } - if (av_hwframe_get_buffer(video_codec->hw_frames_ctx, hw_frame, 0) < 0) { + if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx, hw_frame, 0) < 0) { fprintf(stderr, "Error code: av_hwframe_get_buffer\n"); } if (!hw_frame->hw_frames_ctx) { @@ -2023,11 +2023,11 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra #if HAVE_HW_ACCEL if (hw_en_on && hw_en_supported) { - ret = avcodec_send_frame(video_codec, hw_frame); //hw_frame!!! + ret = avcodec_send_frame(video_codec_ctx, hw_frame); //hw_frame!!! } else #endif // HAVE_HW_ACCEL { - ret = avcodec_send_frame(video_codec, frame_final); + ret = avcodec_send_frame(video_codec_ctx, frame_final); } error_code = ret; if (ret < 0 ) { @@ -2038,14 +2038,14 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra if (ret == AVERROR_EOF ) { std::cerr << "Frame AVERROR_EOF" << "\n"; } - avcodec_send_frame(video_codec, NULL); + avcodec_send_frame(video_codec_ctx, NULL); } else { while (ret >= 0) { - ret = avcodec_receive_packet(video_codec, &pkt); + ret = avcodec_receive_packet(video_codec_ctx, &pkt); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { - avcodec_flush_buffers(video_codec); + avcodec_flush_buffers(video_codec_ctx); got_packet_ptr = 0; break; } @@ -2058,7 +2058,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra #else #if LIBAVFORMAT_VERSION_MAJOR >= 54 // Write video packet (older than FFmpeg 3.2) - error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr); + error_code = avcodec_encode_video2(video_codec_ctx, &pkt, frame_final, &got_packet_ptr); if (error_code != 0) { std::cerr << "Frame AVERROR_EOF" << "\n"; } @@ -2071,11 +2071,11 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra video_outbuf = (uint8_t*) av_malloc(200000); /* encode the image */ - int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final); + int out_size = avcodec_encode_video(video_codec_ctx, video_outbuf, video_outbuf_size, frame_final); /* if zero size, it means the image was buffered */ if (out_size > 0) { - if(video_codec->coded_frame->key_frame) + if(video_codec_ctx->coded_frame->key_frame) pkt.flags |= AV_PKT_FLAG_KEY; pkt.data= video_outbuf; pkt.size= out_size; @@ -2095,11 +2095,11 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra // set the timestamp if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base); + pkt.pts = av_rescale_q(pkt.pts, video_codec_ctx->time_base, video_st->time_base); if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base); + pkt.dts = av_rescale_q(pkt.dts, video_codec_ctx->time_base, video_st->time_base); if (pkt.duration > 0) - pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base); + pkt.duration = av_rescale_q(pkt.duration, video_codec_ctx->time_base, video_st->time_base); pkt.stream_index = video_st->index; /* write the compressed frame in the media file */ From f9a91a5a92d834ee19030b213fadbd9482adc198 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 22 Mar 2020 12:15:02 -0400 Subject: [PATCH 024/148] FFmpegWriter: Replace AVRational casts with av_make_q() Some compilers balk at the compound initializers in the cast form --- src/FFmpegWriter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 435c6b47..54b5bc85 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -811,7 +811,7 @@ void FFmpegWriter::flush_encoders() { for (;;) { // Increment PTS (in frames and scaled to the codec's timebase) - write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec_ctx->time_base); + write_video_count += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base); AVPacket pkt; av_init_packet(&pkt); @@ -915,7 +915,7 @@ void FFmpegWriter::flush_encoders() { // for some reason, it requires me to multiply channels X 2 write_audio_count += av_rescale_q(audio_input_position / (audio_codec_ctx->channels * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)), av_make_q(1, info.sample_rate), audio_codec_ctx->time_base); #else - write_audio_count += av_rescale_q(audio_input_position / audio_codec_ctx->channels, (AVRational){1, info.sample_rate}, audio_codec_ctx->time_base); + write_audio_count += av_rescale_q(audio_input_position / audio_codec_ctx->channels, av_make_q(1, info.sample_rate), audio_codec_ctx->time_base); #endif AVPacket pkt; @@ -1964,7 +1964,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra pkt.size = sizeof(AVPicture); // Increment PTS (in frames and scaled to the codec's timebase) - write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec_ctx->time_base); + write_video_count += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base); pkt.pts = write_video_count; /* write the compressed frame in the media file */ @@ -1991,7 +1991,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra uint8_t *video_outbuf = NULL; // Increment PTS (in frames and scaled to the codec's timebase) - write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec_ctx->time_base); + write_video_count += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base); // Assign the initial AVFrame PTS from the frame counter frame_final->pts = write_video_count; From 999887687c5e406fb8cd8597d2be9fa09a862002 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 22 Mar 2020 12:19:11 -0400 Subject: [PATCH 025/148] FFmpegWriter: Free any old context before clobbering valgrind caught that AVFORMAT_NEW_STREAM() could be leaking pointers when calling avcodec_alloc_context3(), if there's an existing context already assigned. So we check and free it first, if necessary. --- src/FFmpegWriter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 54b5bc85..eb100095 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1067,6 +1067,11 @@ AVStream *FFmpegWriter::add_audio_stream() { if (codec == NULL) throw InvalidCodec("A valid audio codec could not be found for this file.", path); + // Free any previous memory allocations + if (audio_codec_ctx != NULL) { + AV_FREE_CONTEXT(audio_codec_ctx); + } + // Create a new audio stream AV_FORMAT_NEW_STREAM(oc, audio_codec_ctx, codec, st) From 36801445118dee936d94fc5ee0194599191334bb Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 22 Mar 2020 12:33:59 -0400 Subject: [PATCH 026/148] FrameMapper: Eliminate is_open member variable It was being used uninitialized because it's never actually set, therefore it serves no purpose. --- include/FrameMapper.h | 1 - src/FrameMapper.cpp | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/FrameMapper.h b/include/FrameMapper.h index 8be4ec1b..ff4ccd71 100644 --- a/include/FrameMapper.h +++ b/include/FrameMapper.h @@ -138,7 +138,6 @@ namespace openshot */ class FrameMapper : public ReaderBase { private: - bool is_open; bool field_toggle; // Internal odd / even toggle (used when building the mapping) Fraction original; // The original frame rate Fraction target; // The target frame rate diff --git a/src/FrameMapper.cpp b/src/FrameMapper.cpp index 7c4d04bb..e80f355c 100644 --- a/src/FrameMapper.cpp +++ b/src/FrameMapper.cpp @@ -61,9 +61,9 @@ FrameMapper::FrameMapper(ReaderBase *reader, Fraction target, PulldownType targe // Destructor FrameMapper::~FrameMapper() { - if (is_open) - // Auto Close if not already - Close(); + + // Auto Close if not already + Close(); reader = NULL; } From fcf5cc628ca97e07da2efb0b001cc9e3cde81275 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 22 Mar 2020 12:40:31 -0400 Subject: [PATCH 027/148] DummyReader: Initialize is_open --- src/DummyReader.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp index 8fd98bcb..5613a696 100644 --- a/src/DummyReader.cpp +++ b/src/DummyReader.cpp @@ -33,14 +33,16 @@ using namespace openshot; // Blank constructor for DummyReader, with default settings. -DummyReader::DummyReader() { +DummyReader::DummyReader() : is_open(false) { // Call actual constructor with default values DummyReader(Fraction(24,1), 1280, 768, 44100, 2, 30.0); } // Constructor for DummyReader. Pass a framerate and samplerate. -DummyReader::DummyReader(Fraction fps, int width, int height, int sample_rate, int channels, float duration) { +DummyReader::DummyReader(Fraction fps, int width, int height, + int sample_rate, int channels, float duration) + : is_open(false) { // Set key info settings info.has_audio = false; From 8c8b535cc9e83e873c5da1092cc4d6cd31d03c19 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 27 Mar 2020 16:28:43 -0400 Subject: [PATCH 028/148] Fix Win64 Gitlab builds --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6b2645d8..925bf020 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -72,7 +72,6 @@ windows-builder-x64: - cd build - cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR\build\install-x64" -D"PYTHON_MODULE_PATH=python" -D"RUBY_MODULE_PATH=ruby" -G "MSYS Makefiles" -DCMAKE_MAKE_PROGRAM=mingw32-make -D"CMAKE_BUILD_TYPE:STRING=Release" ../ - mingw32-make install - - Move-Item -Force -path "install-x64\lib\python3.7\site-packages\*openshot*" -destination "install-x64\python\" - New-Item -path "install-x64/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force - $PREV_GIT_LABEL=(git describe --tags --abbrev=0 '@^') - git log "$PREV_GIT_LABEL..@" --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log" From ff5095c64d061df1041d2ae5242a2f7dd007c956 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 27 Mar 2020 17:30:42 -0400 Subject: [PATCH 029/148] Update release-log formatting on builders --- .gitlab-ci.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 925bf020..87de2e16 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,9 @@ stages: - build-libopenshot - trigger-openshot-qt +variables: + GIT_LOG_FORMAT: "- %h %ad %s [%aN]" + linux-builder: stage: build-libopenshot artifacts: @@ -22,7 +25,7 @@ linux-builder: - make doc - ~/auto-update-docs "$CI_PROJECT_DIR/build" "$CI_COMMIT_REF_NAME" - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" - - git log $(git describe --tags --abbrev=0 @^)..@ --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log" + - git log $(git describe --tags --abbrev=0 '@^')..@ --oneline --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x64/share/$CI_PROJECT_NAME.log" when: always except: - tags @@ -47,7 +50,7 @@ mac-builder: - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" - - git log $(git describe --tags --abbrev=0 @^)..@ --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log" + - git log $(git describe --tags --abbrev=0 '@^')..@ --oneline --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x64/share/$CI_PROJECT_NAME.log" when: always except: - tags @@ -74,7 +77,7 @@ windows-builder-x64: - mingw32-make install - New-Item -path "install-x64/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force - $PREV_GIT_LABEL=(git describe --tags --abbrev=0 '@^') - - git log "$PREV_GIT_LABEL..@" --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log" + - git log "$PREV_GIT_LABEL..@" --oneline --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x64/share/$CI_PROJECT_NAME.log" when: always except: - tags @@ -101,7 +104,7 @@ windows-builder-x86: - mingw32-make install - New-Item -path "install-x86/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force - $PREV_GIT_LABEL=(git describe --tags --abbrev=0 '@^') - - git log "$PREV_GIT_LABEL..@" --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x86/share/$CI_PROJECT_NAME.log" + - git log "$PREV_GIT_LABEL..@" --oneline --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x86/share/$CI_PROJECT_NAME.log" when: always except: - tags From aac27d5ff7b1453edfb627962d34421194c20b77 Mon Sep 17 00:00:00 2001 From: SuslikV Date: Thu, 21 Nov 2019 14:35:09 +0200 Subject: [PATCH 030/148] Add non-subsampled color format for h264 encoder Forces the 4:4:4 color format for "0 crf" and "0 cqp" setting of the H264 encoder. By default, the 4:2:0 is used, that is not lossless itself. --- include/FFmpegUtilities.h | 3 +++ src/FFmpegWriter.cpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/include/FFmpegUtilities.h b/include/FFmpegUtilities.h index 62d64df1..81c44796 100644 --- a/include/FFmpegUtilities.h +++ b/include/FFmpegUtilities.h @@ -122,6 +122,9 @@ #ifndef PIX_FMT_YUV420P #define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P #endif + #ifndef PIX_FMT_YUV444P + #define PIX_FMT_YUV444P AV_PIX_FMT_YUV444P + #endif // FFmpeg's libavutil/common.h defines an RSHIFT incompatible with Ruby's // definition in ruby/config.h, so we move it to FF_RSHIFT diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 2b97ba91..6cd40e11 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -438,6 +438,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value), 51), 0); // 0-51 if (std::stoi(value) == 0) { av_opt_set(c->priv_data, "preset", "veryslow", 0); + c->pix_fmt = PIX_FMT_YUV444P; // no chroma subsampling } break; case AV_CODEC_ID_HEVC : @@ -497,6 +498,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51 if (std::stoi(value) == 0) { av_opt_set(c->priv_data, "preset", "veryslow", 0); + c->pix_fmt = PIX_FMT_YUV444P; // no chroma subsampling } break; case AV_CODEC_ID_HEVC : From db76d1b886b7c7c87be427d4d721cee768110862 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 16 Apr 2020 18:30:38 -0400 Subject: [PATCH 031/148] Remove some broken macOS defines --- src/CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a57780b0..7d0f6351 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,13 +38,7 @@ if (WIN32) endif() if (APPLE) - # If you still get errors compiling with GCC 4.8, mac headers need to be patched: http://hamelot.co.uk/programming/osx-gcc-dispatch_block_t-has-not-been-declared-invalid-typedef/ - set_property(GLOBAL PROPERTY JUCE_MAC "JUCE_MAC") - add_definitions(-DNDEBUG) set(EXTENSION "mm") - - set(JUCE_PLATFORM_SPECIFIC_DIR build/macosx/platform_specific_code) - set(JUCE_PLATFORM_SPECIFIC_LIBRARIES "-framework Carbon -framework Cocoa -framework CoreFoundation -framework CoreAudio -framework CoreMidi -framework IOKit -framework AGL -framework AudioToolbox -framework QuartzCore -lobjc -framework Accelerate") endif() ################ IMAGE MAGICK ################## From 4f60f45976a71c248d2ce4e9220c7c165ece31e7 Mon Sep 17 00:00:00 2001 From: SuslikV Date: Mon, 27 Apr 2020 21:26:07 +0200 Subject: [PATCH 032/148] Exponential regression rule for Pixelate scale --- src/effects/Pixelate.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/effects/Pixelate.cpp b/src/effects/Pixelate.cpp index c993915c..ed219e4d 100644 --- a/src/effects/Pixelate.cpp +++ b/src/effects/Pixelate.cpp @@ -33,7 +33,7 @@ using namespace openshot; /// Blank constructor, useful when using Json to load the effect properties -Pixelate::Pixelate() : pixelization(0.7), left(0.0), top(0.0), right(0.0), bottom(0.0) { +Pixelate::Pixelate() : pixelization(0.5), left(0.0), top(0.0), right(0.0), bottom(0.0) { // Init effect properties init_effect_details(); } @@ -68,7 +68,7 @@ std::shared_ptr Pixelate::GetFrame(std::shared_ptr frame, int64_t std::shared_ptr frame_image = frame->GetImage(); // Get current keyframe values - double pixelization_value = 1.0 - std::min(fabs(pixelization.GetValue(frame_number)), 1.0); + double pixelization_value = std::min(pow(0.001, fabs(pixelization.GetValue(frame_number))), 1.0); double left_value = left.GetValue(frame_number); double top_value = top.GetValue(frame_number); double right_value = right.GetValue(frame_number); @@ -82,8 +82,12 @@ std::shared_ptr Pixelate::GetFrame(std::shared_ptr frame, int64_t QRect area(QPoint(0,0), frame_image->size()); area = area.marginsRemoved({int(left_value * w), int(top_value * h), int(right_value * w), int(bottom_value * h)}); + int scale_to = (int) (area.width() * pixelization_value); + if (scale_to < 1) { + scale_to = 1; // Not less than one pixel + } // Copy and scale pixels in area to be pixelated - auto frame_scaled = frame_image->copy(area).scaledToWidth(area.width() * pixelization_value, Qt::SmoothTransformation); + auto frame_scaled = frame_image->copy(area).scaledToWidth(scale_to, Qt::SmoothTransformation); // Draw pixelated image back over original QPainter painter(frame_image.get()); From 5c688f1edfb9a39f9b89faf333e052d4a8ba01e2 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 7 May 2020 11:56:44 -0400 Subject: [PATCH 033/148] Add QT_VERSION_STR define to OpenShotVersion.h The CMake process will pick up Qt's Qt5Core_VERSION_STRING and stick it in a cache variable (with forced updating each run), and a new `#define` in the header exports it to the library and to the Python bindings so that it can be queried at runtime. --- CMakeLists.txt | 12 ++++++------ include/OpenShotVersion.h.in | 5 ++++- src/CMakeLists.txt | 4 ++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb3fe8cc..f50c575f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,12 +91,6 @@ if(DEFINED ENABLE_TESTS) set(ENABLE_TESTS ${ENABLE_TESTS} CACHE BOOL "Build unit tests (requires UnitTest++)" FORCE) endif() -########## Configure Version.h header ############## -configure_file(include/OpenShotVersion.h.in include/OpenShotVersion.h @ONLY) -# We'll want that installed later -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/OpenShotVersion.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libopenshot) - #### Work around a GCC < 9 bug with handling of _Pragma() in macros #### See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578 if ((${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") AND @@ -142,6 +136,12 @@ endif() ############## PROCESS src/ DIRECTORIES ############## add_subdirectory(src) +########## Configure Version.h header ############## +configure_file(include/OpenShotVersion.h.in include/OpenShotVersion.h @ONLY) +# We'll want that installed later +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/OpenShotVersion.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libopenshot) + ################### DOCUMENTATION ################### # Find Doxygen (used for documentation) set(DOCS_ENABLED FALSE) # Only set true if Doxygen is found and configured diff --git a/include/OpenShotVersion.h.in b/include/OpenShotVersion.h.in index e15662b2..d8cf0735 100644 --- a/include/OpenShotVersion.h.in +++ b/include/OpenShotVersion.h.in @@ -42,6 +42,9 @@ #define OPENSHOT_VERSION_SO @PROJECT_SO_VERSION@ /// Shared object version number. This increments any time the API and ABI changes (so old apps will no longer link) +// Useful dependency versioning +#define QT_VERSION_STR "@QT_VERSION_STR@" + #include namespace openshot @@ -67,4 +70,4 @@ namespace openshot openshot::OpenShotVersion GetVersion(); } -#endif // OPENSHOT_VERSION_H \ No newline at end of file +#endif // OPENSHOT_VERSION_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 17b73863..24ed7764 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -289,6 +289,10 @@ foreach(_qt_comp IN LISTS _qt_components) endif() endforeach() +# Keep track of Qt version, to embed in our version header +set(QT_VERSION_STR ${Qt5Core_VERSION_STRING} CACHE STRING "Qt version linked with" FORCE) +mark_as_advanced(QT_VERSION_STR) + ################### FFMPEG ##################### # Find FFmpeg libraries (used for video encoding / decoding) find_package(FFmpeg REQUIRED COMPONENTS avcodec avdevice avformat avutil swscale) From 0e79844ed96d262c91dd6dccde2d19271fdf4d91 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 9 May 2020 18:33:03 -0400 Subject: [PATCH 034/148] Add more build-config variables - HAVE_IMAGEMAGICK and HAVE_RESVG will be #defined 0 or 1 - AV{CODEC,FORMAT,UTIL}_VERSION_STR will contain the FFmpeg component versions detected by CMake when configuring the build --- include/OpenShotVersion.h.in | 9 +++++++-- src/CMakeLists.txt | 25 ++++++++++++++++++------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/include/OpenShotVersion.h.in b/include/OpenShotVersion.h.in index d8cf0735..d0b015a4 100644 --- a/include/OpenShotVersion.h.in +++ b/include/OpenShotVersion.h.in @@ -42,8 +42,13 @@ #define OPENSHOT_VERSION_SO @PROJECT_SO_VERSION@ /// Shared object version number. This increments any time the API and ABI changes (so old apps will no longer link) -// Useful dependency versioning -#define QT_VERSION_STR "@QT_VERSION_STR@" +// Useful dependency versioning / feature availability +#cmakedefine QT_VERSION_STR "@QT_VERSION_STR@" +#cmakedefine AVCODEC_VERSION_STR "@AVCODEC_VERSION_STR@" +#cmakedefine AVFORMAT_VERSION_STR "@AVFORMAT_VERSION_STR@" +#cmakedefine AVUTIL_VERSION_STR "@AVUTIL_VERSION_STR@" +#cmakedefine01 HAVE_IMAGEMAGICK +#cmakedefine01 HAVE_RESVG #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24ed7764..90c74ead 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -59,11 +59,6 @@ IF (MAGICKCORE_HDRI_ENABLE) ELSE (MAGICKCORE_HDRI_ENABLE) add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 ) ENDIF (MAGICKCORE_HDRI_ENABLE) -IF (OPENSHOT_IMAGEMAGICK_COMPATIBILITY) - add_definitions( -DOPENSHOT_IMAGEMAGICK_COMPATIBILITY=${OPENSHOT_IMAGEMAGICK_COMPATIBILITY} ) -ELSE (OPENSHOT_IMAGEMAGICK_COMPATIBILITY) - add_definitions( -DOPENSHOT_IMAGEMAGICK_COMPATIBILITY=0 ) -ENDIF (OPENSHOT_IMAGEMAGICK_COMPATIBILITY) # Find the ImageMagick++ library find_package(ImageMagick COMPONENTS Magick++ MagickWand MagickCore) @@ -75,6 +70,8 @@ if (ImageMagick_FOUND) add_definitions( -DUSE_IMAGEMAGICK=1 ) set(CMAKE_SWIG_FLAGS "-DUSE_IMAGEMAGICK=1") + set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE) + mark_as_advanced(HAVE_IMAGEMAGICK) endif() ################# LIBOPENSHOT-AUDIO ################### @@ -297,10 +294,20 @@ mark_as_advanced(QT_VERSION_STR) # Find FFmpeg libraries (used for video encoding / decoding) find_package(FFmpeg REQUIRED COMPONENTS avcodec avdevice avformat avutil swscale) -foreach(ff_comp avcodec avdevice avformat avfilter avutil postproc swscale swresample avresample) +set(all_comps avcodec avdevice avformat avfilter avutil postproc swscale swresample avresample) +set(version_comps avcodec avformat avutil) + +foreach(ff_comp IN LISTS all_comps) if(TARGET FFmpeg::${ff_comp}) - target_link_libraries(openshot PUBLIC FFmpeg::${ff_comp}) + target_link_libraries(openshot PUBLIC FFmpeg::${ff_comp}) + # Keep track of some FFmpeg lib versions, to embed in our version header + if(${ff_comp} IN_LIST version_comps) + string(TOUPPER ${ff_comp} v_name) + set(${v_name}_VERSION_STR ${${ff_comp}_VERSION} CACHE STRING "${ff_comp} version used" FORCE) + mark_as_advanced(${v_name}_VERSION_STR) + endif() endif() + endforeach() ################### Threads #################### @@ -363,6 +370,10 @@ if (TARGET RESVG::resvg) target_compile_definitions(openshot PUBLIC "-DUSE_RESVG=1") set(CMAKE_SWIG_FLAGS "-DUSE_RESVG=1") + + set(HAVE_RESVG TRUE CACHE BOOL "Building with Resvg support" FORCE) + mark_as_advanced(HAVE_RESVG) + endif() ############### LINK LIBRARY ################# From e4dd72669f4778b92d139b12ef5c8d166934c94e Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Mon, 1 Jun 2020 13:24:07 -0500 Subject: [PATCH 035/148] Fix FPS setting on FFmpeg 4, which currently is not setting a valid FPS. --- src/FFmpegWriter.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index ce8f6557..cd3185c4 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1222,6 +1222,13 @@ AVStream *FFmpegWriter::add_video_stream() { st->avg_frame_rate = av_inv_q(c->time_base); st->time_base.num = info.video_timebase.num; st->time_base.den = info.video_timebase.den; +#if (LIBAVFORMAT_VERSION_MAJOR >= 58) + _Pragma ("GCC diagnostic push"); + _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\""); \ + st->codec->time_base.num = info.video_timebase.num; + st->codec->time_base.den = info.video_timebase.den; + _Pragma ("GCC diagnostic pop"); +#endif c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */ c->max_b_frames = 10; From 2a043014824822e74dd4d3710df55609d6919836 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 1 Jun 2020 15:24:15 -0400 Subject: [PATCH 036/148] Travis: allow_failures for FFmpeg 3.2 --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 24e772af..c8af86a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,8 +32,12 @@ addons: - curl jobs: - include: + # The FFmpeg 3.2 backport PPA has gone missing + allow_failures: + - name: "FFmpeg 3.2 GCC (Ubuntu 16.04 Xenial)" + + include: - name: "Coverage + FFmpeg 3.4 GCC (Ubuntu 18.04 Bionic)" env: - BUILD_VERSION=coverage_ffmpeg34 From 58c971a57690b533fba40cd6da077bec538c8c02 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 1 Jun 2020 15:24:15 -0400 Subject: [PATCH 037/148] Travis: allow_failures for FFmpeg 3.2 --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 24e772af..c8af86a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,8 +32,12 @@ addons: - curl jobs: - include: + # The FFmpeg 3.2 backport PPA has gone missing + allow_failures: + - name: "FFmpeg 3.2 GCC (Ubuntu 16.04 Xenial)" + + include: - name: "Coverage + FFmpeg 3.4 GCC (Ubuntu 18.04 Bionic)" env: - BUILD_VERSION=coverage_ffmpeg34 From 456715437a31471209c14a58c03d7a6abea48b1f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 1 Jun 2020 17:05:18 -0400 Subject: [PATCH 038/148] Remove unused Qt PPAs --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c8af86a7..af54662f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,7 +49,6 @@ jobs: apt: sources: - sourceline: 'ppa:openshot.developers/libopenshot-daily' - - sourceline: 'ppa:beineri/opt-qt-5.12.3-bionic' packages: - *p_common - qt5-default @@ -96,7 +95,6 @@ jobs: apt: sources: - sourceline: 'ppa:openshot.developers/libopenshot-daily' - - sourceline: 'ppa:beineri/opt-qt-5.12.3-bionic' packages: - *p_common - qt5-default @@ -114,7 +112,6 @@ jobs: apt: sources: - sourceline: 'ppa:openshot.developers/libopenshot-daily' - - sourceline: 'ppa:beineri/opt-qt-5.10.0-xenial' - sourceline: 'ppa:jon-hedgerows/ffmpeg-backports' packages: - *p_common From 1dd0281deb74d1287da15cf2c4309a76acd3a441 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 1 Jun 2020 17:06:04 -0400 Subject: [PATCH 039/148] Use Ubuntu 20.04 for FFmpeg 4 --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index af54662f..241d5be3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,19 +57,17 @@ jobs: - lcov - binutils-common # For c++filt - - name: "FFmpeg 4 GCC (Ubuntu 18.04 Bionic)" + - name: "FFmpeg 4 GCC (Ubuntu 20.04 Focal)" env: - BUILD_VERSION=ffmpeg4 - CMAKE_EXTRA_ARGS="" - TEST_TARGET=test os: linux - dist: bionic + dist: focal addons: apt: sources: - sourceline: 'ppa:openshot.developers/libopenshot-daily' - - sourceline: 'ppa:beineri/opt-qt-5.12.3-bionic' - - sourceline: 'ppa:jonathonf/ffmpeg-4' packages: - *p_common - qt5-default From 511a6b1da2e349afb593836498b239c5c21dac99 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 1 Jun 2020 17:58:22 -0400 Subject: [PATCH 040/148] Update Ruby compatibility message --- src/bindings/ruby/CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/bindings/ruby/CMakeLists.txt b/src/bindings/ruby/CMakeLists.txt index 4d7b922a..2ec16dcf 100644 --- a/src/bindings/ruby/CMakeLists.txt +++ b/src/bindings/ruby/CMakeLists.txt @@ -48,13 +48,15 @@ option(SILENCE_RUBY_VERSION_WARNING if (${RUBY_VERSION} VERSION_GREATER 2.6.9 AND ${SWIG_VERSION} VERSION_LESS 4.0.3) if (NOT ${SILENCE_RUBY_VERSION_WARNING}) - message(WARNING " + message(WARNING "\ Ruby 2.7.0+ detected, building the libopenshot Ruby API bindings \ -requires a pre-release version of SWIG 4.0.3 with this commit: \ -https://github.com/swig/swig/commit/5542cc228ad10bdc5c91107afb77c808c43bf2a4") - message(STATUS " -To disable this warning, add -DSILENCE_RUBY_VERSION_WARNING:BOOL=1 to the cmake \ -command line, or enable the option in the CMake GUI.") +requires either SWIG 4.0.3 or an older version patched with this commit: \ +https://github.com/swig/swig/commit/5542cc228ad10bdc5c91107afb77c808c43bf2a4 \ +(Recent Fedora and Ubuntu distro packages of SWIG 4.0.1 have already been \ +patched.)") + message(STATUS "To disable the previous warning, add \ +-DSILENCE_RUBY_VERSION_WARNING:BOOL=1 to the cmake command line, \ +or enable the option in the CMake GUI.") endif() endif() From 93d12e7f14e8c4f002e5f98af14412b80a4cd53b Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Tue, 2 Jun 2020 08:53:39 -0700 Subject: [PATCH 041/148] Include data for fps in clip created by ffmpeg 4+ --- src/FFmpegWriter.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index cc4b3d3a..e10b7026 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1266,6 +1266,13 @@ AVStream *FFmpegWriter::add_video_stream() { st->avg_frame_rate = av_inv_q(c->time_base); st->time_base.num = info.video_timebase.num; st->time_base.den = info.video_timebase.den; +#if (LIBAVFORMAT_VERSION_MAJOR >= 58) + _Pragma ("GCC diagnostic push"); + _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\""); \ + st->codec->time_base.num = info.video_timebase.num; + st->codec->time_base.den = info.video_timebase.den; + _Pragma ("GCC diagnostic pop"); +#endif c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */ c->max_b_frames = 10; From 7ed26cf0223fbfd0a6f4988b9dd1099324496e8a Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Tue, 2 Jun 2020 13:30:05 -0500 Subject: [PATCH 042/148] Replace _Pragma with #pragma Co-authored-by: Frank Dana --- src/FFmpegWriter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index cd3185c4..5b57218f 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1223,11 +1223,11 @@ AVStream *FFmpegWriter::add_video_stream() { st->time_base.num = info.video_timebase.num; st->time_base.den = info.video_timebase.den; #if (LIBAVFORMAT_VERSION_MAJOR >= 58) - _Pragma ("GCC diagnostic push"); - _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\""); \ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" st->codec->time_base.num = info.video_timebase.num; st->codec->time_base.den = info.video_timebase.den; - _Pragma ("GCC diagnostic pop"); + #pragma GCC diagnostic pop #endif c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */ From d9e6af5cda54ad7d33569563d86653bcfc58a890 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Tue, 2 Jun 2020 11:35:07 -0700 Subject: [PATCH 043/148] Refert last commit --- src/FFmpegWriter.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index e10b7026..cc4b3d3a 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1266,13 +1266,6 @@ AVStream *FFmpegWriter::add_video_stream() { st->avg_frame_rate = av_inv_q(c->time_base); st->time_base.num = info.video_timebase.num; st->time_base.den = info.video_timebase.den; -#if (LIBAVFORMAT_VERSION_MAJOR >= 58) - _Pragma ("GCC diagnostic push"); - _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\""); \ - st->codec->time_base.num = info.video_timebase.num; - st->codec->time_base.den = info.video_timebase.den; - _Pragma ("GCC diagnostic pop"); -#endif c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */ c->max_b_frames = 10; From f4b40a4e7749f0d45ff850928ca935d9e6c99682 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Thu, 4 Jun 2020 08:28:33 -0700 Subject: [PATCH 044/148] Improvements to handling of new codecs --- src/FFmpegWriter.cpp | 61 +++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index e6a7e5ef..9b348aed 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -479,15 +479,6 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va case AV_CODEC_ID_AV1 : c->bit_rate = 0; av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); - if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { - av_opt_set_int(c->priv_data, "preset", 6, 0); - av_opt_set_int(c->priv_data, "forced-idr",1,0); - } - if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { - av_opt_set_int(c->priv_data, "speed", 7, 0); - av_opt_set_int(c->priv_data, "tile-rows", 2, 0); - av_opt_set_int(c->priv_data, "tile-columns", 4, 0); - } break; #endif case AV_CODEC_ID_VP8 : @@ -547,24 +538,17 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va c->bit_rate = 0; if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); - av_opt_set_int(c->priv_data, "preset", 6, 0); - av_opt_set_int(c->priv_data, "forced-idr",1,0); } else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { // Set number of tiles to a fixed value // TODO Let user choose number of tiles av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); - av_opt_set_int(c->priv_data, "speed", 7, 0); - av_opt_set_int(c->priv_data, "tile-rows", 2, 0); // number of rows - av_opt_set_int(c->priv_data, "tile-columns", 4, 0); // number of columns } else if (strstr(info.vcodec.c_str(), "aom") != NULL) { // Set number of tiles to a fixed value // TODO Let user choose number of tiles // libaom doesn't have qp only crf av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); - av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows - av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns } else { av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); @@ -1222,7 +1206,11 @@ AVStream *FFmpegWriter::add_video_stream() { #endif /* Init video encoder options */ - if (info.video_bit_rate >= 1000) { + if (info.video_bit_rate >= 1000 +#if (LIBAVCODEC_VERSION_MAJOR >= 58) + && c->codec_id != AV_CODEC_ID_AV1 +#endif + ) { c->bit_rate = info.video_bit_rate; if (info.video_bit_rate >= 1500000) { c->qmin = 2; @@ -1231,11 +1219,48 @@ AVStream *FFmpegWriter::add_video_stream() { // Here should be the setting for low fixed bitrate // Defaults are used because mpeg2 otherwise had problems } else { - // Check if codec supports crf + // Check if codec supports crf or qp switch (c->codec_id) { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) #if (LIBAVCODEC_VERSION_MAJOR >= 58) case AV_CODEC_ID_AV1 : + // TODO: + // set crf or qp according to bitrate as bitrate is not supported by + // these encoders (yet) + if (info.video_bit_rate >= 1000) { + c->bit_rate = 0; + if (strstr(info.vcodec.c_str(), "aom") != NULL) { + int calculated_quality = 35; + if (info.video_bit_rate < 500000) calculated_quality = 50; + if (info.video_bit_rate > 5000000) calculated_quality = 10; + av_opt_set_int(c->priv_data, "crf", calculated_quality, 0); + info.video_bit_rate = calculated_quality; + } else { + int calculated_quality = 50; + if (info.video_bit_rate < 500000) calculated_quality = 60; + if (info.video_bit_rate > 5000000) calculated_quality = 15; + av_opt_set_int(c->priv_data, "qp", calculated_quality, 0); + info.video_bit_rate = calculated_quality; + } // medium + } + if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { + av_opt_set_int(c->priv_data, "preset", 6, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + } + else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + av_opt_set_int(c->priv_data, "speed", 7, 0); + av_opt_set_int(c->priv_data, "tile-rows", 2, 0); + av_opt_set_int(c->priv_data, "tile-columns", 4, 0); + } + else if (strstr(info.vcodec.c_str(), "aom") != NULL) { + // Set number of tiles to a fixed value + // TODO Let user choose number of tiles + av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows + av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns + av_opt_set_int(c->priv_data, "row-mt", 1, 0); // use multiple cores + av_opt_set_int(c->priv_data, "cpu-used", 3, 0); // default is 1, usable is 4 + } + //break; #endif case AV_CODEC_ID_VP9 : case AV_CODEC_ID_HEVC : From 62d7fb54596219b993cf432d0a437de6e1fdb7a6 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Thu, 4 Jun 2020 18:52:19 -0500 Subject: [PATCH 045/148] Changing some libopenshot code based on Codacy feedback. Small refactoring, scope limiing. --- include/FFmpegWriter.h | 2 +- src/FFmpegWriter.cpp | 42 ++++++++++++------------------------------ 2 files changed, 13 insertions(+), 31 deletions(-) diff --git a/include/FFmpegWriter.h b/include/FFmpegWriter.h index 37fa22dc..b3bec7ad 100644 --- a/include/FFmpegWriter.h +++ b/include/FFmpegWriter.h @@ -253,7 +253,7 @@ namespace openshot { /// @brief Constructor for FFmpegWriter. Throws one of the following exceptions. /// @param path The file path of the video file you want to open and read - FFmpegWriter(std::string path); + FFmpegWriter(const std::string path); /// Close the writer void Close(); diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index e6a7e5ef..5b5c5410 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -83,7 +83,7 @@ static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int6 } #endif // HAVE_HW_ACCEL -FFmpegWriter::FFmpegWriter(std::string path) : +FFmpegWriter::FFmpegWriter(const std::string path) : path(path), fmt(NULL), oc(NULL), audio_st(NULL), video_st(NULL), samples(NULL), audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0), initial_audio_input_frame_size(0), img_convert_ctx(NULL), cache_size(8), num_of_rescalers(32), @@ -864,9 +864,6 @@ void FFmpegWriter::flush_encoders() { return; #endif - int error_code = 0; - int stop_encoding = 1; - // FLUSH VIDEO ENCODER if (info.has_video) for (;;) { @@ -940,13 +937,9 @@ void FFmpegWriter::flush_encoders() { ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::flush_encoders ERROR [" + (std::string) av_err2str(error_code) + "]", "error_code", error_code); } if (!got_packet) { - stop_encoding = 1; break; } - // Override PTS (in frames and scaled to the codec's timebase) - //pkt.pts = write_video_count; - // set the timestamp if (pkt.pts != AV_NOPTS_VALUE) pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base); @@ -961,10 +954,6 @@ void FFmpegWriter::flush_encoders() { if (error_code < 0) { ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::flush_encoders ERROR [" + (std::string)av_err2str(error_code) + "]", "error_code", error_code); } - - // Deallocate memory (if needed) - if (video_outbuf) - av_freep(&video_outbuf); } // FLUSH AUDIO ENCODER @@ -986,20 +975,15 @@ void FFmpegWriter::flush_encoders() { pkt.pts = pkt.dts = write_audio_count; /* encode the image */ - int got_packet = 0; + int error_code = 0; #if IS_FFMPEG_3_2 - avcodec_send_frame(audio_codec, NULL); - got_packet = 0; + error_code = avcodec_send_frame(audio_codec, NULL); #else error_code = avcodec_encode_audio2(audio_codec, &pkt, NULL, &got_packet); #endif if (error_code < 0) { ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::flush_encoders ERROR [" + (std::string)av_err2str(error_code) + "]", "error_code", error_code); } - if (!got_packet) { - stop_encoding = 1; - break; - } // Since the PTS can change during encoding, set the value again. This seems like a huge hack, // but it fixes lots of PTS related issues when I do this. @@ -1583,29 +1567,27 @@ void FFmpegWriter::write_audio_packets(bool is_final) { channels_in_frame = frame->GetAudioChannelsCount(); channel_layout_in_frame = frame->ChannelsLayout(); - // Get audio sample array float *frame_samples_float = NULL; // Get samples interleaved together (c1 c2 c1 c2 c1 c2) frame_samples_float = frame->GetInterleavedAudioSamples(sample_rate_in_frame, NULL, &samples_in_frame); - // Calculate total samples total_frame_samples = samples_in_frame * channels_in_frame; // Translate audio sample values back to 16 bit integers with saturation - float valF; - int16_t conv; const int16_t max16 = 32767; const int16_t min16 = -32768; for (int s = 0; s < total_frame_samples; s++, frame_position++) { - valF = frame_samples_float[s] * (1 << 15); - if (valF > max16) + float valF = frame_samples_float[s] * (1 << 15); + int16_t conv; + if (valF > max16) { conv = max16; - else if (valF < min16) + } else if (valF < min16) { conv = min16; - else + } else { conv = int(valF + 32768.5) - 32768; // +0.5 is for rounding + } // Copy into buffer all_queued_samples[frame_position] = conv; @@ -1731,10 +1713,11 @@ void FFmpegWriter::write_audio_packets(bool is_final) { // Determine how many samples we need int diff = 0; - if (remaining_frame_samples >= remaining_packet_samples) + if (remaining_frame_samples >= remaining_packet_samples) { diff = remaining_packet_samples; - else if (remaining_frame_samples < remaining_packet_samples) + } else { diff = remaining_frame_samples; + } // Copy frame samples into the packet samples array if (!is_final) @@ -1746,7 +1729,6 @@ void FFmpegWriter::write_audio_packets(bool is_final) { audio_input_position += diff; samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)); remaining_frame_samples -= diff; - remaining_packet_samples -= diff; // Do we have enough samples to proceed? if (audio_input_position < (audio_input_frame_size * info.channels) && !is_final) From 86b83abf5d74f65c67ed6e8c3b5869110e66b43e Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 5 Jun 2020 15:41:23 -0500 Subject: [PATCH 046/148] Fixing undefined got_packet int --- src/FFmpegWriter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 5b5c5410..7eb24156 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -976,6 +976,7 @@ void FFmpegWriter::flush_encoders() { /* encode the image */ int error_code = 0; + int got_packet = 0; #if IS_FFMPEG_3_2 error_code = avcodec_send_frame(audio_codec, NULL); #else From 51fe8549e6364e8d685dd4e5c3a1f5de2fda50d3 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 5 Jun 2020 17:53:21 -0500 Subject: [PATCH 047/148] Fix regression caused by Codacy tweaks --- src/FFmpegWriter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 7eb24156..5a21c6ba 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -985,6 +985,9 @@ void FFmpegWriter::flush_encoders() { if (error_code < 0) { ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::flush_encoders ERROR [" + (std::string)av_err2str(error_code) + "]", "error_code", error_code); } + if (!got_packet) { + break; + } // Since the PTS can change during encoding, set the value again. This seems like a huge hack, // but it fixes lots of PTS related issues when I do this. From 7b94ac838b76f1211ed3c14183fdd15deb354b04 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 5 Jun 2020 18:07:25 -0500 Subject: [PATCH 048/148] Removing bad suggestion. In theory, we could change this signature to take a const reference to a string, but for now, I'm reverting it. --- include/FFmpegWriter.h | 2 +- src/FFmpegWriter.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/FFmpegWriter.h b/include/FFmpegWriter.h index b3bec7ad..37fa22dc 100644 --- a/include/FFmpegWriter.h +++ b/include/FFmpegWriter.h @@ -253,7 +253,7 @@ namespace openshot { /// @brief Constructor for FFmpegWriter. Throws one of the following exceptions. /// @param path The file path of the video file you want to open and read - FFmpegWriter(const std::string path); + FFmpegWriter(std::string path); /// Close the writer void Close(); diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 5a21c6ba..e3dedb28 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -83,7 +83,7 @@ static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int6 } #endif // HAVE_HW_ACCEL -FFmpegWriter::FFmpegWriter(const std::string path) : +FFmpegWriter::FFmpegWriter(std::string path) : path(path), fmt(NULL), oc(NULL), audio_st(NULL), video_st(NULL), samples(NULL), audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0), initial_audio_input_frame_size(0), img_convert_ctx(NULL), cache_size(8), num_of_rescalers(32), From 7831cfe9128502ae894d85c14e033991cd9a3d1b Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sat, 6 Jun 2020 01:55:52 -0500 Subject: [PATCH 049/148] Adding some new functionality and documentation to DummyReader. Adding the ability to add test frames, with fake image and audio data. This will can be used in unittests, and will soon be used to verify some new audio improvements (coming soon). --- include/DummyReader.h | 50 +++++++++++++++++- src/DummyReader.cpp | 31 +++++++++-- src/Frame.cpp | 5 ++ tests/CMakeLists.txt | 1 + tests/DummyReader_Tests.cpp | 102 ++++++++++++++++++++++++++++++++++++ 5 files changed, 185 insertions(+), 4 deletions(-) create mode 100644 tests/DummyReader_Tests.cpp diff --git a/include/DummyReader.h b/include/DummyReader.h index 4c935103..576a0df8 100644 --- a/include/DummyReader.h +++ b/include/DummyReader.h @@ -46,14 +46,58 @@ namespace openshot { /** - * @brief This class is used as a simple, dummy reader, which always returns a blank frame. + * @brief This class is used as a simple, dummy reader, which can be very useful when writing + * unit tests. It can return a single blank frame or it can return custom frame objects + * which were added using the WriteFrame() method. * * A dummy reader can be created with any framerate or samplerate. This is useful in unit * tests that need to test different framerates or samplerates. + * + * @code + * // Create a reader (Fraction fps, int width, int height, int sample_rate, int channels, float duration) + * openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); + * r.Open(); // Open the reader + * + * // Get a frame (which will be blank, since we haven't added any frames yet) + * std::shared_ptr f = r.GetFrame(1); + * + * // Now let's create some test frames + * for (int64_t frame_number = 1; frame_number <= 30; frame_number++) + * { + * // Create blank frame (with specific frame #, samples, and channels) + * // Sample count should be 44100 / 30 fps = 1470 samples per frame + * int sample_count = 1470; + * std::shared_ptr f(new openshot::Frame(frame_number, sample_count, 2)); + * + * // Create test samples with incrementing value + * float *audio_buffer = new float[sample_count]; + * for (int64_t sample_number = 0; sample_number < sample_count; sample_number++) + * { + * // Generate an incrementing audio sample value (just as an example) + * audio_buffer[sample_number] = float(frame_number) + (float(sample_number) / float(sample_count)); + * } + * + * // Add custom audio samples to Frame (bool replaceSamples, int destChannel, int destStartSample, const float* source, + * // int numSamples, float gainToApplyToSource = 1.0f) + * f->AddAudio(true, 0, 0, audio_buffer, sample_count, 1.0); // add channel 1 + * f->AddAudio(true, 1, 0, audio_buffer, sample_count, 1.0); // add channel 2 + * + * // Write test frame to dummy reader + * r.WriteFrame(f); + * } + * + * // Now let's verify our DummyReader works + * std::shared_ptr f = r.GetFrame(1); + * // r.GetFrame(1)->GetAudioSamples(0)[1] should equal 1.00068033 based on our above calculations + * + * // Close the reader + * r.Close(); + * @endcode */ class DummyReader : public ReaderBase { private: + CacheMemory dummy_cache; std::shared_ptr image_frame; bool is_open; @@ -94,6 +138,10 @@ namespace openshot /// Open File - which is called by the constructor automatically void Open() override; + + /// @brief Add a frame to the dummy reader. This is useful when constructing unit tests that require custom frames. + /// @param frame The openshot::Frame object to write to this image + void WriteFrame(std::shared_ptr frame); }; } diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp index 8fd98bcb..1b663a07 100644 --- a/src/DummyReader.cpp +++ b/src/DummyReader.cpp @@ -99,24 +99,49 @@ void DummyReader::Close() { // Mark as "closed" is_open = false; + + // Clear cache + dummy_cache.Clear(); } } -// Get an openshot::Frame object for a specific frame number of this reader. +// Add Frame objects to DummyReader +void DummyReader::WriteFrame(std::shared_ptr frame) +{ + if (frame) { + dummy_cache.Add(frame); + } +} + +// Get an openshot::Frame object for a specific frame number of this reader. It is either a blank frame +// or a custom frame added with the WriteFrame() method. std::shared_ptr DummyReader::GetFrame(int64_t requested_frame) { // Check for open reader (or throw exception) if (!is_open) throw ReaderClosed("The ImageReader is closed. Call Open() before calling this method.", "dummy"); - if (image_frame) - { + if (dummy_cache.Count() == 0 && image_frame) { // Create a scoped lock, allowing only a single thread to run the following code at one time const GenericScopedLock lock(getFrameCriticalSection); // Always return same frame (regardless of which frame number was requested) image_frame->number = requested_frame; return image_frame; + + } else if (dummy_cache.Count() > 0) { + // Create a scoped lock, allowing only a single thread to run the following code at one time + const GenericScopedLock lock(getFrameCriticalSection); + + // Get a frame from the dummy cache + std::shared_ptr f = dummy_cache.GetFrame(requested_frame); + if (f) { + // return frame from cache (if found) + return f; + } else { + // No cached frame found + throw InvalidFile("Requested frame not found. You can only access Frame numbers added with WriteFrame().", "dummy"); + } } else // no frame loaded diff --git a/src/Frame.cpp b/src/Frame.cpp index ae9f1a4b..764b9651 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -480,6 +480,11 @@ const unsigned char* Frame::GetPixels() // Get pixel data (for only a single scan-line) const unsigned char* Frame::GetPixels(int row) { + // Check for blank image + if (!image) + // Fill with black + AddColor(width, height, color); + // Return array of pixel packets return image->constScanLine(row); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 480dfb3d..7ccddba8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -109,6 +109,7 @@ set(OPENSHOT_TEST_FILES Clip_Tests.cpp Color_Tests.cpp Coordinate_Tests.cpp + DummyReader_Tests.cpp ReaderBase_Tests.cpp ImageWriter_Tests.cpp FFmpegReader_Tests.cpp diff --git a/tests/DummyReader_Tests.cpp b/tests/DummyReader_Tests.cpp new file mode 100644 index 00000000..ea410ad0 --- /dev/null +++ b/tests/DummyReader_Tests.cpp @@ -0,0 +1,102 @@ +/** + * @file + * @brief Unit tests for openshot::DummyReader + * @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 "UnitTest++.h" +// Prevent name clashes with juce::UnitTest +#define DONT_SET_USING_JUCE_NAMESPACE 1 + +#include "../include/OpenShot.h" + +using namespace std; +using namespace openshot; + +TEST (DummyReader_Constructor) { + // Create a default fraction (should be 1/1) + openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); + r.Open(); // Open the reader + + // Check values + CHECK_EQUAL(1920, r.info.width); + CHECK_EQUAL(1080, r.info.height); + CHECK_EQUAL(30, r.info.fps.num); + CHECK_EQUAL(1, r.info.fps.den); + CHECK_EQUAL(44100, r.info.sample_rate); + CHECK_EQUAL(2, r.info.channels); + CHECK_EQUAL(30.0, r.info.duration); +} + +TEST (DummyReader_Blank_Frame) { + // Create a default fraction (should be 1/1) + openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); + r.Open(); // Open the reader + + // Get a blank frame (because we have not added any frames using WriteFrame() yet) + // Check values + CHECK_EQUAL(1, r.GetFrame(1)->number); + CHECK_EQUAL(1, r.GetFrame(1)->GetPixels(700)[700] == 0); // black pixel + CHECK_EQUAL(1, r.GetFrame(1)->GetPixels(701)[701] == 0); // black pixel +} + +TEST (DummyReader_Fake_Frame) { + // Create a default fraction (should be 1/1) + openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); + r.Open(); // Open the reader + + // Let's create some test frames + for (int64_t frame_number = 1; frame_number <= 30; frame_number++) { + // Create blank frame (with specific frame #, samples, and channels) + // Sample count should be 44100 / 30 fps = 1470 samples per frame + int sample_count = 1470; + std::shared_ptr f(new openshot::Frame(frame_number, sample_count, 2)); + + // Create test samples with incrementing value + float *audio_buffer = new float[sample_count]; + for (int64_t sample_number = 0; sample_number < sample_count; sample_number++) { + // Generate an incrementing audio sample value (just as an example) + audio_buffer[sample_number] = float(frame_number) + (float(sample_number) / float(sample_count)); + } + + // Add custom audio samples to Frame (bool replaceSamples, int destChannel, int destStartSample, const float* source, + f->AddAudio(true, 0, 0, audio_buffer, sample_count, 1.0); // add channel 1 + f->AddAudio(true, 1, 0, audio_buffer, sample_count, 1.0); // add channel 2 + + // Write test frame to dummy reader + r.WriteFrame(f); + } + + // Verify our artificial audio sample data is correct + CHECK_EQUAL(1, r.GetFrame(1)->number); + CHECK_EQUAL(1, r.GetFrame(1)->GetAudioSamples(0)[0]); + CHECK_CLOSE(1.00068033, r.GetFrame(1)->GetAudioSamples(0)[1], 0.00001); + CHECK_CLOSE(1.00136054, r.GetFrame(1)->GetAudioSamples(0)[2], 0.00001); + CHECK_EQUAL(2, r.GetFrame(2)->GetAudioSamples(0)[0]); + CHECK_CLOSE(2.00068033, r.GetFrame(2)->GetAudioSamples(0)[1], 0.00001); + CHECK_CLOSE(2.00136054, r.GetFrame(2)->GetAudioSamples(0)[2], 0.00001); +} \ No newline at end of file From d29027ae30466f3aeb6ec0b78cc28754d7630174 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sat, 6 Jun 2020 02:03:27 -0500 Subject: [PATCH 050/148] Added an additional unittest for DummyReader (for invalid frame) --- tests/DummyReader_Tests.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/DummyReader_Tests.cpp b/tests/DummyReader_Tests.cpp index ea410ad0..6ec11e08 100644 --- a/tests/DummyReader_Tests.cpp +++ b/tests/DummyReader_Tests.cpp @@ -99,4 +99,23 @@ TEST (DummyReader_Fake_Frame) { CHECK_EQUAL(2, r.GetFrame(2)->GetAudioSamples(0)[0]); CHECK_CLOSE(2.00068033, r.GetFrame(2)->GetAudioSamples(0)[1], 0.00001); CHECK_CLOSE(2.00136054, r.GetFrame(2)->GetAudioSamples(0)[2], 0.00001); +} + +TEST (DummyReader_Invalid_Fake_Frame) { + // Create a default fraction (should be 1/1) + openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); + r.Open(); + + // Create fake frames (with specific frame #, samples, and channels) + std::shared_ptr f1(new openshot::Frame(1, 1470, 2)); + std::shared_ptr f2(new openshot::Frame(2, 1470, 2)); + + // Write test frames to dummy reader + r.WriteFrame(f1); + r.WriteFrame(f2); + + // Verify exception + CHECK_EQUAL(1, r.GetFrame(1)->number); + CHECK_EQUAL(2, r.GetFrame(2)->number); + CHECK_THROW(r.GetFrame(3)->number, InvalidFile); } \ No newline at end of file From 8b12c1fa2173db24246858e744118da544d7e320 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sat, 6 Jun 2020 17:25:45 -0500 Subject: [PATCH 051/148] Replacing WriteFrame() method with custom constructor which can accept a CacheBase* pointer, for instances where a DummyReader needs some specific test Frame objects --- include/DummyReader.h | 33 ++++++++++--------- src/DummyReader.cpp | 64 ++++++++++++++++++++----------------- tests/DummyReader_Tests.cpp | 58 ++++++++++++++++++++++++--------- 3 files changed, 96 insertions(+), 59 deletions(-) diff --git a/include/DummyReader.h b/include/DummyReader.h index 576a0df8..e9c90968 100644 --- a/include/DummyReader.h +++ b/include/DummyReader.h @@ -48,18 +48,14 @@ namespace openshot /** * @brief This class is used as a simple, dummy reader, which can be very useful when writing * unit tests. It can return a single blank frame or it can return custom frame objects - * which were added using the WriteFrame() method. + * which were passed into the constructor with a Cache object. * * A dummy reader can be created with any framerate or samplerate. This is useful in unit * tests that need to test different framerates or samplerates. * * @code - * // Create a reader (Fraction fps, int width, int height, int sample_rate, int channels, float duration) - * openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); - * r.Open(); // Open the reader - * - * // Get a frame (which will be blank, since we haven't added any frames yet) - * std::shared_ptr f = r.GetFrame(1); + * // Create cache object to store fake Frame objects + * CacheMemory cache; * * // Now let's create some test frames * for (int64_t frame_number = 1; frame_number <= 30; frame_number++) @@ -82,25 +78,33 @@ namespace openshot * f->AddAudio(true, 0, 0, audio_buffer, sample_count, 1.0); // add channel 1 * f->AddAudio(true, 1, 0, audio_buffer, sample_count, 1.0); // add channel 2 * - * // Write test frame to dummy reader - * r.WriteFrame(f); + * // Add test frame to cache + * cache.Add(f); * } * + * // Create a reader (Fraction fps, int width, int height, int sample_rate, int channels, float duration, CacheBase* cache) + * openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0, &cache); + * r.Open(); // Open the reader + * * // Now let's verify our DummyReader works * std::shared_ptr f = r.GetFrame(1); * // r.GetFrame(1)->GetAudioSamples(0)[1] should equal 1.00068033 based on our above calculations * - * // Close the reader + * // Clean up * r.Close(); + * cache.Clear() * @endcode */ class DummyReader : public ReaderBase { private: - CacheMemory dummy_cache; + CacheBase* dummy_cache; std::shared_ptr image_frame; bool is_open; + /// Initialize variables used by constructor + void init(Fraction fps, int width, int height, int sample_rate, int channels, float duration); + public: /// Blank constructor for DummyReader, with default settings. @@ -109,6 +113,9 @@ namespace openshot /// Constructor for DummyReader. DummyReader(openshot::Fraction fps, int width, int height, int sample_rate, int channels, float duration); + /// Constructor for DummyReader which takes a frame cache object. + DummyReader(openshot::Fraction fps, int width, int height, int sample_rate, int channels, float duration, CacheBase* cache); + virtual ~DummyReader(); /// Close File @@ -138,10 +145,6 @@ namespace openshot /// Open File - which is called by the constructor automatically void Open() override; - - /// @brief Add a frame to the dummy reader. This is useful when constructing unit tests that require custom frames. - /// @param frame The openshot::Frame object to write to this image - void WriteFrame(std::shared_ptr frame); }; } diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp index 1b663a07..8b6f752f 100644 --- a/src/DummyReader.cpp +++ b/src/DummyReader.cpp @@ -32,16 +32,8 @@ using namespace openshot; -// Blank constructor for DummyReader, with default settings. -DummyReader::DummyReader() { - - // Call actual constructor with default values - DummyReader(Fraction(24,1), 1280, 768, 44100, 2, 30.0); -} - -// Constructor for DummyReader. Pass a framerate and samplerate. -DummyReader::DummyReader(Fraction fps, int width, int height, int sample_rate, int channels, float duration) { - +// Initialize variables used by constructor +void DummyReader::init(Fraction fps, int width, int height, int sample_rate, int channels, float duration) { // Set key info settings info.has_audio = false; info.has_video = true; @@ -68,10 +60,30 @@ DummyReader::DummyReader(Fraction fps, int width, int height, int sample_rate, i // Set the ratio based on the reduced fraction info.display_ratio.num = size.num; info.display_ratio.den = size.den; +} - // Open and Close the reader, to populate its attributes (such as height, width, etc...) - Open(); - Close(); +// Blank constructor for DummyReader, with default settings. +DummyReader::DummyReader() : dummy_cache(NULL), is_open(false) { + + // Initialize important variables + init(Fraction(24,1), 1280, 768, 44100, 2, 30.0); +} + +// Constructor for DummyReader. Pass a framerate and samplerate. +DummyReader::DummyReader(Fraction fps, int width, int height, int sample_rate, int channels, float duration) : dummy_cache(NULL), is_open(false) { + + // Initialize important variables + init(fps, width, height, sample_rate, channels, duration); +} + +// Constructor which also takes a cache object +DummyReader::DummyReader(Fraction fps, int width, int height, int sample_rate, int channels, float duration, CacheBase* cache) : is_open(false) { + + // Initialize important variables + init(fps, width, height, sample_rate, channels, duration); + + // Set cache object + dummy_cache = (CacheBase*) cache; } DummyReader::~DummyReader() { @@ -99,29 +111,23 @@ void DummyReader::Close() { // Mark as "closed" is_open = false; - - // Clear cache - dummy_cache.Clear(); - } -} - -// Add Frame objects to DummyReader -void DummyReader::WriteFrame(std::shared_ptr frame) -{ - if (frame) { - dummy_cache.Add(frame); } } // Get an openshot::Frame object for a specific frame number of this reader. It is either a blank frame -// or a custom frame added with the WriteFrame() method. +// or a custom frame added with passing a Cache object to the constructor. std::shared_ptr DummyReader::GetFrame(int64_t requested_frame) { // Check for open reader (or throw exception) if (!is_open) throw ReaderClosed("The ImageReader is closed. Call Open() before calling this method.", "dummy"); - if (dummy_cache.Count() == 0 && image_frame) { + int dummy_cache_count = 0; + if (dummy_cache) { + dummy_cache_count = dummy_cache->Count(); + } + + if (dummy_cache_count == 0 && image_frame) { // Create a scoped lock, allowing only a single thread to run the following code at one time const GenericScopedLock lock(getFrameCriticalSection); @@ -129,18 +135,18 @@ std::shared_ptr DummyReader::GetFrame(int64_t requested_frame) image_frame->number = requested_frame; return image_frame; - } else if (dummy_cache.Count() > 0) { + } else if (dummy_cache_count > 0) { // Create a scoped lock, allowing only a single thread to run the following code at one time const GenericScopedLock lock(getFrameCriticalSection); // Get a frame from the dummy cache - std::shared_ptr f = dummy_cache.GetFrame(requested_frame); + std::shared_ptr f = dummy_cache->GetFrame(requested_frame); if (f) { // return frame from cache (if found) return f; } else { // No cached frame found - throw InvalidFile("Requested frame not found. You can only access Frame numbers added with WriteFrame().", "dummy"); + throw InvalidFile("Requested frame not found. You can only access Frame numbers that exist in the Cache object.", "dummy"); } } else diff --git a/tests/DummyReader_Tests.cpp b/tests/DummyReader_Tests.cpp index 6ec11e08..c72be2d9 100644 --- a/tests/DummyReader_Tests.cpp +++ b/tests/DummyReader_Tests.cpp @@ -37,9 +37,24 @@ using namespace std; using namespace openshot; +TEST (DummyReader_Basic_Constructor) { + // Create a default fraction (should be 1/1) + openshot::DummyReader r; + r.Open(); // Open the reader + + // Check values + CHECK_EQUAL(1280, r.info.width); + CHECK_EQUAL(768, r.info.height); + CHECK_EQUAL(24, r.info.fps.num); + CHECK_EQUAL(1, r.info.fps.den); + CHECK_EQUAL(44100, r.info.sample_rate); + CHECK_EQUAL(2, r.info.channels); + CHECK_EQUAL(30.0, r.info.duration); +} + TEST (DummyReader_Constructor) { // Create a default fraction (should be 1/1) - openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); + openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 60.0); r.Open(); // Open the reader // Check values @@ -49,7 +64,7 @@ TEST (DummyReader_Constructor) { CHECK_EQUAL(1, r.info.fps.den); CHECK_EQUAL(44100, r.info.sample_rate); CHECK_EQUAL(2, r.info.channels); - CHECK_EQUAL(30.0, r.info.duration); + CHECK_EQUAL(60.0, r.info.duration); } TEST (DummyReader_Blank_Frame) { @@ -57,7 +72,7 @@ TEST (DummyReader_Blank_Frame) { openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); r.Open(); // Open the reader - // Get a blank frame (because we have not added any frames using WriteFrame() yet) + // Get a blank frame (because we have not passed a Cache object (full of Frame objects) to the constructor // Check values CHECK_EQUAL(1, r.GetFrame(1)->number); CHECK_EQUAL(1, r.GetFrame(1)->GetPixels(700)[700] == 0); // black pixel @@ -65,9 +80,9 @@ TEST (DummyReader_Blank_Frame) { } TEST (DummyReader_Fake_Frame) { - // Create a default fraction (should be 1/1) - openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); - r.Open(); // Open the reader + + // Create cache object to hold test frames + CacheMemory cache; // Let's create some test frames for (int64_t frame_number = 1; frame_number <= 30; frame_number++) { @@ -87,10 +102,14 @@ TEST (DummyReader_Fake_Frame) { f->AddAudio(true, 0, 0, audio_buffer, sample_count, 1.0); // add channel 1 f->AddAudio(true, 1, 0, audio_buffer, sample_count, 1.0); // add channel 2 - // Write test frame to dummy reader - r.WriteFrame(f); + // Add test frame to dummy reader + cache.Add(f); } + // Create a default fraction (should be 1/1) + openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0, &cache); + r.Open(); // Open the reader + // Verify our artificial audio sample data is correct CHECK_EQUAL(1, r.GetFrame(1)->number); CHECK_EQUAL(1, r.GetFrame(1)->GetAudioSamples(0)[0]); @@ -99,23 +118,32 @@ TEST (DummyReader_Fake_Frame) { CHECK_EQUAL(2, r.GetFrame(2)->GetAudioSamples(0)[0]); CHECK_CLOSE(2.00068033, r.GetFrame(2)->GetAudioSamples(0)[1], 0.00001); CHECK_CLOSE(2.00136054, r.GetFrame(2)->GetAudioSamples(0)[2], 0.00001); + + // Clean up + cache.Clear(); + r.Close(); } TEST (DummyReader_Invalid_Fake_Frame) { - // Create a default fraction (should be 1/1) - openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0); - r.Open(); - // Create fake frames (with specific frame #, samples, and channels) std::shared_ptr f1(new openshot::Frame(1, 1470, 2)); std::shared_ptr f2(new openshot::Frame(2, 1470, 2)); - // Write test frames to dummy reader - r.WriteFrame(f1); - r.WriteFrame(f2); + // Add test frames to cache object + CacheMemory cache; + cache.Add(f1); + cache.Add(f2); + + // Create a default fraction (should be 1/1) + openshot::DummyReader r(openshot::Fraction(30, 1), 1920, 1080, 44100, 2, 30.0, &cache); + r.Open(); // Verify exception CHECK_EQUAL(1, r.GetFrame(1)->number); CHECK_EQUAL(2, r.GetFrame(2)->number); CHECK_THROW(r.GetFrame(3)->number, InvalidFile); + + // Clean up + cache.Clear(); + r.Close(); } \ No newline at end of file From 7a91ca1d866216e0086d46a430d5666c5525c620 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 8 Jun 2020 15:58:17 -0400 Subject: [PATCH 052/148] FFmpegWriter: Remove unreachable branch --- src/FFmpegWriter.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index e6a7e5ef..3366ac5f 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -552,7 +552,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va } else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { // Set number of tiles to a fixed value - // TODO Let user choose number of tiles + // TODO Let user choose number of tiles av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); av_opt_set_int(c->priv_data, "speed", 7, 0); av_opt_set_int(c->priv_data, "tile-rows", 2, 0); // number of rows @@ -560,7 +560,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va } else if (strstr(info.vcodec.c_str(), "aom") != NULL) { // Set number of tiles to a fixed value - // TODO Let user choose number of tiles + // TODO Let user choose number of tiles // libaom doesn't have qp only crf av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows @@ -691,15 +691,8 @@ void FFmpegWriter::WriteFrame(std::shared_ptr frame) { // Write the frames once it reaches the correct cache size if ((int)spooled_video_frames.size() == cache_size || (int)spooled_audio_frames.size() == cache_size) { - // Is writer currently writing? - if (!is_writing) - // Write frames to video file - write_queued_frames(); - - else { - // Write frames to video file - write_queued_frames(); - } + // Write frames to video file + write_queued_frames(); } // Keep track of the last frame added From c57f8ede3b54776b399b6671f284f7946df757fc Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 8 Jun 2020 16:02:02 -0400 Subject: [PATCH 053/148] FFmpeg: Combine 2 constructors via a default arg, fix docs, const refs --- include/FFmpegReader.h | 15 +++++++-------- include/FFmpegWriter.h | 6 ++++-- src/FFmpegReader.cpp | 23 +---------------------- src/FFmpegWriter.cpp | 2 +- 4 files changed, 13 insertions(+), 33 deletions(-) diff --git a/include/FFmpegReader.h b/include/FFmpegReader.h index ec082965..35e11a42 100644 --- a/include/FFmpegReader.h +++ b/include/FFmpegReader.h @@ -233,14 +233,13 @@ namespace openshot { /// codecs have trouble seeking, and can introduce artifacts or blank images into the video. bool enable_seek; - /// Constructor for FFmpegReader. This automatically opens the media file and loads - /// frame 1, or it throws one of the following exceptions. - FFmpegReader(std::string path); - - /// Constructor for FFmpegReader. This only opens the media file to inspect its properties - /// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful - /// when you are inflating the object using JSON after instantiating it. - FFmpegReader(std::string path, bool inspect_reader); + /// @brief Constructor for FFmpegReader. + /// + /// Sets (and possibly opens) the media file path, + /// or throws an exception. + /// @param path The filesystem location to load + /// @param inspect_reader if true (the default), automatically open the media file and loads frame 1. + FFmpegReader(const std::string& path, bool inspect_reader=true); /// Destructor virtual ~FFmpegReader(); diff --git a/include/FFmpegWriter.h b/include/FFmpegWriter.h index 37fa22dc..f2e28d00 100644 --- a/include/FFmpegWriter.h +++ b/include/FFmpegWriter.h @@ -251,9 +251,11 @@ namespace openshot { public: - /// @brief Constructor for FFmpegWriter. Throws one of the following exceptions. + /// @brief Constructor for FFmpegWriter. + /// Throws an exception on failure to open path. + /// /// @param path The file path of the video file you want to open and read - FFmpegWriter(std::string path); + FFmpegWriter(const std::string& path); /// Close the writer void Close(); diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c8ce141f..12b9776a 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -83,7 +83,7 @@ int hw_de_on = 0; AVHWDeviceType hw_de_av_device_type_global = AV_HWDEVICE_TYPE_NONE; #endif -FFmpegReader::FFmpegReader(std::string path) +FFmpegReader::FFmpegReader(const std::string& path, bool inspect_reader) : last_frame(0), is_seeking(0), seeking_pts(0), seeking_frame(0), seek_count(0), audio_pts_offset(99999), video_pts_offset(99999), path(path), is_video_seek(true), check_interlace(false), check_fps(false), enable_seek(true), is_open(false), seek_audio_frame_found(0), seek_video_frame_found(0), @@ -91,27 +91,6 @@ FFmpegReader::FFmpegReader(std::string path) current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0), packet(NULL) { - // Initialize FFMpeg, and register all formats and codecs - AV_REGISTER_ALL - AVCODEC_REGISTER_ALL - - // Init cache - working_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * info.fps.ToDouble() * 2, info.width, info.height, info.sample_rate, info.channels); - missing_frames.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels); - final_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels); - - // Open and Close the reader, to populate its attributes (such as height, width, etc...) - Open(); - Close(); -} - -FFmpegReader::FFmpegReader(std::string path, bool inspect_reader) - : last_frame(0), is_seeking(0), seeking_pts(0), seeking_frame(0), seek_count(0), - audio_pts_offset(99999), video_pts_offset(99999), path(path), is_video_seek(true), check_interlace(false), - check_fps(false), enable_seek(true), is_open(false), seek_audio_frame_found(0), seek_video_frame_found(0), - prev_samples(0), prev_pts(0), pts_total(0), pts_counter(0), is_duration_known(false), largest_frame_processed(0), - current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0), - packet(NULL) { // Initialize FFMpeg, and register all formats and codecs AV_REGISTER_ALL diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 3366ac5f..eff2507e 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -83,7 +83,7 @@ static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int6 } #endif // HAVE_HW_ACCEL -FFmpegWriter::FFmpegWriter(std::string path) : +FFmpegWriter::FFmpegWriter(const std::string& path) : path(path), fmt(NULL), oc(NULL), audio_st(NULL), video_st(NULL), samples(NULL), audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0), initial_audio_input_frame_size(0), img_convert_ctx(NULL), cache_size(8), num_of_rescalers(32), From 96d84311c68a3fee3e982ca51fd2951bf5bc4c2a Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 8 Jun 2020 16:07:04 -0400 Subject: [PATCH 054/148] OpenMP: Move off deprecated allow_nested boolean - Replacement openmp_set_max_active_levels() takes an int argument - In OpenMP 5.0 it can be set to openmp_get_supported_active_levels() - Below 5.0, we just set it to our processor count - Move configuration of OpenMP from ad-hoc locations to constructors for FFmpegWriter/Reader and Timeline --- include/OpenMPUtilities.h | 7 +++++++ src/FFmpegReader.cpp | 10 +++++----- src/FFmpegWriter.cpp | 11 ++++++----- src/Timeline.cpp | 18 +++++++++++++----- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/include/OpenMPUtilities.h b/include/OpenMPUtilities.h index 9810d636..5b5107c1 100644 --- a/include/OpenMPUtilities.h +++ b/include/OpenMPUtilities.h @@ -41,5 +41,12 @@ #define OPEN_MP_NUM_PROCESSORS (std::min(omp_get_num_procs(), std::max(2, openshot::Settings::Instance()->OMP_THREADS) )) #define FF_NUM_PROCESSORS (std::min(omp_get_num_procs(), std::max(2, openshot::Settings::Instance()->FF_THREADS) )) +// Set max-active-levels to the max supported, if possible +// (supported_active_levels is OpenMP 5.0 (November 2018) or later, only.) +#if (_OPENMP >= 201811) + #define OPEN_MP_MAX_ACTIVE openmp_get_supported_active_levels() +#else + #define OPEN_MP_MAX_ACTIVE OPEN_MP_NUM_PROCESSORS +#endif #endif diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 12b9776a..fea4f60b 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -91,6 +91,11 @@ FFmpegReader::FFmpegReader(const std::string& path, bool inspect_reader) current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0), packet(NULL) { + // Configure OpenMP parallelism + // Default number of threads per section + omp_set_num_threads(OPEN_MP_NUM_PROCESSORS); + // Allow nested parallel sections as deeply as supported + omp_set_max_active_levels(OPEN_MP_MAX_ACTIVE); // Initialize FFMpeg, and register all formats and codecs AV_REGISTER_ALL @@ -877,11 +882,6 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame) { int minimum_packets = OPEN_MP_NUM_PROCESSORS; int max_packets = 4096; - // Set the number of threads in OpenMP - omp_set_num_threads(OPEN_MP_NUM_PROCESSORS); - // Allow nested OpenMP sections - omp_set_nested(true); - // Debug output ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ReadStream", "requested_frame", requested_frame, "OPEN_MP_NUM_PROCESSORS", OPEN_MP_NUM_PROCESSORS); diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index eff2507e..39a3768f 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -95,6 +95,12 @@ FFmpegWriter::FFmpegWriter(const std::string& path) : info.has_audio = false; info.has_video = false; + // Configure OpenMP parallelism + // Default number of threads per block + omp_set_num_threads(OPEN_MP_NUM_PROCESSORS); + // Allow nested parallel sections as deeply as supported + omp_set_max_active_levels(OPEN_MP_MAX_ACTIVE); + // Initialize FFMpeg, and register all formats and codecs AV_REGISTER_ALL @@ -714,11 +720,6 @@ void FFmpegWriter::write_queued_frames() { spooled_video_frames.clear(); spooled_audio_frames.clear(); - // Set the number of threads in OpenMP - omp_set_num_threads(OPEN_MP_NUM_PROCESSORS); - // Allow nested OpenMP sections - omp_set_nested(true); - // Create blank exception bool has_error_encoding_video = false; diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 124058ac..89f0992c 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -67,7 +67,13 @@ Timeline::Timeline(int width, int height, Fraction fps, int sample_rate, int cha info.acodec = "openshot::timeline"; info.vcodec = "openshot::timeline"; - // Init max image size + // Configure OpenMP parallelism + // Default number of threads per block + omp_set_num_threads(OPEN_MP_NUM_PROCESSORS); + // Allow nested parallel sections as deeply as supported + omp_set_max_active_levels(OPEN_MP_MAX_ACTIVE); + + // Init max image size SetMaxSize(info.width, info.height); // Init cache @@ -194,6 +200,12 @@ Timeline::Timeline(std::string projectPath, bool convert_absolute_paths) : info.has_video = true; info.has_audio = true; + // Configure OpenMP parallelism + // Default number of threads per section + omp_set_num_threads(OPEN_MP_NUM_PROCESSORS); + // Allow nested parallel sections as deeply as supported + omp_set_max_active_levels(OPEN_MP_MAX_ACTIVE); + // Init max image size SetMaxSize(info.width, info.height); @@ -892,10 +904,6 @@ std::shared_ptr Timeline::GetFrame(int64_t requested_frame) #pragma omp critical (T_GetFrame) nearby_clips = find_intersecting_clips(requested_frame, minimum_frames, true); - omp_set_num_threads(OPEN_MP_NUM_PROCESSORS); - // Allow nested OpenMP sections - omp_set_nested(true); - // Debug output ZmqLogger::Instance()->AppendDebugMethod("Timeline::GetFrame", "requested_frame", requested_frame, "minimum_frames", minimum_frames, "OPEN_MP_NUM_PROCESSORS", OPEN_MP_NUM_PROCESSORS); From 3f13ed87f0e18e636376be67847f9993670c0302 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 8 Jun 2020 16:07:55 -0400 Subject: [PATCH 055/148] Timeline: const-ref path arg in constructor, docs --- include/Timeline.h | 22 +++++++++++++--------- src/Timeline.cpp | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/Timeline.h b/include/Timeline.h index 932b04ac..32eac6be 100644 --- a/include/Timeline.h +++ b/include/Timeline.h @@ -202,19 +202,23 @@ namespace openshot { public: - /// @brief Default Constructor for the timeline (which sets the canvas width and height and FPS) - /// @param width The width of the timeline (and thus, the generated openshot::Frame objects) - /// @param height The height of the timeline (and thus, the generated openshot::Frame objects) - /// @param fps The frames rate of the timeline - /// @param sample_rate The sample rate of the timeline's audio - /// @param channels The number of audio channels of the timeline + /// @brief Default Constructor for the timeline (which configures the default frame properties) + /// @param width The image width of generated openshot::Frame objects + /// @param height The image height of generated openshot::Frame objects + /// @param fps The frame rate of the generated video + /// @param sample_rate The audio sample rate + /// @param channels The number of audio channels /// @param channel_layout The channel layout (i.e. mono, stereo, 3 point surround, etc...) Timeline(int width, int height, Fraction fps, int sample_rate, int channels, ChannelLayout channel_layout); - /// @brief Constructor for the timeline (which loads a JSON structure from a file path, and initializes a timeline) + /// @brief Project-file constructor for the timeline + /// + /// Loads a JSON structure from a file path, and + /// initializes the timeline described within. + /// /// @param projectPath The path of the UTF-8 *.osp project file (JSON contents). Contents will be loaded automatically. - /// @param convert_absolute_paths Should all paths be converted to absolute paths (based on the folder of the path provided) - Timeline(std::string projectPath, bool convert_absolute_paths); + /// @param convert_absolute_paths Should all paths be converted to absolute paths (relative to the location of projectPath) + Timeline(const std::string& projectPath, bool convert_absolute_paths); virtual ~Timeline(); diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 89f0992c..bbbc6858 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -82,7 +82,7 @@ Timeline::Timeline(int width, int height, Fraction fps, int sample_rate, int cha } // Constructor for the timeline (which loads a JSON structure from a file path, and initializes a timeline) -Timeline::Timeline(std::string projectPath, bool convert_absolute_paths) : +Timeline::Timeline(const std::string& projectPath, bool convert_absolute_paths) : is_open(false), auto_map_clips(true), managed_cache(true), path(projectPath) { // Create CrashHandler and Attach (incase of errors) From 8af624fc4ef40e188571809b4be00c2669581049 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 11 Jun 2020 17:40:53 -0400 Subject: [PATCH 056/148] Add an APPIMAGE_BUILD option to libopenshot - Defaults OFF, must be enabled during build generation - Set (cmake -DAPPIMAGE_BUILD=1) by GitLab linux builder - Stored as a symbol in the library (via OpenShotVersion.h #defines) - Also visible in Python module (`if openshot.APPIMAGE_BUILD: pass`) Also, use CMAKE_SWIG_FLAGS properly (as a list), fix some indentation --- .gitlab-ci.yml | 2 +- CMakeLists.txt | 1 + include/OpenShotVersion.h.in | 1 + src/CMakeLists.txt | 78 ++++++++++++++++++------------------ tests/CMakeLists.txt | 1 - 5 files changed, 42 insertions(+), 41 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 925bf020..d690b8e1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,7 +16,7 @@ linux-builder: - unzip artifacts.zip - export LIBOPENSHOT_AUDIO_DIR=$CI_PROJECT_DIR/build/install-x64 - mkdir -p build; cd build; - - cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -D"PYTHON_MODULE_PATH=python" -D"RUBY_MODULE_PATH=ruby" -DCMAKE_BUILD_TYPE:STRING=Release -DUSE_SYSTEM_JSONCPP=0 ../ + - cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -D"PYTHON_MODULE_PATH=python" -D"RUBY_MODULE_PATH=ruby" -DCMAKE_BUILD_TYPE:STRING=Release -DAPPIMAGE_BUILD=1 -DUSE_SYSTEM_JSONCPP=0 ../ - make - make install - make doc diff --git a/CMakeLists.txt b/CMakeLists.txt index f50c575f..94b09879 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,7 @@ option(DISABLE_BUNDLED_JSONCPP "Don't fall back to bundled JsonCpp" OFF) option(ENABLE_IWYU "Enable 'Include What You Use' scanner (CMake 3.3+)" OFF) option(ENABLE_TESTS "Build unit tests (requires UnitTest++)" ON) option(ENABLE_DOCS "Build API documentation (requires Doxygen)" ON) +option(APPIMAGE_BUILD "Build to install in an AppImage (Linux only)" OFF) # Legacy commandline override if (DISABLE_TESTS) diff --git a/include/OpenShotVersion.h.in b/include/OpenShotVersion.h.in index d0b015a4..5e86e8ce 100644 --- a/include/OpenShotVersion.h.in +++ b/include/OpenShotVersion.h.in @@ -49,6 +49,7 @@ #cmakedefine AVUTIL_VERSION_STR "@AVUTIL_VERSION_STR@" #cmakedefine01 HAVE_IMAGEMAGICK #cmakedefine01 HAVE_RESVG +#cmakedefine01 APPIMAGE_BUILD #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 90c74ead..61892668 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,8 +33,8 @@ include(GNUInstallDirs) # Set some compiler options for Windows # required for libopenshot-audio headers if (WIN32) - add_definitions( -DIGNORE_JUCE_HYPOT=1 ) - set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -include cmath") + add_definitions( -DIGNORE_JUCE_HYPOT=1 ) + set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -include cmath") endif() if (APPLE) @@ -50,28 +50,28 @@ endif() ################ IMAGE MAGICK ################## # Set the Quantum Depth that ImageMagick was built with (default to 16 bits) IF (MAGICKCORE_QUANTUM_DEPTH) - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH} ) + add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH} ) ELSE (MAGICKCORE_QUANTUM_DEPTH) - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 ) + add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 ) ENDIF (MAGICKCORE_QUANTUM_DEPTH) IF (MAGICKCORE_HDRI_ENABLE) - add_definitions( -DMAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE} ) + add_definitions( -DMAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE} ) ELSE (MAGICKCORE_HDRI_ENABLE) - add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 ) + add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 ) ENDIF (MAGICKCORE_HDRI_ENABLE) # Find the ImageMagick++ library find_package(ImageMagick COMPONENTS Magick++ MagickWand MagickCore) if (ImageMagick_FOUND) - # Include ImageMagick++ headers (needed for compile) - include_directories(${ImageMagick_INCLUDE_DIRS}) + # Include ImageMagick++ headers (needed for compile) + include_directories(${ImageMagick_INCLUDE_DIRS}) - # define a global var (used in the C++) - add_definitions( -DUSE_IMAGEMAGICK=1 ) - set(CMAKE_SWIG_FLAGS "-DUSE_IMAGEMAGICK=1") + # define a global var (used in the C++) + add_definitions( -DUSE_IMAGEMAGICK=1 ) + list(APPEND CMAKE_SWIG_FLAGS "-DUSE_IMAGEMAGICK=1") - set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE) - mark_as_advanced(HAVE_IMAGEMAGICK) + set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE) + mark_as_advanced(HAVE_IMAGEMAGICK) endif() ################# LIBOPENSHOT-AUDIO ################### @@ -85,15 +85,15 @@ include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}) # Find BlackMagic DeckLinkAPI libraries if (ENABLE_BLACKMAGIC) - find_package(BlackMagic) + find_package(BlackMagic) - if (BLACKMAGIC_FOUND) - # Include Blackmagic headers (needed for compile) - include_directories(${BLACKMAGIC_INCLUDE_DIR}) + if (BLACKMAGIC_FOUND) + # Include Blackmagic headers (needed for compile) + include_directories(${BLACKMAGIC_INCLUDE_DIR}) - # define a global var (used in the C++) - add_definitions( -DUSE_BLACKMAGIC=1 ) - set(CMAKE_SWIG_FLAGS "-DUSE_BLACKMAGIC=1") + # define a global var (used in the C++) + add_definitions( -DUSE_BLACKMAGIC=1 ) + list(APPEND CMAKE_SWIG_FLAGS "-DUSE_BLACKMAGIC=1") endif() endif() @@ -148,7 +148,7 @@ set(OPENSHOT_SOURCES Fraction.cpp Frame.cpp FrameMapper.cpp - Json.cpp + Json.cpp KeyFrame.cpp OpenShotVersion.cpp ZmqLogger.cpp @@ -216,7 +216,7 @@ set_target_properties(openshot PROPERTIES # Add optional ImageMagic-dependent sources if(ImageMagick_FOUND) - target_sources(openshot PRIVATE + target_sources(openshot PRIVATE ImageReader.cpp ImageWriter.cpp TextReader.cpp) @@ -245,7 +245,7 @@ target_include_directories(openshot ################### JSONCPP ##################### # Include jsoncpp headers (needed for JSON parsing) if (USE_SYSTEM_JSONCPP) - message(STATUS "Looking for system jsoncpp") + message(STATUS "Looking for system jsoncpp") # Either an installed config or our find module will # create the IMPORTED target jsoncpp_lib if successful find_package(jsoncpp) @@ -344,7 +344,7 @@ find_package(cppzmq QUIET) # Creates cppzmq target # Link ZeroMQ library if (TARGET libzmq) - target_link_libraries(openshot PUBLIC libzmq) + target_link_libraries(openshot PUBLIC libzmq) endif() # Include cppzmq headers, if not bundled into libzmq if (TARGET cppzmq) @@ -361,7 +361,7 @@ if(DEFINED ENV{RESVGDIR} AND NOT DEFINED RESVG_ROOT) endif() # Find resvg library (used for rendering svg files) -FIND_PACKAGE(RESVG) +find_package(RESVG) # Include resvg headers (optional SVG library) if (TARGET RESVG::resvg) @@ -369,7 +369,7 @@ if (TARGET RESVG::resvg) target_link_libraries(openshot PUBLIC RESVG::resvg) target_compile_definitions(openshot PUBLIC "-DUSE_RESVG=1") - set(CMAKE_SWIG_FLAGS "-DUSE_RESVG=1") + list(APPEND CMAKE_SWIG_FLAGS "-DUSE_RESVG=1") set(HAVE_RESVG TRUE CACHE BOOL "Building with Resvg support" FORCE) mark_as_advanced(HAVE_RESVG) @@ -379,7 +379,7 @@ endif() ############### LINK LIBRARY ################# # Link remaining dependency libraries target_link_libraries(openshot PUBLIC - ${LIBOPENSHOT_AUDIO_LIBRARIES} + ${LIBOPENSHOT_AUDIO_LIBRARIES} ${PROFILER}) if(ImageMagick_FOUND) @@ -391,8 +391,8 @@ if(BLACKMAGIC_FOUND) endif() if(WIN32) - # Required for exception handling on Windows - target_link_libraries(openshot PUBLIC "imagehlp" "dbghelp" ) + # Required for exception handling on Windows + target_link_libraries(openshot PUBLIC "imagehlp" "dbghelp" ) endif() @@ -401,9 +401,9 @@ endif() add_executable(openshot-example examples/Example.cpp) # Define path to test input files -SET(TEST_MEDIA_PATH "${PROJECT_SOURCE_DIR}/src/examples/") +set(TEST_MEDIA_PATH "${PROJECT_SOURCE_DIR}/src/examples/") if (WIN32) - STRING(REPLACE "/" "\\\\" TEST_MEDIA_PATH TEST_MEDIA_PATH) + string(REPLACE "/" "\\\\" TEST_MEDIA_PATH TEST_MEDIA_PATH) endif() target_compile_definitions(openshot-example PRIVATE -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) @@ -423,12 +423,12 @@ target_link_libraries(openshot-player openshot) ############### TEST BLACKMAGIC CAPTURE APP ################ if (BLACKMAGIC_FOUND) - # Create test executable - add_executable(openshot-blackmagic - examples/ExampleBlackmagic.cpp) + # Create test executable + add_executable(openshot-blackmagic + examples/ExampleBlackmagic.cpp) - # Link test executable to the new library - target_link_libraries(openshot-blackmagic openshot) + # Link test executable to the new library + target_link_libraries(openshot-blackmagic openshot) endif() ############### INCLUDE SWIG BINDINGS ################ @@ -448,13 +448,13 @@ install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ ############### CPACK PACKAGING ############## if(MINGW) - set(CPACK_GENERATOR "NSIS") + set(CPACK_GENERATOR "NSIS") endif() if(UNIX AND NOT APPLE) - set(CPACK_GENERATOR "DEB") + set(CPACK_GENERATOR "DEB") endif() #if(UNIX AND APPLE) -# set(CPACK_GENERATOR "DragNDrop") +# set(CPACK_GENERATOR "DragNDrop") #endif() set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Jonathan Thomas") #required diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7ccddba8..53b4cace 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -80,7 +80,6 @@ if(ImageMagick_FOUND) # define a global var (used in the C++) add_definitions( -DUSE_IMAGEMAGICK=1 ) - set(CMAKE_SWIG_FLAGS "-DUSE_IMAGEMAGICK=1") endif() ################# LIBOPENSHOT-AUDIO ################### From bec21b1c7719e50d2a0e97f4fee83997cfa8f2f5 Mon Sep 17 00:00:00 2001 From: Daniel Jour Date: Fri, 12 Jun 2020 22:30:54 +0200 Subject: [PATCH 057/148] Add a note about the buffering behavior of Timeline to DummyReader Using DummyReader with a custom cache with a Timeline can lead to strange exceptions due to Timeline's buffering. Therefore adding a note to the DummyReader documentation about that. --- include/DummyReader.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/DummyReader.h b/include/DummyReader.h index e9c90968..9a75751d 100644 --- a/include/DummyReader.h +++ b/include/DummyReader.h @@ -53,6 +53,12 @@ namespace openshot * A dummy reader can be created with any framerate or samplerate. This is useful in unit * tests that need to test different framerates or samplerates. * + * @note Timeline does buffering by requesting more frames than it + * strictly needs. Thus if you use this DummyReader with a custom + * cache in a Timeline, make sure it has enough + * frames. Specifically you need some frames after the last frame + * you plan to access through the Timeline. + * * @code * // Create cache object to store fake Frame objects * CacheMemory cache; From 4e2c08db88f30a195836998aa62f05b7713c819f Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Mon, 15 Jun 2020 14:02:26 -0700 Subject: [PATCH 058/148] Update src/FFmpegWriter.cpp Thanks for fixing that Co-authored-by: Jonathan Thomas --- src/FFmpegWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 9b348aed..058b7490 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1254,7 +1254,7 @@ AVStream *FFmpegWriter::add_video_stream() { } else if (strstr(info.vcodec.c_str(), "aom") != NULL) { // Set number of tiles to a fixed value - // TODO Let user choose number of tiles + // TODO: Allow user to chose their own number of tiles av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns av_opt_set_int(c->priv_data, "row-mt", 1, 0); // use multiple cores From 91647e6d0b702fecec9e653ef342a220aa6d9935 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Mon, 15 Jun 2020 14:03:29 -0700 Subject: [PATCH 059/148] Update src/FFmpegWriter.cpp Perfect. I forgot that comment. Co-authored-by: Jonathan Thomas --- src/FFmpegWriter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 058b7490..831db284 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -478,6 +478,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va #if (LIBAVCODEC_VERSION_MAJOR >= 58) case AV_CODEC_ID_AV1 : c->bit_rate = 0; + // AV1 only supports "crf" quality values av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); break; #endif From 2491d402df29ab7a91820acc6239f5477346b12a Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Mon, 15 Jun 2020 14:04:49 -0700 Subject: [PATCH 060/148] Update src/FFmpegWriter.cpp I should take more care of the comments. Co-authored-by: Jonathan Thomas --- src/FFmpegWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 831db284..7ad2eb17 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1225,7 +1225,7 @@ AVStream *FFmpegWriter::add_video_stream() { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) #if (LIBAVCODEC_VERSION_MAJOR >= 58) case AV_CODEC_ID_AV1 : - // TODO: + // TODO: Set `crf` or `qp` according to bitrate, as bitrate is not supported by these encoders yet. // set crf or qp according to bitrate as bitrate is not supported by // these encoders (yet) if (info.video_bit_rate >= 1000) { From bf0e700ae7ffb0370cc3f7721cb2e9a18c36c5b6 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Mon, 15 Jun 2020 14:05:43 -0700 Subject: [PATCH 061/148] Update src/FFmpegWriter.cpp Co-authored-by: Jonathan Thomas --- src/FFmpegWriter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 7ad2eb17..c35edcb4 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1226,7 +1226,6 @@ AVStream *FFmpegWriter::add_video_stream() { #if (LIBAVCODEC_VERSION_MAJOR >= 58) case AV_CODEC_ID_AV1 : // TODO: Set `crf` or `qp` according to bitrate, as bitrate is not supported by these encoders yet. - // set crf or qp according to bitrate as bitrate is not supported by // these encoders (yet) if (info.video_bit_rate >= 1000) { c->bit_rate = 0; From c037d5c01df664bb41e22a00571a900c1512fa76 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Mon, 15 Jun 2020 14:07:09 -0700 Subject: [PATCH 062/148] Update src/FFmpegWriter.cpp We might want to leave some kind of comment though. The encoders will (probably) get these options (soon). Co-authored-by: Jonathan Thomas --- src/FFmpegWriter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index c35edcb4..291ba848 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1226,7 +1226,6 @@ AVStream *FFmpegWriter::add_video_stream() { #if (LIBAVCODEC_VERSION_MAJOR >= 58) case AV_CODEC_ID_AV1 : // TODO: Set `crf` or `qp` according to bitrate, as bitrate is not supported by these encoders yet. - // these encoders (yet) if (info.video_bit_rate >= 1000) { c->bit_rate = 0; if (strstr(info.vcodec.c_str(), "aom") != NULL) { From 3dfcea1dd527d63b1c93dd0251a0723f4f88e4b5 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Mon, 15 Jun 2020 14:33:14 -0700 Subject: [PATCH 063/148] Fix indentation --- src/FFmpegWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 291ba848..cb1c326d 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1225,7 +1225,7 @@ AVStream *FFmpegWriter::add_video_stream() { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) #if (LIBAVCODEC_VERSION_MAJOR >= 58) case AV_CODEC_ID_AV1 : - // TODO: Set `crf` or `qp` according to bitrate, as bitrate is not supported by these encoders yet. + // TODO: Set `crf` or `qp` according to bitrate, as bitrate is not supported by these encoders yet. if (info.video_bit_rate >= 1000) { c->bit_rate = 0; if (strstr(info.vcodec.c_str(), "aom") != NULL) { From 056a72fa17fadaa7a263ffbfa0100b02dc210de8 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Mon, 15 Jun 2020 14:41:38 -0700 Subject: [PATCH 064/148] Fix indentation (2) --- src/FFmpegWriter.cpp | 76 ++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index cb1c326d..741f2f26 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -542,12 +542,12 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va } else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { // Set number of tiles to a fixed value - // TODO Let user choose number of tiles + // TODO Let user choose number of tiles av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); } else if (strstr(info.vcodec.c_str(), "aom") != NULL) { // Set number of tiles to a fixed value - // TODO Let user choose number of tiles + // TODO Let user choose number of tiles // libaom doesn't have qp only crf av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); } @@ -1207,10 +1207,10 @@ AVStream *FFmpegWriter::add_video_stream() { #endif /* Init video encoder options */ - if (info.video_bit_rate >= 1000 + if (info.video_bit_rate >= 1000 #if (LIBAVCODEC_VERSION_MAJOR >= 58) && c->codec_id != AV_CODEC_ID_AV1 -#endif +#endif ) { c->bit_rate = info.video_bit_rate; if (info.video_bit_rate >= 1500000) { @@ -1226,40 +1226,40 @@ AVStream *FFmpegWriter::add_video_stream() { #if (LIBAVCODEC_VERSION_MAJOR >= 58) case AV_CODEC_ID_AV1 : // TODO: Set `crf` or `qp` according to bitrate, as bitrate is not supported by these encoders yet. - if (info.video_bit_rate >= 1000) { - c->bit_rate = 0; - if (strstr(info.vcodec.c_str(), "aom") != NULL) { - int calculated_quality = 35; - if (info.video_bit_rate < 500000) calculated_quality = 50; - if (info.video_bit_rate > 5000000) calculated_quality = 10; - av_opt_set_int(c->priv_data, "crf", calculated_quality, 0); - info.video_bit_rate = calculated_quality; - } else { - int calculated_quality = 50; - if (info.video_bit_rate < 500000) calculated_quality = 60; - if (info.video_bit_rate > 5000000) calculated_quality = 15; - av_opt_set_int(c->priv_data, "qp", calculated_quality, 0); - info.video_bit_rate = calculated_quality; - } // medium - } - if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { - av_opt_set_int(c->priv_data, "preset", 6, 0); - av_opt_set_int(c->priv_data, "forced-idr",1,0); - } - else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { - av_opt_set_int(c->priv_data, "speed", 7, 0); - av_opt_set_int(c->priv_data, "tile-rows", 2, 0); - av_opt_set_int(c->priv_data, "tile-columns", 4, 0); - } - else if (strstr(info.vcodec.c_str(), "aom") != NULL) { - // Set number of tiles to a fixed value - // TODO: Allow user to chose their own number of tiles - av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows - av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns - av_opt_set_int(c->priv_data, "row-mt", 1, 0); // use multiple cores - av_opt_set_int(c->priv_data, "cpu-used", 3, 0); // default is 1, usable is 4 - } - //break; + if (info.video_bit_rate >= 1000) { + c->bit_rate = 0; + if (strstr(info.vcodec.c_str(), "aom") != NULL) { + int calculated_quality = 35; + if (info.video_bit_rate < 500000) calculated_quality = 50; + if (info.video_bit_rate > 5000000) calculated_quality = 10; + av_opt_set_int(c->priv_data, "crf", calculated_quality, 0); + info.video_bit_rate = calculated_quality; + } else { + int calculated_quality = 50; + if (info.video_bit_rate < 500000) calculated_quality = 60; + if (info.video_bit_rate > 5000000) calculated_quality = 15; + av_opt_set_int(c->priv_data, "qp", calculated_quality, 0); + info.video_bit_rate = calculated_quality; + } // medium + } + if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { + av_opt_set_int(c->priv_data, "preset", 6, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + } + else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + av_opt_set_int(c->priv_data, "speed", 7, 0); + av_opt_set_int(c->priv_data, "tile-rows", 2, 0); + av_opt_set_int(c->priv_data, "tile-columns", 4, 0); + } + else if (strstr(info.vcodec.c_str(), "aom") != NULL) { + // Set number of tiles to a fixed value + // TODO: Allow user to chose their own number of tiles + av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows + av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns + av_opt_set_int(c->priv_data, "row-mt", 1, 0); // use multiple cores + av_opt_set_int(c->priv_data, "cpu-used", 3, 0); // default is 1, usable is 4 + } + //break; #endif case AV_CODEC_ID_VP9 : case AV_CODEC_ID_HEVC : From 56736e9505530a4ed5f88da92f803703ddd7aed8 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Tue, 16 Jun 2020 10:22:52 -0700 Subject: [PATCH 065/148] Set the field order when interlace is on --- src/FFmpegWriter.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index d960d677..643eb854 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -340,6 +340,12 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va st = video_st; // Get codec context c = AV_GET_CODEC_PAR_CONTEXT(st, video_codec); + // Was a codec / stream found? + if (c) { + if (info.interlaced_frame) { + c->field_order = info.top_field_first ? AV_FIELD_TT : AV_FIELD_BB; + } + } } else if (info.has_audio && stream == AUDIO_STREAM && audio_st) { st = audio_st; // Get codec context From 001b2d8a71d5d6fa85c5f03c775b016e196fccd3 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Thu, 18 Jun 2020 05:47:40 -0400 Subject: [PATCH 066/148] MagickUtils: Add #pragma to silence IM6 warning --- include/MagickUtilities.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/MagickUtilities.h b/include/MagickUtilities.h index 74365904..953b85ee 100644 --- a/include/MagickUtilities.h +++ b/include/MagickUtilities.h @@ -32,7 +32,11 @@ #ifdef USE_IMAGEMAGICK +// Exclude a warning message with IM6 headers +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wignored-qualifiers" #include "Magick++.h" +#pragma GCC diagnostic pop // Determine ImageMagick version, as IM7 isn't fully // backwards compatible From 3157d757477edfc14f226a1e3ce430a97176e2d6 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Thu, 2 Jul 2020 16:54:32 -0700 Subject: [PATCH 067/148] Leave the values for qmin and qmax at their default values except for mpeg2. Changing them for the other codecs resultet in exporting with the wrong bitrate. --- src/FFmpegWriter.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index d960d677..d8695501 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1202,8 +1202,10 @@ AVStream *FFmpegWriter::add_video_stream() { ) { c->bit_rate = info.video_bit_rate; if (info.video_bit_rate >= 1500000) { - c->qmin = 2; - c->qmax = 30; + if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) { + c->qmin = 3; + c->qmax = 30; + } } // Here should be the setting for low fixed bitrate // Defaults are used because mpeg2 otherwise had problems From accc5a8deb42bcac4ae3caced2bc98a9971f00b6 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sun, 5 Jul 2020 20:45:41 -0500 Subject: [PATCH 068/148] Updating to gcc 8.4 for MacOS Catalina --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 925bf020..2b8d8299 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ mac-builder: - unzip artifacts.zip - export LIBOPENSHOT_AUDIO_DIR=$CI_PROJECT_DIR/build/install-x64 - mkdir -p build; cd build; - - cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc48/bin/g++-4.8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc48/bin/gcc-4.8 -DCMAKE_PREFIX_PATH=/usr/local/qt5/5.5/clang_64 -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ + - cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5/5.5/clang_64 -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" From 7b322a0948d277749f259ef730835617918bc39c Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sun, 5 Jul 2020 20:51:18 -0500 Subject: [PATCH 069/148] Making CMake Threads not required. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 17b73863..f0b0524f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -303,7 +303,7 @@ endforeach() # Threading library -- uses IMPORTED target Threads::Threads (since CMake 3.1) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) -find_package(Threads REQUIRED) +find_package(Threads) target_link_libraries(openshot PUBLIC Threads::Threads) ################### OPENMP ##################### From bfefe501d0d5a2982172c852bdb2e97a6821b009 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sun, 5 Jul 2020 21:09:31 -0500 Subject: [PATCH 070/148] Experimenting with Cmake and Threads failure --- src/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f0b0524f..cd2fe142 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -303,8 +303,8 @@ endforeach() # Threading library -- uses IMPORTED target Threads::Threads (since CMake 3.1) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) -find_package(Threads) -target_link_libraries(openshot PUBLIC Threads::Threads) +#find_package(Threads REQUIRED) +#target_link_libraries(openshot PUBLIC Threads::Threads) ################### OPENMP ##################### # Check for OpenMP (used for multi-core processing) @@ -317,7 +317,7 @@ if(NOT TARGET OpenMP::OpenMP_CXX) add_library(OpenMP_TARGET INTERFACE) add_library(OpenMP::OpenMP_CXX ALIAS OpenMP_TARGET) target_compile_options(OpenMP_TARGET INTERFACE ${OpenMP_CXX_FLAGS}) - target_link_libraries(OpenMP_TARGET INTERFACE Threads::Threads) + #target_link_libraries(OpenMP_TARGET INTERFACE Threads::Threads) target_link_libraries(OpenMP_TARGET INTERFACE ${OpenMP_CXX_FLAGS}) endif() From d2dd3d3e3f21f248043701ed275120afbdcad338 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sun, 5 Jul 2020 21:46:40 -0500 Subject: [PATCH 071/148] Experimenting with new include folder, since Catalina doesn't have a /usr/include/ --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2b8d8299..1835040c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ mac-builder: - unzip artifacts.zip - export LIBOPENSHOT_AUDIO_DIR=$CI_PROJECT_DIR/build/install-x64 - mkdir -p build; cd build; - - cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5/5.5/clang_64 -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ + - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5/5.5/clang_64 -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" From b7dd86e63a579c21c2325ceb79fd797312699236 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Mon, 6 Jul 2020 02:10:35 -0500 Subject: [PATCH 072/148] Experimental ABI fix to deal with '__cxx11' --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cd2fe142..ba485e74 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,8 +41,8 @@ if (APPLE) # If you still get errors compiling with GCC 4.8, mac headers need to be patched: http://hamelot.co.uk/programming/osx-gcc-dispatch_block_t-has-not-been-declared-invalid-typedef/ set_property(GLOBAL PROPERTY JUCE_MAC "JUCE_MAC") add_definitions(-DNDEBUG) + add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) set(EXTENSION "mm") - set(JUCE_PLATFORM_SPECIFIC_DIR build/macosx/platform_specific_code) set(JUCE_PLATFORM_SPECIFIC_LIBRARIES "-framework Carbon -framework Cocoa -framework CoreFoundation -framework CoreAudio -framework CoreMidi -framework IOKit -framework AGL -framework AudioToolbox -framework QuartzCore -lobjc -framework Accelerate") endif() From 6e6b60fa22f774a0717423893b798ba1cf6be8c3 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Mon, 6 Jul 2020 02:33:26 -0500 Subject: [PATCH 073/148] Experimental ABI fix to deal with '__cxx11' (take 2) --- src/CMakeLists.txt | 3 +++ tests/CMakeLists.txt | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ba485e74..50143a6f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,9 @@ if (APPLE) set(EXTENSION "mm") set(JUCE_PLATFORM_SPECIFIC_DIR build/macosx/platform_specific_code) set(JUCE_PLATFORM_SPECIFIC_LIBRARIES "-framework Carbon -framework Cocoa -framework CoreFoundation -framework CoreAudio -framework CoreMidi -framework IOKit -framework AGL -framework AudioToolbox -framework QuartzCore -lobjc -framework Accelerate") + + # Prevent compiling with __cxx11 + add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) endif() ################ IMAGE MAGICK ################## diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7ccddba8..f75d8ab1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -36,6 +36,11 @@ if(WIN32) set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -include cmath") endif() +if (APPLE) + # Prevent compiling with __cxx11 + add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) +endif() + ################### UNITTEST++ ##################### # Find UnitTest++ libraries (used for unit testing) find_package(UnitTest++) From aac43ec038b93496a4fc4ab4457259b6422cb62a Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Tue, 7 Jul 2020 02:34:11 -0500 Subject: [PATCH 074/148] Removing commented out code --- src/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 50143a6f..6b9dd8ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,7 +41,6 @@ if (APPLE) # If you still get errors compiling with GCC 4.8, mac headers need to be patched: http://hamelot.co.uk/programming/osx-gcc-dispatch_block_t-has-not-been-declared-invalid-typedef/ set_property(GLOBAL PROPERTY JUCE_MAC "JUCE_MAC") add_definitions(-DNDEBUG) - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) set(EXTENSION "mm") set(JUCE_PLATFORM_SPECIFIC_DIR build/macosx/platform_specific_code) set(JUCE_PLATFORM_SPECIFIC_LIBRARIES "-framework Carbon -framework Cocoa -framework CoreFoundation -framework CoreAudio -framework CoreMidi -framework IOKit -framework AGL -framework AudioToolbox -framework QuartzCore -lobjc -framework Accelerate") @@ -306,8 +305,6 @@ endforeach() # Threading library -- uses IMPORTED target Threads::Threads (since CMake 3.1) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) -#find_package(Threads REQUIRED) -#target_link_libraries(openshot PUBLIC Threads::Threads) ################### OPENMP ##################### # Check for OpenMP (used for multi-core processing) @@ -320,7 +317,6 @@ if(NOT TARGET OpenMP::OpenMP_CXX) add_library(OpenMP_TARGET INTERFACE) add_library(OpenMP::OpenMP_CXX ALIAS OpenMP_TARGET) target_compile_options(OpenMP_TARGET INTERFACE ${OpenMP_CXX_FLAGS}) - #target_link_libraries(OpenMP_TARGET INTERFACE Threads::Threads) target_link_libraries(OpenMP_TARGET INTERFACE ${OpenMP_CXX_FLAGS}) endif() From 9ef8f8478eca5b128c7bf7e6946c134e1ed82762 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Tue, 7 Jul 2020 10:14:02 -0700 Subject: [PATCH 075/148] Formating --- src/FFmpegWriter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index d8695501..e737462f 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1202,10 +1202,10 @@ AVStream *FFmpegWriter::add_video_stream() { ) { c->bit_rate = info.video_bit_rate; if (info.video_bit_rate >= 1500000) { - if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) { - c->qmin = 3; - c->qmax = 30; - } + if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) { + c->qmin = 3; + c->qmax = 30; + } } // Here should be the setting for low fixed bitrate // Defaults are used because mpeg2 otherwise had problems From 6114be5e0ff9fbdd5ab439dbe98840a97afb8d7d Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Tue, 7 Jul 2020 10:20:48 -0700 Subject: [PATCH 076/148] Fixed typo --- src/FFmpegWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index e737462f..158ef662 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1203,7 +1203,7 @@ AVStream *FFmpegWriter::add_video_stream() { c->bit_rate = info.video_bit_rate; if (info.video_bit_rate >= 1500000) { if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) { - c->qmin = 3; + c->qmin = 2; c->qmax = 30; } } From ca31359327c4d4c4a4c615de550ed8978262b88e Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 8 Jul 2020 17:39:04 -0400 Subject: [PATCH 077/148] FFmpegWriter: Missed 1 rename to video_codec_ctx --- src/FFmpegWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index cbf8a88b..5797d09e 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -845,7 +845,7 @@ void FFmpegWriter::flush_encoders() { if (info.has_video && video_codec_ctx && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) return; #else - if (info.has_video && video_codec && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) + if (info.has_video && video_codec_ctx && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) return; #endif From 85b6a967254af5493f1130631da5aa99559675e3 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 8 Jul 2020 17:56:08 -0400 Subject: [PATCH 078/148] Enable IN_LIST in older CMake --- src/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 61892668..ffaa7e8b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,6 +29,11 @@ include(FeatureSummary) include(GNUInstallDirs) +# Enable IN_LIST in older CMake +if (POLICY CMP0057) + cmake_policy(SET CMP0057 NEW) +endif() + ################ WINDOWS ################## # Set some compiler options for Windows # required for libopenshot-audio headers From f69aa41127fa03b3804007825b86328eb85b1134 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Wed, 8 Jul 2020 17:11:47 -0700 Subject: [PATCH 079/148] Add some comment --- src/FFmpegWriter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 643eb854..6e300bf1 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -344,6 +344,8 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va if (c) { if (info.interlaced_frame) { c->field_order = info.top_field_first ? AV_FIELD_TT : AV_FIELD_BB; + // We only use these two version and ignore AV_FIELD_TB and AV_FIELD_BT + // Otherwise we would need to change the whole export window } } } else if (info.has_audio && stream == AUDIO_STREAM && audio_st) { From b5ebee0bd7b9b81951405e17a48893cacde5ab15 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Mon, 13 Jul 2020 18:17:02 -0500 Subject: [PATCH 080/148] Updating linux to use Ubuntu Bionic build server --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9b026a88..0b2de687 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,7 +27,7 @@ linux-builder: except: - tags tags: - - linux + - linux-bionic mac-builder: stage: build-libopenshot From b8e1aded6752011d4486cce55eaa5a65e0a670f8 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 26 Jul 2020 22:37:12 -0400 Subject: [PATCH 081/148] CMake: Remove threading config variables Using FindThreads and the Threads::Threads target directly was causing problems, and OpenMP seems to handle all this itself now. --- src/CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ccc31949..31cdda98 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -317,11 +317,6 @@ foreach(ff_comp IN LISTS all_comps) endforeach() -################### Threads #################### -# Threading library -- uses IMPORTED target Threads::Threads (since CMake 3.1) -set(CMAKE_THREAD_PREFER_PTHREAD TRUE) -set(THREADS_PREFER_PTHREAD_FLAG TRUE) - ################### OPENMP ##################### # Check for OpenMP (used for multi-core processing) From 128deb51f53e9930f47373630e9777dc50ca9942 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Mon, 27 Jul 2020 18:56:56 -0500 Subject: [PATCH 082/148] Updating path to Qt5 on Mac builder --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0b2de687..fe18593d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ mac-builder: - unzip artifacts.zip - export LIBOPENSHOT_AUDIO_DIR=$CI_PROJECT_DIR/build/install-x64 - mkdir -p build; cd build; - - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5/5.5/clang_64 -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ + - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5.12.x/Qt5.12.9/5.12.9/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" From 1bf6facab59ef113f3157bf2032d1ea87abbea1e Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Tue, 4 Aug 2020 17:06:02 -0500 Subject: [PATCH 083/148] Using new 5.15 qt install for mac builder --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fe18593d..10e498cb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ mac-builder: - unzip artifacts.zip - export LIBOPENSHOT_AUDIO_DIR=$CI_PROJECT_DIR/build/install-x64 - mkdir -p build; cd build; - - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5.12.x/Qt5.12.9/5.12.9/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ + - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5.15.X/qt5.15/5.15.0/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" From 1a3a3a647ce65318f3fd8f712f2e8cc249474654 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Thu, 6 Aug 2020 02:23:01 -0500 Subject: [PATCH 084/148] Testing -stdlib=libc++ to prevent linking with gcc's libstd++ --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 10e498cb..302b2f19 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ mac-builder: - unzip artifacts.zip - export LIBOPENSHOT_AUDIO_DIR=$CI_PROJECT_DIR/build/install-x64 - mkdir -p build; cd build; - - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5.15.X/qt5.15/5.15.0/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ + - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5.15.X/qt5.15/5.15.0/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" -stdlib=libc++ ../ - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" From 099504246b5238587c0cce02a25bd13cbe5dd89a Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Thu, 6 Aug 2020 19:32:08 -0500 Subject: [PATCH 085/148] Experimental clang++ compiling of libopenshot --- .gitlab-ci.yml | 2 +- src/CMakeLists.txt | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 302b2f19..6b0235d6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ mac-builder: - unzip artifacts.zip - export LIBOPENSHOT_AUDIO_DIR=$CI_PROJECT_DIR/build/install-x64 - mkdir -p build; cd build; - - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc@8/bin/g++-8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc@8/bin/gcc-8 -DCMAKE_PREFIX_PATH=/usr/local/qt5.15.X/qt5.15/5.15.0/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" -stdlib=libc++ ../ + - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_PREFIX_PATH=/usr/local/qt5.15.X/qt5.15/5.15.0/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" -stdlib=libc++ ../ - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ccc31949..6c196379 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,6 +34,16 @@ if (POLICY CMP0057) cmake_policy(SET CMP0057 NEW) endif() +# Juce requires either DEBUG or NDEBUG to be defined on MacOS. +# -DNDEBUG is set by cmake for all release configs, so add +# -DDEBUG for debug builds. We'll do this for all OSes, even +# though only MacOS requires it. +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") +# Make sure we've picked some build type, default to debug +if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") + set(CMAKE_BUILD_TYPE "Debug") +endif() + ################ WINDOWS ################## # Set some compiler options for Windows # required for libopenshot-audio headers @@ -45,7 +55,6 @@ endif() if (APPLE) # If you still get errors compiling with GCC 4.8, mac headers need to be patched: http://hamelot.co.uk/programming/osx-gcc-dispatch_block_t-has-not-been-declared-invalid-typedef/ set_property(GLOBAL PROPERTY JUCE_MAC "JUCE_MAC") - add_definitions(-DNDEBUG) set(EXTENSION "mm") set(JUCE_PLATFORM_SPECIFIC_DIR build/macosx/platform_specific_code) set(JUCE_PLATFORM_SPECIFIC_LIBRARIES "-framework Carbon -framework Cocoa -framework CoreFoundation -framework CoreAudio -framework CoreMidi -framework IOKit -framework AGL -framework AudioToolbox -framework QuartzCore -lobjc -framework Accelerate") From cdd2efd32bebd55103efa54f435ae579ba358eb1 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 6 Aug 2020 21:28:56 -0400 Subject: [PATCH 086/148] Replace math.h header with cmath --- include/Fraction.h | 2 +- include/FrameMapper.h | 2 +- include/KeyFrame.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Fraction.h b/include/Fraction.h index 9ffcda1f..88c16fbc 100644 --- a/include/Fraction.h +++ b/include/Fraction.h @@ -31,7 +31,7 @@ #ifndef OPENSHOT_FRACTION_H #define OPENSHOT_FRACTION_H -#include +#include namespace openshot { diff --git a/include/FrameMapper.h b/include/FrameMapper.h index 35dc8fb7..e78401a9 100644 --- a/include/FrameMapper.h +++ b/include/FrameMapper.h @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include #include "CacheMemory.h" diff --git a/include/KeyFrame.h b/include/KeyFrame.h index ee58da8f..6424473a 100644 --- a/include/KeyFrame.h +++ b/include/KeyFrame.h @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include #include "Exceptions.h" From cf8080a67e8dd12b485611ee1251151bba0ac50c Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 6 Aug 2020 23:48:16 -0400 Subject: [PATCH 087/148] Remove .../usr/include path on MacOS --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6b0235d6..fd6f1e2b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ mac-builder: - unzip artifacts.zip - export LIBOPENSHOT_AUDIO_DIR=$CI_PROJECT_DIR/build/install-x64 - mkdir -p build; cd build; - - cmake -DCMAKE_CXX_FLAGS=-I\ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_PREFIX_PATH=/usr/local/qt5.15.X/qt5.15/5.15.0/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" -stdlib=libc++ ../ + - cmake -DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++" -DCMAKE_SHARED_LINKER_FLAGS="-stdlib=libc++" -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_PREFIX_PATH=/usr/local/qt5.15.X/qt5.15/5.15.0/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" From 9f4cdd46fbc58169bdff0a7c415c00f49d7f2ae1 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 7 Aug 2020 01:49:35 -0400 Subject: [PATCH 088/148] Frame: juce::String supports std::basic_ostream --- src/Frame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Frame.cpp b/src/Frame.cpp index 764b9651..cf47556a 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -992,7 +992,7 @@ void Frame::Play() // Output error (if any) if (error.isNotEmpty()) { - cout << "Error on initialise(): " << error.toStdString() << endl; + cout << "Error on initialise(): " << error << endl; } juce::AudioSourcePlayer audioSourcePlayer; From 6b94dbb9dd7b398a9b3f77d5da23b82224f4947f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 7 Aug 2020 00:49:36 -0400 Subject: [PATCH 089/148] Replace C compatibility headers with C++ --- include/ChunkReader.h | 4 ++-- include/ChunkWriter.h | 12 ++++++------ include/OpenMPUtilities.h | 4 ++-- include/Profiles.h | 10 +++++----- include/Qt/PlayerDemo.h | 12 ++++++------ include/ReaderBase.h | 2 +- include/RendererBase.h | 2 +- include/Settings.h | 6 +++--- include/ZmqLogger.h | 6 +++--- src/Qt/PlayerDemo.cpp | 9 ++++++++- src/examples/ExampleHtml.cpp | 5 +++-- 11 files changed, 40 insertions(+), 32 deletions(-) diff --git a/include/ChunkReader.h b/include/ChunkReader.h index cd7cd67f..50b26083 100644 --- a/include/ChunkReader.h +++ b/include/ChunkReader.h @@ -37,10 +37,10 @@ #include #include #include -#include -#include +#include #include #include +#include #include "Json.h" #include "CacheMemory.h" #include "Exceptions.h" diff --git a/include/ChunkWriter.h b/include/ChunkWriter.h index 5fee5a37..a63e4ca1 100644 --- a/include/ChunkWriter.h +++ b/include/ChunkWriter.h @@ -34,19 +34,19 @@ #include "ReaderBase.h" #include "WriterBase.h" #include "FFmpegWriter.h" +#include "CacheMemory.h" +#include "Exceptions.h" +#include "Json.h" #include #include #include #include -#include -#include -#include +#include #include #include -#include "CacheMemory.h" -#include "Exceptions.h" -#include "Json.h" +#include +#include namespace openshot diff --git a/include/OpenMPUtilities.h b/include/OpenMPUtilities.h index 9810d636..30bdd199 100644 --- a/include/OpenMPUtilities.h +++ b/include/OpenMPUtilities.h @@ -32,8 +32,8 @@ #define OPENSHOT_OPENMP_UTILITIES_H #include -#include -#include +#include +#include #include "Settings.h" diff --git a/include/Profiles.h b/include/Profiles.h index 3b5ebd0d..1de7c072 100644 --- a/include/Profiles.h +++ b/include/Profiles.h @@ -35,12 +35,12 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include -#include -#include +#include +#include #include "Exceptions.h" #include "Fraction.h" #include "Json.h" diff --git a/include/Qt/PlayerDemo.h b/include/Qt/PlayerDemo.h index f444334b..8dca83fc 100644 --- a/include/Qt/PlayerDemo.h +++ b/include/Qt/PlayerDemo.h @@ -31,12 +31,12 @@ #ifndef OPENSHOT_PLAYER_DEMO_H #define OPENSHOT_PLAYER_DEMO_H -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include "VideoRenderWidget.h" diff --git a/include/ReaderBase.h b/include/ReaderBase.h index dfb9873d..ab765753 100644 --- a/include/ReaderBase.h +++ b/include/ReaderBase.h @@ -43,7 +43,7 @@ #include "Frame.h" #include "Json.h" #include "ZmqLogger.h" -#include +#include #include #include #include diff --git a/include/RendererBase.h b/include/RendererBase.h index 1c526937..5e65ea87 100644 --- a/include/RendererBase.h +++ b/include/RendererBase.h @@ -32,7 +32,7 @@ #define OPENSHOT_RENDERER_BASE_H #include "Frame.h" -#include // for realloc +#include // for realloc #include namespace openshot diff --git a/include/Settings.h b/include/Settings.h index e82bf56b..4b12c612 100644 --- a/include/Settings.h +++ b/include/Settings.h @@ -35,11 +35,11 @@ #include #include #include -#include +#include #include #include -#include -#include +#include +#include #include #include #include "JuceHeader.h" diff --git a/include/ZmqLogger.h b/include/ZmqLogger.h index c165299e..af1eea6f 100644 --- a/include/ZmqLogger.h +++ b/include/ZmqLogger.h @@ -35,11 +35,11 @@ #include #include #include -#include +#include #include #include -#include -#include +#include +#include #include #include #include "JuceHeader.h" diff --git a/src/Qt/PlayerDemo.cpp b/src/Qt/PlayerDemo.cpp index ba20e5cf..e5f0e11d 100644 --- a/src/Qt/PlayerDemo.cpp +++ b/src/Qt/PlayerDemo.cpp @@ -28,11 +28,18 @@ * along with OpenShot Library. If not, see . */ -#include "stdio.h" +#include #include "../../include/QtPlayer.h" #include "../../include/Qt/PlayerDemo.h" #include #include +#include +#include +#include +#include +#include +#include +#include PlayerDemo::PlayerDemo(QWidget *parent) : QWidget(parent) diff --git a/src/examples/ExampleHtml.cpp b/src/examples/ExampleHtml.cpp index f315e252..576961bc 100644 --- a/src/examples/ExampleHtml.cpp +++ b/src/examples/ExampleHtml.cpp @@ -32,11 +32,12 @@ #include #include #include -#include "../../include/OpenShot.h" -//#include "../../include/CrashHandler.h" #include #include +#include "../../include/OpenShot.h" +#include "../../include/CrashHandler.h" + using namespace openshot; int main(int argc, char* argv[]) { From 8e6c73449e3450cb6c70d5dd22c9f16c6109bc16 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 7 Aug 2020 07:46:26 -0400 Subject: [PATCH 090/148] "Ensure full 40-character hashes in changelog" --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 87de2e16..25fcb43a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,7 +25,7 @@ linux-builder: - make doc - ~/auto-update-docs "$CI_PROJECT_DIR/build" "$CI_COMMIT_REF_NAME" - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" - - git log $(git describe --tags --abbrev=0 '@^')..@ --oneline --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x64/share/$CI_PROJECT_NAME.log" + - git log $(git describe --tags --abbrev=0 '@^')..@ --oneline --no-abbrev --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x64/share/$CI_PROJECT_NAME.log" when: always except: - tags @@ -50,7 +50,7 @@ mac-builder: - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" - - git log $(git describe --tags --abbrev=0 '@^')..@ --oneline --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x64/share/$CI_PROJECT_NAME.log" + - git log $(git describe --tags --abbrev=0 '@^')..@ --oneline --no-abbrev --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x64/share/$CI_PROJECT_NAME.log" when: always except: - tags @@ -77,7 +77,7 @@ windows-builder-x64: - mingw32-make install - New-Item -path "install-x64/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force - $PREV_GIT_LABEL=(git describe --tags --abbrev=0 '@^') - - git log "$PREV_GIT_LABEL..@" --oneline --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x64/share/$CI_PROJECT_NAME.log" + - git log "$PREV_GIT_LABEL..@" --oneline --no-abbrev --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x64/share/$CI_PROJECT_NAME.log" when: always except: - tags @@ -104,7 +104,7 @@ windows-builder-x86: - mingw32-make install - New-Item -path "install-x86/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force - $PREV_GIT_LABEL=(git describe --tags --abbrev=0 '@^') - - git log "$PREV_GIT_LABEL..@" --oneline --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x86/share/$CI_PROJECT_NAME.log" + - git log "$PREV_GIT_LABEL..@" --oneline --no-abbrev --date=short --no-merges --pretty="tformat:$GIT_LOG_FORMAT" > "install-x86/share/$CI_PROJECT_NAME.log" when: always except: - tags From 729e349d62087c4c593d3af1073688b8a35deab1 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Fri, 7 Aug 2020 17:14:39 -0400 Subject: [PATCH 091/148] Remove FFmpeg 3.2 from Travis matrix (#548) --- .travis.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/.travis.yml b/.travis.yml index 241d5be3..ab338bdd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,11 +32,6 @@ addons: - curl jobs: - - # The FFmpeg 3.2 backport PPA has gone missing - allow_failures: - - name: "FFmpeg 3.2 GCC (Ubuntu 16.04 Xenial)" - include: - name: "Coverage + FFmpeg 3.4 GCC (Ubuntu 18.04 Bionic)" env: @@ -99,31 +94,6 @@ jobs: - libavresample-dev - libomp-dev - - name: "FFmpeg 3.2 GCC (Ubuntu 16.04 Xenial)" - env: - - BUILD_VERSION=ffmpeg32 - - CMAKE_EXTRA_ARGS="" - - TEST_TARGET="os_test" - os: linux - dist: xenial - addons: - apt: - sources: - - sourceline: 'ppa:openshot.developers/libopenshot-daily' - - sourceline: 'ppa:jon-hedgerows/ffmpeg-backports' - packages: - - *p_common - - libavresample-dev - - libavcodec57 - - libavdevice57 - - libavfilter6 - - libavformat57 - - libavresample3 - - libavutil55 - - libpostproc54 - - libswresample2 - - libswscale4 - - name: "FFmpeg 2 GCC (Ubuntu 16.04 Xenial)" env: - BUILD_VERSION=ffmpeg2 From 08550fa52269da2de17ffb55bf981eff6a79fb1e Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Mon, 10 Aug 2020 16:08:11 -0400 Subject: [PATCH 092/148] Drop QtMultimedia and QtMultimediaWidgets deps (#551) (Not actually used.) --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31cdda98..ad5b5806 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -284,7 +284,7 @@ endif () ################# QT5 ################### # Find QT5 libraries -set(_qt_components Widgets Core Gui Multimedia MultimediaWidgets) +set(_qt_components Core Gui Widgets) find_package(Qt5 COMPONENTS ${_qt_components} REQUIRED) foreach(_qt_comp IN LISTS _qt_components) From 3e470519fda28851490ca96f5a99396beba27841 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 20 Aug 2020 11:36:57 -0400 Subject: [PATCH 093/148] Use Qt::endl with QTextStream --- src/CacheDisk.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CacheDisk.cpp b/src/CacheDisk.cpp index bb2e12c4..3ab88b3b 100644 --- a/src/CacheDisk.cpp +++ b/src/CacheDisk.cpp @@ -191,10 +191,10 @@ void CacheDisk::Add(std::shared_ptr frame) if (audio_file.open(QIODevice::WriteOnly)) { QTextStream audio_stream(&audio_file); - audio_stream << frame->SampleRate() << endl; - audio_stream << frame->GetAudioChannelsCount() << endl; - audio_stream << frame->GetAudioSamplesCount() << endl; - audio_stream << frame->ChannelsLayout() << endl; + audio_stream << frame->SampleRate() << Qt::endl; + audio_stream << frame->GetAudioChannelsCount() << Qt::endl; + audio_stream << frame->GetAudioSamplesCount() << Qt::endl; + audio_stream << frame->ChannelsLayout() << Qt::endl; // Loop through all samples for (int channel = 0; channel < frame->GetAudioChannelsCount(); channel++) @@ -202,7 +202,7 @@ void CacheDisk::Add(std::shared_ptr frame) // Get audio for this channel float *samples = frame->GetAudioSamples(channel); for (int sample = 0; sample < frame->GetAudioSamplesCount(); sample++) - audio_stream << samples[sample] << endl; + audio_stream << samples[sample] << Qt::endl; } } From 0e2f1eaba67b1b2f5196b13b5302fced1e414efa Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 20 Aug 2020 14:53:16 -0400 Subject: [PATCH 094/148] Include Qt header for Qt::endl --- include/CacheDisk.h | 2 -- src/CacheDisk.cpp | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/CacheDisk.h b/include/CacheDisk.h index 09ebd4ab..c60f5f6e 100644 --- a/include/CacheDisk.h +++ b/include/CacheDisk.h @@ -38,8 +38,6 @@ #include "Frame.h" #include "Exceptions.h" #include -#include -#include namespace openshot { diff --git a/src/CacheDisk.cpp b/src/CacheDisk.cpp index 3ab88b3b..64aba75c 100644 --- a/src/CacheDisk.cpp +++ b/src/CacheDisk.cpp @@ -29,6 +29,9 @@ */ #include "../include/CacheDisk.h" +#include +#include +#include using namespace std; using namespace openshot; From 92293d39abaca7e4fcdde6e9c1971c146980e587 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 20 Aug 2020 15:20:47 -0400 Subject: [PATCH 095/148] Add QtUtilities.h header --- include/QtUtilities.h | 44 +++++++++++++++++++++++++++++++++++++++++++ src/CacheDisk.cpp | 1 + 2 files changed, 45 insertions(+) create mode 100644 include/QtUtilities.h diff --git a/include/QtUtilities.h b/include/QtUtilities.h new file mode 100644 index 00000000..3f9637d9 --- /dev/null +++ b/include/QtUtilities.h @@ -0,0 +1,44 @@ +/** + * @file + * @brief Header file for QtUtilities (compatibiity overlay) + * @author FeRD (Frank Dana) + */ + +/* LICENSE + * + * Copyright (c) 2008-2020 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_UTILITIES_H +#define OPENSHOT_QT_UTILITIES_H + +#include +#include + +// Fix Qt::endl for older Qt versions +// From: https://bugreports.qt.io/browse/QTBUG-82680 +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) +namespace Qt { + using TextStreamFunction = QTextStream& (*)(QTextStream&); + constexpr TextStreamFunction endl = ::endl; +} +#endif + +#endif // OPENSHOT_QT_UTILITIES_H diff --git a/src/CacheDisk.cpp b/src/CacheDisk.cpp index 64aba75c..91153c8f 100644 --- a/src/CacheDisk.cpp +++ b/src/CacheDisk.cpp @@ -29,6 +29,7 @@ */ #include "../include/CacheDisk.h" +#include "../include/QtUtilities.h" #include #include #include From 3c2532b4deb51fee22338f70c094a5f058bf9c7f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 20 Aug 2020 16:50:12 -0400 Subject: [PATCH 096/148] Use std::make_shared to allocate shared ptrs std::make_shared does in a single allocation what the constructors for std::shared_ptr usually take at least 2 allocations to do. May give us an infinitesimal performance/memory improvement. https://www.modernescpp.com/index.php/memory-and-performance-overhead-of-smart-pointer --- include/DummyReader.h | 2 +- include/Frame.h | 2 +- src/CacheDisk.cpp | 6 +-- src/ChunkWriter.cpp | 4 +- src/Clip.cpp | 7 +++- src/DecklinkInput.cpp | 8 ++-- src/DecklinkWriter.cpp | 2 +- src/FFmpegReader.cpp | 6 +-- src/Frame.cpp | 84 +++++++++++++++++++++++-------------- src/FrameMapper.cpp | 8 ++-- src/ImageReader.cpp | 6 ++- src/QtHtmlReader.cpp | 9 ++-- src/QtImageReader.cpp | 23 ++++++---- src/QtTextReader.cpp | 8 ++-- src/TextReader.cpp | 11 +++-- src/effects/Bars.cpp | 3 +- src/effects/Crop.cpp | 3 +- src/effects/Deinterlace.cpp | 4 +- src/effects/Mask.cpp | 11 ++--- 19 files changed, 129 insertions(+), 78 deletions(-) diff --git a/include/DummyReader.h b/include/DummyReader.h index 9a75751d..af06656d 100644 --- a/include/DummyReader.h +++ b/include/DummyReader.h @@ -69,7 +69,7 @@ namespace openshot * // Create blank frame (with specific frame #, samples, and channels) * // Sample count should be 44100 / 30 fps = 1470 samples per frame * int sample_count = 1470; - * std::shared_ptr f(new openshot::Frame(frame_number, sample_count, 2)); + * auto f = std::make_shared(frame_number, sample_count, 2); * * // Create test samples with incrementing value * float *audio_buffer = new float[sample_count]; diff --git a/include/Frame.h b/include/Frame.h index f4ff54d4..7e7866c0 100644 --- a/include/Frame.h +++ b/include/Frame.h @@ -99,7 +99,7 @@ namespace openshot * ); * * // Some methods require a shared pointer to an openshot::Frame object. - * std::shared_ptr f(new Frame(1, 720, 480, "#000000", 44100, 2)); + * auto f = std::make_shared(1, 720, 480, "#000000", 44100, 2); * * @endcode */ diff --git a/src/CacheDisk.cpp b/src/CacheDisk.cpp index bb2e12c4..409d8c4e 100644 --- a/src/CacheDisk.cpp +++ b/src/CacheDisk.cpp @@ -227,14 +227,14 @@ std::shared_ptr CacheDisk::GetFrame(int64_t frame_number) if (path.exists(frame_path)) { // Load image file - std::shared_ptr image = std::shared_ptr(new QImage()); + auto image = std::make_shared(); image->load(frame_path); // Set pixel formatimage-> - image = std::shared_ptr(new QImage(image->convertToFormat(QImage::Format_RGBA8888))); + image = std::make_shared(image->convertToFormat(QImage::Format_RGBA8888)); // Create frame object - std::shared_ptr frame(new Frame()); + auto frame = std::make_shared(); frame->number = frame_number; frame->AddImage(image); diff --git a/src/ChunkWriter.cpp b/src/ChunkWriter.cpp index f9d653b0..c7752cd5 100644 --- a/src/ChunkWriter.cpp +++ b/src/ChunkWriter.cpp @@ -134,7 +134,9 @@ void ChunkWriter::WriteFrame(std::shared_ptr frame) writer_thumb->WriteFrame(last_frame); } else { // Write the 1st frame (of the 1st chunk)... since no previous chunk is available - std::shared_ptr blank_frame(new Frame(1, info.width, info.height, "#000000", info.sample_rate, info.channels)); + auto blank_frame = std::make_shared( + 1, info.width, info.height, "#000000", + info.sample_rate, info.channels); blank_frame->AddColor(info.width, info.height, "#000000"); writer_final->WriteFrame(blank_frame); writer_preview->WriteFrame(blank_frame); diff --git a/src/Clip.cpp b/src/Clip.cpp index d9f69440..f20f32fb 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -339,7 +339,10 @@ std::shared_ptr Clip::GetFrame(int64_t requested_frame) original_frame = GetOrCreateFrame(new_frame_number); // Create a new frame - std::shared_ptr frame(new Frame(new_frame_number, 1, 1, "#000000", original_frame->GetAudioSamplesCount(), original_frame->GetAudioChannelsCount())); + auto frame = std::make_shared( + new_frame_number, 1, 1, "#000000", + original_frame->GetAudioSamplesCount(), + original_frame->GetAudioChannelsCount()); { frame->SampleRate(original_frame->SampleRate()); frame->ChannelsLayout(original_frame->ChannelsLayout()); @@ -347,7 +350,7 @@ std::shared_ptr Clip::GetFrame(int64_t requested_frame) // Copy the image from the odd field if (enabled_video) - frame->AddImage(std::shared_ptr(new QImage(*original_frame->GetImage()))); + frame->AddImage(std::make_shared(*original_frame->GetImage())); // Loop through each channel, add audio if (enabled_audio && reader->info.has_audio) diff --git a/src/DecklinkInput.cpp b/src/DecklinkInput.cpp index da5a8d00..b03ad8e4 100644 --- a/src/DecklinkInput.cpp +++ b/src/DecklinkInput.cpp @@ -139,7 +139,7 @@ HRESULT DeckLinkInputDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* { // Handle Video Frame if(videoFrame) - { + { if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) { @@ -245,7 +245,8 @@ omp_set_nested(true); m_rgbFrame->GetBytes(&frameBytes); // *********** CREATE OPENSHOT FRAME ********** - std::shared_ptr f(new openshot::Frame(copy_frameCount, width, height, "#000000", 2048, 2)); + auto f = std::make_shared( + copy_frameCount, width, height, "#000000", 2048, 2); // Add Image data to openshot frame // TODO: Fix Decklink support with QImage Upgrade @@ -289,6 +290,3 @@ HRESULT DeckLinkInputDelegate::VideoInputFormatChanged(BMDVideoInputFormatChange { return S_OK; } - - - diff --git a/src/DecklinkWriter.cpp b/src/DecklinkWriter.cpp index 4ebbd1f0..3eafda1c 100644 --- a/src/DecklinkWriter.cpp +++ b/src/DecklinkWriter.cpp @@ -142,7 +142,7 @@ void DecklinkWriter::Open() // throw DecklinkError("Failed to enable audio output. Is another application using the card?"); // Begin video preroll by scheduling a second of frames in hardware - //std::shared_ptr f(new Frame(1, displayMode->GetWidth(), displayMode->GetHeight(), "Blue")); + //auto f = std::make_shared(1, displayMode->GetWidth(), displayMode->GetHeight(), "Blue"); //f->AddColor(displayMode->GetWidth(), displayMode->GetHeight(), "Blue"); // Preroll 1 second of video diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c8ce141f..1952e8d6 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -2134,7 +2134,7 @@ bool FFmpegReader::CheckMissingFrame(int64_t requested_frame) { // Add this frame to the processed map (since it's already done) std::shared_ptr parent_image = parent_frame->GetImage(); if (parent_image) { - missing_frame->AddImage(std::shared_ptr(new QImage(*parent_image))); + missing_frame->AddImage(std::make_shared(*parent_image)); processed_video_frames[missing_frame->number] = missing_frame->number; } } @@ -2224,7 +2224,7 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream, int64_t requested_fram if (info.has_video && !is_video_ready && last_video_frame) { // Copy image from last frame - f->AddImage(std::shared_ptr(new QImage(*last_video_frame->GetImage()))); + f->AddImage(std::make_shared(*last_video_frame->GetImage())); is_video_ready = true; } @@ -2246,7 +2246,7 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream, int64_t requested_fram // Add missing image (if needed - sometimes end_of_stream causes frames with only audio) if (info.has_video && !is_video_ready && last_video_frame) // Copy image from last frame - f->AddImage(std::shared_ptr(new QImage(*last_video_frame->GetImage()))); + f->AddImage(std::make_shared(*last_video_frame->GetImage())); // Reset counter since last 'final' frame num_checks_since_final = 0; diff --git a/src/Frame.cpp b/src/Frame.cpp index cf47556a..16f420bc 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -39,7 +39,7 @@ Frame::Frame() : number(1), pixel_ratio(1,1), channels(2), width(1), height(1), max_audio_sample(0) { // Init the image magic and audio buffer - audio = std::shared_ptr(new juce::AudioSampleBuffer(channels, 0)); + audio = std::make_shared(channels, 0); // initialize the audio samples to zero (silence) audio->clear(); @@ -52,7 +52,7 @@ Frame::Frame(int64_t number, int width, int height, std::string color) max_audio_sample(0) { // Init the image magic and audio buffer - audio = std::shared_ptr(new juce::AudioSampleBuffer(channels, 0)); + audio = std::make_shared(channels, 0); // initialize the audio samples to zero (silence) audio->clear(); @@ -65,7 +65,7 @@ Frame::Frame(int64_t number, int samples, int channels) : max_audio_sample(0) { // Init the image magic and audio buffer - audio = std::shared_ptr(new juce::AudioSampleBuffer(channels, samples)); + audio = std::make_shared(channels, samples); // initialize the audio samples to zero (silence) audio->clear(); @@ -78,7 +78,7 @@ Frame::Frame(int64_t number, int width, int height, std::string color, int sampl max_audio_sample(0) { // Init the image magic and audio buffer - audio = std::shared_ptr(new juce::AudioSampleBuffer(channels, samples)); + audio = std::make_shared(channels, samples); // initialize the audio samples to zero (silence) audio->clear(); @@ -117,11 +117,11 @@ void Frame::DeepCopy(const Frame& other) max_audio_sample = other.max_audio_sample; if (other.image) - image = std::shared_ptr(new QImage(*(other.image))); + image = std::make_shared(*(other.image)); if (other.audio) - audio = std::shared_ptr(new juce::AudioSampleBuffer(*(other.audio))); + audio = std::make_shared(*(other.audio)); if (other.wave_image) - wave_image = std::shared_ptr(new QImage(*(other.wave_image))); + wave_image = std::make_shared(*(other.wave_image)); } // Destructor @@ -138,7 +138,7 @@ void Frame::Display() // Only create the QApplication once static int argc = 1; static char* argv[1] = {NULL}; - previewApp = std::shared_ptr(new QApplication(argc, argv)); + previewApp = std::make_shared(argc, argv); } // Get preview image @@ -152,7 +152,8 @@ void Frame::Display() int new_height = previewImage->size().height() * pixel_ratio.Reciprocal().ToDouble(); // Resize to fix DAR - previewImage = std::shared_ptr(new QImage(previewImage->scaled(new_width, new_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); + previewImage = std::make_shared(previewImage->scaled( + new_width, new_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } // Create window @@ -228,7 +229,8 @@ std::shared_ptr Frame::GetWaveform(int width, int height, int Red, int G } // Create blank image - wave_image = std::shared_ptr(new QImage(total_width, total_height, QImage::Format_RGBA8888)); + wave_image = std::make_shared( + total_width, total_height, QImage::Format_RGBA8888); wave_image->fill(QColor(0,0,0,0)); // Load QPainter with wave_image device @@ -253,13 +255,13 @@ std::shared_ptr Frame::GetWaveform(int width, int height, int Red, int G // Resize Image (if requested) if (width != total_width || height != total_height) { QImage scaled_wave_image = wave_image->scaled(width, height, Qt::IgnoreAspectRatio, Qt::FastTransformation); - wave_image = std::shared_ptr(new QImage(scaled_wave_image)); + wave_image = std::make_shared(scaled_wave_image); } } else { // No audio samples present - wave_image = std::shared_ptr(new QImage(width, height, QImage::Format_RGBA8888)); + wave_image = std::make_shared(width, height, QImage::Format_RGBA8888); wave_image->fill(QColor(QString::fromStdString("#000000"))); } @@ -294,7 +296,7 @@ void Frame::DisplayWaveform() // Only create the QApplication once static int argc = 1; static char* argv[1] = {NULL}; - previewApp = std::shared_ptr(new QApplication(argc, argv)); + previewApp = std::make_shared(argc, argv); } // Create window @@ -599,11 +601,15 @@ void Frame::Save(std::string path, float scale, std::string format, int quality) int new_height = previewImage->size().height() * pixel_ratio.Reciprocal().ToDouble(); // Resize to fix DAR - previewImage = std::shared_ptr(new QImage(previewImage->scaled(new_width, new_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); + previewImage = std::make_shared(previewImage->scaled( + new_width, new_height, + Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } // Resize image - previewImage = std::shared_ptr(new QImage(previewImage->scaled(new_width * scale, new_height * scale, Qt::KeepAspectRatio, Qt::SmoothTransformation))); + previewImage = std::make_shared(previewImage->scaled( + new_width * scale, new_height * scale, + Qt::KeepAspectRatio, Qt::SmoothTransformation)); } // Save image @@ -615,7 +621,8 @@ void Frame::Thumbnail(std::string path, int new_width, int new_height, std::stri std::string background_color, bool ignore_aspect, std::string format, int quality, float rotate) { // Create blank thumbnail image & fill background color - std::shared_ptr thumbnail = std::shared_ptr(new QImage(new_width, new_height, QImage::Format_RGBA8888)); + auto thumbnail = std::make_shared( + new_width, new_height, QImage::Format_RGBA8888); thumbnail->fill(QColor(QString::fromStdString(background_color))); // Create painter @@ -633,16 +640,22 @@ void Frame::Thumbnail(std::string path, int new_width, int new_height, std::stri int aspect_height = previewImage->size().height() * pixel_ratio.Reciprocal().ToDouble(); // Resize to fix DAR - previewImage = std::shared_ptr(new QImage(previewImage->scaled(aspect_width, aspect_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); + previewImage = std::make_shared(previewImage->scaled( + aspect_width, aspect_height, + Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } // Resize frame image if (ignore_aspect) // Ignore aspect ratio - previewImage = std::shared_ptr(new QImage(previewImage->scaled(new_width, new_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); + previewImage = std::make_shared(previewImage->scaled( + new_width, new_height, + Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); else // Maintain aspect ratio - previewImage = std::shared_ptr(new QImage(previewImage->scaled(new_width, new_height, Qt::KeepAspectRatio, Qt::SmoothTransformation))); + previewImage = std::make_shared(previewImage->scaled( + new_width, new_height, + Qt::KeepAspectRatio, Qt::SmoothTransformation)); // Composite frame image onto background (centered) int x = (new_width - previewImage->size().width()) / 2.0; // center @@ -666,14 +679,16 @@ void Frame::Thumbnail(std::string path, int new_width, int new_height, std::stri // Overlay Image (if any) if (overlay_path != "") { // Open overlay - std::shared_ptr overlay = std::shared_ptr(new QImage()); + auto overlay = std::make_shared(); overlay->load(QString::fromStdString(overlay_path)); // Set pixel format - overlay = std::shared_ptr(new QImage(overlay->convertToFormat(QImage::Format_RGBA8888))); + overlay = std::make_shared( + overlay->convertToFormat(QImage::Format_RGBA8888)); // Resize to fit - overlay = std::shared_ptr(new QImage(overlay->scaled(new_width, new_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); + overlay = std::make_shared(overlay->scaled( + new_width, new_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); // Composite onto thumbnail painter.setCompositionMode(QPainter::CompositionMode_SourceOver); @@ -684,14 +699,16 @@ void Frame::Thumbnail(std::string path, int new_width, int new_height, std::stri // Mask Image (if any) if (mask_path != "") { // Open mask - std::shared_ptr mask = std::shared_ptr(new QImage()); + auto mask = std::make_shared(); mask->load(QString::fromStdString(mask_path)); // Set pixel format - mask = std::shared_ptr(new QImage(mask->convertToFormat(QImage::Format_RGBA8888))); + mask = std::make_shared( + mask->convertToFormat(QImage::Format_RGBA8888)); // Resize to fit - mask = std::shared_ptr(new QImage(mask->scaled(new_width, new_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); + mask = std::make_shared(mask->scaled( + new_width, new_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); // Negate mask mask->invertPixels(); @@ -744,7 +761,7 @@ void Frame::AddColor(int new_width, int new_height, std::string new_color) const GenericScopedLock lock(addingImageSection); #pragma omp critical (AddImage) { - image = std::shared_ptr(new QImage(new_width, new_height, QImage::Format_RGBA8888)); + image = std::make_shared(new_width, new_height, QImage::Format_RGBA8888); // Fill with solid color image->fill(QColor(QString::fromStdString(color))); @@ -769,11 +786,12 @@ void Frame::AddImage(int new_width, int new_height, int bytes_per_pixel, QImage: // Create new image object, and fill with pixel data #pragma omp critical (AddImage) { - image = std::shared_ptr(new QImage(qbuffer, new_width, new_height, new_width * bytes_per_pixel, type, (QImageCleanupFunction) &openshot::Frame::cleanUpBuffer, (void*) qbuffer)); + image = std::make_shared( + qbuffer, new_width, new_height, new_width * bytes_per_pixel, type, (QImageCleanupFunction) &openshot::Frame::cleanUpBuffer, (void*) qbuffer); // Always convert to RGBA8888 (if different) if (image->format() != QImage::Format_RGBA8888) - *image = image->convertToFormat(QImage::Format_RGBA8888); + *image = image->convertToFormat(QImage::Format_RGBA8888); // Update height and width width = image->width(); @@ -828,7 +846,8 @@ void Frame::AddImage(std::shared_ptr new_image, bool only_odd_lines) ret = true; } else if (new_image->format() != image->format()) { - new_image = std::shared_ptr(new QImage(new_image->convertToFormat(image->format()))); + new_image = std::make_shared( + new_image->convertToFormat(image->format())); } } if (ret) { @@ -938,7 +957,8 @@ std::shared_ptr Frame::GetMagickImage() const QRgb *tmpBits = (const QRgb*)image->constBits(); // Create new image object, and fill with pixel data - std::shared_ptr magick_image = std::shared_ptr(new Magick::Image(image->width(), image->height(),"RGBA", Magick::CharPixel, tmpBits)); + auto magick_image = std::make_shared( + image->width(), image->height(),"RGBA", Magick::CharPixel, tmpBits); // Give image a transparent background color magick_image->backgroundColor(Magick::Color("none")); @@ -967,7 +987,9 @@ void Frame::AddMagickImage(std::shared_ptr new_image) MagickCore::ExportImagePixels(new_image->constImage(), 0, 0, new_image->columns(), new_image->rows(), "RGBA", Magick::CharPixel, buffer, &exception); // Create QImage of frame data - image = std::shared_ptr(new QImage(qbuffer, width, height, width * BPP, QImage::Format_RGBA8888, (QImageCleanupFunction) &cleanUpBuffer, (void*) qbuffer)); + image = std::make_shared( + qbuffer, width, height, width * BPP, QImage::Format_RGBA8888, + (QImageCleanupFunction) &cleanUpBuffer, (void*) qbuffer); // Update height and width width = image->width(); diff --git a/src/FrameMapper.cpp b/src/FrameMapper.cpp index e1e5700c..4946a5c1 100644 --- a/src/FrameMapper.cpp +++ b/src/FrameMapper.cpp @@ -450,7 +450,8 @@ std::shared_ptr FrameMapper::GetFrame(int64_t requested_frame) } // Create a new frame - std::shared_ptr frame = std::make_shared(frame_number, 1, 1, "#000000", samples_in_frame, channels_in_frame); + auto frame = std::make_shared( + frame_number, 1, 1, "#000000", samples_in_frame, channels_in_frame); frame->SampleRate(mapped_frame->SampleRate()); frame->ChannelsLayout(mapped_frame->ChannelsLayout()); @@ -460,13 +461,14 @@ std::shared_ptr FrameMapper::GetFrame(int64_t requested_frame) odd_frame = GetOrCreateFrame(mapped.Odd.Frame); if (odd_frame) - frame->AddImage(std::shared_ptr(new QImage(*odd_frame->GetImage())), true); + frame->AddImage(std::make_shared(*odd_frame->GetImage()), true); if (mapped.Odd.Frame != mapped.Even.Frame) { // Add even lines (if different than the previous image) std::shared_ptr even_frame; even_frame = GetOrCreateFrame(mapped.Even.Frame); if (even_frame) - frame->AddImage(std::shared_ptr(new QImage(*even_frame->GetImage())), false); + frame->AddImage( + std::make_shared(*even_frame->GetImage()), false); } // Resample audio on frame (if needed) diff --git a/src/ImageReader.cpp b/src/ImageReader.cpp index 9ce3a70f..9a001879 100644 --- a/src/ImageReader.cpp +++ b/src/ImageReader.cpp @@ -61,7 +61,7 @@ void ImageReader::Open() try { // load image - image = std::shared_ptr(new Magick::Image(path)); + image = std::make_shared(path); // Give image a transparent background color image->backgroundColor(Magick::Color("none")); @@ -126,7 +126,9 @@ std::shared_ptr ImageReader::GetFrame(int64_t requested_frame) throw ReaderClosed("The FFmpegReader is closed. Call Open() before calling this method.", path); // Create or get frame object - std::shared_ptr image_frame(new Frame(requested_frame, image->size().width(), image->size().height(), "#000000", 0, 2)); + auto image_frame = std::make_shared( + requested_frame, image->size().width(), image->size().height(), + "#000000", 0, 2); // Add Image data to frame image_frame->AddMagickImage(image); diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 6b502fbd..4925d3a8 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -62,7 +62,7 @@ void QtHtmlReader::Open() if (!is_open) { // create image - image = std::shared_ptr(new QImage(width, height, QImage::Format_RGBA8888)); + image = std::make_shared(width, height, QImage::Format_RGBA8888); image->fill(QColor(background_color.c_str())); //start painting @@ -162,7 +162,9 @@ 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)); + auto image_frame = std::make_shared( + requested_frame, image->size().width(), image->size().height(), + background_color, 0, 2); // Add Image data to frame image_frame->AddImage(image); @@ -171,7 +173,8 @@ std::shared_ptr QtHtmlReader::GetFrame(int64_t requested_frame) return image_frame; } else { // return empty frame - std::shared_ptr image_frame(new Frame(1, 640, 480, background_color, 0, 2)); + auto image_frame = std::make_shared( + 1, 640, 480, background_color, 0, 2); // return frame object return image_frame; diff --git a/src/QtImageReader.cpp b/src/QtImageReader.cpp index cf64ef93..b6dd7ee0 100644 --- a/src/QtImageReader.cpp +++ b/src/QtImageReader.cpp @@ -82,7 +82,8 @@ void QtImageReader::Open() ResvgRenderer renderer(path); if (renderer.isValid()) { - image = std::shared_ptr(new QImage(renderer.defaultSize(), QImage::Format_ARGB32_Premultiplied)); + image = std::make_shared( + renderer.defaultSize(), QImage::Format_ARGB32_Premultiplied); image->fill(Qt::transparent); QPainter p(image.get()); @@ -95,7 +96,7 @@ void QtImageReader::Open() if (!loaded) { // Attempt to open file using Qt's build in image processing capabilities - image = std::shared_ptr(new QImage()); + image = std::make_shared(); success = image->load(path); } @@ -105,7 +106,8 @@ void QtImageReader::Open() } // Convert to proper format - image = std::shared_ptr(new QImage(image->convertToFormat(QImage::Format_RGBA8888))); + image = std::make_shared( + image->convertToFormat(QImage::Format_RGBA8888)); // Update image properties info.has_audio = false; @@ -238,7 +240,9 @@ std::shared_ptr QtImageReader::GetFrame(int64_t requested_frame) svg_size.scale(max_width, max_height, Qt::KeepAspectRatio); // Create empty QImage - cached_image = std::shared_ptr(new QImage(QSize(svg_size.width(), svg_size.height()), QImage::Format_ARGB32_Premultiplied)); + cached_image = std::make_shared( + QSize(svg_size.width(), svg_size.height()), + QImage::Format_ARGB32_Premultiplied); cached_image->fill(Qt::transparent); // Render SVG into QImage @@ -253,10 +257,12 @@ std::shared_ptr QtImageReader::GetFrame(int64_t requested_frame) if (!rendered) { // We need to resize the original image to a smaller image (for performance reasons) // Only do this once, to prevent tons of unneeded scaling operations - cached_image = std::shared_ptr(new QImage(image->scaled(max_width, max_height, Qt::KeepAspectRatio, Qt::SmoothTransformation))); + cached_image = std::make_shared(image->scaled( + max_width, max_height, Qt::KeepAspectRatio, Qt::SmoothTransformation)); } - cached_image = std::shared_ptr(new QImage(cached_image->convertToFormat(QImage::Format_RGBA8888))); + cached_image = std::make_shared( + cached_image->convertToFormat(QImage::Format_RGBA8888)); // Set max size (to later determine if max_size is changed) max_size.setWidth(max_width); @@ -264,7 +270,10 @@ std::shared_ptr QtImageReader::GetFrame(int64_t requested_frame) } // Create or get frame object - std::shared_ptr image_frame(new Frame(requested_frame, cached_image->width(), cached_image->height(), "#000000", Frame::GetSamplesPerFrame(requested_frame, info.fps, info.sample_rate, info.channels), info.channels)); + auto image_frame = std::make_shared( + requested_frame, cached_image->width(), cached_image->height(), "#000000", + Frame::GetSamplesPerFrame(requested_frame, info.fps, info.sample_rate, info.channels), + info.channels); // Add Image data to frame image_frame->AddImage(cached_image); diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index d91d164e..bd157ebd 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -67,7 +67,7 @@ void QtTextReader::Open() if (!is_open) { // create image - image = std::shared_ptr(new QImage(width, height, QImage::Format_RGBA8888)); + image = std::make_shared(width, height, QImage::Format_RGBA8888); image->fill(QColor(background_color.c_str())); QPainter painter; @@ -179,7 +179,9 @@ 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)); + auto image_frame = std::make_shared( + requested_frame, image->size().width(), image->size().height(), + background_color, 0, 2); // Add Image data to frame image_frame->AddImage(image); @@ -188,7 +190,7 @@ std::shared_ptr QtTextReader::GetFrame(int64_t requested_frame) return image_frame; } else { // return empty frame - std::shared_ptr image_frame(new Frame(1, 640, 480, background_color, 0, 2)); + auto image_frame = std::make_shared(1, 640, 480, background_color, 0, 2); // return frame object return image_frame; diff --git a/src/TextReader.cpp b/src/TextReader.cpp index e317700c..be8c7375 100644 --- a/src/TextReader.cpp +++ b/src/TextReader.cpp @@ -66,7 +66,8 @@ void TextReader::Open() if (!is_open) { // create image - image = std::shared_ptr(new Magick::Image(Magick::Geometry(width,height), Magick::Color(background_color))); + image = std::make_shared( + Magick::Geometry(width,height), Magick::Color(background_color)); // Give image a transparent background color image->backgroundColor(Magick::Color("none")); @@ -166,10 +167,12 @@ std::shared_ptr TextReader::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(), "#000000", 0, 2)); + auto image_frame = std::make_shared( + requested_frame, image->size().width(), image->size().height(), + "#000000", 0, 2); // Add Image data to frame - std::shared_ptr copy_image(new Magick::Image(*image.get())); + auto copy_image = std::make_shared(*image.get()); copy_image->modifyImage(); // actually copy the image data to this object //TODO: Reimplement this with QImage image_frame->AddMagickImage(copy_image); @@ -178,7 +181,7 @@ std::shared_ptr TextReader::GetFrame(int64_t requested_frame) return image_frame; } else { // return empty frame - std::shared_ptr image_frame(new Frame(1, 640, 480, "#000000", 0, 2)); + auto image_frame = std::make_shared(1, 640, 480, "#000000", 0, 2); // return frame object return image_frame; diff --git a/src/effects/Bars.cpp b/src/effects/Bars.cpp index 3f9aac34..e653b7dd 100644 --- a/src/effects/Bars.cpp +++ b/src/effects/Bars.cpp @@ -68,7 +68,8 @@ std::shared_ptr Bars::GetFrame(std::shared_ptr frame, int64_t fram std::shared_ptr frame_image = frame->GetImage(); // Get bar color (and create small color image) - std::shared_ptr tempColor = std::shared_ptr(new QImage(frame_image->width(), 1, QImage::Format_RGBA8888)); + auto tempColor = std::make_shared( + frame_image->width(), 1, QImage::Format_RGBA8888); tempColor->fill(QColor(QString::fromStdString(color.GetColorHex(frame_number)))); // Get current keyframe values diff --git a/src/effects/Crop.cpp b/src/effects/Crop.cpp index b1c3d38d..f0e0aa95 100644 --- a/src/effects/Crop.cpp +++ b/src/effects/Crop.cpp @@ -68,7 +68,8 @@ std::shared_ptr Crop::GetFrame(std::shared_ptr frame, int64_t fram std::shared_ptr frame_image = frame->GetImage(); // Get transparent color (and create small transparent image) - std::shared_ptr tempColor = std::shared_ptr(new QImage(frame_image->width(), 1, QImage::Format_RGBA8888)); + auto tempColor = std::make_shared( + frame_image->width(), 1, QImage::Format_RGBA8888); tempColor->fill(QColor(QString::fromStdString("transparent"))); // Get current keyframe values diff --git a/src/effects/Deinterlace.cpp b/src/effects/Deinterlace.cpp index 39b3316a..984336aa 100644 --- a/src/effects/Deinterlace.cpp +++ b/src/effects/Deinterlace.cpp @@ -86,7 +86,9 @@ std::shared_ptr Deinterlace::GetFrame(std::shared_ptr frame, int64 } // Resize deinterlaced image back to original size, and update frame's image - image = std::shared_ptr(new QImage(deinterlaced_image.scaled(original_width, original_height, Qt::IgnoreAspectRatio, Qt::FastTransformation))); + image = std::make_shared(deinterlaced_image.scaled( + original_width, original_height, + Qt::IgnoreAspectRatio, Qt::FastTransformation)); // Update image on frame frame->AddImage(image); diff --git a/src/effects/Mask.cpp b/src/effects/Mask.cpp index 11c37f05..f270e410 100644 --- a/src/effects/Mask.cpp +++ b/src/effects/Mask.cpp @@ -84,13 +84,14 @@ std::shared_ptr Mask::GetFrame(std::shared_ptr frame, int64_t fram (original_mask && original_mask->size() != frame_image->size())) { // Only get mask if needed - std::shared_ptr mask_without_sizing = std::shared_ptr( - new QImage(*reader->GetFrame(frame_number)->GetImage())); + auto mask_without_sizing = std::make_shared( + *reader->GetFrame(frame_number)->GetImage()); // Resize mask image to match frame size - original_mask = std::shared_ptr(new QImage( - mask_without_sizing->scaled(frame_image->width(), frame_image->height(), Qt::IgnoreAspectRatio, - Qt::SmoothTransformation))); + original_mask = std::make_shared( + mask_without_sizing->scaled( + frame_image->width(), frame_image->height(), + Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } } From c14922d57ea8226b2876a822dab9911ae2f1fbf9 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 20 Aug 2020 20:40:55 -0400 Subject: [PATCH 097/148] Frame.cpp/h: Fix a bunch of wrong comments Best reason not to narrate the code in the comments: The code gets changed, but the documentation doesn't. --- include/Frame.h | 12 ++++++------ src/Frame.cpp | 22 +++++++--------------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/include/Frame.h b/include/Frame.h index 7e7866c0..8987dcb4 100644 --- a/include/Frame.h +++ b/include/Frame.h @@ -73,17 +73,17 @@ namespace openshot * There are many ways to create an instance of an openshot::Frame: * @code * - * // Most basic: a blank frame (300x200 blank image, 48kHz audio silence) + * // Most basic: a blank frame (all default values) * Frame(); * - * // Image only settings (48kHz audio silence) + * // Image only settings * Frame(1, // Frame number * 720, // Width of image * 480, // Height of image * "#000000" // HTML color code of background color * ); * - * // Audio only (300x200 blank image) + * // Audio only * Frame(number, // Frame number * 44100, // Sample rate of audio stream * 2 // Number of audio channels @@ -131,13 +131,13 @@ namespace openshot bool has_image_data; ///< This frame has been loaded with pixel data - /// Constructor - blank frame (300x200 blank image, 48kHz audio silence) + /// Constructor - blank frame Frame(); - /// Constructor - image only (48kHz audio silence) + /// Constructor - image only Frame(int64_t number, int width, int height, std::string color); - /// Constructor - audio only (300x200 blank image) + /// Constructor - audio only Frame(int64_t number, int samples, int channels); /// Constructor - image & audio diff --git a/src/Frame.cpp b/src/Frame.cpp index 16f420bc..54901cc5 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -33,41 +33,35 @@ using namespace std; using namespace openshot; -// Constructor - blank frame (300x200 blank image, 48kHz audio silence) +// Constructor - blank frame Frame::Frame() : number(1), pixel_ratio(1,1), channels(2), width(1), height(1), color("#000000"), channel_layout(LAYOUT_STEREO), sample_rate(44100), qbuffer(NULL), has_audio_data(false), has_image_data(false), max_audio_sample(0) { - // Init the image magic and audio buffer + // Allocate and zero (fill with silence) the audio buffer audio = std::make_shared(channels, 0); - - // initialize the audio samples to zero (silence) audio->clear(); } -// Constructor - image only (48kHz audio silence) +// Constructor - image only Frame::Frame(int64_t number, int width, int height, std::string color) : number(number), pixel_ratio(1,1), channels(2), width(width), height(height), color(color), channel_layout(LAYOUT_STEREO), sample_rate(44100), qbuffer(NULL), has_audio_data(false), has_image_data(false), max_audio_sample(0) { - // Init the image magic and audio buffer + // Allocate and zero (fill with silence) the audio buffer audio = std::make_shared(channels, 0); - - // initialize the audio samples to zero (silence) audio->clear(); } -// Constructor - audio only (300x200 blank image) +// Constructor - audio only Frame::Frame(int64_t number, int samples, int channels) : number(number), pixel_ratio(1,1), channels(channels), width(1), height(1), color("#000000"), channel_layout(LAYOUT_STEREO), sample_rate(44100), qbuffer(NULL), has_audio_data(false), has_image_data(false), max_audio_sample(0) { - // Init the image magic and audio buffer + // Allocate and zero (fill with silence) the audio buffer audio = std::make_shared(channels, samples); - - // initialize the audio samples to zero (silence) audio->clear(); } @@ -77,10 +71,8 @@ Frame::Frame(int64_t number, int width, int height, std::string color, int sampl channel_layout(LAYOUT_STEREO), sample_rate(44100), qbuffer(NULL), has_audio_data(false), has_image_data(false), max_audio_sample(0) { - // Init the image magic and audio buffer + // Allocate and zero (fill with silence) the audio buffer audio = std::make_shared(channels, samples); - - // initialize the audio samples to zero (silence) audio->clear(); } From f71051e8f1add0b893ffaa9a799625017978e7f8 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Thu, 20 Aug 2020 21:13:42 -0400 Subject: [PATCH 098/148] Tests: Don't enable HW accel as side-effect (#557) The Settings test attempts to test the class by changing settings variables and reading them back again. Problem is, that affects the REST of the unit tests. So instead of enabling HW accel and causing crashes, we'll diddle something innocuous, like OMP_THREADS. --- tests/Settings_Tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Settings_Tests.cpp b/tests/Settings_Tests.cpp index b63b56a8..65bd66a6 100644 --- a/tests/Settings_Tests.cpp +++ b/tests/Settings_Tests.cpp @@ -41,7 +41,7 @@ TEST(Settings_Default_Constructor) // Create an empty color Settings *s = Settings::Instance(); - CHECK_EQUAL(0, s->HARDWARE_DECODER); + CHECK_EQUAL(12, s->OMP_THREADS); CHECK_EQUAL(false, s->HIGH_QUALITY_SCALING); CHECK_EQUAL(false, s->WAIT_FOR_VIDEO_PROCESSING_TASK); } @@ -50,15 +50,15 @@ TEST(Settings_Change_Settings) { // Create an empty color Settings *s = Settings::Instance(); - s->HARDWARE_DECODER = 1; + s->OMP_THREADS = 8; s->HIGH_QUALITY_SCALING = true; s->WAIT_FOR_VIDEO_PROCESSING_TASK = true; - CHECK_EQUAL(1, s->HARDWARE_DECODER); + CHECK_EQUAL(8, s->OMP_THREADS); CHECK_EQUAL(true, s->HIGH_QUALITY_SCALING); CHECK_EQUAL(true, s->WAIT_FOR_VIDEO_PROCESSING_TASK); - CHECK_EQUAL(1, s->HARDWARE_DECODER); + CHECK_EQUAL(8, Settings::Instance()->OMP_THREADS); CHECK_EQUAL(true, Settings::Instance()->HIGH_QUALITY_SCALING); CHECK_EQUAL(true, Settings::Instance()->WAIT_FOR_VIDEO_PROCESSING_TASK); } From 006fb8ef4b8c1335b99a46961b0b9a588c824923 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 27 Aug 2020 12:55:59 -0400 Subject: [PATCH 099/148] Use MacOS 10.11 SDK (still targeting 10.9) --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fd6f1e2b..06c0c6ab 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ mac-builder: - unzip artifacts.zip - export LIBOPENSHOT_AUDIO_DIR=$CI_PROJECT_DIR/build/install-x64 - mkdir -p build; cd build; - - cmake -DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++" -DCMAKE_SHARED_LINKER_FLAGS="-stdlib=libc++" -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_PREFIX_PATH=/usr/local/qt5.15.X/qt5.15/5.15.0/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ + - cmake -DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++" -DCMAKE_SHARED_LINKER_FLAGS="-stdlib=libc++" -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_PREFIX_PATH=/usr/local/qt5.15.X/qt5.15/5.15.0/clang_64/ -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPYTHON_MODULE_PATH=python -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../ - make - make install - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" From bd90b8d6c9524c143e57908329d3e7c8c7903907 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 1 Sep 2020 22:51:52 -0400 Subject: [PATCH 100/148] ReaderBase: Deprecate SetClip/GetClip names - Replacement method names are SetParentClip/GetParentClip - Old names are retained as deprecated alternates, for now - libopenshot internal calls (very few) are updated ReaderBase.cpp: Remove (Set,Get)Clip --- include/ReaderBase.h | 10 ++++++++-- src/Clip.cpp | 8 ++++---- src/FFmpegReader.cpp | 2 +- src/QtImageReader.cpp | 2 +- src/ReaderBase.cpp | 10 ---------- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/include/ReaderBase.h b/include/ReaderBase.h index ab765753..c997b76d 100644 --- a/include/ReaderBase.h +++ b/include/ReaderBase.h @@ -111,10 +111,16 @@ namespace openshot openshot::ReaderInfo info; /// Parent clip object of this reader (which can be unparented and NULL) - openshot::ClipBase* GetClip(); + inline openshot::ClipBase* GetParentClip() { return parent; }; + + /// Deprecated alias for GetParentClip() + inline openshot::ClipBase* GetClip() { return parent; }; /// Set parent clip object of this reader - void SetClip(openshot::ClipBase* clip); + inline void SetParentClip(openshot::ClipBase* clip) { parent = clip; }; + + /// Deprecated alias for SetParentClip() + inline void SetClip(openshot::ClipBase* clip) { parent = clip; }; /// Close the reader (and any resources it was consuming) virtual void Close() = 0; diff --git a/src/Clip.cpp b/src/Clip.cpp index d9f69440..4422211c 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -153,7 +153,7 @@ Clip::Clip(ReaderBase* new_reader) : resampler(NULL), reader(new_reader), alloca // Update duration and set parent if (reader) { End(reader->info.duration); - reader->SetClip(this); + reader->SetParentClip(this); } } @@ -210,7 +210,7 @@ Clip::Clip(std::string path) : resampler(NULL), reader(NULL), allocated_reader(N // Update duration and set parent if (reader) { End(reader->info.duration); - reader->SetClip(this); + reader->SetParentClip(this); allocated_reader = reader; init_reader_rotation(); } @@ -239,7 +239,7 @@ void Clip::Reader(ReaderBase* new_reader) reader = new_reader; // set parent - reader->SetClip(this); + reader->SetParentClip(this); // Init rotation (if any) init_reader_rotation(); @@ -993,7 +993,7 @@ void Clip::SetJsonValue(const Json::Value root) { // mark as managed reader and set parent if (reader) { - reader->SetClip(this); + reader->SetParentClip(this); allocated_reader = reader; } diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c8ce141f..01f83b39 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -1293,7 +1293,7 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame) { if (max_height <= 0) max_height = info.height; - Clip *parent = (Clip *) GetClip(); + Clip *parent = (Clip *) GetParentClip(); if (parent) { if (parent->scale == SCALE_FIT || parent->scale == SCALE_STRETCH) { // Best fit or Stretch scaling (based on max timeline size * scaling keyframes) diff --git a/src/QtImageReader.cpp b/src/QtImageReader.cpp index cf64ef93..59060ccd 100644 --- a/src/QtImageReader.cpp +++ b/src/QtImageReader.cpp @@ -187,7 +187,7 @@ std::shared_ptr QtImageReader::GetFrame(int64_t requested_frame) if (max_height <= 0) max_height = info.height; - Clip* parent = (Clip*) GetClip(); + Clip* parent = (Clip*) GetParentClip(); if (parent) { if (parent->scale == SCALE_FIT || parent->scale == SCALE_STRETCH) { // Best fit or Stretch scaling (based on max timeline size * scaling keyframes) diff --git a/src/ReaderBase.cpp b/src/ReaderBase.cpp index 474dc624..6799d95e 100644 --- a/src/ReaderBase.cpp +++ b/src/ReaderBase.cpp @@ -249,13 +249,3 @@ void ReaderBase::SetJsonValue(const Json::Value root) { } } } - -/// Parent clip object of this reader (which can be unparented and NULL) -openshot::ClipBase* ReaderBase::GetClip() { - return parent; -} - -/// Set parent clip object of this reader -void ReaderBase::SetClip(openshot::ClipBase* clip) { - parent = clip; -} From 466f8713aa19c2b18604ccc28f0b2890f61f70d0 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 1 Sep 2020 22:50:32 -0400 Subject: [PATCH 101/148] Timeline.h: Add lots of openshot:: prefixes --- include/Timeline.h | 65 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/include/Timeline.h b/include/Timeline.h index 932b04ac..98a11f3b 100644 --- a/include/Timeline.h +++ b/include/Timeline.h @@ -61,7 +61,7 @@ namespace openshot { /// from lowest layer to top layer (since that is the sequence they need to be combined), and then /// by position (left to right). struct CompareClips{ - bool operator()( Clip* lhs, Clip* rhs){ + bool operator()( openshot::Clip* lhs, openshot::Clip* rhs){ if( lhs->Layer() < rhs->Layer() ) return true; if( lhs->Layer() == rhs->Layer() && lhs->Position() <= rhs->Position() ) return true; return false; @@ -71,7 +71,7 @@ namespace openshot { /// from lowest layer to top layer (since that is sequence clips are combined), and then by /// position, and then by effect order. struct CompareEffects{ - bool operator()( EffectBase* lhs, EffectBase* rhs){ + bool operator()( openshot::EffectBase* lhs, openshot::EffectBase* rhs){ if( lhs->Layer() < rhs->Layer() ) return true; if( lhs->Layer() == rhs->Layer() && lhs->Position() < rhs->Position() ) return true; if( lhs->Layer() == rhs->Layer() && lhs->Position() == rhs->Position() && lhs->Order() > rhs->Order() ) return true; @@ -146,33 +146,33 @@ namespace openshot { * t.Close(); * @endcode */ - class Timeline : public ReaderBase { + class Timeline : public openshot::ReaderBase { private: bool is_open; /// clips; /// closing_clips; /// open_clips; /// effects; /// allocated_frame_mappers; ///< all the frame mappers we allocated and must free + std::list clips; /// closing_clips; /// open_clips; /// effects; /// allocated_frame_mappers; ///< all the frame mappers we allocated and must free bool managed_cache; ///< Does this timeline instance manage the cache object std::string path; ///< Optional path of loaded UTF-8 OpenShot JSON project file /// Process a new layer of video or audio - void add_layer(std::shared_ptr new_frame, Clip* source_clip, int64_t clip_frame_number, int64_t timeline_frame_number, bool is_top_clip, float max_volume); + void add_layer(std::shared_ptr new_frame, openshot::Clip* source_clip, int64_t clip_frame_number, int64_t timeline_frame_number, bool is_top_clip, float max_volume); /// Apply a FrameMapper to a clip which matches the settings of this timeline - void apply_mapper_to_clip(Clip* clip); + void apply_mapper_to_clip(openshot::Clip* clip); /// Apply JSON Diffs to various objects contained in this timeline void apply_json_to_clips(Json::Value change); /// find_intersecting_clips(int64_t requested_frame, int number_of_frames, bool include); + std::vector find_intersecting_clips(int64_t requested_frame, int number_of_frames, bool include); /// Get or generate a blank frame - std::shared_ptr GetOrCreateFrame(Clip* clip, int64_t number); + std::shared_ptr GetOrCreateFrame(openshot::Clip* clip, int64_t number); /// Apply effects to the source frame (if any) - std::shared_ptr apply_effects(std::shared_ptr frame, int64_t timeline_frame_number, int layer); + std::shared_ptr apply_effects(std::shared_ptr frame, int64_t timeline_frame_number, int layer); /// Compare 2 floating point numbers for equality bool isEqual(double a, double b); @@ -198,7 +198,7 @@ namespace openshot { void sort_effects(); /// Update the list of 'opened' clips - void update_open_clips(Clip *clip, bool does_clip_intersect); + void update_open_clips(openshot::Clip *clip, bool does_clip_intersect); public: @@ -209,7 +209,7 @@ namespace openshot { /// @param sample_rate The sample rate of the timeline's audio /// @param channels The number of audio channels of the timeline /// @param channel_layout The channel layout (i.e. mono, stereo, 3 point surround, etc...) - Timeline(int width, int height, Fraction fps, int sample_rate, int channels, ChannelLayout channel_layout); + Timeline(int width, int height, openshot::Fraction fps, int sample_rate, int channels, openshot::ChannelLayout channel_layout); /// @brief Constructor for the timeline (which loads a JSON structure from a file path, and initializes a timeline) /// @param projectPath The path of the UTF-8 *.osp project file (JSON contents). Contents will be loaded automatically. @@ -220,11 +220,11 @@ namespace openshot { /// @brief Add an openshot::Clip to the timeline /// @param clip Add an openshot::Clip to the timeline. A clip can contain any type of Reader. - void AddClip(Clip* clip); + void AddClip(openshot::Clip* clip); /// @brief Add an effect to the timeline /// @param effect Add an effect to the timeline. An effect can modify the audio or video of an openshot::Frame. - void AddEffect(EffectBase* effect); + void AddEffect(openshot::EffectBase* effect); /// Apply the timeline's framerate and samplerate to all clips void ApplyMapperToClips(); @@ -239,34 +239,34 @@ namespace openshot { void ClearAllCache(); /// Return a list of clips on the timeline - std::list Clips() { return clips; }; + std::list Clips() { return clips; }; /// Close the timeline reader (and any resources it was consuming) void Close() override; /// Return the list of effects on the timeline - std::list Effects() { return effects; }; + std::list Effects() { return effects; }; /// Get the cache object used by this reader - CacheBase* GetCache() override { return final_cache; }; + openshot::CacheBase* GetCache() override { return final_cache; }; /// Set the cache object used by this reader. You must now manage the lifecycle /// of this cache object though (Timeline will not delete it for you). - void SetCache(CacheBase* new_cache); + void SetCache(openshot::CacheBase* new_cache); /// Get an openshot::Frame object for a specific frame number of this timeline. /// /// @returns The requested frame (containing the image) /// @param requested_frame The frame number that is requested. - std::shared_ptr GetFrame(int64_t requested_frame) override; + std::shared_ptr GetFrame(int64_t requested_frame) override; // Curves for the viewport - Keyframe viewport_scale; /// Date: Tue, 1 Sep 2020 22:53:46 -0400 Subject: [PATCH 102/148] Clip: GetEffect implementation --- include/Clip.h | 9 +++++---- src/Clip.cpp | 12 ++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/Clip.h b/include/Clip.h index 0fbed159..0c98526a 100644 --- a/include/Clip.h +++ b/include/Clip.h @@ -169,6 +169,9 @@ namespace openshot { /// Return the list of effects on the timeline std::list Effects() { return effects; }; + /// Look up an effect by ID + openshot::EffectBase* GetEffect(const std::string& id); + /// @brief Get an openshot::Frame object for a specific frame number of this timeline. /// /// @returns The requested frame (containing the image) @@ -253,8 +256,6 @@ namespace openshot { openshot::Keyframe has_audio; ///< An optional override to determine if this clip has audio (-1=undefined, 0=no, 1=yes) openshot::Keyframe has_video; ///< An optional override to determine if this clip has video (-1=undefined, 0=no, 1=yes) }; +} // namespace - -} - -#endif +#endif // OPENSHOT_CLIP_H diff --git a/src/Clip.cpp b/src/Clip.cpp index 4422211c..bb704acc 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -368,6 +368,18 @@ std::shared_ptr Clip::GetFrame(int64_t requested_frame) throw ReaderClosed("No Reader has been initialized for this Clip. Call Reader(*reader) before calling this method."); } +// Look up an effect by ID +openshot::EffectBase* Clip::GetEffect(const std::string& id) +{ + // Find the matching effect (if any) + for (const auto& effect : effects) { + if (effect->Id() == id) { + return effect; + } + } + return nullptr; +} + // Get file extension std::string Clip::get_file_extension(std::string path) { From f49a795749fe27e9c1db79bbd12c7172ca21b2d1 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 1 Sep 2020 22:56:33 -0400 Subject: [PATCH 103/148] Timeline: Add id-lookup API and GetMaxFrame --- include/Timeline.h | 27 +++++++++++++++++++++++ src/Timeline.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/include/Timeline.h b/include/Timeline.h index 98a11f3b..900f05b7 100644 --- a/include/Timeline.h +++ b/include/Timeline.h @@ -78,6 +78,21 @@ namespace openshot { return false; }}; + /// Comparison method for finding the far end of the timeline, by locating + /// the Clip with the highest end-frame number using std::max_element + struct CompareClipEndFrames { + bool operator()(const openshot::Clip* lhs, const openshot::Clip* rhs) { + return (lhs->Position() + lhs->Duration()) + <= (rhs->Position() + rhs->Duration()); + }}; + + /// Like CompareClipEndFrames, but for effects + struct CompareEffectEndFrames { + bool operator()(const openshot::EffectBase* lhs, const openshot::EffectBase* rhs) { + return (lhs->Position() + lhs->Duration()) + <= (rhs->Position() + rhs->Duration()); + }}; + /** * @brief This class represents a timeline * @@ -241,6 +256,18 @@ namespace openshot { /// Return a list of clips on the timeline std::list Clips() { return clips; }; + /// Look up a single clip by ID + openshot::ClipBase* GetClip(const std::string& id); + + /// Look up a clip effect by ID + openshot::EffectBase* GetClipEffect(const std::string& id); + + /// Look up a timeline effect by ID + openshot::EffectBase* GetEffect(const std::string& id); + + /// Look up the end frame number of the latest element on the timeline + int64_t GetMaxFrame(); + /// Close the timeline reader (and any resources it was consuming) void Close() override; diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 124058ac..993326f7 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -263,6 +263,59 @@ void Timeline::RemoveClip(Clip* clip) clips.remove(clip); } +// Look up a clip +openshot::ClipBase* Timeline::GetClip(const std::string& id) +{ + // Find the matching clip (if any) + for (const auto& clip : clips) { + if (clip->Id() == id) { + return clip; + } + } + return nullptr; +} + +// Look up a timeline effect +openshot::EffectBase* Timeline::GetEffect(const std::string& id) +{ + // Find the matching effect (if any) + for (const auto& effect : effects) { + if (effect->Id() == id) { + return effect; + } + } + return nullptr; +} + +openshot::EffectBase* Timeline::GetClipEffect(const std::string& id) +{ + // Search all clips for matching effect ID + for (const auto& clip : clips) { + auto e = clip->GetEffect(id); + if (e != nullptr) { + return e; + } + } + return nullptr; +} + +int64_t Timeline::GetMaxFrame() { + int64_t last_clip = 1; + int64_t last_effect = 1; + + if (!clips.empty()) { + const auto max_clip = std::max_element( + clips.begin(), clips.end(), CompareClipEndFrames()); + last_clip = (*max_clip)->Position() + (*max_clip)->Duration(); + } + if (!effects.empty()) { + const auto max_effect = std::max_element( + effects.begin(), effects.end(), CompareEffectEndFrames()); + last_effect = (*max_effect)->Position() + (*max_effect)->Duration(); + } + return std::max(last_clip, last_effect); +} + // Apply a FrameMapper to a clip which matches the settings of this timeline void Timeline::apply_mapper_to_clip(Clip* clip) { From 41af336d11a8827965624c19c272e4bb6610aa62 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Wed, 2 Sep 2020 01:03:06 -0400 Subject: [PATCH 104/148] Add GetMaxTime --- include/Timeline.h | 2 ++ src/Timeline.cpp | 14 +++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/Timeline.h b/include/Timeline.h index 900f05b7..a7111380 100644 --- a/include/Timeline.h +++ b/include/Timeline.h @@ -265,6 +265,8 @@ namespace openshot { /// Look up a timeline effect by ID openshot::EffectBase* GetEffect(const std::string& id); + /// Look up the end time of the latest timeline element + double GetMaxTime(); /// Look up the end frame number of the latest element on the timeline int64_t GetMaxFrame(); diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 993326f7..58ccb5ad 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -299,9 +299,10 @@ openshot::EffectBase* Timeline::GetClipEffect(const std::string& id) return nullptr; } -int64_t Timeline::GetMaxFrame() { - int64_t last_clip = 1; - int64_t last_effect = 1; +// Compute the end time of the latest timeline element +double Timeline::GetMaxTime() { + double last_clip = 0.0; + double last_effect = 0.0; if (!clips.empty()) { const auto max_clip = std::max_element( @@ -316,6 +317,13 @@ int64_t Timeline::GetMaxFrame() { return std::max(last_clip, last_effect); } +// Compute the highest frame# based on the latest time and FPS +int64_t Timeline::GetMaxFrame() { + double fps = info.fps.ToDouble(); + auto max_time = GetMaxTime(); + return std::round(max_time * fps) + 1; +} + // Apply a FrameMapper to a clip which matches the settings of this timeline void Timeline::apply_mapper_to_clip(Clip* clip) { From 6d1e22f5455f14612e980a7e67a99326860c3c10 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 1 Sep 2020 22:57:32 -0400 Subject: [PATCH 105/148] Timeline_Tests: Unit tests for new methods Add GetMaxTime tests --- tests/Timeline_Tests.cpp | 173 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 166 insertions(+), 7 deletions(-) diff --git a/tests/Timeline_Tests.cpp b/tests/Timeline_Tests.cpp index 946693a1..47683b79 100644 --- a/tests/Timeline_Tests.cpp +++ b/tests/Timeline_Tests.cpp @@ -36,7 +36,10 @@ using namespace std; using namespace openshot; -TEST(Timeline_Constructor) +SUITE(Timeline) +{ + +TEST(Constructor) { // Create a default fraction (should be 1/1) Fraction fps(30000,1000); @@ -54,7 +57,7 @@ TEST(Timeline_Constructor) CHECK_EQUAL(240, t2.info.height); } -TEST(Timeline_Width_and_Height_Functions) +TEST(Width_and_Height_Functions) { // Create a default fraction (should be 1/1) Fraction fps(30000,1000); @@ -79,7 +82,7 @@ TEST(Timeline_Width_and_Height_Functions) CHECK_EQUAL(400, t1.info.height); } -TEST(Timeline_Framerate) +TEST(Framerate) { // Create a default fraction (should be 1/1) Fraction fps(24,1); @@ -89,7 +92,7 @@ TEST(Timeline_Framerate) CHECK_CLOSE(24.0f, t1.info.fps.ToFloat(), 0.00001); } -TEST(Timeline_Check_Two_Track_Video) +TEST(Check_Two_Track_Video) { // Create a reader stringstream path; @@ -186,7 +189,7 @@ TEST(Timeline_Check_Two_Track_Video) t.Close(); } -TEST(Timeline_Clip_Order) +TEST(Clip_Order) { // Create a timeline Timeline t(640, 480, Fraction(30, 1), 44100, 2, LAYOUT_STEREO); @@ -281,7 +284,7 @@ TEST(Timeline_Clip_Order) } -TEST(Timeline_Effect_Order) +TEST(Effect_Order) { // Create a timeline Timeline t(640, 480, Fraction(30, 1), 44100, 2, LAYOUT_STEREO); @@ -413,7 +416,127 @@ TEST(Timeline_Effect_Order) t.Close(); } -TEST(Timeline_Effect_Blur) +TEST(GetClip_by_id) +{ + Timeline t(640, 480, Fraction(30, 1), 44100, 2, LAYOUT_STEREO); + + stringstream path1; + path1 << TEST_MEDIA_PATH << "interlaced.png"; + auto media_path1 = path1.str(); + + stringstream path2; + path2 << TEST_MEDIA_PATH << "front.png"; + auto media_path2 = path2.str(); + + Clip clip1(media_path1); + std::string clip1_id("CLIP00001"); + clip1.Id(clip1_id); + clip1.Layer(1); + + Clip clip2(media_path2); + std::string clip2_id("CLIP00002"); + clip2.Id(clip2_id); + clip2.Layer(2); + + t.AddClip(&clip1); + t.AddClip(&clip2); + + auto matched = t.GetClip(clip1_id); + CHECK_EQUAL(clip1_id, matched->Id()); + CHECK_EQUAL(1, matched->Layer()); + + auto matched2 = t.GetClip(clip2_id); + CHECK_EQUAL(clip2_id, matched2->Id()); + CHECK_EQUAL(false, matched2->Layer() < 2); + + auto matched3 = t.GetClip("BAD_ID"); + CHECK_EQUAL(true, matched3 == nullptr); +} + +TEST(GetClipEffect_by_id) +{ + Timeline t(640, 480, Fraction(30, 1), 44100, 2, LAYOUT_STEREO); + + stringstream path1; + path1 << TEST_MEDIA_PATH << "interlaced.png"; + auto media_path1 = path1.str(); + + // Create a clip, nothing special + Clip clip1(media_path1); + std::string clip1_id("CLIP00001"); + clip1.Id(clip1_id); + clip1.Layer(1); + + // Add a blur effect + Keyframe horizontal_radius(5.0); + Keyframe vertical_radius(5.0); + Keyframe sigma(3.0); + Keyframe iterations(3.0); + Blur blur1(horizontal_radius, vertical_radius, sigma, iterations); + std::string blur1_id("EFFECT00011"); + blur1.Id(blur1_id); + clip1.AddEffect(&blur1); + + // A second clip, different layer + Clip clip2(media_path1); + std::string clip2_id("CLIP00002"); + clip2.Id(clip2_id); + clip2.Layer(2); + + // Some effects for clip2 + Negate neg2; + std::string neg2_id("EFFECT00021"); + neg2.Id(neg2_id); + neg2.Layer(2); + clip2.AddEffect(&neg2); + Blur blur2(horizontal_radius, vertical_radius, sigma, iterations); + std::string blur2_id("EFFECT00022"); + blur2.Id(blur2_id); + blur2.Layer(2); + clip2.AddEffect(&blur2); + + t.AddClip(&clip1); + + // Check that we can look up clip1's effect + auto match1 = t.GetClipEffect("EFFECT00011"); + CHECK_EQUAL(blur1_id, match1->Id()); + + // clip2 hasn't been added yet, shouldn't be found + match1 = t.GetClipEffect(blur2_id); + CHECK_EQUAL(true, match1 == nullptr); + + t.AddClip(&clip2); + + // Check that blur2 can now be found via clip2 + match1 = t.GetClipEffect(blur2_id); + CHECK_EQUAL(blur2_id, match1->Id()); + CHECK_EQUAL(2, match1->Layer()); +} + +TEST(GetEffect_by_id) +{ + Timeline t(640, 480, Fraction(30, 1), 44100, 2, LAYOUT_STEREO); + + // Create a timeline effect + Keyframe horizontal_radius(5.0); + Keyframe vertical_radius(5.0); + Keyframe sigma(3.0); + Keyframe iterations(3.0); + Blur blur1(horizontal_radius, vertical_radius, sigma, iterations); + std::string blur1_id("EFFECT00011"); + blur1.Id(blur1_id); + blur1.Layer(1); + t.AddEffect(&blur1); + + auto match1 = t.GetEffect(blur1_id); + CHECK_EQUAL(blur1_id, match1->Id()); + CHECK_EQUAL(1, match1->Layer()); + + match1 = t.GetEffect("NOSUCHNAME"); + CHECK_EQUAL(true, match1 == nullptr); +} + +TEST(Effect_Blur) { // Create a timeline Timeline t(640, 480, Fraction(30, 1), 44100, 2, LAYOUT_STEREO); @@ -443,3 +566,39 @@ TEST(Timeline_Effect_Blur) // Close reader t.Close(); } + +TEST(GetMaxFrame_GetMaxTime) +{ + // Create a timeline + Timeline t(640, 480, Fraction(30, 1), 44100, 2, LAYOUT_STEREO); + + stringstream path1; + path1 << TEST_MEDIA_PATH << "interlaced.png"; + Clip clip1(path1.str()); + clip1.Layer(1); + clip1.Position(50); + clip1.End(45); + t.AddClip(&clip1); + + CHECK_CLOSE(95.0, t.GetMaxTime(), 0.001); + CHECK_EQUAL(95 * 30 + 1, t.GetMaxFrame()); + + Clip clip2(path1.str()); + clip2.Layer(2); + clip2.Position(0); + clip2.End(55); + t.AddClip(&clip2); + + CHECK_EQUAL(95 * 30 + 1, t.GetMaxFrame()); + CHECK_CLOSE(95.0, t.GetMaxTime(), 0.001); + + clip2.Position(100); + clip1.Position(80); + CHECK_EQUAL(155 * 30 + 1, t.GetMaxFrame()); + CHECK_CLOSE(155.0, t.GetMaxTime(), 0.001); + t.RemoveClip(&clip2); + CHECK_EQUAL(125 * 30 + 1, t.GetMaxFrame()); + CHECK_CLOSE(125.0, t.GetMaxTime(), 0.001); +} + +} // SUITE From e500cae9f5b9c535c2343ee27d46bf06a58dba96 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 2 Sep 2020 02:07:54 -0400 Subject: [PATCH 106/148] Replace sleep()/usleep() with std::chrono calls (#473) --- src/FFmpegReader.cpp | 7 +- src/Frame.cpp | 5 +- src/Qt/AudioPlaybackThread.cpp | 5 +- src/Qt/PlayerPrivate.cpp | 168 ++++++++++++++++++--------------- src/Qt/VideoCacheThread.cpp | 15 ++- src/ZmqLogger.cpp | 8 +- 6 files changed, 122 insertions(+), 86 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c8ce141f..dfd8eb8d 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -33,6 +33,9 @@ #include "../include/FFmpegReader.h" +#include // for std::this_thread::sleep_for +#include // for std::chrono::milliseconds + #define ENABLE_VAAPI 0 #if HAVE_HW_ACCEL @@ -925,7 +928,7 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame) { // Wait if too many frames are being processed while (processing_video_frames_size + processing_audio_frames_size >= minimum_packets) { - usleep(2500); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); const GenericScopedLock lock(processingCriticalSection); processing_video_frames_size = processing_video_frames.size(); processing_audio_frames_size = processing_audio_frames.size(); @@ -1716,7 +1719,7 @@ void FFmpegReader::Seek(int64_t requested_frame) { // Wait for any processing frames to complete while (processing_video_frames_size + processing_audio_frames_size > 0) { - usleep(2500); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); const GenericScopedLock lock(processingCriticalSection); processing_video_frames_size = processing_video_frames.size(); processing_audio_frames_size = processing_audio_frames.size(); diff --git a/src/Frame.cpp b/src/Frame.cpp index cf47556a..483df768 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -30,6 +30,9 @@ #include "../include/Frame.h" +#include // for std::this_thread::sleep_for +#include // for std::chrono::milliseconds + using namespace std; using namespace openshot; @@ -1028,7 +1031,7 @@ void Frame::Play() while (transport1.isPlaying()) { cout << "playing" << endl; - usleep(1000000); + std::this_thread::sleep_for(std::chrono::seconds(1)); } cout << "DONE!!!" << endl; diff --git a/src/Qt/AudioPlaybackThread.cpp b/src/Qt/AudioPlaybackThread.cpp index 44c837e7..2ee1009c 100644 --- a/src/Qt/AudioPlaybackThread.cpp +++ b/src/Qt/AudioPlaybackThread.cpp @@ -31,6 +31,9 @@ #include "../../include/Qt/AudioPlaybackThread.h" +#include // for std::this_thread::sleep_for +#include // for std::chrono::milliseconds + namespace openshot { @@ -194,7 +197,7 @@ namespace openshot transport.start(); while (!threadShouldExit() && transport.isPlaying() && is_playing) - usleep(2500); + std::this_thread::sleep_for(std::chrono::milliseconds(2)); // Stop audio and shutdown transport Stop(); diff --git a/src/Qt/PlayerPrivate.cpp b/src/Qt/PlayerPrivate.cpp index e7c881f8..db6f2ff1 100644 --- a/src/Qt/PlayerPrivate.cpp +++ b/src/Qt/PlayerPrivate.cpp @@ -31,6 +31,9 @@ #include "../../include/Qt/PlayerPrivate.h" +#include // for std::this_thread::sleep_for +#include // for std::chrono milliseconds, high_resolution_clock + namespace openshot { // Constructor @@ -54,109 +57,120 @@ namespace openshot // Start thread void PlayerPrivate::run() { - // bail if no reader set - if (!reader) - return; + // bail if no reader set + if (!reader) + return; - // Start the threads - if (reader->info.has_audio) - audioPlayback->startThread(8); - if (reader->info.has_video) { - videoCache->startThread(2); - videoPlayback->startThread(4); - } + // Start the threads + if (reader->info.has_audio) + audioPlayback->startThread(8); + if (reader->info.has_video) { + videoCache->startThread(2); + videoPlayback->startThread(4); + } - while (!threadShouldExit()) { + using std::chrono::duration_cast; - // Calculate the milliseconds a single frame should stay on the screen - double frame_time = (1000.0 / reader->info.fps.ToDouble()); + // Types for storing time durations in whole and fractional milliseconds + using ms = std::chrono::milliseconds; + using double_ms = std::chrono::duration; - // Get the start time (to track how long a frame takes to render) - const Time t1 = Time::getCurrentTime(); + // Calculate on-screen time for a single frame in milliseconds + const auto frame_duration = double_ms(1000.0 / reader->info.fps.ToDouble()); - // Get the current video frame (if it's different) - frame = getFrame(); + while (!threadShouldExit()) { + // Get the start time (to track how long a frame takes to render) + const auto time1 = std::chrono::high_resolution_clock::now(); - // Experimental Pausing Code (if frame has not changed) - if ((speed == 0 && video_position == last_video_position) || (video_position > reader->info.video_length)) { - speed = 0; - sleep(frame_time); - continue; - } + // Get the current video frame (if it's different) + frame = getFrame(); - // Set the video frame on the video thread and render frame - videoPlayback->frame = frame; - videoPlayback->render.signal(); + // Experimental Pausing Code (if frame has not changed) + if ((speed == 0 && video_position == last_video_position) + || (video_position > reader->info.video_length) + ) { + speed = 0; + std::this_thread::sleep_for(frame_duration); + continue; + } - // Keep track of the last displayed frame - last_video_position = video_position; + // Set the video frame on the video thread and render frame + videoPlayback->frame = frame; + videoPlayback->render.signal(); - // How many frames ahead or behind is the video thread? - int64_t video_frame_diff = 0; - if (reader->info.has_audio && reader->info.has_video) { - if (speed != 1) - // Set audio frame again (since we are not in normal speed, and not paused) - audioPlayback->Seek(video_position); + // Keep track of the last displayed frame + last_video_position = video_position; - // Only calculate this if a reader contains both an audio and video thread - audio_position = audioPlayback->getCurrentFramePosition(); - video_frame_diff = video_position - audio_position; - } + // How many frames ahead or behind is the video thread? + int64_t video_frame_diff = 0; + if (reader->info.has_audio && reader->info.has_video) { + if (speed != 1) + // Set audio frame again (since we are not in normal speed, and not paused) + audioPlayback->Seek(video_position); - // Get the end time (to track how long a frame takes to render) - const Time t2 = Time::getCurrentTime(); + // Only calculate this if a reader contains both an audio and video thread + audio_position = audioPlayback->getCurrentFramePosition(); + video_frame_diff = video_position - audio_position; + } - // Determine how many milliseconds it took to render the frame - int64_t render_time = t2.toMilliseconds() - t1.toMilliseconds(); + // Get the end time (to track how long a frame takes to render) + const auto time2 = std::chrono::high_resolution_clock::now(); - // Calculate the amount of time to sleep (by subtracting the render time) - int sleep_time = int(frame_time - render_time); + // Determine how many milliseconds it took to render the frame + const auto render_time = double_ms(time2 - time1); - // Debug - ZmqLogger::Instance()->AppendDebugMethod("PlayerPrivate::run (determine sleep)", "video_frame_diff", video_frame_diff, "video_position", video_position, "audio_position", audio_position, "speed", speed, "render_time", render_time, "sleep_time", sleep_time); + // Calculate the amount of time to sleep (by subtracting the render time) + auto sleep_time = duration_cast(frame_duration - render_time); - // Adjust drift (if more than a few frames off between audio and video) - if (video_frame_diff > 0 && reader->info.has_audio && reader->info.has_video) - // Since the audio and video threads are running independently, they will quickly get out of sync. - // To fix this, we calculate how far ahead or behind the video frame is, and adjust the amount of time - // the frame is displayed on the screen (i.e. the sleep time). If a frame is ahead of the audio, - // we sleep for longer. If a frame is behind the audio, we sleep less (or not at all), in order for - // the video to catch up. - sleep_time += (video_frame_diff * (1000.0 / reader->info.fps.ToDouble())); + // Debug + ZmqLogger::Instance()->AppendDebugMethod("PlayerPrivate::run (determine sleep)", "video_frame_diff", video_frame_diff, "video_position", video_position, "audio_position", audio_position, "speed", speed, "render_time(ms)", render_time.count(), "sleep_time(ms)", sleep_time.count()); + // Adjust drift (if more than a few frames off between audio and video) + if (video_frame_diff > 0 && reader->info.has_audio && reader->info.has_video) { + // Since the audio and video threads are running independently, + // they will quickly get out of sync. To fix this, we calculate + // how far ahead or behind the video frame is, and adjust the amount + // of time the frame is displayed on the screen (i.e. the sleep time). + // If a frame is ahead of the audio, we sleep for longer. + // If a frame is behind the audio, we sleep less (or not at all), + // in order for the video to catch up. + sleep_time += duration_cast(video_frame_diff * frame_duration); + } - else if (video_frame_diff < -10 && reader->info.has_audio && reader->info.has_video) { - // Skip frame(s) to catch up to the audio (if more than 10 frames behind) - video_position += abs(video_frame_diff) / 2; // Seek forward 1/2 the difference - sleep_time = 0; // Don't sleep now... immediately go to next position - } + else if (video_frame_diff < -10 && reader->info.has_audio && reader->info.has_video) { + // Skip frame(s) to catch up to the audio (if more than 10 frames behind) + video_position += std::fabs(video_frame_diff) / 2; // Seek forward 1/2 the difference + sleep_time = sleep_time.zero(); // Don't sleep now... immediately go to next position + } - // Sleep (leaving the video frame on the screen for the correct amount of time) - if (sleep_time > 0) usleep(sleep_time * 1000); + // Sleep (leaving the video frame on the screen for the correct amount of time) + if (sleep_time > sleep_time.zero()) { + std::this_thread::sleep_for(sleep_time); + } - } + } } // Get the next displayed frame (based on speed and direction) std::shared_ptr PlayerPrivate::getFrame() { - try { - // Get the next frame (based on speed) - if (video_position + speed >= 1 && video_position + speed <= reader->info.video_length) - video_position = video_position + speed; + try { + // Get the next frame (based on speed) + if (video_position + speed >= 1 && video_position + speed <= reader->info.video_length) + video_position = video_position + speed; - if (frame && frame->number == video_position && video_position == last_video_position) { - // return cached frame - return frame; - } - else - { - // Update cache on which frame was retrieved - videoCache->setCurrentFramePosition(video_position); + if (frame && frame->number == video_position && video_position == last_video_position) { + // return cached frame + return frame; + } + else + { + // Update cache on which frame was retrieved + videoCache->setCurrentFramePosition(video_position); - // return frame from reader - return reader->GetFrame(video_position); - } + // return frame from reader + return reader->GetFrame(video_position); + } } catch (const ReaderClosed & e) { // ... diff --git a/src/Qt/VideoCacheThread.cpp b/src/Qt/VideoCacheThread.cpp index 6cff46ba..4279e238 100644 --- a/src/Qt/VideoCacheThread.cpp +++ b/src/Qt/VideoCacheThread.cpp @@ -31,6 +31,9 @@ #include "../../include/Qt/VideoCacheThread.h" #include +#include // for std::this_thread::sleep_for +#include // for std::chrono::milliseconds + namespace openshot { // Constructor @@ -81,10 +84,14 @@ namespace openshot // Start the thread void VideoCacheThread::run() { - while (!threadShouldExit() && is_playing) { + // Types for storing time durations in whole and fractional milliseconds + using ms = std::chrono::milliseconds; + using double_ms = std::chrono::duration; - // Calculate sleep time for frame rate - double frame_time = (1000.0 / reader->info.fps.ToDouble()); + // Calculate on-screen time for a single frame in milliseconds + const auto frame_duration = double_ms(1000.0 / reader->info.fps.ToDouble()); + + while (!threadShouldExit() && is_playing) { // Cache frames before the other threads need them // Cache frames up to the max frames @@ -117,7 +124,7 @@ namespace openshot } // Sleep for 1 frame length - usleep(frame_time * 1000); + std::this_thread::sleep_for(frame_duration); } return; diff --git a/src/ZmqLogger.cpp b/src/ZmqLogger.cpp index 103de73d..b7299230 100644 --- a/src/ZmqLogger.cpp +++ b/src/ZmqLogger.cpp @@ -36,6 +36,12 @@ using namespace std; using namespace openshot; +#include +#include +#include +#include +#include // for std::this_thread::sleep_for +#include // for std::duration::microseconds // Global reference to logger @@ -108,7 +114,7 @@ void ZmqLogger::Connection(std::string new_connection) } // Sleeping to allow connection to wake up (0.25 seconds) - usleep(250000); + std::this_thread::sleep_for(std::chrono::milliseconds(250)); } void ZmqLogger::Log(std::string message) From 20c75ff227bb667f1cebae0e99509162e324c25d Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Thu, 10 Sep 2020 18:39:24 -0400 Subject: [PATCH 107/148] Const temporary variable --- src/Timeline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 58ccb5ad..b2f46519 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -291,7 +291,7 @@ openshot::EffectBase* Timeline::GetClipEffect(const std::string& id) { // Search all clips for matching effect ID for (const auto& clip : clips) { - auto e = clip->GetEffect(id); + const auto e = clip->GetEffect(id); if (e != nullptr) { return e; } From f33d5cb2614579c60ffbe47c148d4fc22a2a65f2 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Thu, 10 Sep 2020 18:40:32 -0400 Subject: [PATCH 108/148] Timeline.h: Formatting --- include/Timeline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Timeline.h b/include/Timeline.h index a7111380..5c275abb 100644 --- a/include/Timeline.h +++ b/include/Timeline.h @@ -83,7 +83,7 @@ namespace openshot { struct CompareClipEndFrames { bool operator()(const openshot::Clip* lhs, const openshot::Clip* rhs) { return (lhs->Position() + lhs->Duration()) - <= (rhs->Position() + rhs->Duration()); + <= (rhs->Position() + rhs->Duration()); }}; /// Like CompareClipEndFrames, but for effects From 6acc1c1d2a6497c02ee438b49f880beeb7debfb9 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Thu, 10 Sep 2020 19:48:16 -0400 Subject: [PATCH 109/148] README: Wrap to 80-col, copyright => 2020 --- README.md | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index cf69c1cf..6105915d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -OpenShot Video Library (libopenshot) is a free, open-source C++ library dedicated to -delivering high quality video editing, animation, and playback solutions to the -world. +OpenShot Video Library (libopenshot) is a free, open-source C++ library +dedicated to delivering high quality video editing, animation, and playback +solutions to the world. ## Build Status @@ -15,7 +15,8 @@ world. * Time Mapping (Curve-based Slow Down, Speed Up, Reverse) * Audio Mixing & Resampling (Curve-based) * Audio Plug-ins (VST & AU) -* Audio Drivers (ASIO, WASAPI, DirectSound, CoreAudio, iPhone Audio, ALSA, JACK, and Android) +* Audio Drivers (ASIO, WASAPI, DirectSound, CoreAudio, iPhone Audio, + ALSA, JACK, and Android) * Telecine and Inverse Telecine (Film to TV, TV to Film) * Frame Rate Conversions * Multi-Processor Support (Performance) @@ -27,8 +28,8 @@ world. ## Install -Detailed instructions for building libopenshot and libopenshot-audio for each OS. These instructions -are also available in the /docs/ source folder. +Detailed instructions for building libopenshot and libopenshot-audio for +each OS. These instructions are also available in the `/docs/` source folder. * [Linux](https://github.com/OpenShot/libopenshot/wiki/Linux-Build-Instructions) * [Mac](https://github.com/OpenShot/libopenshot/wiki/Mac-Build-Instructions) @@ -36,10 +37,12 @@ are also available in the /docs/ source folder. ## Hardware Acceleration -OpenShot now supports experimental hardware acceleration, both for encoding and -decoding videos. When enabled, this can either speed up those operations or slow -them down, depending on the power and features supported by your graphics card. -Please see [doc/HW-ACCELL.md](doc/HW-ACCEL.md) for more information. +OpenShot now supports experimental hardware acceleration, both for encoding +and decoding videos. When enabled, this can either speed up those operations +or slow them down, depending on the power and features supported by your +graphics card. + +Please see [`doc/HW-ACCEL.md`](doc/HW-ACCEL.md) for more information. ## Documentation @@ -51,10 +54,11 @@ make doc ## Developers -Are you interested in becoming more involved in the development of -OpenShot? Build exciting new features, fix bugs, make friends, and become a hero! -Please read the [step-by-step](https://github.com/OpenShot/openshot-qt/wiki/Become-a-Developer) -instructions for getting source code, configuring dependencies, and building OpenShot. +Are you interested in becoming more involved in the development of OpenShot? +Build exciting new features, fix bugs, make friends, and become a hero! +Please read the [step-by-step](https://github.com/OpenShot/openshot-qt/wiki/Become-a-Developer) +instructions for getting source code, configuring dependencies, and building +OpenShot. ## Report a bug @@ -72,7 +76,7 @@ https://github.com/OpenShot/libopenshot/issues ### License -Copyright (c) 2008-2019 OpenShot Studios, LLC. +Copyright (c) 2008-2020 OpenShot Studios, LLC. OpenShot Library (libopenshot) is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License From 650adf639de2d27a6763d8e0fd92934bd15a0279 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 11 Sep 2020 00:55:50 -0500 Subject: [PATCH 110/148] Fix the PTS offset logic error when first reading a file on FFmpegReader. Use the calculated 0 - PTS, unless it is too large (more than 1 second off from zero) --- src/FFmpegReader.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index dfd8eb8d..097bc8d7 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -1868,8 +1868,18 @@ void FFmpegReader::UpdatePTSOffset(bool is_video) { // VIDEO PACKET if (video_pts_offset == 99999) // Has the offset been set yet? { - // Find the difference between PTS and frame number (no more than 10 timebase units allowed) - video_pts_offset = 0 - std::max(GetVideoPTS(), (int64_t) info.video_timebase.ToInt() * 10); + // Find the difference between PTS and frame number + video_pts_offset = 0 - GetVideoPTS(); + + // Find the difference between PTS and frame number + // Also, determine if PTS is invalid (too far away from zero) + // We compare the PTS to the timebase value equal to 1 second (which means the PTS + // must be within the -1 second to +1 second of zero, otherwise we ignore it) + int64_t max_offset = info.video_timebase.Reciprocal().ToFloat(); + if (video_pts_offset < -max_offset || video_pts_offset > max_offset) { + // Ignore PTS, it seems invalid + video_pts_offset = 0; + } // debug output ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::UpdatePTSOffset (Video)", "video_pts_offset", video_pts_offset, "is_video", is_video); @@ -1878,8 +1888,16 @@ void FFmpegReader::UpdatePTSOffset(bool is_video) { // AUDIO PACKET if (audio_pts_offset == 99999) // Has the offset been set yet? { - // Find the difference between PTS and frame number (no more than 10 timebase units allowed) - audio_pts_offset = 0 - std::max(packet->pts, (int64_t) info.audio_timebase.ToInt() * 10); + // Find the difference between PTS and frame number + // Also, determine if PTS is invalid (too far away from zero) + // We compare the PTS to the timebase value equal to 1 second (which means the PTS + // must be within the -1 second to +1 second of zero, otherwise we ignore it) + audio_pts_offset = 0 - packet->pts; + int64_t max_offset = info.audio_timebase.Reciprocal().ToFloat(); + if (audio_pts_offset < -max_offset || audio_pts_offset > max_offset) { + // Ignore PTS, it seems invalid + audio_pts_offset = 0; + } // debug output ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::UpdatePTSOffset (Audio)", "audio_pts_offset", audio_pts_offset, "is_video", is_video); From 7dc9eb6927b0d4f72fbb908e703fdc7073ffbe42 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sat, 12 Sep 2020 17:05:33 -0500 Subject: [PATCH 111/148] Adding TODO for future improvements --- src/FFmpegReader.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 097bc8d7..c047ea51 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -1875,6 +1875,8 @@ void FFmpegReader::UpdatePTSOffset(bool is_video) { // Also, determine if PTS is invalid (too far away from zero) // We compare the PTS to the timebase value equal to 1 second (which means the PTS // must be within the -1 second to +1 second of zero, otherwise we ignore it) + // TODO: Please see https://github.com/OpenShot/libopenshot/pull/565#issuecomment-690985272 + // for ideas to improve this logic. int64_t max_offset = info.video_timebase.Reciprocal().ToFloat(); if (video_pts_offset < -max_offset || video_pts_offset > max_offset) { // Ignore PTS, it seems invalid @@ -1892,6 +1894,8 @@ void FFmpegReader::UpdatePTSOffset(bool is_video) { // Also, determine if PTS is invalid (too far away from zero) // We compare the PTS to the timebase value equal to 1 second (which means the PTS // must be within the -1 second to +1 second of zero, otherwise we ignore it) + // TODO: Please see https://github.com/OpenShot/libopenshot/pull/565#issuecomment-690985272 + // for ideas to improve this logic. audio_pts_offset = 0 - packet->pts; int64_t max_offset = info.audio_timebase.Reciprocal().ToFloat(); if (audio_pts_offset < -max_offset || audio_pts_offset > max_offset) { From 158c594973bdc65883db4ca0b00b36a706e25e76 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 13 Sep 2020 08:42:17 -0700 Subject: [PATCH 112/148] Change of name of library --- src/FFmpegWriter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 1fd19b43..b2aec5f1 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -539,7 +539,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va switch (c->codec_id) { case AV_CODEC_ID_AV1 : c->bit_rate = 0; - if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { + if (strstr(info.vcodec.c_str(), "svtav1") != NULL) { av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); } else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { @@ -1239,7 +1239,7 @@ AVStream *FFmpegWriter::add_video_stream() { info.video_bit_rate = calculated_quality; } // medium } - if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { + if (strstr(info.vcodec.c_str(), "svtav1") != NULL) { av_opt_set_int(c->priv_data, "preset", 6, 0); av_opt_set_int(c->priv_data, "forced-idr",1,0); } From 47fca0254043f7d3fbf9d9577bac4ba570b10e2c Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 13 Sep 2020 09:07:14 -0700 Subject: [PATCH 113/148] video_codec -> video_codec_ctx --- src/FFmpegWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 8b89de7f..5dd14200 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -339,7 +339,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va if (info.has_video && stream == VIDEO_STREAM && video_st) { st = video_st; // Get codec context - c = AV_GET_CODEC_PAR_CONTEXT(st, video_codec); + c = AV_GET_CODEC_PAR_CONTEXT(st, video_codec_ctx); // Was a codec / stream found? if (c) { if (info.interlaced_frame) { From 1c8aea94d0a86985934fb07e28dfdd4ecdf850ee Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 13 Sep 2020 16:28:31 -0400 Subject: [PATCH 114/148] Frame: Put Qt includes where they're used --- include/Frame.h | 12 ++---------- src/Frame.cpp | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/Frame.h b/include/Frame.h index 8987dcb4..b3416d38 100644 --- a/include/Frame.h +++ b/include/Frame.h @@ -34,16 +34,8 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include #include #include "ZmqLogger.h" diff --git a/src/Frame.cpp b/src/Frame.cpp index 54901cc5..48af2a28 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -29,6 +29,21 @@ */ #include "../include/Frame.h" +#include "JuceHeader.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace std; using namespace openshot; From 9c83429ab1042a992511a30ede220214c593c31b Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 13 Sep 2020 16:33:36 -0400 Subject: [PATCH 115/148] Frame: Use delegating constructors --- src/Frame.cpp | 54 +++++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/src/Frame.cpp b/src/Frame.cpp index 48af2a28..67371655 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -48,49 +48,31 @@ using namespace std; using namespace openshot; -// Constructor - blank frame -Frame::Frame() : number(1), pixel_ratio(1,1), channels(2), width(1), height(1), color("#000000"), - channel_layout(LAYOUT_STEREO), sample_rate(44100), qbuffer(NULL), has_audio_data(false), has_image_data(false), - max_audio_sample(0) -{ - // Allocate and zero (fill with silence) the audio buffer - audio = std::make_shared(channels, 0); - audio->clear(); -} - -// Constructor - image only -Frame::Frame(int64_t number, int width, int height, std::string color) - : number(number), pixel_ratio(1,1), channels(2), width(width), height(height), color(color), - channel_layout(LAYOUT_STEREO), sample_rate(44100), qbuffer(NULL), has_audio_data(false), has_image_data(false), - max_audio_sample(0) -{ - // Allocate and zero (fill with silence) the audio buffer - audio = std::make_shared(channels, 0); - audio->clear(); -} - -// Constructor - audio only -Frame::Frame(int64_t number, int samples, int channels) : - number(number), pixel_ratio(1,1), channels(channels), width(1), height(1), color("#000000"), - channel_layout(LAYOUT_STEREO), sample_rate(44100), qbuffer(NULL), has_audio_data(false), has_image_data(false), - max_audio_sample(0) -{ - // Allocate and zero (fill with silence) the audio buffer - audio = std::make_shared(channels, samples); - audio->clear(); -} - // Constructor - image & audio Frame::Frame(int64_t number, int width, int height, std::string color, int samples, int channels) - : number(number), pixel_ratio(1,1), channels(channels), width(width), height(height), color(color), - channel_layout(LAYOUT_STEREO), sample_rate(44100), qbuffer(NULL), has_audio_data(false), has_image_data(false), + : audio(std::make_shared(channels, samples)), + number(number), width(width), height(height), + pixel_ratio(1,1), color(color), qbuffer(NULL), + channels(channels), channel_layout(LAYOUT_STEREO), + sample_rate(44100), + has_audio_data(false), has_image_data(false), max_audio_sample(0) { - // Allocate and zero (fill with silence) the audio buffer - audio = std::make_shared(channels, samples); + // zero (fill with silence) the audio buffer audio->clear(); } +// Delegating Constructor - blank frame +Frame::Frame() : Frame::Frame(1, 1, 1, "#000000", 0, 2) {}; + +// Delegating Constructor - image only +Frame::Frame(int64_t number, int width, int height, std::string color) + : Frame::Frame(number, width, height, color, 0, 2) {}; + +// Delegating Constructor - audio only +Frame::Frame(int64_t number, int samples, int channels) + : Frame::Frame(number, 1, 1, "#000000", samples, channels) {}; + // Copy constructor Frame::Frame ( const Frame &other ) From 0974637a3a71a1acd115bac33634ea6d646c7472 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 13 Sep 2020 16:33:16 -0400 Subject: [PATCH 116/148] Pixelate: Fix missing includes --- include/effects/Pixelate.h | 1 - src/effects/Pixelate.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/effects/Pixelate.h b/include/effects/Pixelate.h index 4cdd440f..793f4d46 100644 --- a/include/effects/Pixelate.h +++ b/include/effects/Pixelate.h @@ -36,7 +36,6 @@ #include #include #include -#include "../Color.h" #include "../Json.h" #include "../KeyFrame.h" diff --git a/src/effects/Pixelate.cpp b/src/effects/Pixelate.cpp index c993915c..41d97c5c 100644 --- a/src/effects/Pixelate.cpp +++ b/src/effects/Pixelate.cpp @@ -29,6 +29,12 @@ */ #include "../../include/effects/Pixelate.h" +#include "Json.h" + +#include +#include +#include +#include using namespace openshot; From 92d33a1ebd5a7da249195db37afb7edb4a3abceb Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 13 Sep 2020 16:38:23 -0400 Subject: [PATCH 117/148] VideoRenderWidget: missing includes --- include/Qt/VideoRenderWidget.h | 6 ++++-- src/Qt/VideoRenderWidget.cpp | 8 +++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/Qt/VideoRenderWidget.h b/include/Qt/VideoRenderWidget.h index 07c61037..4d9ac17f 100644 --- a/include/Qt/VideoRenderWidget.h +++ b/include/Qt/VideoRenderWidget.h @@ -31,11 +31,13 @@ #ifndef OPENSHOT_VIDEO_RENDERER_WIDGET_H #define OPENSHOT_VIDEO_RENDERER_WIDGET_H -#include -#include #include "../Fraction.h" #include "VideoRenderer.h" +#include +#include +#include +#include class VideoRenderWidget : public QWidget { diff --git a/src/Qt/VideoRenderWidget.cpp b/src/Qt/VideoRenderWidget.cpp index 2bfe8fa2..4af1ac6a 100644 --- a/src/Qt/VideoRenderWidget.cpp +++ b/src/Qt/VideoRenderWidget.cpp @@ -29,7 +29,13 @@ */ #include "../../include/Qt/VideoRenderWidget.h" -#include +#include +#include +#include +#include +#include +#include + VideoRenderWidget::VideoRenderWidget(QWidget *parent) : QWidget(parent), renderer(new VideoRenderer(this)) From 0bcf1e49247977e2821e093573d9d64cf7585caf Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 13 Sep 2020 19:56:40 -0400 Subject: [PATCH 118/148] Frame: Reduce code duplication --- src/Frame.cpp | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/Frame.cpp b/src/Frame.cpp index 67371655..c3c50bcd 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -762,31 +762,31 @@ void Frame::AddColor(int new_width, int new_height, std::string new_color) } // Add (or replace) pixel data to the frame -void Frame::AddImage(int new_width, int new_height, int bytes_per_pixel, QImage::Format type, const unsigned char *pixels_) +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); - int buffer_size = new_width * new_height * bytes_per_pixel; - qbuffer = new unsigned char[buffer_size](); - - // Copy buffer data - memcpy((unsigned char*)qbuffer, pixels_, buffer_size); - - // Create new image object, and fill with pixel data - #pragma omp critical (AddImage) { - image = std::make_shared( - qbuffer, new_width, new_height, new_width * bytes_per_pixel, type, (QImageCleanupFunction) &openshot::Frame::cleanUpBuffer, (void*) qbuffer); + const GenericScopedLock lock(addingImageSection); + int buffer_size = new_width * new_height * bytes_per_pixel; + qbuffer = new unsigned char[buffer_size](); - // Always convert to RGBA8888 (if different) - if (image->format() != QImage::Format_RGBA8888) - *image = image->convertToFormat(QImage::Format_RGBA8888); + // Copy buffer data + memcpy((unsigned char*)qbuffer, pixels_, buffer_size); - // Update height and width - width = image->width(); - height = image->height(); - has_image_data = true; - } + } // Release addingImageSection lock + + // Create new image object from pixel data + auto new_image = std::make_shared( + qbuffer, + new_width, new_height, + new_width * bytes_per_pixel, + type, + (QImageCleanupFunction) &openshot::Frame::cleanUpBuffer, + (void*) qbuffer + ); + AddImage(new_image); } // Add (or replace) pixel data to the frame @@ -826,7 +826,6 @@ void Frame::AddImage(std::shared_ptr new_image, bool only_odd_lines) AddImage(new_image); } else { - // Ignore image of different sizes or formats bool ret=false; #pragma omp critical (AddImage) From 6537278c1c1acead097aa3ea8f51f9ae7c0c4573 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Mon, 14 Sep 2020 03:13:54 -0500 Subject: [PATCH 119/148] This padding is needed to not lose samples in the first frame of a resample. Apparently, we need enough padding, so we exceed the # of samples required for the first frame, and 20 was just too low for many frame rates / sample rates. --- src/FrameMapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FrameMapper.cpp b/src/FrameMapper.cpp index e1e5700c..4c561f8f 100644 --- a/src/FrameMapper.cpp +++ b/src/FrameMapper.cpp @@ -487,7 +487,7 @@ std::shared_ptr FrameMapper::GetFrame(int64_t requested_frame) // includes some additional input samples on first iteration, // and continues the offset to ensure that the sample rate // converter isn't input limited. - const int EXTRA_INPUT_SAMPLES = 20; + const int EXTRA_INPUT_SAMPLES = 100; // Extend end sample count by an additional EXTRA_INPUT_SAMPLES samples copy_samples.sample_end += EXTRA_INPUT_SAMPLES; From 965de9df5bdd1597858d533128b7091128ab9358 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 3 Oct 2020 20:23:42 -0400 Subject: [PATCH 120/148] Add ENABLE_MAGICK CMake option (default ON) --- CMakeLists.txt | 1 + src/CMakeLists.txt | 42 ++++++++++++++++---------------- tests/CMakeLists.txt | 57 ++++++++++++++++++++++---------------------- 3 files changed, 52 insertions(+), 48 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94b09879..77aede7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ option(ENABLE_IWYU "Enable 'Include What You Use' scanner (CMake 3.3+)" OFF) option(ENABLE_TESTS "Build unit tests (requires UnitTest++)" ON) option(ENABLE_DOCS "Build API documentation (requires Doxygen)" ON) option(APPIMAGE_BUILD "Build to install in an AppImage (Linux only)" OFF) +option(ENABLE_MAGICK "Use ImageMagick, if available" ON) # Legacy commandline override if (DISABLE_TESTS) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dec7c853..04121c22 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -65,29 +65,31 @@ endif() ################ IMAGE MAGICK ################## # Set the Quantum Depth that ImageMagick was built with (default to 16 bits) -IF (MAGICKCORE_QUANTUM_DEPTH) - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH} ) -ELSE (MAGICKCORE_QUANTUM_DEPTH) - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 ) -ENDIF (MAGICKCORE_QUANTUM_DEPTH) -IF (MAGICKCORE_HDRI_ENABLE) - add_definitions( -DMAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE} ) -ELSE (MAGICKCORE_HDRI_ENABLE) - add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 ) -ENDIF (MAGICKCORE_HDRI_ENABLE) +if(ENABLE_MAGICK) + IF (MAGICKCORE_QUANTUM_DEPTH) + add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH} ) + ELSE (MAGICKCORE_QUANTUM_DEPTH) + add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 ) + ENDIF (MAGICKCORE_QUANTUM_DEPTH) + IF (MAGICKCORE_HDRI_ENABLE) + add_definitions( -DMAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE} ) + ELSE (MAGICKCORE_HDRI_ENABLE) + add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 ) + ENDIF (MAGICKCORE_HDRI_ENABLE) -# Find the ImageMagick++ library -find_package(ImageMagick COMPONENTS Magick++ MagickWand MagickCore) -if (ImageMagick_FOUND) - # Include ImageMagick++ headers (needed for compile) - include_directories(${ImageMagick_INCLUDE_DIRS}) + # Find the ImageMagick++ library + find_package(ImageMagick COMPONENTS Magick++ MagickWand MagickCore) + if (ImageMagick_FOUND) + # Include ImageMagick++ headers (needed for compile) + include_directories(${ImageMagick_INCLUDE_DIRS}) - # define a global var (used in the C++) - add_definitions( -DUSE_IMAGEMAGICK=1 ) - list(APPEND CMAKE_SWIG_FLAGS "-DUSE_IMAGEMAGICK=1") + # define a global var (used in the C++) + add_definitions( -DUSE_IMAGEMAGICK=1 ) + list(APPEND CMAKE_SWIG_FLAGS "-DUSE_IMAGEMAGICK=1") - set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE) - mark_as_advanced(HAVE_IMAGEMAGICK) + set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE) + mark_as_advanced(HAVE_IMAGEMAGICK) + endif() endif() ################# LIBOPENSHOT-AUDIO ################### diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3d0dd2d4..78d4ae97 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -58,35 +58,36 @@ set_package_properties(UnitTest++ PROPERTIES PURPOSE "Unit testing framework") ################ IMAGE MAGICK ################## -# Set the Quantum Depth that ImageMagick was built with (default to 16 bits) -if(MAGICKCORE_QUANTUM_DEPTH) - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH} ) -else() - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 ) +if(ENABLE_MAGICK) + # Set the Quantum Depth that ImageMagick was built with (default to 16 bits) + if(MAGICKCORE_QUANTUM_DEPTH) + add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH} ) + else() + add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 ) + endif() + + if(MAGICKCORE_HDRI_ENABLE) + add_definitions( -DMAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE} ) + else() + add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 ) + endif() + + if(OPENSHOT_IMAGEMAGICK_COMPATIBILITY) + add_definitions( -DOPENSHOT_IMAGEMAGICK_COMPATIBILITY=${OPENSHOT_IMAGEMAGICK_COMPATIBILITY} ) + else() + add_definitions( -DOPENSHOT_IMAGEMAGICK_COMPATIBILITY=0 ) + endif() + + # Find the ImageMagick++ library + find_package(ImageMagick COMPONENTS Magick++ MagickWand MagickCore) + if(ImageMagick_FOUND) + # Include ImageMagick++ headers (needed for compile) + include_directories(${ImageMagick_INCLUDE_DIRS}) + + # define a global var (used in the C++) + add_definitions( -DUSE_IMAGEMAGICK=1 ) + endif() endif() - -if(MAGICKCORE_HDRI_ENABLE) - add_definitions( -DMAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE} ) -else() - add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 ) -endif() - -if(OPENSHOT_IMAGEMAGICK_COMPATIBILITY) - add_definitions( -DOPENSHOT_IMAGEMAGICK_COMPATIBILITY=${OPENSHOT_IMAGEMAGICK_COMPATIBILITY} ) -else() - add_definitions( -DOPENSHOT_IMAGEMAGICK_COMPATIBILITY=0 ) -endif() - -# Find the ImageMagick++ library -find_package(ImageMagick COMPONENTS Magick++ MagickWand MagickCore) -if(ImageMagick_FOUND) - # Include ImageMagick++ headers (needed for compile) - include_directories(${ImageMagick_INCLUDE_DIRS}) - - # define a global var (used in the C++) - add_definitions( -DUSE_IMAGEMAGICK=1 ) -endif() - ################# LIBOPENSHOT-AUDIO ################### # Find JUCE-based openshot Audio libraries find_package(OpenShotAudio 0.2.0 REQUIRED) From 172c3c0e0f1623297137c88bc23112805f0c0256 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 3 Oct 2020 20:24:13 -0400 Subject: [PATCH 121/148] CMake: Switch default build type to Release --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77aede7d..38abe4f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,9 +130,9 @@ add_feature_info("Coverage" ENABLE_COVERAGE "analyze test coverage and generate # -DDEBUG for debug builds. We'll do this for all OSes, even # though only MacOS requires it. set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") -# Make sure we've picked some build type, default to debug +# Make sure we've picked some build type, default to release if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") - set(CMAKE_BUILD_TYPE "Debug") + set(CMAKE_BUILD_TYPE "Release") endif() ############## PROCESS src/ DIRECTORIES ############## From 88677a9c3c03d903c82b69fd81365a5329a97960 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 16 Oct 2020 02:54:54 -0500 Subject: [PATCH 122/148] Update Saturation.cpp Removing alpha channel access (undefined) --- src/effects/Saturation.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/effects/Saturation.cpp b/src/effects/Saturation.cpp index 5ce958a5..25fc51bc 100644 --- a/src/effects/Saturation.cpp +++ b/src/effects/Saturation.cpp @@ -154,7 +154,6 @@ std::shared_ptr Saturation::GetFrame(std::shared_ptr frame, int64_ pixels[byte_index] = R; pixels[byte_index + 1] = G; pixels[byte_index + 2] = B; - pixels[byte_index + 3] = A; // leave the alpha value alone } // return the modified frame From a7fe41cc1a796036a85f4917a7e845285bc64c6c Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 16 Oct 2020 03:03:26 -0500 Subject: [PATCH 123/148] Update Saturation.cpp Fixing regression after conflict resolution --- src/effects/Saturation.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/effects/Saturation.cpp b/src/effects/Saturation.cpp index 25fc51bc..cad9c08d 100644 --- a/src/effects/Saturation.cpp +++ b/src/effects/Saturation.cpp @@ -151,9 +151,9 @@ std::shared_ptr Saturation::GetFrame(std::shared_ptr frame, int64_ B = constrain(B); // Set all pixels to new value - pixels[byte_index] = R; - pixels[byte_index + 1] = G; - pixels[byte_index + 2] = B; + pixels[pixel * 4] = R; + pixels[pixel * 4 + 1] = G; + pixels[pixel * 4 + 2] = B; } // return the modified frame From 9c3a2975be569df5cd18fe790dd6941b3b13f8ba Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 16 Oct 2020 18:56:34 -0500 Subject: [PATCH 124/148] Update the stale github message --- .github/stale.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/stale.yml b/.github/stale.yml index c5ec1048..bba68742 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -11,9 +11,17 @@ exemptLabels: staleLabel: stale # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > - This issue has been automatically marked as **stale** because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. + Thank you so much for submitting an issue to help improve OpenShot Video Editor. We are sorry about this, but this particular issue has gone unnoticed for quite some time. To help keep the OpenShot GitHub Issue Tracker organized and focused, we must ensure that every issue is correctly labelled and triaged, to get the proper attention. + + This issue will be closed, as it meets the following criteria: + - No activity in the past 90 days + - No one is assigned to this issue + + We'd like to ask you to help us out and determine whether this issue should be reopened. + - If this issue is reporting a bug, please can you attempt to reproduce on the [latest daily build](https://www.openshot.org/download/#daily) to help us to understand whether the bug still needs our attention. + - If this issue is proposing a new feature, please can you verify whether the feature proposal is still relevant. + + Thanks again for your help! # Comment to post when closing a stale issue. Set to `false` to disable closeComment: false # Only close issues From 06d45cb88aed5af39c08142147169eced2cf7f2b Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 17 Oct 2020 05:56:02 -0400 Subject: [PATCH 125/148] ImageReader: Consolidate ctors using default arg --- include/ImageReader.h | 18 +++++++++--------- src/ImageReader.cpp | 9 +-------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/include/ImageReader.h b/include/ImageReader.h index 5aafcc8f..aa96272f 100644 --- a/include/ImageReader.h +++ b/include/ImageReader.h @@ -76,15 +76,15 @@ namespace openshot bool is_open; public: - - /// Constructor for ImageReader. This automatically opens the media file and loads - /// frame 1, or it throws one of the following exceptions. - ImageReader(std::string path); - - /// Constructor for ImageReader. This only opens the media file to inspect its properties - /// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful - /// when you are inflating the object using JSON after instantiating it. - ImageReader(std::string path, bool inspect_reader); + /// @brief Constructor for ImageReader. + /// + /// Opens the media file to inspect its properties and loads frame 1, + /// iff inspect_reader == true (the default). Pass a false value in + /// the optional parameter to defer this initial Open()/Close() cycle. + /// + /// When not inspecting the media file, it's much faster, and useful + /// when you are inflating the object using JSON after instantiation. + ImageReader(const std::string& path, bool inspect_reader=true); /// Close File void Close() override; diff --git a/src/ImageReader.cpp b/src/ImageReader.cpp index 9a001879..2a4d411e 100644 --- a/src/ImageReader.cpp +++ b/src/ImageReader.cpp @@ -35,14 +35,7 @@ using namespace openshot; -ImageReader::ImageReader(std::string path) : path(path), is_open(false) -{ - // Open and Close the reader, to populate its attributes (such as height, width, etc...) - Open(); - Close(); -} - -ImageReader::ImageReader(std::string path, bool inspect_reader) : path(path), is_open(false) +ImageReader::ImageReader(const std::string& path, bool inspect_reader) : path(path), is_open(false) { // Open and Close the reader, to populate its attributes (such as height, width, etc...) if (inspect_reader) { From 6e4476dc6c34029544cc01eb660a954d6a76ed4d Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 17 Oct 2020 05:56:39 -0400 Subject: [PATCH 126/148] Tests: Increase coverage for ImageReader/Writer --- tests/ImageWriter_Tests.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/ImageWriter_Tests.cpp b/tests/ImageWriter_Tests.cpp index bdf73a07..6d3a2e22 100644 --- a/tests/ImageWriter_Tests.cpp +++ b/tests/ImageWriter_Tests.cpp @@ -37,17 +37,33 @@ using namespace std; using namespace openshot; #ifdef USE_IMAGEMAGICK -TEST(ImageWriter_Test_Gif) +SUITE(ImageWriter) { - // Reader + +TEST(Gif) +{ + // Reader --------------- + + // Bad path + FFmpegReader bad_r("/tmp/bleeblorp.xls", false); + CHECK_THROW(bad_r.Open(), InvalidFile); + + // Good path stringstream path; path << TEST_MEDIA_PATH << "sintel_trailer-720p.mp4"; FFmpegReader r(path.str()); + + // Read-before-open error + CHECK_THROW(r.GetFrame(1), ReaderClosed); + r.Open(); /* WRITER ---------------- */ ImageWriter w("output1.gif"); + // Check for exception on write-before-open + CHECK_THROW(w.WriteFrame(&r, 500, 504), WriterClosed); + // Set the image output settings (format, fps, width, height, quality, loops, combine) w.SetVideoOptions("GIF", r.info.fps, r.info.width, r.info.height, 70, 1, true); @@ -82,4 +98,6 @@ TEST(ImageWriter_Test_Gif) CHECK_CLOSE(11, (int)pixels[pixel_index + 2], 5); CHECK_CLOSE(255, (int)pixels[pixel_index + 3], 5); } + +} // SUITE #endif From 6c656dd7f7c1f54b9d71cb428d1c9f32ecef1a7b Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sat, 17 Oct 2020 06:23:44 -0400 Subject: [PATCH 127/148] QtImageReader: Consolidate ctors --- include/QtImageReader.h | 18 +++++++++--------- src/QtImageReader.cpp | 7 ------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/include/QtImageReader.h b/include/QtImageReader.h index 3848065a..5162b8f4 100644 --- a/include/QtImageReader.h +++ b/include/QtImageReader.h @@ -72,15 +72,15 @@ namespace openshot QSize max_size; ///> Current max_size as calculated with Clip properties public: - - /// Constructor for QtImageReader. This automatically opens the media file and loads - /// frame 1, or it throws one of the following exceptions. - QtImageReader(std::string path); - - /// Constructor for QtImageReader. This only opens the media file to inspect its properties - /// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful - /// when you are inflating the object using JSON after instantiating it. - QtImageReader(std::string path, bool inspect_reader); + /// @brief Constructor for QtImageReader. + /// + /// Opens the media file to inspect its properties and loads frame 1, + /// iff inspect_reader == true (the default). Pass a false value in + /// the optional parameter to defer this initial Open()/Close() cycle. + /// + /// When not inspecting the media file, it's much faster, and useful + /// when you are inflating the object using JSON after instantiation. + QtImageReader(std::string path, bool inspect_reader=true); virtual ~QtImageReader(); diff --git a/src/QtImageReader.cpp b/src/QtImageReader.cpp index 2e8d0642..78c2b009 100644 --- a/src/QtImageReader.cpp +++ b/src/QtImageReader.cpp @@ -44,13 +44,6 @@ using namespace openshot; -QtImageReader::QtImageReader(std::string path) : path{QString::fromStdString(path)}, is_open(false) -{ - // Open and Close the reader, to populate its attributes (such as height, width, etc...) - Open(); - Close(); -} - QtImageReader::QtImageReader(std::string path, bool inspect_reader) : path{QString::fromStdString(path)}, is_open(false) { // Open and Close the reader, to populate its attributes (such as height, width, etc...) From a6441d822d6e5c4dcff784e3ade27d0134deea66 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:05:29 -0400 Subject: [PATCH 128/148] Reorganize source tree (headers in src/) - src/bindings/ moves to /bindings/ - src/examples/ moves to /examples/ - Contents of include/ merged into src/ with same hierarchy - src/Qt/demo/ moves to examples/qt-demo/ --- {src/bindings => bindings}/CMakeLists.txt | 0 {src/bindings => bindings}/python/CMakeLists.txt | 0 {src/bindings => bindings}/python/openshot.i | 0 {src/bindings => bindings}/ruby/CMakeLists.txt | 0 {src/bindings => bindings}/ruby/openshot.i | 0 {src/examples => examples}/Example.cpp | 0 {src/examples => examples}/Example.py | 0 {src/examples => examples}/Example.rb | 0 {src/examples => examples}/ExampleBlackmagic.cpp | 0 {src/examples => examples}/ExampleHtml.cpp | 0 {src/examples => examples}/ExampleHtml.py | 0 {src/examples => examples}/OpenShot Wipe Tests.py | 0 {src/examples => examples}/back.png | Bin {src/examples => examples}/final-composite.png | Bin {src/examples => examples}/front.png | Bin {src/examples => examples}/front3.png | Bin {src/examples => examples}/interlaced.png | Bin {src/examples => examples}/mask.png | Bin {src/examples => examples}/mask2.png | Bin {src/examples => examples}/output-final.png | Bin {src/examples => examples}/piano-mono.wav | Bin {src/examples => examples}/piano.wav | Bin {src/Qt/demo => examples/qt-demo}/main.cpp | 0 {src/examples => examples}/sintel_trailer-720p.mp4 | Bin {src/examples => examples}/test.mp4 | Bin {src/examples => examples}/test.wav | Bin {src/examples => examples}/test1.mp4 | Bin {include => src}/AudioBufferSource.h | 0 {include => src}/AudioDeviceInfo.h | 0 {include => src}/AudioReaderSource.h | 0 {include => src}/AudioResampler.h | 0 {include => src}/CacheBase.h | 0 {include => src}/CacheDisk.h | 0 {include => src}/CacheMemory.h | 0 {include => src}/ChannelLayouts.h | 0 {include => src}/ChunkReader.h | 0 {include => src}/ChunkWriter.h | 0 {include => src}/Clip.h | 0 {include => src}/ClipBase.h | 0 {include => src}/Color.h | 0 {include => src}/Coordinate.h | 0 {include => src}/CrashHandler.h | 0 {include => src}/DecklinkInput.h | 0 {include => src}/DecklinkOutput.h | 0 {include => src}/DecklinkReader.h | 0 {include => src}/DecklinkWriter.h | 0 {include => src}/DummyReader.h | 0 {include => src}/EffectBase.h | 0 {include => src}/EffectInfo.h | 0 {include => src}/Effects.h | 0 {include => src}/Enums.h | 0 {include => src}/Exceptions.h | 0 {include => src}/FFmpegReader.h | 0 {include => src}/FFmpegUtilities.h | 0 {include => src}/FFmpegWriter.h | 0 {include => src}/Fraction.h | 0 {include => src}/Frame.h | 0 {include => src}/FrameMapper.h | 0 {include => src}/ImageReader.h | 0 {include => src}/ImageWriter.h | 0 {include => src}/Json.h | 0 {include => src}/KeyFrame.h | 0 {include => src}/MagickUtilities.h | 0 {include => src}/OpenMPUtilities.h | 0 {include => src}/OpenShot.h | 0 {include => src}/OpenShotVersion.h.in | 0 {include => src}/PlayerBase.h | 0 {include => src}/Point.h | 0 {include => src}/Profiles.h | 0 {include => src}/Qt/AudioPlaybackThread.h | 0 {include => src}/Qt/PlayerDemo.h | 0 {include => src}/Qt/PlayerPrivate.h | 0 {include => src}/Qt/VideoCacheThread.h | 0 {include => src}/Qt/VideoPlaybackThread.h | 0 {include => src}/Qt/VideoRenderWidget.h | 0 {include => src}/Qt/VideoRenderer.h | 0 {include => src}/QtHtmlReader.h | 0 {include => src}/QtImageReader.h | 0 {include => src}/QtPlayer.h | 0 {include => src}/QtTextReader.h | 0 {include => src}/QtUtilities.h | 0 {include => src}/ReaderBase.h | 0 {include => src}/RendererBase.h | 0 {include => src}/Settings.h | 0 {include => src}/TextReader.h | 0 {include => src}/Timeline.h | 0 {include => src}/WriterBase.h | 0 {include => src}/ZmqLogger.h | 0 {include => src}/effects/Bars.h | 0 {include => src}/effects/Blur.h | 0 {include => src}/effects/Brightness.h | 0 {include => src}/effects/ChromaKey.h | 0 {include => src}/effects/ColorShift.h | 0 {include => src}/effects/Crop.h | 0 {include => src}/effects/Deinterlace.h | 0 {include => src}/effects/Hue.h | 0 {include => src}/effects/Mask.h | 0 {include => src}/effects/Negate.h | 0 {include => src}/effects/Pixelate.h | 0 {include => src}/effects/Saturation.h | 0 {include => src}/effects/Shift.h | 0 {include => src}/effects/Wave.h | 0 102 files changed, 0 insertions(+), 0 deletions(-) rename {src/bindings => bindings}/CMakeLists.txt (100%) rename {src/bindings => bindings}/python/CMakeLists.txt (100%) rename {src/bindings => bindings}/python/openshot.i (100%) rename {src/bindings => bindings}/ruby/CMakeLists.txt (100%) rename {src/bindings => bindings}/ruby/openshot.i (100%) rename {src/examples => examples}/Example.cpp (100%) rename {src/examples => examples}/Example.py (100%) rename {src/examples => examples}/Example.rb (100%) rename {src/examples => examples}/ExampleBlackmagic.cpp (100%) rename {src/examples => examples}/ExampleHtml.cpp (100%) rename {src/examples => examples}/ExampleHtml.py (100%) rename {src/examples => examples}/OpenShot Wipe Tests.py (100%) rename {src/examples => examples}/back.png (100%) rename {src/examples => examples}/final-composite.png (100%) rename {src/examples => examples}/front.png (100%) rename {src/examples => examples}/front3.png (100%) rename {src/examples => examples}/interlaced.png (100%) rename {src/examples => examples}/mask.png (100%) rename {src/examples => examples}/mask2.png (100%) rename {src/examples => examples}/output-final.png (100%) rename {src/examples => examples}/piano-mono.wav (100%) rename {src/examples => examples}/piano.wav (100%) rename {src/Qt/demo => examples/qt-demo}/main.cpp (100%) rename {src/examples => examples}/sintel_trailer-720p.mp4 (100%) rename {src/examples => examples}/test.mp4 (100%) rename {src/examples => examples}/test.wav (100%) rename {src/examples => examples}/test1.mp4 (100%) rename {include => src}/AudioBufferSource.h (100%) rename {include => src}/AudioDeviceInfo.h (100%) rename {include => src}/AudioReaderSource.h (100%) rename {include => src}/AudioResampler.h (100%) rename {include => src}/CacheBase.h (100%) rename {include => src}/CacheDisk.h (100%) rename {include => src}/CacheMemory.h (100%) rename {include => src}/ChannelLayouts.h (100%) rename {include => src}/ChunkReader.h (100%) rename {include => src}/ChunkWriter.h (100%) rename {include => src}/Clip.h (100%) rename {include => src}/ClipBase.h (100%) rename {include => src}/Color.h (100%) rename {include => src}/Coordinate.h (100%) rename {include => src}/CrashHandler.h (100%) rename {include => src}/DecklinkInput.h (100%) rename {include => src}/DecklinkOutput.h (100%) rename {include => src}/DecklinkReader.h (100%) rename {include => src}/DecklinkWriter.h (100%) rename {include => src}/DummyReader.h (100%) rename {include => src}/EffectBase.h (100%) rename {include => src}/EffectInfo.h (100%) rename {include => src}/Effects.h (100%) rename {include => src}/Enums.h (100%) rename {include => src}/Exceptions.h (100%) rename {include => src}/FFmpegReader.h (100%) rename {include => src}/FFmpegUtilities.h (100%) rename {include => src}/FFmpegWriter.h (100%) rename {include => src}/Fraction.h (100%) rename {include => src}/Frame.h (100%) rename {include => src}/FrameMapper.h (100%) rename {include => src}/ImageReader.h (100%) rename {include => src}/ImageWriter.h (100%) rename {include => src}/Json.h (100%) rename {include => src}/KeyFrame.h (100%) rename {include => src}/MagickUtilities.h (100%) rename {include => src}/OpenMPUtilities.h (100%) rename {include => src}/OpenShot.h (100%) rename {include => src}/OpenShotVersion.h.in (100%) rename {include => src}/PlayerBase.h (100%) rename {include => src}/Point.h (100%) rename {include => src}/Profiles.h (100%) rename {include => src}/Qt/AudioPlaybackThread.h (100%) rename {include => src}/Qt/PlayerDemo.h (100%) rename {include => src}/Qt/PlayerPrivate.h (100%) rename {include => src}/Qt/VideoCacheThread.h (100%) rename {include => src}/Qt/VideoPlaybackThread.h (100%) rename {include => src}/Qt/VideoRenderWidget.h (100%) rename {include => src}/Qt/VideoRenderer.h (100%) rename {include => src}/QtHtmlReader.h (100%) rename {include => src}/QtImageReader.h (100%) rename {include => src}/QtPlayer.h (100%) rename {include => src}/QtTextReader.h (100%) rename {include => src}/QtUtilities.h (100%) rename {include => src}/ReaderBase.h (100%) rename {include => src}/RendererBase.h (100%) rename {include => src}/Settings.h (100%) rename {include => src}/TextReader.h (100%) rename {include => src}/Timeline.h (100%) rename {include => src}/WriterBase.h (100%) rename {include => src}/ZmqLogger.h (100%) rename {include => src}/effects/Bars.h (100%) rename {include => src}/effects/Blur.h (100%) rename {include => src}/effects/Brightness.h (100%) rename {include => src}/effects/ChromaKey.h (100%) rename {include => src}/effects/ColorShift.h (100%) rename {include => src}/effects/Crop.h (100%) rename {include => src}/effects/Deinterlace.h (100%) rename {include => src}/effects/Hue.h (100%) rename {include => src}/effects/Mask.h (100%) rename {include => src}/effects/Negate.h (100%) rename {include => src}/effects/Pixelate.h (100%) rename {include => src}/effects/Saturation.h (100%) rename {include => src}/effects/Shift.h (100%) rename {include => src}/effects/Wave.h (100%) diff --git a/src/bindings/CMakeLists.txt b/bindings/CMakeLists.txt similarity index 100% rename from src/bindings/CMakeLists.txt rename to bindings/CMakeLists.txt diff --git a/src/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt similarity index 100% rename from src/bindings/python/CMakeLists.txt rename to bindings/python/CMakeLists.txt diff --git a/src/bindings/python/openshot.i b/bindings/python/openshot.i similarity index 100% rename from src/bindings/python/openshot.i rename to bindings/python/openshot.i diff --git a/src/bindings/ruby/CMakeLists.txt b/bindings/ruby/CMakeLists.txt similarity index 100% rename from src/bindings/ruby/CMakeLists.txt rename to bindings/ruby/CMakeLists.txt diff --git a/src/bindings/ruby/openshot.i b/bindings/ruby/openshot.i similarity index 100% rename from src/bindings/ruby/openshot.i rename to bindings/ruby/openshot.i diff --git a/src/examples/Example.cpp b/examples/Example.cpp similarity index 100% rename from src/examples/Example.cpp rename to examples/Example.cpp diff --git a/src/examples/Example.py b/examples/Example.py similarity index 100% rename from src/examples/Example.py rename to examples/Example.py diff --git a/src/examples/Example.rb b/examples/Example.rb similarity index 100% rename from src/examples/Example.rb rename to examples/Example.rb diff --git a/src/examples/ExampleBlackmagic.cpp b/examples/ExampleBlackmagic.cpp similarity index 100% rename from src/examples/ExampleBlackmagic.cpp rename to examples/ExampleBlackmagic.cpp diff --git a/src/examples/ExampleHtml.cpp b/examples/ExampleHtml.cpp similarity index 100% rename from src/examples/ExampleHtml.cpp rename to examples/ExampleHtml.cpp diff --git a/src/examples/ExampleHtml.py b/examples/ExampleHtml.py similarity index 100% rename from src/examples/ExampleHtml.py rename to examples/ExampleHtml.py diff --git a/src/examples/OpenShot Wipe Tests.py b/examples/OpenShot Wipe Tests.py similarity index 100% rename from src/examples/OpenShot Wipe Tests.py rename to examples/OpenShot Wipe Tests.py diff --git a/src/examples/back.png b/examples/back.png similarity index 100% rename from src/examples/back.png rename to examples/back.png diff --git a/src/examples/final-composite.png b/examples/final-composite.png similarity index 100% rename from src/examples/final-composite.png rename to examples/final-composite.png diff --git a/src/examples/front.png b/examples/front.png similarity index 100% rename from src/examples/front.png rename to examples/front.png diff --git a/src/examples/front3.png b/examples/front3.png similarity index 100% rename from src/examples/front3.png rename to examples/front3.png diff --git a/src/examples/interlaced.png b/examples/interlaced.png similarity index 100% rename from src/examples/interlaced.png rename to examples/interlaced.png diff --git a/src/examples/mask.png b/examples/mask.png similarity index 100% rename from src/examples/mask.png rename to examples/mask.png diff --git a/src/examples/mask2.png b/examples/mask2.png similarity index 100% rename from src/examples/mask2.png rename to examples/mask2.png diff --git a/src/examples/output-final.png b/examples/output-final.png similarity index 100% rename from src/examples/output-final.png rename to examples/output-final.png diff --git a/src/examples/piano-mono.wav b/examples/piano-mono.wav similarity index 100% rename from src/examples/piano-mono.wav rename to examples/piano-mono.wav diff --git a/src/examples/piano.wav b/examples/piano.wav similarity index 100% rename from src/examples/piano.wav rename to examples/piano.wav diff --git a/src/Qt/demo/main.cpp b/examples/qt-demo/main.cpp similarity index 100% rename from src/Qt/demo/main.cpp rename to examples/qt-demo/main.cpp diff --git a/src/examples/sintel_trailer-720p.mp4 b/examples/sintel_trailer-720p.mp4 similarity index 100% rename from src/examples/sintel_trailer-720p.mp4 rename to examples/sintel_trailer-720p.mp4 diff --git a/src/examples/test.mp4 b/examples/test.mp4 similarity index 100% rename from src/examples/test.mp4 rename to examples/test.mp4 diff --git a/src/examples/test.wav b/examples/test.wav similarity index 100% rename from src/examples/test.wav rename to examples/test.wav diff --git a/src/examples/test1.mp4 b/examples/test1.mp4 similarity index 100% rename from src/examples/test1.mp4 rename to examples/test1.mp4 diff --git a/include/AudioBufferSource.h b/src/AudioBufferSource.h similarity index 100% rename from include/AudioBufferSource.h rename to src/AudioBufferSource.h diff --git a/include/AudioDeviceInfo.h b/src/AudioDeviceInfo.h similarity index 100% rename from include/AudioDeviceInfo.h rename to src/AudioDeviceInfo.h diff --git a/include/AudioReaderSource.h b/src/AudioReaderSource.h similarity index 100% rename from include/AudioReaderSource.h rename to src/AudioReaderSource.h diff --git a/include/AudioResampler.h b/src/AudioResampler.h similarity index 100% rename from include/AudioResampler.h rename to src/AudioResampler.h diff --git a/include/CacheBase.h b/src/CacheBase.h similarity index 100% rename from include/CacheBase.h rename to src/CacheBase.h diff --git a/include/CacheDisk.h b/src/CacheDisk.h similarity index 100% rename from include/CacheDisk.h rename to src/CacheDisk.h diff --git a/include/CacheMemory.h b/src/CacheMemory.h similarity index 100% rename from include/CacheMemory.h rename to src/CacheMemory.h diff --git a/include/ChannelLayouts.h b/src/ChannelLayouts.h similarity index 100% rename from include/ChannelLayouts.h rename to src/ChannelLayouts.h diff --git a/include/ChunkReader.h b/src/ChunkReader.h similarity index 100% rename from include/ChunkReader.h rename to src/ChunkReader.h diff --git a/include/ChunkWriter.h b/src/ChunkWriter.h similarity index 100% rename from include/ChunkWriter.h rename to src/ChunkWriter.h diff --git a/include/Clip.h b/src/Clip.h similarity index 100% rename from include/Clip.h rename to src/Clip.h diff --git a/include/ClipBase.h b/src/ClipBase.h similarity index 100% rename from include/ClipBase.h rename to src/ClipBase.h diff --git a/include/Color.h b/src/Color.h similarity index 100% rename from include/Color.h rename to src/Color.h diff --git a/include/Coordinate.h b/src/Coordinate.h similarity index 100% rename from include/Coordinate.h rename to src/Coordinate.h diff --git a/include/CrashHandler.h b/src/CrashHandler.h similarity index 100% rename from include/CrashHandler.h rename to src/CrashHandler.h diff --git a/include/DecklinkInput.h b/src/DecklinkInput.h similarity index 100% rename from include/DecklinkInput.h rename to src/DecklinkInput.h diff --git a/include/DecklinkOutput.h b/src/DecklinkOutput.h similarity index 100% rename from include/DecklinkOutput.h rename to src/DecklinkOutput.h diff --git a/include/DecklinkReader.h b/src/DecklinkReader.h similarity index 100% rename from include/DecklinkReader.h rename to src/DecklinkReader.h diff --git a/include/DecklinkWriter.h b/src/DecklinkWriter.h similarity index 100% rename from include/DecklinkWriter.h rename to src/DecklinkWriter.h diff --git a/include/DummyReader.h b/src/DummyReader.h similarity index 100% rename from include/DummyReader.h rename to src/DummyReader.h diff --git a/include/EffectBase.h b/src/EffectBase.h similarity index 100% rename from include/EffectBase.h rename to src/EffectBase.h diff --git a/include/EffectInfo.h b/src/EffectInfo.h similarity index 100% rename from include/EffectInfo.h rename to src/EffectInfo.h diff --git a/include/Effects.h b/src/Effects.h similarity index 100% rename from include/Effects.h rename to src/Effects.h diff --git a/include/Enums.h b/src/Enums.h similarity index 100% rename from include/Enums.h rename to src/Enums.h diff --git a/include/Exceptions.h b/src/Exceptions.h similarity index 100% rename from include/Exceptions.h rename to src/Exceptions.h diff --git a/include/FFmpegReader.h b/src/FFmpegReader.h similarity index 100% rename from include/FFmpegReader.h rename to src/FFmpegReader.h diff --git a/include/FFmpegUtilities.h b/src/FFmpegUtilities.h similarity index 100% rename from include/FFmpegUtilities.h rename to src/FFmpegUtilities.h diff --git a/include/FFmpegWriter.h b/src/FFmpegWriter.h similarity index 100% rename from include/FFmpegWriter.h rename to src/FFmpegWriter.h diff --git a/include/Fraction.h b/src/Fraction.h similarity index 100% rename from include/Fraction.h rename to src/Fraction.h diff --git a/include/Frame.h b/src/Frame.h similarity index 100% rename from include/Frame.h rename to src/Frame.h diff --git a/include/FrameMapper.h b/src/FrameMapper.h similarity index 100% rename from include/FrameMapper.h rename to src/FrameMapper.h diff --git a/include/ImageReader.h b/src/ImageReader.h similarity index 100% rename from include/ImageReader.h rename to src/ImageReader.h diff --git a/include/ImageWriter.h b/src/ImageWriter.h similarity index 100% rename from include/ImageWriter.h rename to src/ImageWriter.h diff --git a/include/Json.h b/src/Json.h similarity index 100% rename from include/Json.h rename to src/Json.h diff --git a/include/KeyFrame.h b/src/KeyFrame.h similarity index 100% rename from include/KeyFrame.h rename to src/KeyFrame.h diff --git a/include/MagickUtilities.h b/src/MagickUtilities.h similarity index 100% rename from include/MagickUtilities.h rename to src/MagickUtilities.h diff --git a/include/OpenMPUtilities.h b/src/OpenMPUtilities.h similarity index 100% rename from include/OpenMPUtilities.h rename to src/OpenMPUtilities.h diff --git a/include/OpenShot.h b/src/OpenShot.h similarity index 100% rename from include/OpenShot.h rename to src/OpenShot.h diff --git a/include/OpenShotVersion.h.in b/src/OpenShotVersion.h.in similarity index 100% rename from include/OpenShotVersion.h.in rename to src/OpenShotVersion.h.in diff --git a/include/PlayerBase.h b/src/PlayerBase.h similarity index 100% rename from include/PlayerBase.h rename to src/PlayerBase.h diff --git a/include/Point.h b/src/Point.h similarity index 100% rename from include/Point.h rename to src/Point.h diff --git a/include/Profiles.h b/src/Profiles.h similarity index 100% rename from include/Profiles.h rename to src/Profiles.h diff --git a/include/Qt/AudioPlaybackThread.h b/src/Qt/AudioPlaybackThread.h similarity index 100% rename from include/Qt/AudioPlaybackThread.h rename to src/Qt/AudioPlaybackThread.h diff --git a/include/Qt/PlayerDemo.h b/src/Qt/PlayerDemo.h similarity index 100% rename from include/Qt/PlayerDemo.h rename to src/Qt/PlayerDemo.h diff --git a/include/Qt/PlayerPrivate.h b/src/Qt/PlayerPrivate.h similarity index 100% rename from include/Qt/PlayerPrivate.h rename to src/Qt/PlayerPrivate.h diff --git a/include/Qt/VideoCacheThread.h b/src/Qt/VideoCacheThread.h similarity index 100% rename from include/Qt/VideoCacheThread.h rename to src/Qt/VideoCacheThread.h diff --git a/include/Qt/VideoPlaybackThread.h b/src/Qt/VideoPlaybackThread.h similarity index 100% rename from include/Qt/VideoPlaybackThread.h rename to src/Qt/VideoPlaybackThread.h diff --git a/include/Qt/VideoRenderWidget.h b/src/Qt/VideoRenderWidget.h similarity index 100% rename from include/Qt/VideoRenderWidget.h rename to src/Qt/VideoRenderWidget.h diff --git a/include/Qt/VideoRenderer.h b/src/Qt/VideoRenderer.h similarity index 100% rename from include/Qt/VideoRenderer.h rename to src/Qt/VideoRenderer.h diff --git a/include/QtHtmlReader.h b/src/QtHtmlReader.h similarity index 100% rename from include/QtHtmlReader.h rename to src/QtHtmlReader.h diff --git a/include/QtImageReader.h b/src/QtImageReader.h similarity index 100% rename from include/QtImageReader.h rename to src/QtImageReader.h diff --git a/include/QtPlayer.h b/src/QtPlayer.h similarity index 100% rename from include/QtPlayer.h rename to src/QtPlayer.h diff --git a/include/QtTextReader.h b/src/QtTextReader.h similarity index 100% rename from include/QtTextReader.h rename to src/QtTextReader.h diff --git a/include/QtUtilities.h b/src/QtUtilities.h similarity index 100% rename from include/QtUtilities.h rename to src/QtUtilities.h diff --git a/include/ReaderBase.h b/src/ReaderBase.h similarity index 100% rename from include/ReaderBase.h rename to src/ReaderBase.h diff --git a/include/RendererBase.h b/src/RendererBase.h similarity index 100% rename from include/RendererBase.h rename to src/RendererBase.h diff --git a/include/Settings.h b/src/Settings.h similarity index 100% rename from include/Settings.h rename to src/Settings.h diff --git a/include/TextReader.h b/src/TextReader.h similarity index 100% rename from include/TextReader.h rename to src/TextReader.h diff --git a/include/Timeline.h b/src/Timeline.h similarity index 100% rename from include/Timeline.h rename to src/Timeline.h diff --git a/include/WriterBase.h b/src/WriterBase.h similarity index 100% rename from include/WriterBase.h rename to src/WriterBase.h diff --git a/include/ZmqLogger.h b/src/ZmqLogger.h similarity index 100% rename from include/ZmqLogger.h rename to src/ZmqLogger.h diff --git a/include/effects/Bars.h b/src/effects/Bars.h similarity index 100% rename from include/effects/Bars.h rename to src/effects/Bars.h diff --git a/include/effects/Blur.h b/src/effects/Blur.h similarity index 100% rename from include/effects/Blur.h rename to src/effects/Blur.h diff --git a/include/effects/Brightness.h b/src/effects/Brightness.h similarity index 100% rename from include/effects/Brightness.h rename to src/effects/Brightness.h diff --git a/include/effects/ChromaKey.h b/src/effects/ChromaKey.h similarity index 100% rename from include/effects/ChromaKey.h rename to src/effects/ChromaKey.h diff --git a/include/effects/ColorShift.h b/src/effects/ColorShift.h similarity index 100% rename from include/effects/ColorShift.h rename to src/effects/ColorShift.h diff --git a/include/effects/Crop.h b/src/effects/Crop.h similarity index 100% rename from include/effects/Crop.h rename to src/effects/Crop.h diff --git a/include/effects/Deinterlace.h b/src/effects/Deinterlace.h similarity index 100% rename from include/effects/Deinterlace.h rename to src/effects/Deinterlace.h diff --git a/include/effects/Hue.h b/src/effects/Hue.h similarity index 100% rename from include/effects/Hue.h rename to src/effects/Hue.h diff --git a/include/effects/Mask.h b/src/effects/Mask.h similarity index 100% rename from include/effects/Mask.h rename to src/effects/Mask.h diff --git a/include/effects/Negate.h b/src/effects/Negate.h similarity index 100% rename from include/effects/Negate.h rename to src/effects/Negate.h diff --git a/include/effects/Pixelate.h b/src/effects/Pixelate.h similarity index 100% rename from include/effects/Pixelate.h rename to src/effects/Pixelate.h diff --git a/include/effects/Saturation.h b/src/effects/Saturation.h similarity index 100% rename from include/effects/Saturation.h rename to src/effects/Saturation.h diff --git a/include/effects/Shift.h b/src/effects/Shift.h similarity index 100% rename from include/effects/Shift.h rename to src/effects/Shift.h diff --git a/include/effects/Wave.h b/src/effects/Wave.h similarity index 100% rename from include/effects/Wave.h rename to src/effects/Wave.h From aa40ea29e050fe0bca5104a68872dc7401071c8b Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 07:43:37 -0400 Subject: [PATCH 129/148] Update include paths in all source/header files --- src/AudioBufferSource.cpp | 2 +- src/AudioReaderSource.cpp | 2 +- src/AudioResampler.cpp | 2 +- src/CacheBase.cpp | 2 +- src/CacheDisk.cpp | 4 ++-- src/CacheMemory.cpp | 2 +- src/ChunkReader.cpp | 6 ++++-- src/ChunkReader.h | 12 +++--------- src/ChunkWriter.cpp | 2 +- src/Clip.cpp | 18 +++++++++--------- src/ClipBase.cpp | 2 +- src/Color.cpp | 2 +- src/Coordinate.cpp | 2 +- src/CrashHandler.cpp | 2 +- src/DecklinkInput.cpp | 2 +- src/DecklinkOutput.cpp | 2 +- src/DecklinkReader.cpp | 2 +- src/DecklinkWriter.cpp | 2 +- src/DummyReader.cpp | 2 +- src/EffectBase.cpp | 2 +- src/EffectInfo.cpp | 3 +-- src/FFmpegReader.cpp | 2 +- src/FFmpegWriter.cpp | 2 +- src/Fraction.cpp | 2 +- src/Frame.cpp | 2 +- src/FrameMapper.cpp | 2 +- src/ImageReader.cpp | 2 +- src/ImageWriter.cpp | 2 +- src/Json.cpp | 2 +- src/KeyFrame.cpp | 2 +- src/PlayerBase.cpp | 2 +- src/Point.cpp | 2 +- src/Profiles.cpp | 2 +- src/Qt/AudioPlaybackThread.cpp | 2 +- src/Qt/PlayerDemo.cpp | 8 +++++--- src/Qt/PlayerPrivate.cpp | 2 +- src/Qt/VideoCacheThread.cpp | 2 +- src/Qt/VideoPlaybackThread.cpp | 2 +- src/Qt/VideoRenderWidget.cpp | 2 +- src/Qt/VideoRenderer.cpp | 2 +- src/QtHtmlReader.cpp | 2 +- src/QtImageReader.cpp | 8 ++++---- src/QtPlayer.cpp | 12 ++++++------ src/QtTextReader.cpp | 2 +- src/ReaderBase.cpp | 2 +- src/RendererBase.cpp | 2 +- src/Settings.cpp | 2 +- src/TextReader.cpp | 2 +- src/Timeline.cpp | 2 +- src/WriterBase.cpp | 2 +- src/ZmqLogger.cpp | 2 +- src/effects/Bars.cpp | 2 +- src/effects/Bars.h | 6 +++--- src/effects/Blur.cpp | 2 +- src/effects/Blur.h | 17 ++++------------- src/effects/Brightness.cpp | 2 +- src/effects/Brightness.h | 16 ++++------------ src/effects/ChromaKey.cpp | 2 +- src/effects/ChromaKey.h | 10 ++++------ src/effects/ColorShift.cpp | 2 +- src/effects/Crop.cpp | 2 +- src/effects/Crop.h | 7 ++++--- src/effects/Deinterlace.cpp | 2 +- src/effects/Deinterlace.h | 9 ++------- src/effects/Hue.cpp | 2 +- src/effects/Hue.h | 7 ++++--- src/effects/Mask.cpp | 7 ++++++- src/effects/Mask.h | 21 +++++---------------- src/effects/Negate.cpp | 2 +- src/effects/Negate.h | 14 ++++++-------- src/effects/Pixelate.cpp | 2 +- src/effects/Pixelate.h | 6 +++--- src/effects/Saturation.cpp | 2 +- src/effects/Shift.cpp | 2 +- src/effects/Shift.h | 7 ++++--- src/effects/Wave.cpp | 2 +- src/effects/Wave.h | 7 ++++--- 77 files changed, 143 insertions(+), 174 deletions(-) diff --git a/src/AudioBufferSource.cpp b/src/AudioBufferSource.cpp index 69e5713a..6b2bc59e 100644 --- a/src/AudioBufferSource.cpp +++ b/src/AudioBufferSource.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/AudioBufferSource.h" +#include "AudioBufferSource.h" using namespace std; using namespace openshot; diff --git a/src/AudioReaderSource.cpp b/src/AudioReaderSource.cpp index 999d109d..b6a01a89 100644 --- a/src/AudioReaderSource.cpp +++ b/src/AudioReaderSource.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/AudioReaderSource.h" +#include "AudioReaderSource.h" using namespace std; using namespace openshot; diff --git a/src/AudioResampler.cpp b/src/AudioResampler.cpp index 145f5d91..8c27043e 100644 --- a/src/AudioResampler.cpp +++ b/src/AudioResampler.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/AudioResampler.h" +#include "AudioResampler.h" using namespace std; using namespace openshot; diff --git a/src/CacheBase.cpp b/src/CacheBase.cpp index bc57f3f4..72381792 100644 --- a/src/CacheBase.cpp +++ b/src/CacheBase.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/CacheBase.h" +#include "CacheBase.h" using namespace std; using namespace openshot; diff --git a/src/CacheDisk.cpp b/src/CacheDisk.cpp index b3fd119f..c252d0b2 100644 --- a/src/CacheDisk.cpp +++ b/src/CacheDisk.cpp @@ -28,8 +28,8 @@ * along with OpenShot Library. If not, see . */ -#include "../include/CacheDisk.h" -#include "../include/QtUtilities.h" +#include "CacheDisk.h" +#include "QtUtilities.h" #include #include #include diff --git a/src/CacheMemory.cpp b/src/CacheMemory.cpp index 70feef03..685c86ec 100644 --- a/src/CacheMemory.cpp +++ b/src/CacheMemory.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/CacheMemory.h" +#include "CacheMemory.h" using namespace std; using namespace openshot; diff --git a/src/ChunkReader.cpp b/src/ChunkReader.cpp index c194ce33..5301c687 100644 --- a/src/ChunkReader.cpp +++ b/src/ChunkReader.cpp @@ -28,8 +28,10 @@ * along with OpenShot Library. If not, see . */ -#include "../include/ChunkReader.h" -#include "../include/FFmpegReader.h" +#include "ChunkReader.h" +#include "FFmpegReader.h" + +#include using namespace openshot; diff --git a/src/ChunkReader.h b/src/ChunkReader.h index 50b26083..7a041f71 100644 --- a/src/ChunkReader.h +++ b/src/ChunkReader.h @@ -32,18 +32,12 @@ #define OPENSHOT_CHUNK_READER_H #include "ReaderBase.h" -#include -#include -#include -#include -#include -#include -#include +#include #include -#include + +#include "Frame.h" #include "Json.h" #include "CacheMemory.h" -#include "Exceptions.h" namespace openshot { diff --git a/src/ChunkWriter.cpp b/src/ChunkWriter.cpp index c7752cd5..bbb10be9 100644 --- a/src/ChunkWriter.cpp +++ b/src/ChunkWriter.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/ChunkWriter.h" +#include "ChunkWriter.h" using namespace openshot; diff --git a/src/Clip.cpp b/src/Clip.cpp index 1f738282..f3660f0a 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -28,17 +28,17 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Clip.h" -#include "../include/FFmpegReader.h" -#include "../include/FrameMapper.h" +#include "Clip.h" +#include "FFmpegReader.h" +#include "FrameMapper.h" #ifdef USE_IMAGEMAGICK - #include "../include/ImageReader.h" - #include "../include/TextReader.h" + #include "ImageReader.h" + #include "TextReader.h" #endif -#include "../include/QtImageReader.h" -#include "../include/ChunkReader.h" -#include "../include/DummyReader.h" -#include "../include/Timeline.h" +#include "QtImageReader.h" +#include "ChunkReader.h" +#include "DummyReader.h" +#include "Timeline.h" using namespace openshot; diff --git a/src/ClipBase.cpp b/src/ClipBase.cpp index a51c6573..f7695904 100644 --- a/src/ClipBase.cpp +++ b/src/ClipBase.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/ClipBase.h" +#include "ClipBase.h" using namespace openshot; diff --git a/src/Color.cpp b/src/Color.cpp index 705ece4a..622a912c 100644 --- a/src/Color.cpp +++ b/src/Color.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Color.h" +#include "Color.h" using namespace openshot; diff --git a/src/Coordinate.cpp b/src/Coordinate.cpp index f87fb7a0..0d4f577a 100644 --- a/src/Coordinate.cpp +++ b/src/Coordinate.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Coordinate.h" +#include "Coordinate.h" using namespace std; using namespace openshot; diff --git a/src/CrashHandler.cpp b/src/CrashHandler.cpp index 1782f5ba..7b6c4e7e 100644 --- a/src/CrashHandler.cpp +++ b/src/CrashHandler.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/CrashHandler.h" +#include "CrashHandler.h" using namespace std; using namespace openshot; diff --git a/src/DecklinkInput.cpp b/src/DecklinkInput.cpp index b03ad8e4..21c4f7bb 100644 --- a/src/DecklinkInput.cpp +++ b/src/DecklinkInput.cpp @@ -53,7 +53,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/DecklinkInput.h" +#include "DecklinkInput.h" using namespace std; diff --git a/src/DecklinkOutput.cpp b/src/DecklinkOutput.cpp index 2dee7e9e..13da185f 100644 --- a/src/DecklinkOutput.cpp +++ b/src/DecklinkOutput.cpp @@ -53,7 +53,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/DecklinkOutput.h" +#include "DecklinkOutput.h" using namespace std; diff --git a/src/DecklinkReader.cpp b/src/DecklinkReader.cpp index 14c2f87c..bb31f316 100644 --- a/src/DecklinkReader.cpp +++ b/src/DecklinkReader.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/DecklinkReader.h" +#include "DecklinkReader.h" using namespace openshot; diff --git a/src/DecklinkWriter.cpp b/src/DecklinkWriter.cpp index 3eafda1c..1bfb59a8 100644 --- a/src/DecklinkWriter.cpp +++ b/src/DecklinkWriter.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/DecklinkWriter.h" +#include "DecklinkWriter.h" using namespace openshot; diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp index 8b6f752f..c295c298 100644 --- a/src/DummyReader.cpp +++ b/src/DummyReader.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/DummyReader.h" +#include "DummyReader.h" using namespace openshot; diff --git a/src/EffectBase.cpp b/src/EffectBase.cpp index 05ed97c2..f1d7d030 100644 --- a/src/EffectBase.cpp +++ b/src/EffectBase.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/EffectBase.h" +#include "EffectBase.h" using namespace openshot; diff --git a/src/EffectInfo.cpp b/src/EffectInfo.cpp index 6829f4eb..1359238d 100644 --- a/src/EffectInfo.cpp +++ b/src/EffectInfo.cpp @@ -28,8 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/EffectInfo.h" - +#include "EffectInfo.h" using namespace openshot; diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 5b7b7ddd..f17e0359 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -31,7 +31,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/FFmpegReader.h" +#include "FFmpegReader.h" #include // for std::this_thread::sleep_for #include // for std::chrono::milliseconds diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 76bc9890..e5e92fd4 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -31,7 +31,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/FFmpegWriter.h" +#include "FFmpegWriter.h" #include diff --git a/src/Fraction.cpp b/src/Fraction.cpp index c9cdad55..869ef35f 100644 --- a/src/Fraction.cpp +++ b/src/Fraction.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Fraction.h" +#include "Fraction.h" using namespace openshot; diff --git a/src/Frame.cpp b/src/Frame.cpp index 8be00246..3bae8854 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Frame.h" +#include "Frame.h" #include "JuceHeader.h" #include diff --git a/src/FrameMapper.cpp b/src/FrameMapper.cpp index 8eff6e70..85c6bfdf 100644 --- a/src/FrameMapper.cpp +++ b/src/FrameMapper.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/FrameMapper.h" +#include "FrameMapper.h" using namespace std; using namespace openshot; diff --git a/src/ImageReader.cpp b/src/ImageReader.cpp index 9a001879..1b7c1af0 100644 --- a/src/ImageReader.cpp +++ b/src/ImageReader.cpp @@ -31,7 +31,7 @@ // Require ImageMagick support #ifdef USE_IMAGEMAGICK -#include "../include/ImageReader.h" +#include "ImageReader.h" using namespace openshot; diff --git a/src/ImageWriter.cpp b/src/ImageWriter.cpp index 1b7a01e9..275ea270 100644 --- a/src/ImageWriter.cpp +++ b/src/ImageWriter.cpp @@ -34,7 +34,7 @@ //Require ImageMagick support #ifdef USE_IMAGEMAGICK -#include "../include/ImageWriter.h" +#include "ImageWriter.h" using namespace openshot; diff --git a/src/Json.cpp b/src/Json.cpp index 0c83d9d6..9d6d9ba4 100644 --- a/src/Json.cpp +++ b/src/Json.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Json.h" +#include "Json.h" const Json::Value openshot::stringToJson(const std::string value) { diff --git a/src/KeyFrame.cpp b/src/KeyFrame.cpp index 57e424cf..b113e632 100644 --- a/src/KeyFrame.cpp +++ b/src/KeyFrame.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/KeyFrame.h" +#include "KeyFrame.h" #include #include #include diff --git a/src/PlayerBase.cpp b/src/PlayerBase.cpp index f152fbbb..844b8d60 100644 --- a/src/PlayerBase.cpp +++ b/src/PlayerBase.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/PlayerBase.h" +#include "PlayerBase.h" using namespace openshot; diff --git a/src/Point.cpp b/src/Point.cpp index 13679977..4636b437 100644 --- a/src/Point.cpp +++ b/src/Point.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Point.h" +#include "Point.h" using namespace std; using namespace openshot; diff --git a/src/Profiles.cpp b/src/Profiles.cpp index 5351520e..167affe2 100644 --- a/src/Profiles.cpp +++ b/src/Profiles.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Profiles.h" +#include "Profiles.h" using namespace openshot; diff --git a/src/Qt/AudioPlaybackThread.cpp b/src/Qt/AudioPlaybackThread.cpp index 2ee1009c..178642f6 100644 --- a/src/Qt/AudioPlaybackThread.cpp +++ b/src/Qt/AudioPlaybackThread.cpp @@ -29,7 +29,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/Qt/AudioPlaybackThread.h" +#include "AudioPlaybackThread.h" #include // for std::this_thread::sleep_for #include // for std::chrono::milliseconds diff --git a/src/Qt/PlayerDemo.cpp b/src/Qt/PlayerDemo.cpp index e5f0e11d..e8751a62 100644 --- a/src/Qt/PlayerDemo.cpp +++ b/src/Qt/PlayerDemo.cpp @@ -28,9 +28,11 @@ * along with OpenShot Library. If not, see . */ -#include -#include "../../include/QtPlayer.h" -#include "../../include/Qt/PlayerDemo.h" +#include + +#include "PlayerDemo.h" +#include "../QtPlayer.h" + #include #include #include diff --git a/src/Qt/PlayerPrivate.cpp b/src/Qt/PlayerPrivate.cpp index db6f2ff1..75052fc3 100644 --- a/src/Qt/PlayerPrivate.cpp +++ b/src/Qt/PlayerPrivate.cpp @@ -29,7 +29,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/Qt/PlayerPrivate.h" +#include "PlayerPrivate.h" #include // for std::this_thread::sleep_for #include // for std::chrono milliseconds, high_resolution_clock diff --git a/src/Qt/VideoCacheThread.cpp b/src/Qt/VideoCacheThread.cpp index 4279e238..f817c93f 100644 --- a/src/Qt/VideoCacheThread.cpp +++ b/src/Qt/VideoCacheThread.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/Qt/VideoCacheThread.h" +#include "VideoCacheThread.h" #include #include // for std::this_thread::sleep_for diff --git a/src/Qt/VideoPlaybackThread.cpp b/src/Qt/VideoPlaybackThread.cpp index f1cff756..01e2871b 100644 --- a/src/Qt/VideoPlaybackThread.cpp +++ b/src/Qt/VideoPlaybackThread.cpp @@ -29,7 +29,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/Qt/VideoPlaybackThread.h" +#include "VideoPlaybackThread.h" namespace openshot { diff --git a/src/Qt/VideoRenderWidget.cpp b/src/Qt/VideoRenderWidget.cpp index 4af1ac6a..52898372 100644 --- a/src/Qt/VideoRenderWidget.cpp +++ b/src/Qt/VideoRenderWidget.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/Qt/VideoRenderWidget.h" +#include "VideoRenderWidget.h" #include #include #include diff --git a/src/Qt/VideoRenderer.cpp b/src/Qt/VideoRenderer.cpp index 8d0e3a1d..e70e8545 100644 --- a/src/Qt/VideoRenderer.cpp +++ b/src/Qt/VideoRenderer.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/Qt/VideoRenderer.h" +#include "VideoRenderer.h" VideoRenderer::VideoRenderer(QObject *parent) diff --git a/src/QtHtmlReader.cpp b/src/QtHtmlReader.cpp index 4925d3a8..b40041ac 100644 --- a/src/QtHtmlReader.cpp +++ b/src/QtHtmlReader.cpp @@ -30,7 +30,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/QtHtmlReader.h" +#include "QtHtmlReader.h" #include #include #include diff --git a/src/QtImageReader.cpp b/src/QtImageReader.cpp index 2e8d0642..281cb363 100644 --- a/src/QtImageReader.cpp +++ b/src/QtImageReader.cpp @@ -28,10 +28,10 @@ * along with OpenShot Library. If not, see . */ -#include "../include/QtImageReader.h" -#include "../include/Settings.h" -#include "../include/Clip.h" -#include "../include/CacheMemory.h" +#include "QtImageReader.h" +#include "Settings.h" +#include "Clip.h" +#include "CacheMemory.h" #include #include #include diff --git a/src/QtPlayer.cpp b/src/QtPlayer.cpp index e4d862d1..345bc24f 100644 --- a/src/QtPlayer.cpp +++ b/src/QtPlayer.cpp @@ -29,12 +29,12 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Clip.h" -#include "../include/FFmpegReader.h" -#include "../include/Timeline.h" -#include "../include/QtPlayer.h" -#include "../include/Qt/PlayerPrivate.h" -#include "../include/Qt/VideoRenderer.h" +#include "Clip.h" +#include "FFmpegReader.h" +#include "Timeline.h" +#include "QtPlayer.h" +#include "Qt/PlayerPrivate.h" +#include "Qt/VideoRenderer.h" namespace openshot { diff --git a/src/QtTextReader.cpp b/src/QtTextReader.cpp index bd157ebd..2c3d1c3a 100644 --- a/src/QtTextReader.cpp +++ b/src/QtTextReader.cpp @@ -30,7 +30,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/QtTextReader.h" +#include "QtTextReader.h" #include #include diff --git a/src/ReaderBase.cpp b/src/ReaderBase.cpp index 6799d95e..220925d7 100644 --- a/src/ReaderBase.cpp +++ b/src/ReaderBase.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/ReaderBase.h" +#include "ReaderBase.h" using namespace openshot; diff --git a/src/RendererBase.cpp b/src/RendererBase.cpp index b2bea40e..ca9ad26e 100644 --- a/src/RendererBase.cpp +++ b/src/RendererBase.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/RendererBase.h" +#include "RendererBase.h" using namespace openshot; RendererBase::RendererBase() diff --git a/src/Settings.cpp b/src/Settings.cpp index e48fd981..e3f44aed 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Settings.h" +#include "Settings.h" using namespace std; using namespace openshot; diff --git a/src/TextReader.cpp b/src/TextReader.cpp index be8c7375..0407460a 100644 --- a/src/TextReader.cpp +++ b/src/TextReader.cpp @@ -31,7 +31,7 @@ // Require ImageMagick support #ifdef USE_IMAGEMAGICK -#include "../include/TextReader.h" +#include "TextReader.h" using namespace openshot; diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 9ccf9a84..71ab8efa 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/Timeline.h" +#include "Timeline.h" using namespace openshot; diff --git a/src/WriterBase.cpp b/src/WriterBase.cpp index 38821917..9755c61d 100644 --- a/src/WriterBase.cpp +++ b/src/WriterBase.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/WriterBase.h" +#include "WriterBase.h" using namespace openshot; diff --git a/src/ZmqLogger.cpp b/src/ZmqLogger.cpp index b7299230..8d72f352 100644 --- a/src/ZmqLogger.cpp +++ b/src/ZmqLogger.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../include/ZmqLogger.h" +#include "ZmqLogger.h" #if USE_RESVG == 1 #include "ResvgQt.h" diff --git a/src/effects/Bars.cpp b/src/effects/Bars.cpp index e653b7dd..6b319569 100644 --- a/src/effects/Bars.cpp +++ b/src/effects/Bars.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Bars.h" +#include "Bars.h" using namespace openshot; diff --git a/src/effects/Bars.h b/src/effects/Bars.h index 7c92255a..c2e24f73 100644 --- a/src/effects/Bars.h +++ b/src/effects/Bars.h @@ -33,13 +33,13 @@ #include "../EffectBase.h" -#include -#include -#include #include "../Color.h" +#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" +#include +#include namespace openshot { diff --git a/src/effects/Blur.cpp b/src/effects/Blur.cpp index 6ddba88e..c7e36b7b 100644 --- a/src/effects/Blur.cpp +++ b/src/effects/Blur.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Blur.h" +#include "Blur.h" using namespace openshot; diff --git a/src/effects/Blur.h b/src/effects/Blur.h index 60a0cd08..59b75fff 100644 --- a/src/effects/Blur.h +++ b/src/effects/Blur.h @@ -33,21 +33,12 @@ #include "../EffectBase.h" -#include -#include -#include -#include -#include -#include -#include -#include "../Color.h" -#include "../Exceptions.h" +#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" -#include "../ReaderBase.h" -#include "../FFmpegReader.h" -#include "../QtImageReader.h" -#include "../ChunkReader.h" + +#include +#include namespace openshot { diff --git a/src/effects/Brightness.cpp b/src/effects/Brightness.cpp index 321a19a7..d73de899 100644 --- a/src/effects/Brightness.cpp +++ b/src/effects/Brightness.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Brightness.h" +#include "Brightness.h" using namespace openshot; diff --git a/src/effects/Brightness.h b/src/effects/Brightness.h index 5f25b94a..22860068 100644 --- a/src/effects/Brightness.h +++ b/src/effects/Brightness.h @@ -33,20 +33,12 @@ #include "../EffectBase.h" -#include -#include -#include -#include -#include -#include -#include "../Color.h" -#include "../Exceptions.h" +#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" -#include "../ReaderBase.h" -#include "../FFmpegReader.h" -#include "../QtImageReader.h" -#include "../ChunkReader.h" + +#include +#include namespace openshot { diff --git a/src/effects/ChromaKey.cpp b/src/effects/ChromaKey.cpp index dbb56a69..0f4d626e 100644 --- a/src/effects/ChromaKey.cpp +++ b/src/effects/ChromaKey.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/ChromaKey.h" +#include "ChromaKey.h" using namespace openshot; diff --git a/src/effects/ChromaKey.h b/src/effects/ChromaKey.h index fcc8c3b1..7c267642 100644 --- a/src/effects/ChromaKey.h +++ b/src/effects/ChromaKey.h @@ -33,16 +33,14 @@ #include "../EffectBase.h" -#include -#include -#include -#include -#include -#include #include "../Color.h" +#include "../Frame.h" #include "../Exceptions.h" #include "../KeyFrame.h" +#include +#include + namespace openshot { diff --git a/src/effects/ColorShift.cpp b/src/effects/ColorShift.cpp index 7ec62e14..361f852d 100644 --- a/src/effects/ColorShift.cpp +++ b/src/effects/ColorShift.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/ColorShift.h" +#include "ColorShift.h" using namespace openshot; diff --git a/src/effects/Crop.cpp b/src/effects/Crop.cpp index f0e0aa95..02e3f17c 100644 --- a/src/effects/Crop.cpp +++ b/src/effects/Crop.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Crop.h" +#include "Crop.h" using namespace openshot; diff --git a/src/effects/Crop.h b/src/effects/Crop.h index f5ba07f2..2b746a01 100644 --- a/src/effects/Crop.h +++ b/src/effects/Crop.h @@ -33,13 +33,14 @@ #include "../EffectBase.h" -#include -#include -#include #include "../Color.h" +#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" +#include +#include + namespace openshot { diff --git a/src/effects/Deinterlace.cpp b/src/effects/Deinterlace.cpp index 984336aa..36014349 100644 --- a/src/effects/Deinterlace.cpp +++ b/src/effects/Deinterlace.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Deinterlace.h" +#include "Deinterlace.h" using namespace openshot; diff --git a/src/effects/Deinterlace.h b/src/effects/Deinterlace.h index 97c77853..84212d67 100644 --- a/src/effects/Deinterlace.h +++ b/src/effects/Deinterlace.h @@ -33,14 +33,9 @@ #include "../EffectBase.h" -#include -#include -#include -#include -#include +#include #include -#include "../Color.h" -#include "../Exceptions.h" +#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" diff --git a/src/effects/Hue.cpp b/src/effects/Hue.cpp index eb4808e3..35ee3709 100644 --- a/src/effects/Hue.cpp +++ b/src/effects/Hue.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Hue.h" +#include "Hue.h" using namespace openshot; diff --git a/src/effects/Hue.h b/src/effects/Hue.h index 833bf087..039aa3a8 100644 --- a/src/effects/Hue.h +++ b/src/effects/Hue.h @@ -33,12 +33,13 @@ #include "../EffectBase.h" -#include -#include -#include +#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" +#include +#include + namespace openshot { diff --git a/src/effects/Mask.cpp b/src/effects/Mask.cpp index f270e410..9fbc1824 100644 --- a/src/effects/Mask.cpp +++ b/src/effects/Mask.cpp @@ -28,7 +28,12 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Mask.h" +#include "Mask.h" +#include "FFmpegReader.h" +#ifdef USE_IMAGEMAGICK + #include "ImageReader.h" +#endif +#include "ReaderBase.h" using namespace openshot; diff --git a/src/effects/Mask.h b/src/effects/Mask.h index 8156b843..1a76ea47 100644 --- a/src/effects/Mask.h +++ b/src/effects/Mask.h @@ -33,27 +33,16 @@ #include "../EffectBase.h" -#include -#include -#include -#include -#include -#include -#include "../Color.h" -#include "../Exceptions.h" #include "../Json.h" #include "../KeyFrame.h" -#include "../ReaderBase.h" -#include "../FFmpegReader.h" -#include "../QtImageReader.h" -#include "../ChunkReader.h" -#ifdef USE_IMAGEMAGICK - #include "../MagickUtilities.h" - #include "../ImageReader.h" -#endif + +#include +#include namespace openshot { + // Forward declaration + class ReaderBase; /** * @brief This class uses the image libraries to apply alpha (or transparency) masks diff --git a/src/effects/Negate.cpp b/src/effects/Negate.cpp index 18a5d194..9cffd613 100644 --- a/src/effects/Negate.cpp +++ b/src/effects/Negate.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Negate.h" +#include "Negate.h" using namespace openshot; diff --git a/src/effects/Negate.h b/src/effects/Negate.h index c691a86c..c3a67efd 100644 --- a/src/effects/Negate.h +++ b/src/effects/Negate.h @@ -33,16 +33,14 @@ #include "../EffectBase.h" -#include -#include -#include -#include -#include -#include -#include "../Color.h" -#include "../Exceptions.h" +#include "../Frame.h" #include "../KeyFrame.h" +#include +#include + +#include + namespace openshot { diff --git a/src/effects/Pixelate.cpp b/src/effects/Pixelate.cpp index 057b28e2..15c416fb 100644 --- a/src/effects/Pixelate.cpp +++ b/src/effects/Pixelate.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Pixelate.h" +#include "Pixelate.h" #include "Json.h" #include diff --git a/src/effects/Pixelate.h b/src/effects/Pixelate.h index 793f4d46..11223150 100644 --- a/src/effects/Pixelate.h +++ b/src/effects/Pixelate.h @@ -33,12 +33,12 @@ #include "../EffectBase.h" -#include -#include -#include +#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" +#include +#include namespace openshot { diff --git a/src/effects/Saturation.cpp b/src/effects/Saturation.cpp index cad9c08d..df2ddad3 100644 --- a/src/effects/Saturation.cpp +++ b/src/effects/Saturation.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Saturation.h" +#include "Saturation.h" using namespace openshot; diff --git a/src/effects/Shift.cpp b/src/effects/Shift.cpp index ee581591..e591a171 100644 --- a/src/effects/Shift.cpp +++ b/src/effects/Shift.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Shift.h" +#include "Shift.h" using namespace openshot; diff --git a/src/effects/Shift.h b/src/effects/Shift.h index 7a7efbea..86e4ad37 100644 --- a/src/effects/Shift.h +++ b/src/effects/Shift.h @@ -33,12 +33,13 @@ #include "../EffectBase.h" -#include -#include -#include +#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" +#include +#include + namespace openshot { diff --git a/src/effects/Wave.cpp b/src/effects/Wave.cpp index 499fc958..1e796d4c 100644 --- a/src/effects/Wave.cpp +++ b/src/effects/Wave.cpp @@ -28,7 +28,7 @@ * along with OpenShot Library. If not, see . */ -#include "../../include/effects/Wave.h" +#include "Wave.h" using namespace openshot; diff --git a/src/effects/Wave.h b/src/effects/Wave.h index d4759c24..7f6e37b7 100644 --- a/src/effects/Wave.h +++ b/src/effects/Wave.h @@ -33,12 +33,13 @@ #include "../EffectBase.h" -#include -#include -#include +#include "../Frame.h" #include "../Json.h" #include "../KeyFrame.h" +#include +#include + namespace openshot { From 990155ad93add5e445df3a6de43316e110f2812b Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 07:46:11 -0400 Subject: [PATCH 130/148] Update src/CMakeLists.txt for source tree reorg --- src/CMakeLists.txt | 104 ++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 73 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 04121c22..e4b99567 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,7 +85,7 @@ if(ENABLE_MAGICK) # define a global var (used in the C++) add_definitions( -DUSE_IMAGEMAGICK=1 ) - list(APPEND CMAKE_SWIG_FLAGS "-DUSE_IMAGEMAGICK=1") + list(APPEND CMAKE_SWIG_FLAGS -DUSE_IMAGEMAGICK=1) set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE) mark_as_advanced(HAVE_IMAGEMAGICK) @@ -98,24 +98,6 @@ find_package(OpenShotAudio 0.2.0 REQUIRED) # Include Juce headers (needed for compile) include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}) - -################# BLACKMAGIC DECKLINK ################### -# Find BlackMagic DeckLinkAPI libraries -if (ENABLE_BLACKMAGIC) - - find_package(BlackMagic) - - if (BLACKMAGIC_FOUND) - # Include Blackmagic headers (needed for compile) - include_directories(${BLACKMAGIC_INCLUDE_DIR}) - - # define a global var (used in the C++) - add_definitions( -DUSE_BLACKMAGIC=1 ) - list(APPEND CMAKE_SWIG_FLAGS "-DUSE_BLACKMAGIC=1") - endif() - -endif() - ############### PROFILING ################# #set(PROFILER "/usr/lib/libprofiler.so.0.3.2") #set(PROFILER "/usr/lib/libtcmalloc.so.4") @@ -207,9 +189,6 @@ set(QT_PLAYER_SOURCES Qt/VideoRenderer.cpp Qt/VideoRenderWidget.cpp) -# Get list of MOC'able headers -file(GLOB_RECURSE OPENSHOT_QT_HEADERS ${CMAKE_SOURCE_DIR}/include/Qt/*.h) - # Disable RPATH set(CMAKE_MACOSX_RPATH 0) @@ -221,7 +200,6 @@ target_sources(openshot PRIVATE ${OPENSHOT_SOURCES} ${EFFECTS_SOURCES} ${QT_PLAYER_SOURCES} - ${OPENSHOT_QT_HEADERS} ) # Set SONAME and other library properties @@ -230,7 +208,7 @@ set_target_properties(openshot PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_SO_VERSION} INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" - ) +) # Add optional ImageMagic-dependent sources if(ImageMagick_FOUND) @@ -252,11 +230,11 @@ endif() # Location of our includes, both internally and when installed target_include_directories(openshot PRIVATE - ${CMAKE_SOURCE_DIR}/include - ${CMAKE_BINARY_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} PUBLIC - $ - $ + $ + $ $) @@ -378,12 +356,26 @@ if (TARGET RESVG::resvg) #include_directories(${RESVG_INCLUDE_DIRS}) target_link_libraries(openshot PUBLIC RESVG::resvg) - target_compile_definitions(openshot PUBLIC "-DUSE_RESVG=1") - list(APPEND CMAKE_SWIG_FLAGS "-DUSE_RESVG=1") + target_compile_definitions(openshot PUBLIC -DUSE_RESVG=1) + list(APPEND CMAKE_SWIG_FLAGS -DUSE_RESVG=1) set(HAVE_RESVG TRUE CACHE BOOL "Building with Resvg support" FORCE) mark_as_advanced(HAVE_RESVG) +endif() +################# BLACKMAGIC DECKLINK ################### +# Find BlackMagic DeckLinkAPI libraries +if (ENABLE_BLACKMAGIC) + find_package(BlackMagic) + + if (BLACKMAGIC_FOUND) + # Include Blackmagic headers (needed for compile) + target_include_directories(openshot PRIVATE ${BLACKMAGIC_INCLUDE_DIR}) + + # define a preprocessor macro (used in the C++) + target_compile_definitions(openshot PUBLIC -DUSE_BLACKMAGIC=1) + list(APPEND CMAKE_SWIG_FLAGS -DUSE_BLACKMAGIC=1) + endif() endif() ############### LINK LIBRARY ################# @@ -405,56 +397,22 @@ if(WIN32) target_link_libraries(openshot PUBLIC "imagehlp" "dbghelp" ) endif() - -############### CLI EXECUTABLES ################ -# Create test executable -add_executable(openshot-example examples/Example.cpp) - -# Define path to test input files -set(TEST_MEDIA_PATH "${PROJECT_SOURCE_DIR}/src/examples/") -if (WIN32) - string(REPLACE "/" "\\\\" TEST_MEDIA_PATH TEST_MEDIA_PATH) -endif() -target_compile_definitions(openshot-example PRIVATE - -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) - -# Link test executable to the new library -target_link_libraries(openshot-example openshot) - -add_executable(openshot-html-test examples/ExampleHtml.cpp) -target_link_libraries(openshot-html-test openshot Qt5::Gui) - -############### PLAYER EXECUTABLE ################ -# Create test executable -add_executable(openshot-player Qt/demo/main.cpp) - -# Link test executable to the new library -target_link_libraries(openshot-player openshot) - -############### TEST BLACKMAGIC CAPTURE APP ################ -if (BLACKMAGIC_FOUND) - # Create test executable - add_executable(openshot-blackmagic - examples/ExampleBlackmagic.cpp) - - # Link test executable to the new library - target_link_libraries(openshot-blackmagic openshot) -endif() - -############### INCLUDE SWIG BINDINGS ################ -add_subdirectory(bindings) - -############### INSTALL HEADERS & LIBRARY ################ +### +### INSTALL HEADERS & LIBRARY +### # Install primary library install(TARGETS openshot ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}) + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libopenshot) -install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ +install( + DIRECTORY . DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libopenshot - FILES_MATCHING PATTERN "*.h") + FILES_MATCHING PATTERN "*.h" +) ############### CPACK PACKAGING ############## if(MINGW) From 630e7ac4df172608aa26fb45f068caaf491d3981 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 07:46:53 -0400 Subject: [PATCH 131/148] Use new OpenShot::Audio target in CMakeLists.txt FindOpenShotAudio.cmake: Enhance with targets - Also, migrate as much config as possible from CMakeLists.txt files to properties of IMPORTED OpenShot::Audio target (including platform- specific configs) --- cmake/Modules/FindOpenShotAudio.cmake | 101 ++++++++++++++++++++------ src/CMakeLists.txt | 35 ++------- tests/CMakeLists.txt | 20 ----- 3 files changed, 87 insertions(+), 69 deletions(-) diff --git a/cmake/Modules/FindOpenShotAudio.cmake b/cmake/Modules/FindOpenShotAudio.cmake index a0cb9200..0683a864 100644 --- a/cmake/Modules/FindOpenShotAudio.cmake +++ b/cmake/Modules/FindOpenShotAudio.cmake @@ -11,12 +11,14 @@ endif() # Find the libopenshot-audio header files (check env/cache vars first) find_path( - LIBOPENSHOT_AUDIO_INCLUDE_DIR + OpenShotAudio_INCLUDE_DIR JuceHeader.h HINTS ENV LIBOPENSHOT_AUDIO_DIR PATHS ${LIBOPENSHOT_AUDIO_DIR} + ${OpenShotAudio_ROOT} + ${OpenShotAudio_INCLUDE_DIR} PATH_SUFFIXES include/libopenshot-audio libopenshot-audio @@ -26,12 +28,14 @@ find_path( # Find the libopenshot-audio header files (fallback to std. paths) find_path( - LIBOPENSHOT_AUDIO_INCLUDE_DIR + OpenShotAudio_INCLUDE_DIR JuceHeader.h HINTS ENV LIBOPENSHOT_AUDIO_DIR PATHS ${LIBOPENSHOT_AUDIO_DIR} + ${OpenShotAudio_ROOT} + ${OpenShotAudio_INCLUDE_DIR} PATH_SUFFIXES include/libopenshot-audio libopenshot-audio @@ -40,7 +44,7 @@ find_path( # Find libopenshot-audio.so / libopenshot-audio.dll (check env/cache vars first) find_library( - LIBOPENSHOT_AUDIO_LIBRARY + OpenShotAudio_LIBRARY NAMES libopenshot-audio openshot-audio @@ -48,6 +52,8 @@ find_library( ENV LIBOPENSHOT_AUDIO_DIR PATHS ${LIBOPENSHOT_AUDIO_DIR} + ${OpenShotAudio_ROOT} + ${OpenShotAudio_LIBRARY} PATH_SUFFIXES lib/libopenshot-audio libopenshot-audio @@ -57,7 +63,7 @@ find_library( # Find libopenshot-audio.so / libopenshot-audio.dll (fallback) find_library( - LIBOPENSHOT_AUDIO_LIBRARY + OpenShotAudio_LIBRARY NAMES libopenshot-audio openshot-audio @@ -65,39 +71,41 @@ find_library( ENV LIBOPENSHOT_AUDIO_DIR PATHS ${LIBOPENSHOT_AUDIO_DIR} + ${OpenShotAudio_ROOT} + ${OpenShotAudio_LIBRARY} PATH_SUFFIXES lib/libopenshot-audio libopenshot-audio lib ) -set(LIBOPENSHOT_AUDIO_LIBRARIES "${LIBOPENSHOT_AUDIO_LIBRARY}") -set(LIBOPENSHOT_AUDIO_LIBRARY "${LIBOPENSHOT_AUDIO_LIBRARIES}") -set(LIBOPENSHOT_AUDIO_INCLUDE_DIRS "${LIBOPENSHOT_AUDIO_INCLUDE_DIR}") +set(OpenShotAudio_LIBRARIES "${OpenShotAudio_LIBRARY}") +set(OpenShotAudio_LIBRARY "${OpenShotAudio_LIBRARIES}") +set(OpenShotAudio_INCLUDE_DIRS "${OpenShotAudio_INCLUDE_DIR}") -if(LIBOPENSHOT_AUDIO_INCLUDE_DIR AND EXISTS "${LIBOPENSHOT_AUDIO_INCLUDE_DIR}/JuceHeader.h") - file(STRINGS "${LIBOPENSHOT_AUDIO_INCLUDE_DIR}/JuceHeader.h" libosa_version_str +if(OpenShotAudio_INCLUDE_DIR AND EXISTS "${OpenShotAudio_INCLUDE_DIR}/JuceHeader.h") + file(STRINGS "${OpenShotAudio_INCLUDE_DIR}/JuceHeader.h" libosa_version_str REGEX "versionString.*=.*\"[^\"]+\"") if(libosa_version_str MATCHES "versionString.*=.*\"([^\"]+)\"") - set(LIBOPENSHOT_AUDIO_VERSION_STRING ${CMAKE_MATCH_1}) + set(OpenShotAudio_VERSION_STRING ${CMAKE_MATCH_1}) endif() unset(libosa_version_str) string(REGEX REPLACE "^([0-9]+\.[0-9]+\.[0-9]+).*$" "\\1" - LIBOPENSHOT_AUDIO_VERSION "${LIBOPENSHOT_AUDIO_VERSION_STRING}") + OpenShotAudio_VERSION "${OpenShotAudio_VERSION_STRING}") endif() # If we couldn't parse M.N.B version, don't keep any of it -if(NOT LIBOPENSHOT_AUDIO_VERSION) - unset(LIBOPENSHOT_AUDIO_VERSION) - unset(LIBOPENSHOT_AUDIO_VERSION_STRING) +if(NOT OpenShotAudio_VERSION) + unset(OpenShotAudio_VERSION) + unset(OpenShotAudio_VERSION_STRING) endif() # Determine compatibility with requested version in find_package() -if(OpenShotAudio_FIND_VERSION AND LIBOPENSHOT_AUDIO_VERSION) - if("${OpenShotAudio_FIND_VERSION}" STREQUAL "${LIBOPENSHOT_AUDIO_VERSION}") +if(OpenShotAudio_FIND_VERSION AND OpenShotAudio_VERSION) + if("${OpenShotAudio_FIND_VERSION}" STREQUAL "${OpenShotAudio_VERSION}") set(OpenShotAudio_VERSION_EXACT TRUE) endif() - if("${OpenShotAudio_FIND_VERSION}" VERSION_GREATER "${LIBOPENSHOT_AUDIO_VERSION}") + if("${OpenShotAudio_FIND_VERSION}" VERSION_GREATER "${OpenShotAudio_VERSION}") set(OpenShotAudio_VERSION_COMPATIBLE FALSE) else() set(OpenShotAudio_VERSION_COMPATIBLE TRUE) @@ -105,12 +113,63 @@ if(OpenShotAudio_FIND_VERSION AND LIBOPENSHOT_AUDIO_VERSION) endif() include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments and set LIBOPENSHOT_AUDIO_FOUND to TRUE +# handle the QUIETLY and REQUIRED arguments and set OpenShotAudio_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args(OpenShotAudio REQUIRED_VARS - LIBOPENSHOT_AUDIO_LIBRARY - LIBOPENSHOT_AUDIO_INCLUDE_DIRS + OpenShotAudio_LIBRARIES + OpenShotAudio_INCLUDE_DIRS VERSION_VAR - LIBOPENSHOT_AUDIO_VERSION_STRING + OpenShotAudio_VERSION_STRING ) + +if(OpenShotAudio_FOUND) + set(OpenShotAudio_INCLUDE_DIRS "${OpenShotAudio_INCLUDE_DIRS}" + CACHE PATH "The paths to libopenshot-audio's header files" FORCE) + set(OpenShotAudio_LIBRARIES "${OpenShotAudio_LIBRARIES}" + CACHE STRING "The libopenshot-audio library to link with" FORCE) + if(DEFINED OpenShotAudio_VERSION) + set(OpenShotAudio_VERSION ${OpenShotAudio_VERSION} + CACHE STRING "The version of libopenshot-audio detected" FORCE) + endif() +endif() + +if(OpenShotAudio_FOUND AND NOT TARGET OpenShot::Audio) + message(STATUS "Creating IMPORTED target OpenShot::Audio") + if(WIN32) + add_library(OpenShot::Audio UNKNOWN IMPORTED) + else() + add_library(OpenShot::Audio SHARED IMPORTED) + endif() + + set_property(TARGET OpenShot::Audio APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${OpenShotAudio_INCLUDE_DIRS}") + + if(WIN32) + set_property(TARGET OpenShot::Audio APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS -DIGNORE_JUCE_HYPOT=1) + set_property(TARGET OpenShot::Audio APPEND PROPERTY + INTERFACE_COMPILE_OPTIONS -include cmath) + elseif(APPLE) + # Prevent compiling with __cxx11 + set_property(TARGET OpenShot::Audio APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS -D_GLIBCXX_USE_CXX11_ABI=0) + list(APPEND framework_deps + "-framework Carbon" + "-framework Cocoa" + "-framework CoreFoundation" + "-framework CoreAudio" + "-framework CoreMidi" + "-framework IOKit" + "-framework AGL" + "-framework AudioToolbox" + "-framework QuartzCore" + "-lobjc" + "-framework Accelerate" + ) + target_link_libraries(OpenShot::Audio PRIVATE ${framework_deps}) + endif() + + set_property(TARGET OpenShot::Audio APPEND PROPERTY + IMPORTED_LOCATION "${OpenShotAudio_LIBRARIES}") +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e4b99567..16b95f32 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,25 +44,6 @@ if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "Debug") endif() -################ WINDOWS ################## -# Set some compiler options for Windows -# required for libopenshot-audio headers -if (WIN32) - add_definitions( -DIGNORE_JUCE_HYPOT=1 ) - set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -include cmath") -endif() - -if (APPLE) - # If you still get errors compiling with GCC 4.8, mac headers need to be patched: http://hamelot.co.uk/programming/osx-gcc-dispatch_block_t-has-not-been-declared-invalid-typedef/ - set_property(GLOBAL PROPERTY JUCE_MAC "JUCE_MAC") - set(EXTENSION "mm") - set(JUCE_PLATFORM_SPECIFIC_DIR build/macosx/platform_specific_code) - set(JUCE_PLATFORM_SPECIFIC_LIBRARIES "-framework Carbon -framework Cocoa -framework CoreFoundation -framework CoreAudio -framework CoreMidi -framework IOKit -framework AGL -framework AudioToolbox -framework QuartzCore -lobjc -framework Accelerate") - - # Prevent compiling with __cxx11 - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) -endif() - ################ IMAGE MAGICK ################## # Set the Quantum Depth that ImageMagick was built with (default to 16 bits) if(ENABLE_MAGICK) @@ -92,12 +73,6 @@ if(ENABLE_MAGICK) endif() endif() -################# LIBOPENSHOT-AUDIO ################### -# Find JUCE-based openshot Audio libraries -find_package(OpenShotAudio 0.2.0 REQUIRED) - -# Include Juce headers (needed for compile) -include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}) ############### PROFILING ################# #set(PROFILER "/usr/lib/libprofiler.so.0.3.2") #set(PROFILER "/usr/lib/libtcmalloc.so.4") @@ -237,6 +212,10 @@ target_include_directories(openshot $ $) +################# LIBOPENSHOT-AUDIO ################### +# Find JUCE-based openshot Audio libraries +find_package(OpenShotAudio 0.2.0 REQUIRED) +target_link_libraries(openshot PUBLIC OpenShot::Audio) ################### JSONCPP ##################### # Include jsoncpp headers (needed for JSON parsing) @@ -380,9 +359,9 @@ endif() ############### LINK LIBRARY ################# # Link remaining dependency libraries -target_link_libraries(openshot PUBLIC - ${LIBOPENSHOT_AUDIO_LIBRARIES} - ${PROFILER}) +if(DEFINED PROFILER) + target_link_libraries(openshot PUBLIC ${PROFILER}) +endif() if(ImageMagick_FOUND) target_link_libraries(openshot PUBLIC ${ImageMagick_LIBRARIES}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 78d4ae97..146ffad1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -28,19 +28,6 @@ file(TO_NATIVE_PATH "${PROJECT_SOURCE_DIR}/src/examples/" TEST_MEDIA_PATH) add_definitions( -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) -################ WINDOWS ################## -# Set some compiler options for Windows -# required for libopenshot-audio headers -if(WIN32) - add_definitions( -DIGNORE_JUCE_HYPOT=1 ) - set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -include cmath") -endif() - -if (APPLE) - # Prevent compiling with __cxx11 - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) -endif() - ################### UNITTEST++ ##################### # Find UnitTest++ libraries (used for unit testing) find_package(UnitTest++) @@ -88,13 +75,6 @@ if(ENABLE_MAGICK) add_definitions( -DUSE_IMAGEMAGICK=1 ) endif() endif() -################# LIBOPENSHOT-AUDIO ################### -# Find JUCE-based openshot Audio libraries -find_package(OpenShotAudio 0.2.0 REQUIRED) - -# Include Juce headers (needed for compile) -include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}) - ################# BLACKMAGIC DECKLINK ################### if(ENABLE_BLACKMAGIC) From fcebbead83d68f68db358b7b7f472c6e707cb742 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:10:06 -0400 Subject: [PATCH 132/148] tests: Update include paths --- tests/Cache_Tests.cpp | 4 ++-- tests/Clip_Tests.cpp | 2 +- tests/Color_Tests.cpp | 2 +- tests/Coordinate_Tests.cpp | 2 +- tests/DummyReader_Tests.cpp | 2 +- tests/FFmpegReader_Tests.cpp | 2 +- tests/FFmpegWriter_Tests.cpp | 2 +- tests/Fraction_Tests.cpp | 2 +- tests/FrameMapper_Tests.cpp | 2 +- tests/Frame_Tests.cpp | 2 +- tests/ImageWriter_Tests.cpp | 2 +- tests/KeyFrame_Tests.cpp | 2 +- tests/Point_Tests.cpp | 2 +- tests/ReaderBase_Tests.cpp | 2 +- tests/Settings_Tests.cpp | 2 +- tests/Timeline_Tests.cpp | 2 +- 16 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/Cache_Tests.cpp b/tests/Cache_Tests.cpp index ddf698f5..d834a003 100644 --- a/tests/Cache_Tests.cpp +++ b/tests/Cache_Tests.cpp @@ -31,8 +31,8 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" -#include "../include/Json.h" +#include "OpenShot.h" +#include "Json.h" using namespace openshot; diff --git a/tests/Clip_Tests.cpp b/tests/Clip_Tests.cpp index f72d8b05..2f2e850c 100644 --- a/tests/Clip_Tests.cpp +++ b/tests/Clip_Tests.cpp @@ -37,7 +37,7 @@ // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace openshot; diff --git a/tests/Color_Tests.cpp b/tests/Color_Tests.cpp index 82c7d180..81d6070e 100644 --- a/tests/Color_Tests.cpp +++ b/tests/Color_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/Coordinate_Tests.cpp b/tests/Coordinate_Tests.cpp index a666ce8c..b57af38f 100644 --- a/tests/Coordinate_Tests.cpp +++ b/tests/Coordinate_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/DummyReader_Tests.cpp b/tests/DummyReader_Tests.cpp index c72be2d9..b889391f 100644 --- a/tests/DummyReader_Tests.cpp +++ b/tests/DummyReader_Tests.cpp @@ -32,7 +32,7 @@ // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/FFmpegReader_Tests.cpp b/tests/FFmpegReader_Tests.cpp index b79820ad..d6a2d6e7 100644 --- a/tests/FFmpegReader_Tests.cpp +++ b/tests/FFmpegReader_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/FFmpegWriter_Tests.cpp b/tests/FFmpegWriter_Tests.cpp index cb75a118..83764b61 100644 --- a/tests/FFmpegWriter_Tests.cpp +++ b/tests/FFmpegWriter_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/Fraction_Tests.cpp b/tests/Fraction_Tests.cpp index 8f4f5f83..b061ba48 100644 --- a/tests/Fraction_Tests.cpp +++ b/tests/Fraction_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/FrameMapper_Tests.cpp b/tests/FrameMapper_Tests.cpp index 921f3a15..777bdd7b 100644 --- a/tests/FrameMapper_Tests.cpp +++ b/tests/FrameMapper_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/Frame_Tests.cpp b/tests/Frame_Tests.cpp index a92906a3..8c2ebc40 100644 --- a/tests/Frame_Tests.cpp +++ b/tests/Frame_Tests.cpp @@ -32,7 +32,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" #include diff --git a/tests/ImageWriter_Tests.cpp b/tests/ImageWriter_Tests.cpp index bdf73a07..a9b9e07d 100644 --- a/tests/ImageWriter_Tests.cpp +++ b/tests/ImageWriter_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/KeyFrame_Tests.cpp b/tests/KeyFrame_Tests.cpp index dbd81500..84025165 100644 --- a/tests/KeyFrame_Tests.cpp +++ b/tests/KeyFrame_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/Point_Tests.cpp b/tests/Point_Tests.cpp index dfe35d2a..3e63778d 100644 --- a/tests/Point_Tests.cpp +++ b/tests/Point_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/ReaderBase_Tests.cpp b/tests/ReaderBase_Tests.cpp index 776529d3..3e68b40d 100644 --- a/tests/ReaderBase_Tests.cpp +++ b/tests/ReaderBase_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/Settings_Tests.cpp b/tests/Settings_Tests.cpp index 65bd66a6..cc7b86d2 100644 --- a/tests/Settings_Tests.cpp +++ b/tests/Settings_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; diff --git a/tests/Timeline_Tests.cpp b/tests/Timeline_Tests.cpp index 47683b79..536b2133 100644 --- a/tests/Timeline_Tests.cpp +++ b/tests/Timeline_Tests.cpp @@ -31,7 +31,7 @@ #include "UnitTest++.h" // Prevent name clashes with juce::UnitTest #define DONT_SET_USING_JUCE_NAMESPACE 1 -#include "../include/OpenShot.h" +#include "OpenShot.h" using namespace std; using namespace openshot; From 68ed2602b22100b18abf43e2cdef762022286cd8 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:10:33 -0400 Subject: [PATCH 133/148] Examples: Update include paths --- examples/Example.cpp | 4 ++-- examples/ExampleHtml.cpp | 4 ++-- examples/qt-demo/main.cpp | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/Example.cpp b/examples/Example.cpp index c9e61628..2cd77071 100644 --- a/examples/Example.cpp +++ b/examples/Example.cpp @@ -31,8 +31,8 @@ #include #include #include -#include "../../include/OpenShot.h" -#include "../../include/CrashHandler.h" +#include "OpenShot.h" +#include "CrashHandler.h" using namespace openshot; diff --git a/examples/ExampleHtml.cpp b/examples/ExampleHtml.cpp index 576961bc..928a05fe 100644 --- a/examples/ExampleHtml.cpp +++ b/examples/ExampleHtml.cpp @@ -35,8 +35,8 @@ #include #include -#include "../../include/OpenShot.h" -#include "../../include/CrashHandler.h" +#include "OpenShot.h" +#include "CrashHandler.h" using namespace openshot; diff --git a/examples/qt-demo/main.cpp b/examples/qt-demo/main.cpp index 3e5f00ba..8c02795a 100644 --- a/examples/qt-demo/main.cpp +++ b/examples/qt-demo/main.cpp @@ -28,7 +28,9 @@ * along with OpenShot Library. If not, see . */ -#include "../../../include/Qt/PlayerDemo.h" +#include "Qt/PlayerDemo.h" + +#include int main(int argc, char *argv[]) { From 51650016a7a64156a63fb89cfac103f6873ba4a5 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:11:09 -0400 Subject: [PATCH 134/148] Bindings: Update include paths --- bindings/python/CMakeLists.txt | 4 ++-- bindings/ruby/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 6d7ce79e..7bbf4613 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -50,8 +50,8 @@ include_directories(${PYTHON_INCLUDE_PATH}) if (CMAKE_VERSION VERSION_LESS 3.12) ### Include project headers include_directories( - "${PROJECT_SOURCE_DIR}/include" - "${PROJECT_BINARY_DIR}/include") + "${PROJECT_SOURCE_DIR}/src" + "${PROJECT_BINARY_DIR}/src") endif() ### Enable C++ support in SWIG diff --git a/bindings/ruby/CMakeLists.txt b/bindings/ruby/CMakeLists.txt index 2ec16dcf..cd1061c9 100644 --- a/bindings/ruby/CMakeLists.txt +++ b/bindings/ruby/CMakeLists.txt @@ -66,8 +66,8 @@ include_directories(${RUBY_INCLUDE_DIRS}) if (CMAKE_VERSION VERSION_LESS 3.12) ### Include Ruby header files and project headers include_directories( - "${PROJECT_SOURCE_DIR}/include" - "${PROJECT_BINARY_DIR}/include") + "${PROJECT_SOURCE_DIR}/src" + "${PROJECT_BINARY_DIR}/src") endif() ### Enable C++ in SWIG From ce8512b84e95ed78961c00b4912dcaf2e398ae95 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:11:43 -0400 Subject: [PATCH 135/148] Bindings: Use SWIG shared_ptr for Ruby, also --- bindings/ruby/openshot.i | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/bindings/ruby/openshot.i b/bindings/ruby/openshot.i index 2f24d220..349ce54d 100644 --- a/bindings/ruby/openshot.i +++ b/bindings/ruby/openshot.i @@ -46,19 +46,15 @@ /* Unhandled STL Exception Handling */ %include -namespace std { - template class shared_ptr { - public: - T *operator->(); - }; -} +/* Include shared pointer code */ +%include /* Mark these classes as shared_ptr classes */ #ifdef USE_IMAGEMAGICK - %template(SPtrImage) std::shared_ptr; + %shared_ptr(Magick::Image) #endif -%template(SPtrAudioBuffer) std::shared_ptr; -%template(SPtrOpenFrame) std::shared_ptr; +%shared_ptr(juce::AudioSampleBuffer) +%shared_ptr(openshot::Frame) %{ /* Ruby and FFmpeg define competing RSHIFT macros, From 600f5594604ae4aa6e0bc99b57268b1d48e1960c Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:12:06 -0400 Subject: [PATCH 136/148] Bindings: Rename MappedMetadata to MetadataMap --- bindings/python/openshot.i | 2 +- bindings/ruby/openshot.i | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/openshot.i b/bindings/python/openshot.i index 53e514c1..e74b6494 100644 --- a/bindings/python/openshot.i +++ b/bindings/python/openshot.i @@ -237,5 +237,5 @@ %template(PointsVector) std::vector; %template(FieldVector) std::vector; %template(MappedFrameVector) std::vector; -%template(MappedMetadata) std::map; +%template(MetadataMap) std::map; %template(AudioDeviceInfoVector) std::vector; diff --git a/bindings/ruby/openshot.i b/bindings/ruby/openshot.i index 349ce54d..5e6f9311 100644 --- a/bindings/ruby/openshot.i +++ b/bindings/ruby/openshot.i @@ -223,5 +223,5 @@ %template(PointsVector) std::vector; %template(FieldVector) std::vector; %template(MappedFrameVector) std::vector; -%template(MappedMetadata) std::map; +%template(MetadataMap) std::map; %template(AudioDeviceInfoVector) std::vector; From 0fe29540b2e19ef883bab8e2235b3e3405ddfb6f Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:28:07 -0400 Subject: [PATCH 137/148] Examples: Add new CMakeLists.txt for directory --- examples/CMakeLists.txt | 65 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 examples/CMakeLists.txt diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 00000000..87475128 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,65 @@ +####################### CMakeLists.txt (libopenshot) ######################### +# @brief CMake build file for libopenshot (used to generate makefiles) +# @author Jonathan Thomas +# @author FeRD (Frank Dana) +# +# @section LICENSE +# +# Copyright (c) 2008-2020 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(GNUInstallDirs) + +# Dependencies +find_package(Qt5 COMPONENTS Gui REQUIRED) + +############### CLI EXECUTABLES ################ +# Create test executable +add_executable(openshot-example Example.cpp) + +# Define path to test input files +file(TO_NATIVE_PATH "${PROJECT_SOURCE_DIR}/examples/" TEST_MEDIA_PATH) +target_compile_definitions(openshot-example PRIVATE + -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) + +# Link test executable to the new library +target_link_libraries(openshot-example openshot) + +add_executable(openshot-html-test ExampleHtml.cpp) +target_link_libraries(openshot-html-test openshot Qt5::Gui) + +############### PLAYER EXECUTABLE ################ +# Create test executable +add_executable(openshot-player qt-demo/main.cpp) + +set_target_properties(openshot-player PROPERTIES AUTOMOC ON) + +# Link test executable to the new library +target_link_libraries(openshot-player openshot) + +############### TEST BLACKMAGIC CAPTURE APP ################ +if (BLACKMAGIC_FOUND) + # Create test executable + add_executable(openshot-blackmagic + examples/ExampleBlackmagic.cpp) + + # Link test executable to the new library + target_link_libraries(openshot-blackmagic openshot) +endif() From a2d540aa2cc9c9e8079c3cf5de5eca8aa0131f6e Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:15:12 -0400 Subject: [PATCH 138/148] Root CMakeLists: Adjust paths for tree reorg - Also, add missing ENABLE_COVERAGE option(), tweak option processing --- CMakeLists.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38abe4f3..3533e236 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,18 +75,14 @@ option(USE_SYSTEM_JSONCPP "Use system installed JsonCpp, if found" ON) option(DISABLE_BUNDLED_JSONCPP "Don't fall back to bundled JsonCpp" OFF) option(ENABLE_IWYU "Enable 'Include What You Use' scanner (CMake 3.3+)" OFF) option(ENABLE_TESTS "Build unit tests (requires UnitTest++)" ON) +option(ENABLE_COVERAGE "Scan test coverage using gcov and report" OFF) option(ENABLE_DOCS "Build API documentation (requires Doxygen)" ON) option(APPIMAGE_BUILD "Build to install in an AppImage (Linux only)" OFF) option(ENABLE_MAGICK "Use ImageMagick, if available" ON) # Legacy commandline override if (DISABLE_TESTS) - if(ENABLE_COVERAGE) - message(WARNING "ENABLE_COVERAGE requires tests, overriding DISABLE_TESTS") - set(ENABLE_TESTS ON) - else() - set(ENABLE_TESTS OFF) - endif() + set(ENABLE_TESTS OFF) endif() if(DEFINED ENABLE_TESTS) @@ -110,7 +106,7 @@ IF (WIN32) ENDIF(WIN32) ############## Code Coverage ######################### -if (DISABLE_TESTS AND ENABLE_COVERAGE) +if (ENABLE_COVERAGE AND NOT ENABLE_TESTS) message(WARNING "ENABLE_COVERAGE requires tests, overriding DISABLE_TESTS") set(DISABLE_TESTS OFF CACHE BOOL "Don't build unit tests" FORCE) endif() @@ -135,13 +131,17 @@ if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "Release") endif() -############## PROCESS src/ DIRECTORIES ############## +### +### Process subdirectories +### add_subdirectory(src) +add_subdirectory(examples) +add_subdirectory(bindings) ########## Configure Version.h header ############## -configure_file(include/OpenShotVersion.h.in include/OpenShotVersion.h @ONLY) +configure_file(src/OpenShotVersion.h.in src/OpenShotVersion.h @ONLY) # We'll want that installed later -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/OpenShotVersion.h +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/src/OpenShotVersion.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libopenshot) ################### DOCUMENTATION ################### From 10d994dce4ac5e2b626818b0a709f4c5cd78ae61 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:15:35 -0400 Subject: [PATCH 139/148] tests/CmakeLists, Doxyfile.in: Update paths --- Doxyfile.in | 28 ++++++++++++---------------- tests/CMakeLists.txt | 2 +- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/Doxyfile.in b/Doxyfile.in index c47d6e65..343190a1 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -148,7 +148,7 @@ INLINE_INHERITED_MEMB = NO # shortest path that makes the file name unique will be used # The default value is: YES. -FULL_PATH_NAMES = NO +FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand @@ -160,7 +160,7 @@ FULL_PATH_NAMES = NO # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = "@PROJECT_SOURCE_DIR@/src" # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -169,7 +169,7 @@ STRIP_FROM_PATH = # specify the list of include paths that are normally passed to the compiler # using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = "@PROJECT_SOURCE_DIR@/src" # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't @@ -803,9 +803,9 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = "@CMAKE_CURRENT_SOURCE_DIR@/include" \ - "@CMAKE_CURRENT_SOURCE_DIR@/src" \ - "@CMAKE_CURRENT_SOURCE_DIR@/doc" +INPUT = "@PROJECT_SOURCE_DIR@/src" \ + "@PROJECT_SOURCE_DIR@/doc" \ + "@PROJECT_BINARY_DIR@/src/OpenShotVersion.h" # This tag can be used to specify the character encoding of the source files @@ -862,11 +862,7 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = "*/.*" \ - "*/.*/*" \ - "*/src/examples/*" \ - "*/src/bindings/*" \ - "*.py" +EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -883,27 +879,27 @@ EXCLUDE_SYMBOLS = # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = "@CMAKE_CURRENT_SOURCE_DIR@/tests" +EXAMPLE_PATH = "@PROJECT_SOURCE_DIR@/examples" # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. -EXAMPLE_PATTERNS = +EXAMPLE_PATTERNS = "*.cpp" # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. -EXAMPLE_RECURSIVE = NO +EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = "@CMAKE_CURRENT_SOURCE_DIR@" +IMAGE_PATH = "@PROJECT_SOURCE_DIR@" # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -2086,7 +2082,7 @@ INCLUDE_PATH = # used. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = "*.h" # The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 146ffad1..437c6eb0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -25,7 +25,7 @@ ################################################################################ # Test media path, used by unit tests for input data -file(TO_NATIVE_PATH "${PROJECT_SOURCE_DIR}/src/examples/" TEST_MEDIA_PATH) +file(TO_NATIVE_PATH "${PROJECT_SOURCE_DIR}/examples/" TEST_MEDIA_PATH) add_definitions( -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) ################### UNITTEST++ ##################### From 3e9e99207e86f1ec2c198f0c7fb09e35b0c4fccc Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:15:52 -0400 Subject: [PATCH 140/148] Update INSTALL.md instructions for tree reorg --- INSTALL.md | 194 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 116 insertions(+), 78 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index f2d0dda7..7cb1ec40 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -2,72 +2,90 @@ Operating system specific install instructions are located in: -* [doc/INSTALL-LINUX.md][INSTALL-LINUX] -* [doc/INSTALL-MAC.md][INSTALL-MAC] -* [doc/INSTALL-WINDOWS.md][INSTALL-WINDOWS] +* [doc/INSTALL-LINUX.md][INSTALL-LINUX] +* [doc/INSTALL-MAC.md][INSTALL-MAC] +* [doc/INSTALL-WINDOWS.md][INSTALL-WINDOWS] ## Getting Started -The best way to get started with libopenshot, is to learn about our build system, obtain all the source code, -install a development IDE and tools, and better understand our dependencies. So, please read through the -following sections, and follow the instructions. And keep in mind, that your computer is likely different -than the one used when writing these instructions. Your file paths and versions of applications might be -slightly different, so keep an eye out for subtle file path differences in the commands you type. +The best way to get started with libopenshot is to learn about our build system, +obtain all the source code, install a development IDE and tools, +and better understand our dependencies. +So, please read through the following sections, and follow the instructions. +And keep in mind, your computer is likely different than the one used when writing these instructions. +Your file paths and versions of applications will be different, +so you should treat the specifics used here as examples and adjust as necessary. +Keep an eye out for subtle file path differences in the commands you type. ## Dependencies The following libraries are required to build libopenshot. Instructions on how to install these dependencies vary for each operating system. -Libraries and Executables have been labeled in the list below to help distinguish between them. +Libraries and executables have been labeled in the list below to help distinguish between them. #### FFmpeg (libavformat, libavcodec, libavutil, libavdevice, libavresample, libswscale) - * http://www.ffmpeg.org/ **(Library)** - * This library is used to decode and encode video, audio, and image files. It is also used to obtain information about media files, such as frame rate, sample rate, aspect ratio, and other common attributes. +* **(Library)** +* This library is used to decode and encode video, audio, and image files. + It is also used to obtain information about media files, + such as frame rate, sample rate, aspect ratio, and other common attributes. #### ImageMagick++ (libMagick++, libMagickWand, libMagickCore) - * http://www.imagemagick.org/script/magick++.php **(Library)** - * This library is **optional**, and used to decode and encode images. +* **(Library)** +* This library is **optional**, and used to decode and encode images. #### OpenShot Audio Library (libopenshot-audio) - * https://github.com/OpenShot/libopenshot-audio/ **(Library)** - * This library is used to mix, resample, host plug-ins, and play audio. It is based on the JUCE project, which is an outstanding audio library used by many different applications +* **(Library)** +* This library is used to mix, resample, host plug-ins, and play audio. + It is based on the JUCE project, + an outstanding audio library used by many different applications. #### Qt 5 (libqt5) - * http://www.qt.io/qt5/ **(Library)** - * Qt5 is used to display video, store image data, composite images, apply image effects, and many other utility functions, such as file system manipulation, high resolution timers, etc... +* **(Library)** +* Qt5 is used to display video, store image data, composite images, + apply image effects, and many other utility functions, + such as file system manipulation, high resolution timers, etc. #### ZeroMQ (libzmq) - * http://zeromq.org/ **(Library)** - * This library is used to communicate between libopenshot and other applications (publisher / subscriber). Primarily used to send debug data from libopenshot. +* **(Library)** +* This library is used to communicate between libopenshot and other applications (publisher / subscriber). + Primarily used to send debug data from libopenshot. #### OpenMP (`-fopenmp`) - * http://openmp.org/wp/ **(Compiler Flag)** - * If your compiler supports this flag (GCC, Clang, and most other compilers), it provides libopenshot with easy methods of using parallel programming techniques to improve performance and take advantage of multi-core processors. +* **(Compiler Flag)** +* If your compiler supports this flag (GCC, Clang, and most other compilers), + it provides libopenshot with implementations of common parallel programming techniques + used to improve performance and take advantage of multi-core processors. #### CMake (`cmake`) - * http://www.cmake.org/ **(Executable)** - * This executable is used to automate the generation of Makefiles, check for dependencies, and is the backbone of libopenshot’s cross-platform build process. +* **(Executable)** +* This executable is used to automate the generation of Makefiles, + check for dependencies, and is the backbone of libopenshot’s cross-platform build process. #### SWIG (`swig`) - * http://www.swig.org/ **(Executable)** - * This executable is used to generate the Python and Ruby bindings for libopenshot. It is a simple and powerful wrapper for C++ libraries, and supports many languages. +* **(Executable)** +* This executable is used to generate the Python and Ruby bindings for libopenshot. + It is a powerful wrapper for C++ libraries, and supports many languages. #### Python 3 (libpython) - * http://www.python.org/ **(Executable and Library)** - * This library is used by swig to create the Python (version 3+) bindings for libopenshot. This is also the official language used by OpenShot Video Editor (a graphical interface to libopenshot). +* **(Executable and Library)** +* This library is used by swig to create the Python (version 3+) bindings for libopenshot. + This is also the official language used by OpenShot Video Editor (a graphical interface to libopenshot). #### Doxygen (doxygen) - * http://www.stack.nl/~dimitri/doxygen/ **(Executable)** - * This executable is used to auto-generate the documentation used by libopenshot. +* **(Executable)** +* This executable is used to auto-generate the documentation used by libopenshot. #### UnitTest++ (libunittest++) - * https://github.com/unittest-cpp/ **(Library)** - * This library is used to execute unit tests for libopenshot. It contains many macros used to keep our unit testing code very clean and simple. +* **(Library)** +* This library is used to execute unit tests for libopenshot. + It contains many macros used to keep our unit testing code clean and easy-to-follow. ## Obtaining Source Code -The first step in installing libopenshot is to obtain the most recent source code. The source code is available on [GitHub](https://github.com/OpenShot/libopenshot). Use the following command to obtain the latest libopenshot source code. +The first step in installing libopenshot is to obtain the most recent source code. +The source code is available on [GitHub](https://github.com/OpenShot/libopenshot). +Use the following command to obtain the latest libopenshot source code. ``` git clone https://github.com/OpenShot/libopenshot.git @@ -79,27 +97,36 @@ git clone https://github.com/OpenShot/libopenshot-audio.git The source code is divided up into the following folders. #### `build/` -This folder needs to be manually created, and is used by cmake to store the temporary build files, such as makefiles, as well as the final binaries (library and test executables). +This folder needs to be manually created, +and is used by cmake to store the build system control files and generated output +(such as compiled object files and the result of template-file processing) +as well as the final results of the build (library, tool, and test program binaries). #### `cmake/` This folder contains custom modules not included by default in cmake. -CMake find modules are used to discover dependency libraries on the system, and to incorporate their headers and object files. +CMake find modules are used to discover dependency libraries on the system, +and to incorporate their headers and object files. CMake code modules are used to implement build features such as test coverage scanning. #### `doc/` This folder contains documentation and related files. This includes logos and images required by the doxygen-generated API documentation. -#### `include/` -This folder contains all headers (*.h) used by libopenshot. - #### `src/` -This folder contains all source code (*.cpp) used by libopenshot. +This folder contains all source code (`*.cpp`) and headers (`*.h`) for libopenshot. + +#### `bindings/` +This folder contains language bindings for the libopenshot API. +Current supported languages are Python and Ruby. + +#### `examples/` +This folder contains various pieces of example code written in C++, Ruby, or Python. +It also holds the media files (data files) used in examples and unit tests. #### `tests/` This folder contains all unit test code. Each test file (`_Tests.cpp`) contains the tests for the named class. -We use UnitTest++ macros to keep the test code simple and manageable. +We use UnitTest++ macros to keep the test code uncomplicated and manageable. #### `thirdparty/` This folder contains code not written by the OpenShot team. @@ -113,79 +140,90 @@ locates header files and libraries, and generates a build system in various form We use CMake's Makefile generators to compile libopenshot and libopenshot-audio. CMake uses an out-of-source build concept. -This means that the build system, all temporary files, and all generated products are kept separate from the source code. +This means that the build system, +along with all temporary/intermediate files and generated products output during the build, +is kept strictly separate from the source code. This includes Makefiles, object files, and even the final binaries. -While it is possible to build in-tree, we highly recommend you use a `/build/` sub-folder to compile each library. -This prevents the build process from cluttering up the source -code. -These instructions have only been tested with the GNU compiler suite (including MSYS2/MinGW for Windows), and the Clang compiler (including AppleClang on MacOS). +The source code files and directories are never modified by the build system, +which makes it convenient and safe to re-run, reconfigure, or discard builds as needed. +While it is possible to build in-tree, +we highly recommend you use a `/build/` sub-folder to compile each library. + +These instructions have only been tested with the following compiler stacks: +* The GNU compiler suite (including MSYS2/MinGW for Windows) +* The Clang compiler (including AppleClang on MacOS) +Other compilers, including MSVC, are entirely unsupported. +It may be possible to build libopenshot using other compiler stacks, +but most likely not without modifications to the build system which you would have to make yourself. ## CMake Flags (Optional) -There are many different build flags that can be passed to cmake to adjust how libopenshot is compiled. Some of these flags might be required when compiling on certain OSes, just depending on how your build environment is setup. +There are many different build flags that can be passed to cmake to adjust how libopenshot is compiled. +Some of these flags might be required when compiling on certain OSes, +depending on how your build environment is setup. To add a build flag, follow this general syntax: ```sh -$ cmake -DMAGICKCORE_HDRI_ENABLE=1 -DENABLE_TESTS=1 .. +$ cmake -B build -S . -DMAGICKCORE_HDRI_ENABLE=1 -DENABLE_TESTS=1 ... ``` Following are some of the flags you might need to set when generating your build system. ##### Optional behavior: -* `-DENABLE_TESTS=0` (default: `ON`) -* `-DENABLE_COVERAGE=1` (default: `OFF`) -* `-DENABLE_DOCS=0` (default: `ON` if doxygen found) +* `-DENABLE_TESTS=0` (default: `ON`) +* `-DENABLE_COVERAGE=1` (default: `OFF`) +* `-DENABLE_DOCS=0` (default: `ON` if doxygen found) +* `-DENABLE_RUBY=0` (default: `ON` if SWIG and Ruby detected) +* `-DENABLE_PYTHON=0` (default: `ON` if SWIG and Python detected) ##### Compiler configuration: -* `-DCMAKE_BUILD_TYPE=Release`, `-DCMAKE_BUILD_TYPE=Debug` (default: `Debug` if unset) -* `-DCMAKE_CXX_FLAGS="-Wall -Wextra"` (default: CMake builtin defaults for build type) -* `-DCMAKE_CXX_COMPILER=/path/to/g++`, `-DCMAKE_CXX_COMPILER=/path/to/clang++` -* `-DCMAKE_C_COMPILER=/path/to/gcc`, `-DCMAKE_CXX_COMPILER=/path/to/clang` (used by CMake for OS probes) +* `-DCMAKE_BUILD_TYPE=Release`, `-DCMAKE_BUILD_TYPE=Debug` (default: `Release` if unset) +* `-DCMAKE_CXX_FLAGS="-Wall -Wextra"` (default: CMake builtin defaults for build type) +* `-DCMAKE_CXX_COMPILER=/path/to/g++`, `-DCMAKE_CXX_COMPILER=/path/to/clang++` +* `-DCMAKE_C_COMPILER=/path/to/gcc`, `-DCMAKE_CXX_COMPILER=/path/to/clang` (used by CMake for OS probes) ##### Dependency configuration: -* `-DCMAKE_PREFIX_PATH=/extra/path/to/search/for/libraries/` -* `-DUSE_SYSTEM_JSONCPP=0` (default: auto if discovered) -* `-DImageMagick_FOUND=0` (default: auto if discovered) +* `-DCMAKE_PREFIX_PATH=/extra/path/to/search/for/libraries/` +* `-DUSE_SYSTEM_JSONCPP=0` (default: auto if discovered) +* `-DENABLE_MAGICK=0` (default: auto if discovered) ##### To compile bindings for a specific Python installation: -* `-DPYTHON_INCLUDE_DIR=/location/of/python/includes/` -* `-DPYTHON_LIBRARY=/location/of/libpython*.so` -* `-DPYTHON_FRAMEWORKS=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/` (MacOS only) +* `-DPYTHON_INCLUDE_DIR=/location/of/python/includes/` +* `-DPYTHON_LIBRARY=/location/of/libpython*.so` +* `-DPYTHON_FRAMEWORKS=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/` (MacOS only) ##### Only used when building with ImageMagick enabled: -* `-DMAGICKCORE_HDRI_ENABLE=1` (default `0`) -* `-DMAGICKCORE_QUANTUM_DEPTH=8` (default `16`) +* `-DMAGICKCORE_HDRI_ENABLE=1` (default `0`) +* `-DMAGICKCORE_QUANTUM_DEPTH=8` (default `16`) ## Linux Build Instructions (libopenshot-audio) -To compile libopenshot-audio, we need to go through a few additional steps to manually build and install it. Launch a terminal and enter: +To compile libopenshot-audio, we need to build it from source code and install the results. +Launch a terminal and enter: -``` +```sh cd [libopenshot-audio repo folder] -mkdir build -cd build -cmake ../ -make -make install -./src/openshot-audio-test-sound (This should play a test sound) +cmake -B build -S . +cmake --build build +./build/src/openshot-audio-test-sound (This should play a test sound) +cmake --install build ``` ## Linux Build Instructions (libopenshot) Run the following commands to compile libopenshot: -``` +```sh cd [libopenshot repo directory] -mkdir -p build -cd build -cmake ../ -make -make install +cmake -B build -S . +cmake --build build +cmake --build build --target test +cmake --install build ``` For more detailed instructions, please see: -* [doc/INSTALL-LINUX.md][INSTALL-LINUX] -* [doc/INSTALL-MAC.md][INSTALL-MAC] -* [doc/INSTALL-WINDOWS.md][INSTALL-WINDOWS] +* [doc/INSTALL-LINUX.md][INSTALL-LINUX] +* [doc/INSTALL-MAC.md][INSTALL-MAC] +* [doc/INSTALL-WINDOWS.md][INSTALL-WINDOWS] [INSTALL-LINUX]: https://github.com/OpenShot/libopenshot/blob/develop/doc/INSTALL-LINUX.md [INSTALL-MAC]: https://github.com/OpenShot/libopenshot/blob/develop/doc/INSTALL-MAC.md From b0e406be497ec6a083afea38fd0ee8194d4c0260 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 05:17:27 -0400 Subject: [PATCH 141/148] Fix Ruby example script bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ruby: Relax SWIG version for compatibility check - Turns out the Ruby-2.7.0-compatibility commit made it into SWIG 4.0.2 Ruby bindings: Fix all kinds of brokenness - Turns out int64_t function args require stdint.i for auto-conversion. - The imported module name is (still) 'Openshot' — lowercase 's'. - #TIL that accidentally dropping the OUTPUT_NAME config leads to a non-loadable shared library, due to the filename being wrong. --- bindings/python/CMakeLists.txt | 2 +- bindings/ruby/CMakeLists.txt | 14 +++++++++++--- bindings/ruby/openshot.i | 1 + examples/Example.rb | 6 +++--- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 7bbf4613..b020592b 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -54,7 +54,7 @@ if (CMAKE_VERSION VERSION_LESS 3.12) "${PROJECT_BINARY_DIR}/src") endif() -### Enable C++ support in SWIG +### Enable C++ in SWIG set_property(SOURCE openshot.i PROPERTY CPLUSPLUS ON) set_property(SOURCE openshot.i PROPERTY SWIG_MODULE_NAME openshot) diff --git a/bindings/ruby/CMakeLists.txt b/bindings/ruby/CMakeLists.txt index cd1061c9..de47b94f 100644 --- a/bindings/ruby/CMakeLists.txt +++ b/bindings/ruby/CMakeLists.txt @@ -46,11 +46,11 @@ endif() option(SILENCE_RUBY_VERSION_WARNING "Don't warn about possible SWIG incompatibilities with Ruby 2.7.0+" OFF) -if (${RUBY_VERSION} VERSION_GREATER 2.6.9 AND ${SWIG_VERSION} VERSION_LESS 4.0.3) +if (${RUBY_VERSION} VERSION_GREATER 2.6.9 AND ${SWIG_VERSION} VERSION_LESS 4.0.2) if (NOT ${SILENCE_RUBY_VERSION_WARNING}) message(WARNING "\ Ruby 2.7.0+ detected, building the libopenshot Ruby API bindings \ -requires either SWIG 4.0.3 or an older version patched with this commit: \ +requires either SWIG 4.0.2+ or an older version patched with this commit: \ https://github.com/swig/swig/commit/5542cc228ad10bdc5c91107afb77c808c43bf2a4 \ (Recent Fedora and Ubuntu distro packages of SWIG 4.0.1 have already been \ patched.)") @@ -64,7 +64,7 @@ endif() include_directories(${RUBY_INCLUDE_DIRS}) if (CMAKE_VERSION VERSION_LESS 3.12) - ### Include Ruby header files and project headers + ### Include project headers include_directories( "${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/src") @@ -99,6 +99,14 @@ else() swig_add_library(rbopenshot LANGUAGE ruby SOURCES openshot.i) endif() +### Set name of target (with no prefix, since Ruby does not like that) +# XXX: If this is not done exactly this way, the module builds as +# e.g. rbopenshot.so, but its initializer method will be named +# 'Init_openshot()' (via the module name set in the SWIG .i file). +# Which leads to Ruby barfing when it attempts to load the module. +set_target_properties(${SWIG_MODULE_rbopenshot_REAL_NAME} PROPERTIES + PREFIX "" OUTPUT_NAME "openshot") + ### Link the new Ruby wrapper library with libopenshot target_link_libraries(${SWIG_MODULE_rbopenshot_REAL_NAME} PUBLIC ${RUBY_LIBRARY} openshot) diff --git a/bindings/ruby/openshot.i b/bindings/ruby/openshot.i index 5e6f9311..b27510e2 100644 --- a/bindings/ruby/openshot.i +++ b/bindings/ruby/openshot.i @@ -42,6 +42,7 @@ %include "std_list.i" %include "std_vector.i" %include "std_map.i" +%include /* Unhandled STL Exception Handling */ %include diff --git a/examples/Example.rb b/examples/Example.rb index 7d2e4e1a..5e4c7940 100644 --- a/examples/Example.rb +++ b/examples/Example.rb @@ -1,13 +1,13 @@ # Find and load the ruby libopenshot wrapper library -require "./openshot" +require "openshot" # Create a new FFmpegReader and Open it -r = OpenShot::FFmpegReader.new("myfile.mp4") +r = Openshot::FFmpegReader.new("test.mp4") r.Open() # Get frame 1 f = r.GetFrame(1) # Display the frame -r.Display() +f.Display() From aff469535fea1c93362b8fd4c41f8a3ec74a9a06 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 10:22:34 -0400 Subject: [PATCH 142/148] ImageReader/Writer.h: Goose coverage to 100% --- tests/ImageWriter_Tests.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/ImageWriter_Tests.cpp b/tests/ImageWriter_Tests.cpp index 6d3a2e22..eb7b31e9 100644 --- a/tests/ImageWriter_Tests.cpp +++ b/tests/ImageWriter_Tests.cpp @@ -61,6 +61,8 @@ TEST(Gif) /* WRITER ---------------- */ ImageWriter w("output1.gif"); + CHECK_EQUAL(false, w.IsOpen()); + // Check for exception on write-before-open CHECK_THROW(w.WriteFrame(&r, 500, 504), WriterClosed); @@ -79,7 +81,16 @@ TEST(Gif) // Open up the 5th frame from the newly created GIF ImageReader r1("output1.gif[4]"); + + // Basic Reader state queries + CHECK_EQUAL("ImageReader", r1.Name()); + + CacheMemory* c = r1.GetCache(); + CHECK_EQUAL(true, c == nullptr); + + CHECK_EQUAL(false, r1.IsOpen()); r1.Open(); + CHECK_EQUAL(true, r1.IsOpen()); // Verify various settings CHECK_EQUAL(r.info.width, r1.info.width); From 4bd3af0c7150ec3e1b333783d7f24957ef3897be Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 10:41:53 -0400 Subject: [PATCH 143/148] Rename FindResvg, target is now Resvg::Resvg --- .../{FindRESVG.cmake => FindResvg.cmake} | 56 +++++++++---------- src/CMakeLists.txt | 21 ++++--- 2 files changed, 40 insertions(+), 37 deletions(-) rename cmake/Modules/{FindRESVG.cmake => FindResvg.cmake} (59%) diff --git a/cmake/Modules/FindRESVG.cmake b/cmake/Modules/FindResvg.cmake similarity index 59% rename from cmake/Modules/FindRESVG.cmake rename to cmake/Modules/FindResvg.cmake index 0538eacd..452a81c8 100644 --- a/cmake/Modules/FindRESVG.cmake +++ b/cmake/Modules/FindResvg.cmake @@ -1,13 +1,13 @@ # vim: ts=2 sw=2 #[=======================================================================[.rst: -FindRESVG +FindResvg --------- Try to find the shared-library build of resvg, the Rust SVG library IMPORTED targets ^^^^^^^^^^^^^^^^ -This module defines :prop_tgt:`IMPORTED` target ``RESVG::resvg`` when +This module defines :prop_tgt:`IMPORTED` target ``Resvg::Resvg`` when the library and headers are found. Result Variables @@ -17,10 +17,10 @@ This module defines the following variables: :: - RESVG_FOUND - Library and header files found - RESVG_INCLUDE_DIRS - Include directory path - RESVG_LIBRARIES - Link path to the library - RESVG_DEFINITIONS - Compiler switches (currently unused) + Resvg_FOUND - Library and header files found + Resvg_INCLUDE_DIRS - Include directory path + Resvg_LIBRARIES - Link path to the library + Resvg_DEFINITIONS - Compiler switches (currently unused) Backwards compatibility ^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ if(DEFINED RESVGDIR AND CMAKE_VERSION VERSION_GREATER 3.4) BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}) endif() -find_path(RESVG_INCLUDE_DIRS +find_path(Resvg_INCLUDE_DIRS ResvgQt.h PATHS ${RESVGDIR} @@ -62,7 +62,7 @@ find_path(RESVG_INCLUDE_DIRS resvg/capi/include ) -find_library(RESVG_LIBRARIES +find_library(Resvg_LIBRARIES NAMES resvg PATHS ${RESVGDIR} @@ -77,39 +77,39 @@ find_library(RESVG_LIBRARIES resvg/target/release ) -if (RESVG_INCLUDE_DIRS AND RESVG_LIBRARIES) - set(RESVG_FOUND TRUE) +if (Resvg_INCLUDE_DIRS AND Resvg_LIBRARIES) + set(Resvg_FOUND TRUE) endif() -set(RESVG_LIBRARIES ${RESVG_LIBRARIES} CACHE STRING "The Resvg library link path") -set(RESVG_INCLUDE_DIRS ${RESVG_INCLUDE_DIRS} CACHE STRING "The Resvg include directories") -set(RESVG_DEFINITIONS "" CACHE STRING "The Resvg CFLAGS") +set(Resvg_LIBRARIES ${Resvg_LIBRARIES} CACHE STRING "The Resvg library link path") +set(Resvg_INCLUDE_DIRS ${Resvg_INCLUDE_DIRS} CACHE STRING "The Resvg include directories") +set(Resvg_DEFINITIONS "" CACHE STRING "The Resvg CFLAGS") -mark_as_advanced(RESVG_LIBRARIES RESVG_INCLUDE_DIRS RESVG_DEFINITIONS) +mark_as_advanced(Resvg_LIBRARIES Resvg_INCLUDE_DIRS Resvg_DEFINITIONS) # Give a nice error message if some of the required vars are missing. -find_package_handle_standard_args(RESVG - "Could NOT find RESVG, using Qt SVG parsing instead" - RESVG_LIBRARIES RESVG_INCLUDE_DIRS ) +find_package_handle_standard_args(Resvg + "Could NOT find Resvg, using Qt SVG parsing instead" + Resvg_LIBRARIES Resvg_INCLUDE_DIRS ) # Export target -if(RESVG_FOUND AND NOT TARGET RESVG::resvg) - message(STATUS "Creating IMPORTED target RESVG::resvg") +if(Resvg_FOUND AND NOT TARGET Resvg::Resvg) + message(STATUS "Creating IMPORTED target Resvg::Resvg") if (WIN32) # Windows mis-links SHARED library targets - add_library(RESVG::resvg UNKNOWN IMPORTED) + add_library(Resvg::Resvg UNKNOWN IMPORTED) else() # Linux needs SHARED to link because libresvg has no SONAME - add_library(RESVG::resvg SHARED IMPORTED) - set_property(TARGET RESVG::resvg APPEND PROPERTY + add_library(Resvg::Resvg SHARED IMPORTED) + set_property(TARGET Resvg::Resvg APPEND PROPERTY IMPORTED_NO_SONAME TRUE) endif() - set_property(TARGET RESVG::resvg APPEND PROPERTY - INTERFACE_INCLUDE_DIRECTORIES "${RESVG_INCLUDE_DIRS}") + set_property(TARGET Resvg::Resvg APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Resvg_INCLUDE_DIRS}") - set_property(TARGET RESVG::resvg APPEND PROPERTY - INTERFACE_COMPILE_DEFINITIONS "${RESVG_DEFINITIONS}") + set_property(TARGET Resvg::Resvg APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS "${Resvg_DEFINITIONS}") - set_property(TARGET RESVG::resvg APPEND PROPERTY - IMPORTED_LOCATION "${RESVG_LIBRARIES}") + set_property(TARGET Resvg::Resvg APPEND PROPERTY + IMPORTED_LOCATION "${Resvg_LIBRARIES}") endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 16b95f32..0307b987 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -318,22 +318,25 @@ if (TARGET cppzmq) target_link_libraries(openshot PUBLIC cppzmq) endif() -################### RESVG ##################### +### +### Resvg, the Rust SVG library +### + # Migrate some legacy variable names -if(DEFINED RESVGDIR AND NOT DEFINED RESVG_ROOT) - set(RESVG_ROOT ${RESVGDIR}) +if(DEFINED RESVGDIR AND NOT DEFINED Resvg_ROOT) + set(Resvg_ROOT ${RESVGDIR}) endif() -if(DEFINED ENV{RESVGDIR} AND NOT DEFINED RESVG_ROOT) - set(RESVG_ROOT $ENV{RESVGDIR}) +if(DEFINED ENV{RESVGDIR} AND NOT DEFINED Resvg_ROOT) + set(Resvg_ROOT $ENV{RESVGDIR}) endif() # Find resvg library (used for rendering svg files) -find_package(RESVG) +find_package(Resvg) # Include resvg headers (optional SVG library) -if (TARGET RESVG::resvg) - #include_directories(${RESVG_INCLUDE_DIRS}) - target_link_libraries(openshot PUBLIC RESVG::resvg) +if (TARGET Resvg::Resvg) + #include_directories(${Resvg_INCLUDE_DIRS}) + target_link_libraries(openshot PUBLIC Resvg::Resvg) target_compile_definitions(openshot PUBLIC -DUSE_RESVG=1) list(APPEND CMAKE_SWIG_FLAGS -DUSE_RESVG=1) From 1ae52808c7459fd0d8025018eb75544a3f1c2872 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 10:55:59 -0400 Subject: [PATCH 144/148] CMake: Add target for ImageMagick dependency - Parameters assigned to ImageMagick::Magick++ will now follow the 'openshot' shared-library target wherever it's linked, even in build subdirectories that aren't children or siblings of the location where the target was created. - Removed the redundant code duplicating `find_package(ImageMagick)` checks. Multiple dependency scans have only been necessary as a workaround to overcome CMake variables' restricted scope. Targets do not share that limitation. --- cmake/Modules/FindOpenShotAudio.cmake | 17 ++++- src/CMakeLists.txt | 96 ++++++++++++++++----------- tests/CMakeLists.txt | 31 --------- 3 files changed, 71 insertions(+), 73 deletions(-) diff --git a/cmake/Modules/FindOpenShotAudio.cmake b/cmake/Modules/FindOpenShotAudio.cmake index 0683a864..edb5c3fc 100644 --- a/cmake/Modules/FindOpenShotAudio.cmake +++ b/cmake/Modules/FindOpenShotAudio.cmake @@ -145,15 +145,28 @@ if(OpenShotAudio_FOUND AND NOT TARGET OpenShot::Audio) set_property(TARGET OpenShot::Audio APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${OpenShotAudio_INCLUDE_DIRS}") + # Juce requires either DEBUG or NDEBUG to be defined on MacOS. + # -DNDEBUG is set by cmake for all release configs, so add + # -DDEBUG for debug builds. We'll do this for all OSes, even + # though only MacOS requires it. + # The generator expression translates to: + # CONFIG == "DEBUG" ? "DEBUG" : "" + set_property(TARGET OpenShot::Audio APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS $<$:DEBUG>) + + # For the Ruby bindings + set_property(TARGET OpenShot::Audio APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS HAVE_ISFINITE=1) + if(WIN32) set_property(TARGET OpenShot::Audio APPEND PROPERTY - INTERFACE_COMPILE_DEFINITIONS -DIGNORE_JUCE_HYPOT=1) + INTERFACE_COMPILE_DEFINITIONS IGNORE_JUCE_HYPOT=1) set_property(TARGET OpenShot::Audio APPEND PROPERTY INTERFACE_COMPILE_OPTIONS -include cmath) elseif(APPLE) # Prevent compiling with __cxx11 set_property(TARGET OpenShot::Audio APPEND PROPERTY - INTERFACE_COMPILE_DEFINITIONS -D_GLIBCXX_USE_CXX11_ABI=0) + INTERFACE_COMPILE_DEFINITIONS _GLIBCXX_USE_CXX11_ABI=0) list(APPEND framework_deps "-framework Carbon" "-framework Cocoa" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0307b987..776c6301 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -43,36 +43,6 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "Debug") endif() - -################ IMAGE MAGICK ################## -# Set the Quantum Depth that ImageMagick was built with (default to 16 bits) -if(ENABLE_MAGICK) - IF (MAGICKCORE_QUANTUM_DEPTH) - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH} ) - ELSE (MAGICKCORE_QUANTUM_DEPTH) - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 ) - ENDIF (MAGICKCORE_QUANTUM_DEPTH) - IF (MAGICKCORE_HDRI_ENABLE) - add_definitions( -DMAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE} ) - ELSE (MAGICKCORE_HDRI_ENABLE) - add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 ) - ENDIF (MAGICKCORE_HDRI_ENABLE) - - # Find the ImageMagick++ library - find_package(ImageMagick COMPONENTS Magick++ MagickWand MagickCore) - if (ImageMagick_FOUND) - # Include ImageMagick++ headers (needed for compile) - include_directories(${ImageMagick_INCLUDE_DIRS}) - - # define a global var (used in the C++) - add_definitions( -DUSE_IMAGEMAGICK=1 ) - list(APPEND CMAKE_SWIG_FLAGS -DUSE_IMAGEMAGICK=1) - - set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE) - mark_as_advanced(HAVE_IMAGEMAGICK) - endif() -endif() - ############### PROFILING ################# #set(PROFILER "/usr/lib/libprofiler.so.0.3.2") #set(PROFILER "/usr/lib/libtcmalloc.so.4") @@ -185,13 +155,6 @@ set_target_properties(openshot PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" ) -# Add optional ImageMagic-dependent sources -if(ImageMagick_FOUND) - target_sources(openshot PRIVATE - ImageReader.cpp - ImageWriter.cpp - TextReader.cpp) -endif() # BlackMagic related files if(BLACKMAGIC_FOUND) @@ -217,6 +180,62 @@ target_include_directories(openshot find_package(OpenShotAudio 0.2.0 REQUIRED) target_link_libraries(openshot PUBLIC OpenShot::Audio) +### +### ImageMagick +### + +# Find the ImageMagick++ library +find_package(ImageMagick COMPONENTS Magick++ MagickWand MagickCore) + +if(ImageMagick_FOUND) + if(NOT TARGET ImageMagick::Magick++ AND NOT TARGET Magick++_TARGET) + add_library(Magick++_TARGET INTERFACE) + + # Include ImageMagick++ headers (needed for compile) + set_property(TARGET Magick++_TARGET APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${ImageMagick_INCLUDE_DIRS}) + + # Set the Quantum Depth that ImageMagick was built with (default to 16 bits) + if(NOT DEFINED MAGICKCORE_QUANTUM_DEPTH) + set(MAGICKCORE_QUANTUM_DEPTH 16) + endif() + if(NOT DEFINED MAGICKCORE_HDRI_ENABLE) + set(MAGICKCORE_HDRI_ENABLE 0) + endif() + + set_property(TARGET Magick++_TARGET APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS + MAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH}) + set_property(TARGET Magick++_TARGET APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS + MAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE}) + + target_link_libraries(Magick++_TARGET INTERFACE + ${ImageMagick_LIBRARIES}) + + # Alias to our namespaced name + add_library(ImageMagick::Magick++ ALIAS Magick++_TARGET) + + endif() + + # Add optional ImageMagic-dependent sources + target_sources(openshot PRIVATE + ImageReader.cpp + ImageWriter.cpp + TextReader.cpp) + + # define a preprocessor macro (used in the C++ source) + target_compile_definitions(openshot PUBLIC USE_IMAGEMAGICK=1) + list(APPEND CMAKE_SWIG_FLAGS -DUSE_IMAGEMAGICK=1) + + # Link with ImageMagick library + target_link_libraries(openshot PUBLIC ImageMagick::Magick++) + + set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE) + mark_as_advanced(HAVE_IMAGEMAGICK) +endif() + + ################### JSONCPP ##################### # Include jsoncpp headers (needed for JSON parsing) if (USE_SYSTEM_JSONCPP) @@ -366,9 +385,6 @@ if(DEFINED PROFILER) target_link_libraries(openshot PUBLIC ${PROFILER}) endif() -if(ImageMagick_FOUND) - target_link_libraries(openshot PUBLIC ${ImageMagick_LIBRARIES}) -endif() if(BLACKMAGIC_FOUND) target_link_libraries(openshot PUBLIC ${BLACKMAGIC_LIBRARY_DIR}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 437c6eb0..73a812b5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -44,37 +44,6 @@ set_package_properties(UnitTest++ PROPERTIES TYPE RECOMMENDED PURPOSE "Unit testing framework") -################ IMAGE MAGICK ################## -if(ENABLE_MAGICK) - # Set the Quantum Depth that ImageMagick was built with (default to 16 bits) - if(MAGICKCORE_QUANTUM_DEPTH) - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH} ) - else() - add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 ) - endif() - - if(MAGICKCORE_HDRI_ENABLE) - add_definitions( -DMAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE} ) - else() - add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 ) - endif() - - if(OPENSHOT_IMAGEMAGICK_COMPATIBILITY) - add_definitions( -DOPENSHOT_IMAGEMAGICK_COMPATIBILITY=${OPENSHOT_IMAGEMAGICK_COMPATIBILITY} ) - else() - add_definitions( -DOPENSHOT_IMAGEMAGICK_COMPATIBILITY=0 ) - endif() - - # Find the ImageMagick++ library - find_package(ImageMagick COMPONENTS Magick++ MagickWand MagickCore) - if(ImageMagick_FOUND) - # Include ImageMagick++ headers (needed for compile) - include_directories(${ImageMagick_INCLUDE_DIRS}) - - # define a global var (used in the C++) - add_definitions( -DUSE_IMAGEMAGICK=1 ) - endif() -endif() ################# BLACKMAGIC DECKLINK ################### if(ENABLE_BLACKMAGIC) From d910949189d370e9de4072fdb8183fcd3b68bb5e Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 11:04:28 -0400 Subject: [PATCH 145/148] CMake: Code and Find module tweaks - FindOpenShotAudio takes over -DDEBUG, -DHAVE_ISFINITE logic (now set on OpenShot::Audio target when appropriate) - Tweaks to BlackMagic dependency discovery - Reverse the test-disabling logic, `DISABLE_TESTS FALSE` cache variable changed to `ENABLE_TESTS TRUE` --- CMakeLists.txt | 22 +++++++++++--------- bindings/ruby/CMakeLists.txt | 3 --- src/CMakeLists.txt | 39 +++++++++++++----------------------- 3 files changed, 26 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3533e236..ec608257 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,8 +107,8 @@ ENDIF(WIN32) ############## Code Coverage ######################### if (ENABLE_COVERAGE AND NOT ENABLE_TESTS) - message(WARNING "ENABLE_COVERAGE requires tests, overriding DISABLE_TESTS") - set(DISABLE_TESTS OFF CACHE BOOL "Don't build unit tests" FORCE) + message(WARNING "ENABLE_COVERAGE requires unit tests, forcing ENABLE_TESTS") + set(ENABLE_TESTS ON CACHE BOOL "Don't build unit tests" FORCE) endif() if (ENABLE_COVERAGE) @@ -121,11 +121,6 @@ if (ENABLE_COVERAGE) endif() add_feature_info("Coverage" ENABLE_COVERAGE "analyze test coverage and generate report") -# Juce requires either DEBUG or NDEBUG to be defined on MacOS. -# -DNDEBUG is set by cmake for all release configs, so add -# -DDEBUG for debug builds. We'll do this for all OSes, even -# though only MacOS requires it. -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") # Make sure we've picked some build type, default to release if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "Release") @@ -138,12 +133,17 @@ add_subdirectory(src) add_subdirectory(examples) add_subdirectory(bindings) -########## Configure Version.h header ############## +### +### Configure Version.h header +### +# (Note: This comes after the subdirectories, because it needs variables +# set during the dependency discovery in src/CMakeLists.txt) configure_file(src/OpenShotVersion.h.in src/OpenShotVersion.h @ONLY) # We'll want that installed later install(FILES ${CMAKE_CURRENT_BINARY_DIR}/src/OpenShotVersion.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libopenshot) + ################### DOCUMENTATION ################### # Find Doxygen (used for documentation) set(DOCS_ENABLED FALSE) # Only set true if Doxygen is found and configured @@ -180,8 +180,10 @@ if (ENABLE_COVERAGE) NAME coverage LCOV_ARGS "--no-external" EXECUTABLE openshot-test - DEPENDENCIES openshot-test) - message("Generate coverage report with 'make coverage'") + DEPENDENCIES openshot-test + EXCLUDE "bindings" "examples" "${CMAKE_CURRENT_BINARY_DIR}/bindings" + ) + message("Generate coverage report with 'make coverage'") endif() ########### PRINT FEATURE SUMMARY ############## diff --git a/bindings/ruby/CMakeLists.txt b/bindings/ruby/CMakeLists.txt index de47b94f..72d1a985 100644 --- a/bindings/ruby/CMakeLists.txt +++ b/bindings/ruby/CMakeLists.txt @@ -74,9 +74,6 @@ endif() set_property(SOURCE openshot.i PROPERTY CPLUSPLUS ON) set_property(SOURCE openshot.i PROPERTY SWIG_MODULE_NAME openshot) -### Unbreak std::isfinite() -add_definitions(-DHAVE_ISFINITE=1) - ### Suppress a ton of warnings in the generated SWIG C++ code set(SWIG_CXX_FLAGS "-Wno-unused-variable -Wno-unused-function \ -Wno-deprecated-copy -Wno-class-memaccess -Wno-cast-function-type \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 776c6301..f8bd4436 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,15 +34,6 @@ if (POLICY CMP0057) cmake_policy(SET CMP0057 NEW) endif() -# Juce requires either DEBUG or NDEBUG to be defined on MacOS. -# -DNDEBUG is set by cmake for all release configs, so add -# -DDEBUG for debug builds. We'll do this for all OSes, even -# though only MacOS requires it. -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") -# Make sure we've picked some build type, default to debug -if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") - set(CMAKE_BUILD_TYPE "Debug") -endif() ############### PROFILING ################# #set(PROFILER "/usr/lib/libprofiler.so.0.3.2") #set(PROFILER "/usr/lib/libtcmalloc.so.4") @@ -155,16 +146,6 @@ set_target_properties(openshot PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" ) - -# BlackMagic related files -if(BLACKMAGIC_FOUND) - target_sources(openshot PRIVATE - DecklinkInput.cpp - DecklinkReader.cpp - DecklinkOutput.cpp - DecklinkWriter.cpp) -endif() - # Location of our includes, both internally and when installed target_include_directories(openshot PRIVATE @@ -320,7 +301,10 @@ endif() target_link_libraries(openshot PUBLIC OpenMP::OpenMP_CXX) -################### ZEROMQ ##################### +### +### ZeroMQ +### + # Find ZeroMQ library (used for socket communication & logging) find_package(ZeroMQ REQUIRED) # Creates libzmq target @@ -370,9 +354,19 @@ if (ENABLE_BLACKMAGIC) find_package(BlackMagic) if (BLACKMAGIC_FOUND) + # BlackMagic related files + target_sources(openshot PRIVATE + DecklinkInput.cpp + DecklinkReader.cpp + DecklinkOutput.cpp + DecklinkWriter.cpp) + # Include Blackmagic headers (needed for compile) target_include_directories(openshot PRIVATE ${BLACKMAGIC_INCLUDE_DIR}) + # Link libopenshot with BlackMagic libs + target_link_libraries(openshot PUBLIC ${BLACKMAGIC_LIBRARY_DIR}) + # define a preprocessor macro (used in the C++) target_compile_definitions(openshot PUBLIC -DUSE_BLACKMAGIC=1) list(APPEND CMAKE_SWIG_FLAGS -DUSE_BLACKMAGIC=1) @@ -385,11 +379,6 @@ if(DEFINED PROFILER) target_link_libraries(openshot PUBLIC ${PROFILER}) endif() - -if(BLACKMAGIC_FOUND) - target_link_libraries(openshot PUBLIC ${BLACKMAGIC_LIBRARY_DIR}) -endif() - if(WIN32) # Required for exception handling on Windows target_link_libraries(openshot PUBLIC "imagehlp" "dbghelp" ) From 46902b1641b37b82106a19239f260fdbfaa3bc46 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 11:04:41 -0400 Subject: [PATCH 146/148] Codecov: Update excludes for new repo layout --- codecov.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/codecov.yml b/codecov.yml index ee151daa..e00103e7 100644 --- a/codecov.yml +++ b/codecov.yml @@ -7,10 +7,11 @@ coverage: base: pr # Only post a status to pull requests informational: true # Don't block PRs based on coverage stats (yet?) ignore: - - "/src/examples" - - "/src/Qt/demo" - - "/thirdparty/jsoncpp/*.cpp" - - "/thirdparty/jsoncpp/json/*.h" + - "/examples" + - "/bindings" + - "/thirdparty/jsoncpp" - "/doc" - "/cmake" - "/*.md" + - "bindings" + - "src/openshot_autogen" From 3854fe9c0e2efd83c66098a788b0fedf1c1ae6a5 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Sun, 18 Oct 2020 11:14:20 -0400 Subject: [PATCH 147/148] FindOpenShotAudio: Fix linking --- cmake/Modules/FindOpenShotAudio.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Modules/FindOpenShotAudio.cmake b/cmake/Modules/FindOpenShotAudio.cmake index edb5c3fc..4716112e 100644 --- a/cmake/Modules/FindOpenShotAudio.cmake +++ b/cmake/Modules/FindOpenShotAudio.cmake @@ -180,7 +180,7 @@ if(OpenShotAudio_FOUND AND NOT TARGET OpenShot::Audio) "-lobjc" "-framework Accelerate" ) - target_link_libraries(OpenShot::Audio PRIVATE ${framework_deps}) + target_link_libraries(OpenShot::Audio INTERFACE ${framework_deps}) endif() set_property(TARGET OpenShot::Audio APPEND PROPERTY From b741eff7f2cb2ca6b9d563e632e56b0dd2c3f1c3 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Mon, 19 Oct 2020 04:33:58 -0400 Subject: [PATCH 148/148] INSTALL.md: Fix Markdown style --- INSTALL.md | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 7cb1ec40..b1ddc796 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -24,8 +24,8 @@ Instructions on how to install these dependencies vary for each operating system Libraries and executables have been labeled in the list below to help distinguish between them. #### FFmpeg (libavformat, libavcodec, libavutil, libavdevice, libavresample, libswscale) - * **(Library)** + * This library is used to decode and encode video, audio, and image files. It is also used to obtain information about media files, such as frame rate, sample rate, aspect ratio, and other common attributes. @@ -36,39 +36,46 @@ Libraries and executables have been labeled in the list below to help distinguis #### OpenShot Audio Library (libopenshot-audio) * **(Library)** + * This library is used to mix, resample, host plug-ins, and play audio. It is based on the JUCE project, an outstanding audio library used by many different applications. #### Qt 5 (libqt5) * **(Library)** + * Qt5 is used to display video, store image data, composite images, apply image effects, and many other utility functions, such as file system manipulation, high resolution timers, etc. #### ZeroMQ (libzmq) * **(Library)** + * This library is used to communicate between libopenshot and other applications (publisher / subscriber). Primarily used to send debug data from libopenshot. #### OpenMP (`-fopenmp`) * **(Compiler Flag)** + * If your compiler supports this flag (GCC, Clang, and most other compilers), it provides libopenshot with implementations of common parallel programming techniques used to improve performance and take advantage of multi-core processors. #### CMake (`cmake`) * **(Executable)** + * This executable is used to automate the generation of Makefiles, check for dependencies, and is the backbone of libopenshot’s cross-platform build process. #### SWIG (`swig`) * **(Executable)** + * This executable is used to generate the Python and Ruby bindings for libopenshot. It is a powerful wrapper for C++ libraries, and supports many languages. #### Python 3 (libpython) * **(Executable and Library)** + * This library is used by swig to create the Python (version 3+) bindings for libopenshot. This is also the official language used by OpenShot Video Editor (a graphical interface to libopenshot). @@ -78,6 +85,7 @@ Libraries and executables have been labeled in the list below to help distinguis #### UnitTest++ (libunittest++) * **(Library)** + * This library is used to execute unit tests for libopenshot. It contains many macros used to keep our unit testing code clean and easy-to-follow. @@ -87,7 +95,7 @@ The first step in installing libopenshot is to obtain the most recent source cod The source code is available on [GitHub](https://github.com/OpenShot/libopenshot). Use the following command to obtain the latest libopenshot source code. -``` +```sh git clone https://github.com/OpenShot/libopenshot.git git clone https://github.com/OpenShot/libopenshot-audio.git ``` @@ -152,11 +160,12 @@ we highly recommend you use a `/build/` sub-folder to compile each library. These instructions have only been tested with the following compiler stacks: * The GNU compiler suite (including MSYS2/MinGW for Windows) * The Clang compiler (including AppleClang on MacOS) + Other compilers, including MSVC, are entirely unsupported. It may be possible to build libopenshot using other compiler stacks, but most likely not without modifications to the build system which you would have to make yourself. -## CMake Flags (Optional) +### CMake Flags (Optional) There are many different build flags that can be passed to cmake to adjust how libopenshot is compiled. Some of these flags might be required when compiling on certain OSes, depending on how your build environment is setup. @@ -164,35 +173,35 @@ depending on how your build environment is setup. To add a build flag, follow this general syntax: ```sh -$ cmake -B build -S . -DMAGICKCORE_HDRI_ENABLE=1 -DENABLE_TESTS=1 ... +cmake -B build -S . -DMAGICKCORE_HDRI_ENABLE=1 -DENABLE_TESTS=1 ... ``` Following are some of the flags you might need to set when generating your build system. -##### Optional behavior: +#### Optional behaviors of the build system * `-DENABLE_TESTS=0` (default: `ON`) * `-DENABLE_COVERAGE=1` (default: `OFF`) * `-DENABLE_DOCS=0` (default: `ON` if doxygen found) * `-DENABLE_RUBY=0` (default: `ON` if SWIG and Ruby detected) * `-DENABLE_PYTHON=0` (default: `ON` if SWIG and Python detected) -##### Compiler configuration: +#### Options to configure the compiler * `-DCMAKE_BUILD_TYPE=Release`, `-DCMAKE_BUILD_TYPE=Debug` (default: `Release` if unset) * `-DCMAKE_CXX_FLAGS="-Wall -Wextra"` (default: CMake builtin defaults for build type) * `-DCMAKE_CXX_COMPILER=/path/to/g++`, `-DCMAKE_CXX_COMPILER=/path/to/clang++` * `-DCMAKE_C_COMPILER=/path/to/gcc`, `-DCMAKE_CXX_COMPILER=/path/to/clang` (used by CMake for OS probes) -##### Dependency configuration: +#### Options to configure dependencies * `-DCMAKE_PREFIX_PATH=/extra/path/to/search/for/libraries/` * `-DUSE_SYSTEM_JSONCPP=0` (default: auto if discovered) * `-DENABLE_MAGICK=0` (default: auto if discovered) -##### To compile bindings for a specific Python installation: +#### Options to compile bindings for a specific Python installation * `-DPYTHON_INCLUDE_DIR=/location/of/python/includes/` * `-DPYTHON_LIBRARY=/location/of/libpython*.so` * `-DPYTHON_FRAMEWORKS=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/` (MacOS only) -##### Only used when building with ImageMagick enabled: +#### Options only relevant when building with ImageMagick * `-DMAGICKCORE_HDRI_ENABLE=1` (default `0`) * `-DMAGICKCORE_QUANTUM_DEPTH=8` (default `16`)