├── .gitattributes ├── .github ├── dependabot.yml ├── labeler.yml ├── stale.yml └── workflows │ ├── ci.yml │ ├── label-merge-conflicts.yml │ └── reuse.yml ├── .gitignore ├── .gitlab-ci.yml ├── .gitmodules ├── .reuse └── dep5 ├── AUTHORS ├── CMakeLists.txt ├── COPYING ├── INSTALL.md ├── LICENSES ├── BSD-3-Clause.txt ├── CC-BY-3.0.txt ├── CC0-1.0.txt ├── LGPL-3.0-or-later.txt └── MIT.txt ├── README.md ├── bindings ├── CMakeLists.txt ├── godot │ ├── CMakeLists.txt │ ├── libopenshot_godot.gdextension │ ├── osg_timeline.cpp │ ├── osg_timeline.h │ ├── register_types.cpp │ └── register_types.h ├── java │ ├── CMakeLists.txt │ └── openshot.i ├── python │ ├── CMakeLists.txt │ └── openshot.i └── ruby │ ├── CMakeLists.txt │ └── openshot.i ├── cmake └── Modules │ ├── CodeCoverage.cmake │ ├── FindFFmpeg.cmake │ ├── FindResvg.cmake │ ├── FindZeroMQ.cmake │ ├── Findbabl.cmake │ └── Findjsoncpp.cmake ├── codecov.yml ├── doc ├── HW-ACCEL.md ├── INSTALL-LINUX.md ├── INSTALL-MAC.md ├── INSTALL-WINDOWS.md └── images │ ├── FrameMapper.png │ ├── Playhead.png │ ├── Timeline_Layers.png │ ├── logo.png │ └── logo.svg ├── examples ├── 1F0CF.svg ├── CMakeLists.txt ├── Example.cpp ├── Example.py ├── Example.rb ├── ExampleHtml.cpp ├── ExampleHtml.py ├── Example_opencv.cpp ├── OpenShot Wipe Tests.py ├── back.png ├── eq_sphere.png ├── example-lut.cube ├── example_profile1 ├── example_profile2 ├── final-composite.png ├── fisheye.png ├── front.png ├── front3.png ├── interlaced.png ├── mask.png ├── mask2.png ├── output-final.png ├── piano-mono.wav ├── piano.wav ├── qt-demo │ └── main.cpp ├── run.mp4 ├── sine.wav ├── sintel_trailer-720p.mp4 ├── test.avi ├── test.mp4 ├── test.wav ├── test1.mp4 ├── test_video.mp4 └── test_video_sync.mp4 ├── src ├── AudioBufferSource.cpp ├── AudioBufferSource.h ├── AudioDevices.cpp ├── AudioDevices.h ├── AudioLocation.h ├── AudioReaderSource.cpp ├── AudioReaderSource.h ├── AudioResampler.cpp ├── AudioResampler.h ├── AudioWaveformer.cpp ├── AudioWaveformer.h ├── CMakeLists.txt ├── CVObjectDetection.cpp ├── CVObjectDetection.h ├── CVStabilization.cpp ├── CVStabilization.h ├── CVTracker.cpp ├── CVTracker.h ├── CacheBase.cpp ├── CacheBase.h ├── CacheDisk.cpp ├── CacheDisk.h ├── CacheMemory.cpp ├── CacheMemory.h ├── ChannelLayouts.h ├── ChunkReader.cpp ├── ChunkReader.h ├── ChunkWriter.cpp ├── ChunkWriter.h ├── Clip.cpp ├── Clip.h ├── ClipBase.cpp ├── ClipBase.h ├── ClipProcessingJobs.cpp ├── ClipProcessingJobs.h ├── Color.cpp ├── Color.h ├── Coordinate.cpp ├── Coordinate.h ├── CrashHandler.cpp ├── CrashHandler.h ├── DummyReader.cpp ├── DummyReader.h ├── EffectBase.cpp ├── EffectBase.h ├── EffectInfo.cpp ├── EffectInfo.h ├── Effects.h ├── Enums.h ├── Exceptions.h ├── FFmpegReader.cpp ├── FFmpegReader.h ├── FFmpegUtilities.h ├── FFmpegWriter.cpp ├── FFmpegWriter.h ├── Fraction.cpp ├── Fraction.h ├── Frame.cpp ├── Frame.h ├── FrameMapper.cpp ├── FrameMapper.h ├── ImageReader.cpp ├── ImageReader.h ├── ImageWriter.cpp ├── ImageWriter.h ├── Json.cpp ├── Json.h ├── KeyFrame.cpp ├── KeyFrame.h ├── MagickUtilities.cpp ├── MagickUtilities.h ├── OpenCVUtilities.h ├── OpenMPUtilities.h ├── OpenShot.h ├── OpenShotVersion.cpp ├── OpenShotVersion.h.in ├── PlayerBase.cpp ├── PlayerBase.h ├── Point.cpp ├── Point.h ├── ProcessingController.h ├── Profiles.cpp ├── Profiles.h ├── Qt │ ├── AudioPlaybackThread.cpp │ ├── AudioPlaybackThread.h │ ├── PlayerDemo.cpp │ ├── PlayerDemo.h │ ├── PlayerPrivate.cpp │ ├── PlayerPrivate.h │ ├── VideoCacheThread.cpp │ ├── VideoCacheThread.h │ ├── VideoPlaybackThread.cpp │ ├── VideoPlaybackThread.h │ ├── VideoRenderWidget.cpp │ ├── VideoRenderWidget.h │ ├── VideoRenderer.cpp │ └── VideoRenderer.h ├── QtHtmlReader.cpp ├── QtHtmlReader.h ├── QtImageReader.cpp ├── QtImageReader.h ├── QtPlayer.cpp ├── QtPlayer.h ├── QtTextReader.cpp ├── QtTextReader.h ├── QtUtilities.h ├── ReaderBase.cpp ├── ReaderBase.h ├── RendererBase.cpp ├── RendererBase.h ├── Settings.cpp ├── Settings.h ├── TextReader.cpp ├── TextReader.h ├── Timeline.cpp ├── Timeline.h ├── TimelineBase.cpp ├── TimelineBase.h ├── TrackedObjectBBox.cpp ├── TrackedObjectBBox.h ├── TrackedObjectBase.cpp ├── TrackedObjectBase.h ├── WriterBase.cpp ├── WriterBase.h ├── ZmqLogger.cpp ├── ZmqLogger.h ├── audio_effects │ ├── Compressor.cpp │ ├── Compressor.h │ ├── Delay.cpp │ ├── Delay.h │ ├── Distortion.cpp │ ├── Distortion.h │ ├── Echo.cpp │ ├── Echo.h │ ├── Expander.cpp │ ├── Expander.h │ ├── Noise.cpp │ ├── Noise.h │ ├── ParametricEQ.cpp │ ├── ParametricEQ.h │ ├── Robotization.cpp │ ├── Robotization.h │ ├── STFT.cpp │ ├── STFT.h │ ├── Whisperization.cpp │ └── Whisperization.h ├── effects │ ├── Bars.cpp │ ├── Bars.h │ ├── Blur.cpp │ ├── Blur.h │ ├── Brightness.cpp │ ├── Brightness.h │ ├── Caption.cpp │ ├── Caption.h │ ├── ChromaKey.cpp │ ├── ChromaKey.h │ ├── ColorMap.cpp │ ├── ColorMap.h │ ├── ColorShift.cpp │ ├── ColorShift.h │ ├── Crop.cpp │ ├── Crop.h │ ├── Deinterlace.cpp │ ├── Deinterlace.h │ ├── Hue.cpp │ ├── Hue.h │ ├── LensFlare.cpp │ ├── LensFlare.h │ ├── Mask.cpp │ ├── Mask.h │ ├── Negate.cpp │ ├── Negate.h │ ├── ObjectDetection.cpp │ ├── ObjectDetection.h │ ├── Outline.cpp │ ├── Outline.h │ ├── Pixelate.cpp │ ├── Pixelate.h │ ├── Saturation.cpp │ ├── Saturation.h │ ├── Sharpen.cpp │ ├── Sharpen.h │ ├── Shift.cpp │ ├── Shift.h │ ├── SphericalProjection.cpp │ ├── SphericalProjection.h │ ├── Stabilizer.cpp │ ├── Stabilizer.h │ ├── Tracker.cpp │ ├── Tracker.h │ ├── Wave.cpp │ └── Wave.h ├── objdetectdata.proto ├── sort_filter │ ├── Hungarian.cpp │ ├── Hungarian.h │ ├── KalmanTracker.cpp │ ├── KalmanTracker.h │ ├── sort.cpp │ └── sort.hpp ├── stabilizedata.proto └── trackerdata.proto ├── tests ├── AudioDeviceManager.cpp ├── AudioWaveformer.cpp ├── CMakeLists.txt ├── CVObjectDetection.cpp ├── CVOutline.cpp ├── CVStabilizer.cpp ├── CVTracker.cpp ├── CacheDisk.cpp ├── CacheMemory.cpp ├── Caption.cpp ├── ChromaKey.cpp ├── Clip.cpp ├── Color.cpp ├── ColorMap.cpp ├── Coordinate.cpp ├── Crop.cpp ├── DummyReader.cpp ├── FFmpegReader.cpp ├── FFmpegWriter.cpp ├── Fraction.cpp ├── Frame.cpp ├── FrameMapper.cpp ├── ImageWriter.cpp ├── KeyFrame.cpp ├── LensFlare.cpp ├── Point.cpp ├── Profiles.cpp ├── QtImageReader.cpp ├── ReaderBase.cpp ├── Settings.cpp ├── Sharpen.cpp ├── SphericalEffect.cpp ├── SphericalMetadata.cpp ├── Timeline.cpp ├── VideoCacheThread.cpp ├── catch2v2.h.in ├── catch2v3.h.in └── catch_main.cpp ├── thirdparty └── jsoncpp │ ├── LICENSE │ ├── json │ ├── json-forwards.h │ └── json.h │ └── jsoncpp.cpp └── version.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | * text=auto 6 | 7 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | # Set update schedule for GitHub Actions 6 | 7 | version: 2 8 | updates: 9 | 10 | - package-ecosystem: "github-actions" 11 | directory: "/" 12 | schedule: 13 | interval: "weekly" 14 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | # Add 'build' label to CMake changes 6 | build: 7 | - /**/CMakeList.txt 8 | - /cmake/**/*.cmake 9 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | # Number of days of inactivity before an issue becomes stale 6 | daysUntilStale: 90 7 | # Number of days of inactivity before a stale issue is closed 8 | daysUntilClose: 10 9 | # Issues with these labels will never be considered stale 10 | exemptLabels: 11 | - pinned 12 | - security 13 | - enhancement 14 | # Label to use when marking an issue as stale 15 | staleLabel: stale 16 | # Comment to post when marking an issue as stale. Set to `false` to disable 17 | markComment: | 18 | 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. 19 | 20 | This issue will be closed, as it meets the following criteria: 21 | - No activity in the past 90 days 22 | - No one is assigned to this issue 23 | 24 | We'd like to ask you to help us out and determine whether this issue should be reopened. 25 | - 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. 26 | - If this issue is proposing a new feature, please can you verify whether the feature proposal is still relevant. 27 | 28 | Thanks again for your help! 29 | # Comment to post when closing a stale issue. Set to `false` to disable 30 | closeComment: false 31 | # Only close issues 32 | only: issues 33 | # Don't close issues which are assigned to somebody 34 | exemptAssignees: true 35 | -------------------------------------------------------------------------------- /.github/workflows/label-merge-conflicts.yml: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | name: Label merge conflicts 6 | 7 | # Controls when the action will run. Triggers the workflow on push to repo branches 8 | # (It shouldn't run on pull requests, as it won't have the right credentials to 9 | # edit labels on other PRs.) 10 | on: push 11 | 12 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 13 | jobs: 14 | triage: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: eps1lon/actions-label-merge-conflict@v2.1.0 18 | with: 19 | # Token for the repository. Can be passed in using {{ secrets.GITHUB_TOKEN }} 20 | repoToken: ${{ secrets.GITHUB_TOKEN }} 21 | # Name of the label which indicates that the branch is dirty 22 | dirtyLabel: 'conflicts' 23 | # Number of seconds after which the action runs again if the mergable state is unknown. 24 | retryAfter: 60 25 | # Number of times the action retries calculating the mergable state 26 | retryMax: 5 27 | # String. Comment to add when the pull request is conflicting. Supports markdown. 28 | commentOnDirty: 'Merge conflicts have been detected on this PR, please resolve.' 29 | 30 | -------------------------------------------------------------------------------- /.github/workflows/reuse.yml: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | # Workflow to run 'reuse lint' via the reuse-action script, 6 | # which will flag any files added or changed in the repo 7 | # that don't have valid, verifiable license data associated 8 | # with them. See the .reuse/ directory in the repo, and 9 | # for more information visit https://reuse.software/ 10 | 11 | name: Validate source licensing 12 | 13 | on: 14 | # Triggers the workflow on push or pull request events but only for the develop branch 15 | push: 16 | branches: [ develop ] 17 | pull_request: 18 | branches: [ develop ] 19 | # Allows you to run this workflow manually from the Actions tab 20 | workflow_dispatch: 21 | jobs: 22 | check: 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v3 27 | - name: REUSE Compliance Check 28 | uses: fsfe/reuse-action@v2.0.0 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | /build* 6 | *.DS_Store 7 | .pydevproject 8 | .settings 9 | .idea/* 10 | .project 11 | .cproject 12 | /.metadata/ 13 | cmake-build-debug/* 14 | tags 15 | *~ 16 | **/.claude/* 17 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/godot-cpp"] 2 | path = external/godot-cpp 3 | url = https://github.com/godotengine/godot-cpp 4 | -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: libopenshot 3 | Upstream-Contact: Jonathan Thomas 4 | Source: https://github.com/OpenShot/libopenshot 5 | 6 | Files: examples/*.png examples/*.svg examples/*.wav examples/*.mp4 examples/* doc/images/* 7 | Copyright: OpenShot Studios, LLC 8 | License: LGPL-3.0-or-later 9 | 10 | Files: examples/sintel_trailer-720p.mp4 11 | Copyright: © copyright Blender Foundation | durian.blender.org 12 | License: CC-BY-3.0 13 | 14 | Files: thirdparty/jsoncpp/* 15 | Copyright: Copyright (c) 2007-2010 by Baptiste Lepilleur and The JsonCpp Authors 16 | License: CC0-1.0 or MIT 17 | 18 | Files: external/godot-cpp/* 19 | Copyright: 2017-present Godot Engine contributors 20 | License: MIT 21 | 22 | Files: bindings/godot/libopenshot_godot.gdextension 23 | Copyright: OpenShot Studios, LLC 24 | License: LGPL-3.0-or-later 25 | 26 | Files: .gitmodules 27 | Copyright: OpenShot Studios, LLC 28 | License: LGPL-3.0-or-later -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | Jonathan Thomas 6 | Duzy Chan -------------------------------------------------------------------------------- /LICENSES/BSD-3-Clause.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) . All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /bindings/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ####################### CMakeLists.txt (libopenshot) ######################### 2 | # @brief CMake build file for libopenshot (used to generate makefiles) 3 | # @author Jonathan Thomas 4 | # 5 | # @section LICENSE 6 | # 7 | # Copyright (c) 2008-2024 OpenShot Studios, LLC 8 | # 9 | # SPDX-License-Identifier: LGPL-3.0-or-later 10 | 11 | IF(NOT DEFINED ENABLE_PYTHON) 12 | SET(ENABLE_PYTHON 1) 13 | ENDIF() 14 | 15 | IF(NOT DEFINED ENABLE_RUBY) 16 | SET(ENABLE_RUBY 1) 17 | ENDIF() 18 | 19 | IF(NOT DEFINED ENABLE_JAVA) 20 | SET(ENABLE_JAVA 0) 21 | ENDIF() 22 | 23 | IF(NOT DEFINED ENABLE_GODOT) 24 | SET(ENABLE_GODOT 0) 25 | ENDIF() 26 | 27 | ############### INCLUDE EACH LANGUAGE BINDING ################ 28 | IF (ENABLE_PYTHON) 29 | add_subdirectory(python) 30 | ENDIF (ENABLE_PYTHON) 31 | 32 | IF (ENABLE_RUBY) 33 | add_subdirectory(ruby) 34 | ENDIF (ENABLE_RUBY) 35 | 36 | IF (ENABLE_JAVA) 37 | add_subdirectory(java) 38 | ENDIF (ENABLE_JAVA) 39 | 40 | IF (ENABLE_GODOT) 41 | add_subdirectory(godot) 42 | ENDIF (ENABLE_GODOT) -------------------------------------------------------------------------------- /bindings/godot/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ####################### CMakeLists.txt (libopenshot) ######################### 2 | # @brief CMake build file for libopenshot-godot (used to generate GDExtension) 3 | # @author Jonathan Thomas 4 | # 5 | # @section LICENSE 6 | # 7 | # Copyright (c) 2008-2025 OpenShot Studios, LLC 8 | # 9 | # SPDX-License-Identifier: LGPL-3.0-or-later 10 | 11 | cmake_minimum_required(VERSION 3.17) 12 | 13 | project(libopenshot_godot) 14 | 15 | # Clone and build GoDot CPP 16 | # git submodule add https://github.com/godotengine/godot-cpp.git external/godot-cpp 17 | # git submodule update --init --recursive 18 | # cd external/godot-cpp 19 | # scons -c 20 | # scons platform=linux generate_bindings=yes -j$(nproc) 21 | set(GODOT_CPP_PATH ${CMAKE_SOURCE_DIR}/external/godot-cpp) 22 | 23 | include_directories( 24 | ${GODOT_CPP_PATH}/include 25 | ${GODOT_CPP_PATH}/gen/include 26 | ${GODOT_CPP_PATH}/gdextension 27 | ${CMAKE_SOURCE_DIR}/include 28 | ) 29 | 30 | link_directories(${GODOT_CPP_PATH}/bin) 31 | 32 | add_library(libopenshot_godot SHARED 33 | register_types.cpp 34 | osg_timeline.cpp 35 | ) 36 | 37 | target_link_libraries(libopenshot_godot 38 | ${GODOT_CPP_PATH}/bin/libgodot-cpp.linux.template_debug.x86_64.a 39 | openshot 40 | ) 41 | 42 | set_target_properties(libopenshot_godot PROPERTIES 43 | OUTPUT_NAME "libopenshot_godot" 44 | PREFIX "" 45 | ) 46 | -------------------------------------------------------------------------------- /bindings/godot/libopenshot_godot.gdextension: -------------------------------------------------------------------------------- 1 | [configuration] 2 | 3 | entry_symbol = "example_library_init" 4 | compatibility_minimum = "4.1" 5 | 6 | [libraries] 7 | linux.debug.x86_64 = "res://bin/libopenshot_godot.so" -------------------------------------------------------------------------------- /bindings/godot/osg_timeline.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for Godot wrapper 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "osg_timeline.h" 14 | #include "FFmpegReader.h" 15 | #include "Profiles.h" 16 | #include "Timeline.h" 17 | 18 | #include "godot_cpp/classes/image.hpp" 19 | #include "godot_cpp/classes/image_texture.hpp" 20 | #include "godot_cpp/variant/utility_functions.hpp" 21 | #include "godot_cpp/core/class_db.hpp" 22 | 23 | using namespace godot; 24 | 25 | void ExampleClass::_bind_methods() { 26 | ClassDB::bind_method(D_METHOD("load_file", "path"), &ExampleClass::load_file); 27 | ClassDB::bind_method(D_METHOD("print_type", "variant"), &ExampleClass::print_type); 28 | ClassDB::bind_method(D_METHOD("print_json"), &ExampleClass::print_json); 29 | ClassDB::bind_method(D_METHOD("get_image", "frame_number"), &ExampleClass::get_image); 30 | } 31 | 32 | ExampleClass::ExampleClass() { 33 | constructor_called = true; 34 | print_line("Constructor called!"); 35 | 36 | // Create example timeline 37 | timeline = new openshot::Timeline( 38 | 1920, 1080, 39 | openshot::Fraction(30, 1), 40 | 44100, 2, 41 | openshot::LAYOUT_STEREO); 42 | 43 | print_line("Timeline instantiated!"); 44 | } 45 | 46 | ExampleClass::~ExampleClass() { 47 | print_line("Destructor called!"); 48 | delete timeline; 49 | timeline = nullptr; 50 | delete reader; 51 | reader = nullptr; 52 | } 53 | 54 | void ExampleClass::load_file(const String path) { 55 | if (reader == nullptr) 56 | { 57 | // Create example reader 58 | reader = new openshot::FFmpegReader(path.utf8().get_data(), true); 59 | reader->Open(); 60 | } 61 | } 62 | 63 | void ExampleClass::print_type(const Variant &p_variant) const { 64 | print_line(vformat("Type: %d", p_variant.get_type())); 65 | } 66 | 67 | void ExampleClass::print_json(const Variant &p_variant) { 68 | print_line("print_json!"); 69 | openshot::Profile p("/home/jonathan/apps/openshot-qt/src/profiles/01920x1080p2997_16-09"); 70 | std::string s = timeline->Json(); 71 | String output = "OpenShot Profile JSON: " + String(s.c_str()); 72 | UtilityFunctions::print(output); 73 | } 74 | 75 | Ref ExampleClass::get_image(const int64_t frame_number) { 76 | if (reader && reader->IsOpen()) 77 | { 78 | // Load video frame 79 | auto frame = reader->GetFrame(frame_number); 80 | std::shared_ptr qimg = frame->GetImage(); 81 | 82 | // Convert ARGB32_Premultiplied to RGBA8888, keeping premultiplied alpha 83 | QImage rgba_image = qimg->convertToFormat(QImage::Format_RGBA8888); 84 | 85 | // Copy pixel data 86 | int width = rgba_image.width(); 87 | int height = rgba_image.height(); 88 | PackedByteArray buffer; 89 | buffer.resize(width * height * 4); 90 | memcpy(buffer.ptrw(), rgba_image.constBits(), buffer.size()); 91 | 92 | // Create Godot Image 93 | Ref image = Image::create(width, height, false, Image::FORMAT_RGBA8); 94 | image->set_data(width, height, false, Image::FORMAT_RGBA8, buffer); 95 | 96 | print_line(vformat("✅ Image created: %dx%d (premultiplied alpha)", width, height)); 97 | return image; 98 | } 99 | 100 | // Empty image 101 | return Ref(); 102 | } 103 | 104 | 105 | -------------------------------------------------------------------------------- /bindings/godot/osg_timeline.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Godot wrapper 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #pragma once 14 | 15 | #include "godot_cpp/classes/ref_counted.hpp" 16 | #include "godot_cpp/classes/image.hpp" 17 | #include "godot_cpp/variant/variant.hpp" 18 | #include "Timeline.h" 19 | #include "FFmpegReader.h" 20 | 21 | using namespace godot; 22 | 23 | class ExampleClass : public RefCounted { 24 | GDCLASS(ExampleClass, RefCounted) 25 | 26 | protected: 27 | static void _bind_methods(); 28 | 29 | public: 30 | ExampleClass(); 31 | ~ExampleClass() override; 32 | 33 | void load_file(String path); 34 | void print_type(const Variant &p_variant) const; 35 | void print_json(const Variant &p_variant); 36 | Ref get_image(int64_t frame_number); 37 | 38 | private: 39 | openshot::Timeline* timeline = nullptr; 40 | openshot::FFmpegReader* reader = nullptr; 41 | bool constructor_called = false; 42 | }; 43 | -------------------------------------------------------------------------------- /bindings/godot/register_types.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for registering Godot wrapper 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "register_types.h" 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "osg_timeline.h" 21 | 22 | using namespace godot; 23 | 24 | void initialize_gdextension_types(godot::ModuleInitializationLevel p_level) { 25 | if (p_level != godot::MODULE_INITIALIZATION_LEVEL_SCENE) return; 26 | 27 | godot::ClassDB::register_class(); 28 | } 29 | 30 | void uninitialize_gdextension_types(ModuleInitializationLevel p_level) { 31 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { 32 | return; 33 | } 34 | } 35 | 36 | extern "C" 37 | { 38 | // Initialization 39 | GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) 40 | { 41 | GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); 42 | init_obj.register_initializer(initialize_gdextension_types); 43 | init_obj.register_terminator(uninitialize_gdextension_types); 44 | init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE); 45 | 46 | return init_obj.init(); 47 | } 48 | } -------------------------------------------------------------------------------- /bindings/godot/register_types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for registering Godot wrapper 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef EXAMPLE_REGISTER_TYPES_H 14 | #define EXAMPLE_REGISTER_TYPES_H 15 | 16 | void initialize_gdextension_types(); 17 | void uninitialize_gdextension_types(); 18 | 19 | #endif // EXAMPLE_REGISTER_TYPES_H -------------------------------------------------------------------------------- /cmake/Modules/FindZeroMQ.cmake: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON) 6 | find_package(PkgConfig) 7 | pkg_check_modules(PC_LIBZMQ QUIET libzmq) 8 | 9 | set(ZeroMQ_VERSION ${PC_LIBZMQ_VERSION}) 10 | 11 | find_path(ZeroMQ_INCLUDE_DIR zmq.h 12 | PATHS 13 | ${ZeroMQ_DIR}/include 14 | ${PC_LIBZMQ_INCLUDE_DIRS}) 15 | 16 | find_library(ZeroMQ_LIBRARY 17 | NAMES zmq 18 | PATHS 19 | ${ZeroMQ_DIR}/lib 20 | ${PC_LIBZMQ_LIBDIR} 21 | ${PC_LIBZMQ_LIBRARY_DIRS}) 22 | 23 | if(ZeroMQ_LIBRARY) 24 | set(ZeroMQ_FOUND ON) 25 | endif() 26 | 27 | set ( ZeroMQ_LIBRARIES ${ZeroMQ_LIBRARY} ) 28 | set ( ZeroMQ_INCLUDE_DIRS ${ZeroMQ_INCLUDE_DIR} ) 29 | 30 | if(NOT TARGET libzmq) 31 | add_library(libzmq UNKNOWN IMPORTED) 32 | set_target_properties(libzmq PROPERTIES 33 | IMPORTED_LOCATION ${ZeroMQ_LIBRARIES} 34 | INTERFACE_INCLUDE_DIRECTORIES ${ZeroMQ_INCLUDE_DIRS}) 35 | endif() 36 | 37 | include ( FindPackageHandleStandardArgs ) 38 | # handle the QUIETLY and REQUIRED arguments and set ZMQ_FOUND to TRUE 39 | # if all listed variables are TRUE 40 | find_package_handle_standard_args(ZeroMQ 41 | REQUIRED_VARS 42 | ZeroMQ_LIBRARIES 43 | ZeroMQ_INCLUDE_DIRS 44 | VERSION_VAR 45 | ZeroMQ_VERSION) 46 | -------------------------------------------------------------------------------- /cmake/Modules/Findbabl.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2021 OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | function(_babl_GET_VERSION _header) 6 | file(STRINGS "${_header}" _version_defs 7 | REGEX "^[ \t]*#define[ \t]+BABL_[A-Z]+_VERSION.*") 8 | if(_version_defs) 9 | string(REGEX REPLACE 10 | ".*BABL_MAJOR_VERSION[ \t]+([0-9]+).*" "\\1" 11 | babl_MAJOR "${_version_defs}") 12 | string(REGEX REPLACE 13 | ".*BABL_MINOR_VERSION[ \t]+([0-9]+).*" "\\1" 14 | babl_MINOR "${_version_defs}") 15 | string(REGEX REPLACE 16 | ".*BABL_MICRO_VERSION[ \t]+([0-9]+).*" "\\1" 17 | babl_PATCH "${_version_defs}") 18 | set(babl_VERSION "${babl_MAJOR}.${babl_MINOR}.${babl_PATCH}" PARENT_SCOPE) 19 | endif() 20 | endfunction() 21 | 22 | find_package(PkgConfig) 23 | pkg_check_modules(PC_BABL babl) 24 | 25 | set(babl_VERSION ${PC_BABL_VERSION}) 26 | 27 | find_path(babl_INCLUDE_DIR 28 | NAMES babl/babl.h 29 | PATH_SUFFIXES babl-0.1 30 | HINTS 31 | ${babl_DIR}/include 32 | ${PC_BABL_INCLUDE_DIRS} 33 | DOC "babl include dir" 34 | ) 35 | 36 | find_library(babl_LIBRARY 37 | NAMES babl-0.1 38 | HINTS 39 | ${babl_DIR}/lib 40 | ${PC_BABL_LIBDIR} 41 | ${PC_BABL_LIBRARY_DIRS} 42 | DOC "babl library" 43 | ) 44 | 45 | set ( babl_LIBRARIES ${babl_LIBRARY} ) 46 | set ( babl_INCLUDE_DIRS ${babl_INCLUDE_DIR} ) 47 | 48 | if(babl_INCLUDE_DIR AND NOT babl_VERSION) 49 | set(_version_hdr "${babl_INCLUDE_DIR}/babl/babl-version.h") 50 | if(EXISTS "${_version_hdr}") 51 | _babl_GET_VERSION("${_version_hdr}") 52 | endif() 53 | endif() 54 | 55 | if (babl_INCLUDE_DIRS AND babl_LIBRARIES) 56 | set(babl_FOUND TRUE) 57 | endif() 58 | 59 | if(babl_FOUND AND NOT TARGET babl_lib) 60 | add_library(babl_lib UNKNOWN IMPORTED) 61 | 62 | set_property(TARGET babl_lib PROPERTY 63 | INTERFACE_INCLUDE_DIRECTORIES ${babl_INCLUDE_DIR}) 64 | set_property(TARGET babl_lib PROPERTY 65 | IMPORTED_LOCATION ${babl_LIBRARY}) 66 | endif() 67 | 68 | include ( FindPackageHandleStandardArgs ) 69 | # handle the QUIETLY and REQUIRED arguments and set babl_FOUND to TRUE 70 | # if all listed variables are TRUE 71 | find_package_handle_standard_args(babl 72 | REQUIRED_VARS 73 | babl_INCLUDE_DIR 74 | babl_LIBRARY 75 | VERSION_VAR 76 | babl_VERSION) 77 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | coverage: 6 | status: 7 | project: 8 | default: 9 | only_pulls: true # Only post a status to pull requests 10 | informational: true # Don't block PRs based on coverage stats (yet?) 11 | ignore: 12 | - "examples" 13 | - "bindings" 14 | - "thirdparty/jsoncpp" 15 | - "doc" 16 | - "cmake" 17 | - "*.md" 18 | - "src/openshot_autogen" 19 | -------------------------------------------------------------------------------- /doc/images/FrameMapper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/doc/images/FrameMapper.png -------------------------------------------------------------------------------- /doc/images/Playhead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/doc/images/Playhead.png -------------------------------------------------------------------------------- /doc/images/Timeline_Layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/doc/images/Timeline_Layers.png -------------------------------------------------------------------------------- /doc/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/doc/images/logo.png -------------------------------------------------------------------------------- /examples/1F0CF.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ####################### CMakeLists.txt (libopenshot) ######################### 2 | # @brief CMake build file for libopenshot (used to generate makefiles) 3 | # @author Jonathan Thomas 4 | # @author FeRD (Frank Dana) 5 | # 6 | # @section LICENSE 7 | # 8 | # Copyright (c) 2008-2020 OpenShot Studios, LLC 9 | # 10 | # SPDX-License-Identifier: LGPL-3.0-or-later 11 | 12 | include(GNUInstallDirs) 13 | 14 | # Dependencies 15 | find_package(Qt5 COMPONENTS Gui REQUIRED) 16 | 17 | ############### CLI EXECUTABLES ################ 18 | # Create test executable 19 | add_executable(openshot-example Example.cpp) 20 | 21 | # Define path to test input files 22 | file(TO_NATIVE_PATH "${PROJECT_SOURCE_DIR}/examples/" TEST_MEDIA_PATH) 23 | target_compile_definitions(openshot-example PRIVATE 24 | -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) 25 | 26 | # Link test executable to the new library 27 | target_link_libraries(openshot-example openshot) 28 | 29 | add_executable(openshot-html-example ExampleHtml.cpp) 30 | target_link_libraries(openshot-html-example openshot Qt5::Gui) 31 | 32 | ############### PLAYER EXECUTABLE ################ 33 | # Create test executable 34 | add_executable(openshot-player qt-demo/main.cpp) 35 | 36 | set_target_properties(openshot-player 37 | PROPERTIES 38 | AUTOMOC ON 39 | WIN32_EXECUTABLE ON 40 | ) 41 | 42 | # Link test executable to the new library 43 | target_link_libraries(openshot-player openshot) 44 | 45 | ############### OPENCV EXAMPLE ################ 46 | #if (DEFINED CACHE{HAVE_OPENCV}) 47 | # # Create test executable 48 | # add_executable(openshot-example-opencv 49 | # Example_opencv.cpp) 50 | # 51 | # target_compile_definitions(openshot-example-opencv PRIVATE 52 | # -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) 53 | # # Link test executable to the new library 54 | # target_link_libraries(openshot-example-opencv openshot) 55 | #endif() 56 | -------------------------------------------------------------------------------- /examples/Example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | @file 5 | @brief Python source file for openshot.py example 6 | @author Jonathan Thomas 7 | @author FeRD (Frank Dana) 8 | 9 | @ref License 10 | """ 11 | 12 | # Copyright (c) 2008-2019 OpenShot Studios, LLC 13 | # 14 | # SPDX-License-Identifier: LGPL-3.0-or-later 15 | 16 | # This can be run against an uninstalled build of libopenshot, just set the 17 | # environment variable PYTHONPATH to the location of the Python bindings. 18 | # 19 | # For example: 20 | # $ PYTHONPATH=../../build/src/bindings/python python3 Example.py 21 | # 22 | import openshot 23 | 24 | 25 | # Create an FFmpegReader 26 | r = openshot.FFmpegReader("sintel_trailer-720p.mp4") 27 | 28 | r.Open() # Open the reader 29 | r.DisplayInfo() # Display metadata 30 | 31 | # Set up Writer 32 | w = openshot.FFmpegWriter("pythonExample.mp4") 33 | 34 | w.SetAudioOptions(True, "libmp3lame", r.info.sample_rate, r.info.channels, r.info.channel_layout, 128000) 35 | w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720, 36 | openshot.Fraction(1, 1), False, False, 3000000) 37 | 38 | w.info.metadata["title"] = "testtest" 39 | w.info.metadata["artist"] = "aaa" 40 | w.info.metadata["album"] = "bbb" 41 | w.info.metadata["year"] = "2015" 42 | w.info.metadata["description"] = "ddd" 43 | w.info.metadata["comment"] = "eee" 44 | w.info.metadata["comment"] = "comment" 45 | w.info.metadata["copyright"] = "copyright OpenShot!" 46 | 47 | # Open the Writer 48 | w.Open() 49 | 50 | # Grab 30 frames from Reader and encode to Writer 51 | for frame in range(100): 52 | f = r.GetFrame(frame) 53 | w.WriteFrame(f) 54 | 55 | # Close out Reader & Writer 56 | w.Close() 57 | r.Close() 58 | 59 | print("Completed successfully!") 60 | -------------------------------------------------------------------------------- /examples/Example.rb: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | # Find and load the ruby libopenshot wrapper library 6 | require "openshot" 7 | 8 | # Create a new FFmpegReader and Open it 9 | r = Openshot::FFmpegReader.new("test.mp4") 10 | r.Open() 11 | 12 | # Get frame 1 13 | f = r.GetFrame(1) 14 | 15 | # Display the frame 16 | f.Display() 17 | 18 | -------------------------------------------------------------------------------- /examples/ExampleHtml.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for QtHtmlReader Example (example app for libopenshot) 4 | * @author Jonathan Thomas 5 | * @author FeRD (Frank Dana) 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "QtHtmlReader.h" 21 | #include "FFmpegWriter.h" 22 | #include "Fraction.h" 23 | #include "Enums.h" // for GRAVITY_BOTTOM_RIGHT 24 | #include "CrashHandler.h" 25 | 26 | using namespace openshot; 27 | 28 | int main(int argc, char* argv[]) { 29 | 30 | QGuiApplication app(argc, argv); 31 | 32 | std::string html_code = R"html(

Check out this HTML!

)html"; 33 | 34 | std::string css_code = R"css( 35 | * {font-family:sans-serif; font-size:18pt; color:#ffffff;} 36 | #red {color: #ff0000;} 37 | )css"; 38 | 39 | // Create a reader to generate an openshot::Frame containing text 40 | QtHtmlReader r(1280, // width 41 | 720, // height 42 | -16, // x_offset 43 | -16, // y_offset 44 | GRAVITY_BOTTOM_RIGHT, // gravity 45 | html_code, // html 46 | css_code, // css 47 | "#000000" // background_color 48 | ); 49 | 50 | r.Open(); // Open the reader 51 | 52 | r.DisplayInfo(); 53 | 54 | /* WRITER ---------------- */ 55 | FFmpegWriter w("cppHtmlExample.mp4"); 56 | 57 | // Set options 58 | //w.SetAudioOptions(true, "libmp3lame", r.info.sample_rate, r.info.channels, r.info.channel_layout, 128000); 59 | w.SetVideoOptions(true, "libx264", Fraction(30000, 1000), 1280, 720, Fraction(1, 1), false, false, 3000000); 60 | 61 | w.info.metadata["title"] = "testtest"; 62 | w.info.metadata["artist"] = "aaa"; 63 | w.info.metadata["album"] = "bbb"; 64 | w.info.metadata["year"] = "2015"; 65 | w.info.metadata["description"] = "ddd"; 66 | w.info.metadata["comment"] = "eee"; 67 | w.info.metadata["comment"] = "comment"; 68 | w.info.metadata["copyright"] = "copyright OpenShot!"; 69 | 70 | // Open writer 71 | w.Open(); 72 | 73 | for (long int frame = 1; frame <= 100; ++frame) 74 | { 75 | std::shared_ptr f = r.GetFrame(frame); // Same frame every time 76 | w.WriteFrame(f); 77 | } 78 | 79 | // Close writer & reader 80 | w.Close(); 81 | r.Close(); 82 | 83 | // Set a timer with 0 timeout to terminate immediately after 84 | // processing events 85 | QTimer::singleShot(0, &app, SLOT(quit())); 86 | 87 | // Run QGuiApplication to completion 88 | return app.exec(); 89 | } 90 | -------------------------------------------------------------------------------- /examples/ExampleHtml.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | @file 5 | @brief Python source file for QtHtmlReader example 6 | @author Jonathan Thomas 7 | @author FeRD (Frank Dana) 8 | 9 | @ref License 10 | """ 11 | 12 | # Copyright (c) 2008-2019 OpenShot Studios, LLC 13 | # 14 | # SPDX-License-Identifier: LGPL-3.0-or-later 15 | 16 | import sys 17 | from PyQt5.QtCore import QTimer 18 | from PyQt5.QtGui import QGuiApplication 19 | import openshot 20 | 21 | app = QGuiApplication(sys.argv) 22 | 23 | html_code = """

Check out this HTML!

""" 24 | 25 | css_code = """ 26 | * {font-family:sans-serif; font-size:18pt; color:#ffffff;} 27 | #red {color: #ff0000;} 28 | """ 29 | 30 | # Create a QtHtmlReader 31 | r = openshot.QtHtmlReader(1280, # width 32 | 720, # height 33 | -16, # x offset 34 | -16, # y offset 35 | openshot.GRAVITY_BOTTOM_RIGHT, 36 | html_code, 37 | css_code, 38 | "#000000" # background color 39 | ) 40 | 41 | r.Open() # Open the reader 42 | 43 | r.DisplayInfo() # Display metadata 44 | 45 | # Set up Writer 46 | w = openshot.FFmpegWriter("pyHtmlExample.mp4") 47 | 48 | w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720, 49 | openshot.Fraction(1, 1), False, False, 3000000) 50 | 51 | w.info.metadata["title"] = "testtest" 52 | w.info.metadata["artist"] = "aaa" 53 | w.info.metadata["album"] = "bbb" 54 | w.info.metadata["year"] = "2015" 55 | w.info.metadata["description"] = "ddd" 56 | w.info.metadata["comment"] = "eee" 57 | w.info.metadata["comment"] = "comment" 58 | w.info.metadata["copyright"] = "copyright OpenShot!" 59 | 60 | # Open the Writer 61 | w.Open() 62 | 63 | # Grab 30 frames from Reader and encode to Writer 64 | for frame in range(100): 65 | f = r.GetFrame(frame) 66 | w.WriteFrame(f) 67 | 68 | # Close out Reader & Writer 69 | w.Close() 70 | r.Close() 71 | 72 | # Set a timer to terminate the app as soon as the event queue empties 73 | QTimer.singleShot(0, app.quit) 74 | 75 | # Run QGuiApplication to completion 76 | sys.exit(app.exec()) 77 | -------------------------------------------------------------------------------- /examples/OpenShot Wipe Tests.py: -------------------------------------------------------------------------------- 1 | # © OpenShot Studios, LLC 2 | # 3 | # SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | import openshot 6 | 7 | # Create an empty timeline 8 | t = openshot.Timeline(720, 480, openshot.Fraction(24,1), 44100, 2, openshot.LAYOUT_STEREO) 9 | t.Open() 10 | 11 | # lower layer 12 | lower = openshot.QtImageReader("back.png") 13 | c1 = openshot.Clip(lower) 14 | c1.Layer(1) 15 | t.AddClip(c1) 16 | 17 | # higher layer 18 | higher = openshot.QtImageReader("front3.png") 19 | c2 = openshot.Clip(higher) 20 | c2.Layer(2) 21 | #c2.alpha = openshot.Keyframe(0.5) 22 | t.AddClip(c2) 23 | 24 | # Wipe / Transition 25 | brightness = openshot.Keyframe() 26 | brightness.AddPoint(1, 1.0, openshot.BEZIER) 27 | brightness.AddPoint(24, -1.0, openshot.BEZIER) 28 | 29 | contrast = openshot.Keyframe() 30 | contrast.AddPoint(1, 20.0, openshot.BEZIER) 31 | contrast.AddPoint(24, 20.0, openshot.BEZIER) 32 | 33 | reader = openshot.QtImageReader("mask.png") 34 | e = openshot.Mask(reader, brightness, contrast) 35 | e.Layer(2) 36 | e.End(60) 37 | t.AddEffect(e) 38 | 39 | reader1 = openshot.QtImageReader("mask2.png") 40 | e1 = openshot.Mask(reader1, brightness, contrast) 41 | e1.Layer(2) 42 | e1.Order(2) 43 | e1.End(60) 44 | #t.AddEffect(e1) 45 | 46 | for n in range(1,25): 47 | print(n, end=" ", flush=1) 48 | t.GetFrame(n).Save("%s.png" % n, 1.0) 49 | -------------------------------------------------------------------------------- /examples/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/back.png -------------------------------------------------------------------------------- /examples/eq_sphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/eq_sphere.png -------------------------------------------------------------------------------- /examples/example_profile1: -------------------------------------------------------------------------------- 1 | description=HD 720p 24 fps 2 | frame_rate_num=24 3 | frame_rate_den=1 4 | width=1280 5 | height=720 6 | progressive=1 7 | sample_aspect_num=1 8 | sample_aspect_den=1 9 | display_aspect_num=16 10 | display_aspect_den=9 11 | colorspace=709 12 | -------------------------------------------------------------------------------- /examples/example_profile2: -------------------------------------------------------------------------------- 1 | description=HD 1080i 29.97 fps 2 | frame_rate_num=30000 3 | frame_rate_den=1001 4 | width=1920 5 | height=1080 6 | progressive=0 7 | sample_aspect_num=1 8 | sample_aspect_den=1 9 | display_aspect_num=16 10 | display_aspect_den=9 11 | colorspace=709 12 | -------------------------------------------------------------------------------- /examples/final-composite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/final-composite.png -------------------------------------------------------------------------------- /examples/fisheye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/fisheye.png -------------------------------------------------------------------------------- /examples/front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/front.png -------------------------------------------------------------------------------- /examples/front3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/front3.png -------------------------------------------------------------------------------- /examples/interlaced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/interlaced.png -------------------------------------------------------------------------------- /examples/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/mask.png -------------------------------------------------------------------------------- /examples/mask2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/mask2.png -------------------------------------------------------------------------------- /examples/output-final.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/output-final.png -------------------------------------------------------------------------------- /examples/piano-mono.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/piano-mono.wav -------------------------------------------------------------------------------- /examples/piano.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/piano.wav -------------------------------------------------------------------------------- /examples/qt-demo/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Demo Qt application to test the QtPlayer class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "Qt/PlayerDemo.h" 14 | #include "ZmqLogger.h" 15 | #include 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | // Enable logging for openshot-player since this is primarily used for 20 | // profiling and debugging video playback issues. 21 | openshot::ZmqLogger::Instance()->Enable(true); 22 | openshot::ZmqLogger::Instance()->Path("./player.log"); 23 | 24 | QApplication app(argc, argv); 25 | PlayerDemo demo; 26 | demo.show(); 27 | return app.exec(); 28 | } 29 | -------------------------------------------------------------------------------- /examples/run.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/run.mp4 -------------------------------------------------------------------------------- /examples/sine.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/sine.wav -------------------------------------------------------------------------------- /examples/sintel_trailer-720p.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/sintel_trailer-720p.mp4 -------------------------------------------------------------------------------- /examples/test.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/test.avi -------------------------------------------------------------------------------- /examples/test.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/test.mp4 -------------------------------------------------------------------------------- /examples/test.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/test.wav -------------------------------------------------------------------------------- /examples/test1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/test1.mp4 -------------------------------------------------------------------------------- /examples/test_video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/test_video.mp4 -------------------------------------------------------------------------------- /examples/test_video_sync.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenShot/libopenshot/7b4e9992428d92edd107d361376019d117e40a21/examples/test_video_sync.mp4 -------------------------------------------------------------------------------- /src/AudioBufferSource.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for AudioBufferSource class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_AUDIOBUFFERSOURCE_H 14 | #define OPENSHOT_AUDIOBUFFERSOURCE_H 15 | 16 | #include 17 | #include 18 | 19 | namespace openshot 20 | { 21 | /** 22 | * @brief This class is used to expose an AudioBuffer as an AudioSource in JUCE. 23 | * 24 | * The JUCE library cannot play audio directly from an AudioBuffer, so this class exposes 25 | * an AudioBuffer as a AudioSource, so that JUCE can play the audio. 26 | */ 27 | class AudioBufferSource : public juce::PositionableAudioSource 28 | { 29 | private: 30 | int position; 31 | bool repeat; 32 | juce::AudioBuffer *buffer; 33 | 34 | public: 35 | /// @brief Default constructor 36 | /// @param audio_buffer This buffer contains the samples you want to play through JUCE. 37 | AudioBufferSource(juce::AudioBuffer *audio_buffer); 38 | 39 | /// Destructor 40 | ~AudioBufferSource(); 41 | 42 | /// @brief Get the next block of audio samples 43 | /// @param info This struct informs us of which samples are needed next. 44 | void getNextAudioBlock (const juce::AudioSourceChannelInfo& info); 45 | 46 | /// Prepare to play this audio source 47 | void prepareToPlay(int, double); 48 | 49 | /// Release all resources 50 | void releaseResources(); 51 | 52 | /// @brief Set the next read position of this source 53 | /// @param newPosition The sample # to start reading from 54 | void setNextReadPosition (juce::int64 newPosition); 55 | 56 | /// Get the next read position of this source 57 | juce::int64 getNextReadPosition() const; 58 | 59 | /// Get the total length (in samples) of this audio source 60 | juce::int64 getTotalLength() const; 61 | 62 | /// Determines if this audio source should repeat when it reaches the end 63 | bool isLooping() const; 64 | 65 | /// @brief Set if this audio source should repeat when it reaches the end 66 | /// @param shouldLoop Determines if the audio source should repeat when it reaches the end 67 | void setLooping (bool shouldLoop); 68 | 69 | /// Update the internal buffer used by this source 70 | void setBuffer (juce::AudioBuffer *audio_buffer); 71 | }; 72 | 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/AudioDevices.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Utility methods for identifying audio devices 4 | * @author Jonathan Thomas 5 | * @author FeRD (Frank Dana) 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #include "AudioDevices.h" 15 | 16 | using namespace openshot; 17 | 18 | using AudioDeviceList = std::vector>; 19 | 20 | // Build a list of devices found, and return 21 | AudioDeviceList AudioDevices::getNames() { 22 | // A temporary device manager, used to scan device names. 23 | // Its initialize() is never called, and devices are not opened. 24 | std::unique_ptr 25 | manager(new juce::AudioDeviceManager()); 26 | 27 | m_devices.clear(); 28 | 29 | auto &types = manager->getAvailableDeviceTypes(); 30 | for (auto* t : types) { 31 | t->scanForDevices(); 32 | const auto names = t->getDeviceNames(); 33 | for (const auto& name : names) { 34 | m_devices.emplace_back( 35 | name.toStdString(), t->getTypeName().toStdString()); 36 | } 37 | } 38 | return m_devices; 39 | } 40 | -------------------------------------------------------------------------------- /src/AudioDevices.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Audio Device Info struct 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_AUDIODEVICEINFO_H 14 | #define OPENSHOT_AUDIODEVICEINFO_H 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | namespace openshot { 21 | /** 22 | * @brief This struct hold information about Audio Devices 23 | * 24 | * The type and name of the audio device. 25 | */ 26 | struct 27 | AudioDeviceInfo { 28 | juce::String type; 29 | juce::String name; 30 | 31 | // Get the std::string device type 32 | std::string get_type() { 33 | return type.toStdString(); 34 | } 35 | 36 | // Get the std::string device name 37 | std::string get_name() { 38 | return name.toStdString(); 39 | } 40 | }; 41 | 42 | using AudioDeviceList = std::vector>; 43 | 44 | /// A class which probes the available audio devices 45 | class AudioDevices 46 | { 47 | public: 48 | AudioDevices() = default; 49 | 50 | /// Return a vector of std::pair<> objects holding the 51 | /// device name and type for each audio device detected 52 | AudioDeviceList getNames(); 53 | private: 54 | AudioDeviceList m_devices; 55 | }; 56 | 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /src/AudioLocation.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for AudioLocation class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2023 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_AUDIOLOCATION_H 14 | #define OPENSHOT_AUDIOLOCATION_H 15 | 16 | 17 | namespace openshot 18 | { 19 | /** 20 | * @brief This struct holds the associated video frame and starting sample # for an audio packet. 21 | * 22 | * Because audio packets do not match up with video frames, this helps determine exactly 23 | * where the audio packet's samples belong. 24 | */ 25 | struct AudioLocation { 26 | int64_t frame; 27 | int sample_start; 28 | 29 | bool is_near(AudioLocation location, int samples_per_frame, int64_t amount); 30 | AudioLocation() : frame(0), sample_start(0) {} 31 | AudioLocation(int64_t frame, int sample_start) : frame(frame), sample_start(sample_start) {} 32 | }; 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/AudioResampler.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for AudioResampler class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_RESAMPLER_H 14 | #define OPENSHOT_RESAMPLER_H 15 | 16 | #include "AudioBufferSource.h" 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace openshot { 23 | 24 | /** 25 | * @brief This class is used to resample audio data for many sequential frames. 26 | * 27 | * It maintains some data from the last call to GetResampledBuffer(), so there 28 | * are no pops and clicks between frames. 29 | */ 30 | class AudioResampler { 31 | private: 32 | juce::AudioBuffer *buffer; 33 | juce::AudioBuffer *resampled_buffer; 34 | openshot::AudioBufferSource *buffer_source; 35 | juce::ResamplingAudioSource *resample_source; 36 | juce::AudioSourceChannelInfo resample_callback_buffer; 37 | 38 | int num_of_samples; 39 | int new_num_of_samples; 40 | double dest_ratio; 41 | double source_ratio; 42 | bool isPrepared; 43 | 44 | public: 45 | /// Default constructor 46 | AudioResampler(int numChannels=2); 47 | 48 | /// Destructor 49 | ~AudioResampler(); 50 | 51 | /// @brief Sets the audio buffer and key settings 52 | /// @param new_buffer The buffer of audio samples needing to be resampled 53 | /// @param sample_rate The original sample rate of the buffered samples 54 | /// @param new_sample_rate The requested sample rate you need 55 | void SetBuffer(juce::AudioBuffer *new_buffer, double sample_rate, double new_sample_rate); 56 | 57 | /// @brief Sets the audio buffer and key settings 58 | /// @param new_buffer The buffer of audio samples needing to be resampled 59 | /// @param ratio The multiplier that needs to be applied to the sample rate (this is how resampling happens) 60 | void SetBuffer(juce::AudioBuffer *new_buffer, double ratio); 61 | 62 | /// Get the resampled audio buffer 63 | juce::AudioBuffer* GetResampledBuffer(); 64 | }; 65 | 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/AudioWaveformer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for AudioWaveformer class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2022 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_WAVEFORMER_H 14 | #define OPENSHOT_WAVEFORMER_H 15 | 16 | #include "ReaderBase.h" 17 | #include "Frame.h" 18 | #include 19 | 20 | 21 | namespace openshot { 22 | 23 | /** 24 | * @brief This struct holds the extracted waveform data (both the RMS root-mean-squared average, and the max values) 25 | * 26 | * Because we extract 2 different datasets from the audio, we return this struct with access to both sets of data, 27 | * the average root mean squared values, and the max sample values. 28 | */ 29 | struct AudioWaveformData 30 | { 31 | std::vector max_samples; 32 | std::vector rms_samples; 33 | 34 | /// Resize both datasets 35 | void resize(int total_samples) { 36 | max_samples.resize(total_samples); 37 | rms_samples.resize(total_samples); 38 | } 39 | 40 | /// Zero out # of values in both datasets 41 | void zero(int total_samples) { 42 | std::fill(max_samples.begin(), max_samples.end(), 0); 43 | std::fill(rms_samples.begin(), rms_samples.end(), 0); 44 | } 45 | 46 | /// Scale # of values by some factor 47 | void scale(int total_samples, float factor) { 48 | for (auto s = 0; s < total_samples; s++) { 49 | max_samples[s] *= factor; 50 | rms_samples[s] *= factor; 51 | } 52 | } 53 | 54 | /// Clear and free memory of both datasets 55 | void clear() { 56 | max_samples.clear(); 57 | max_samples.shrink_to_fit(); 58 | rms_samples.clear(); 59 | rms_samples.shrink_to_fit(); 60 | } 61 | 62 | /// Return a vector of vectors (containing both datasets) 63 | std::vector> vectors() { 64 | std::vector> output; 65 | output.push_back(max_samples); 66 | output.push_back(rms_samples); 67 | return output; 68 | } 69 | }; 70 | 71 | /** 72 | * @brief This class is used to extra audio data used for generating waveforms. 73 | * 74 | * Pass in a ReaderBase* with audio data, and this class will iterate the reader, 75 | * and sample down the dataset to a much smaller set - more useful for generating 76 | * waveforms. For example, take 44100 samples per second, and reduce it to 20 77 | * "max" or "average" samples per second - much easier to graph. 78 | */ 79 | class AudioWaveformer { 80 | private: 81 | ReaderBase* reader; 82 | 83 | public: 84 | /// Default constructor 85 | AudioWaveformer(ReaderBase* reader); 86 | 87 | /// @brief Extract audio samples from any ReaderBase class 88 | /// @param channel Which audio channel should we extract data from (-1 == all channels) 89 | /// @param num_per_second How many samples per second to return 90 | /// @param normalize Should we scale the data range so the largest value is 1.0 91 | AudioWaveformData ExtractSamples(int channel, int num_per_second, bool normalize); 92 | 93 | /// Destructor 94 | ~AudioWaveformer(); 95 | }; 96 | 97 | } 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /src/ChannelLayouts.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for ChannelLayout class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_CHANNEL_LAYOUT_H 14 | #define OPENSHOT_CHANNEL_LAYOUT_H 15 | 16 | // Include FFmpeg headers and macros 17 | #include "FFmpegUtilities.h" 18 | 19 | namespace openshot 20 | { 21 | 22 | /** 23 | * @brief This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround, etc...) 24 | * 25 | * When writing video and audio files, you will need to specify the channel layout of the audio stream. libopenshot 26 | * can convert between many different channel layouts (such as stereo, mono, 5 point surround, etc...) 27 | */ 28 | enum ChannelLayout 29 | { 30 | LAYOUT_MONO = AV_CH_LAYOUT_MONO, 31 | LAYOUT_STEREO = AV_CH_LAYOUT_STEREO, 32 | LAYOUT_2POINT1 = AV_CH_LAYOUT_2POINT1, 33 | LAYOUT_2_1 = AV_CH_LAYOUT_2_1, 34 | LAYOUT_SURROUND = AV_CH_LAYOUT_SURROUND, 35 | LAYOUT_3POINT1 = AV_CH_LAYOUT_3POINT1, 36 | LAYOUT_4POINT0 = AV_CH_LAYOUT_4POINT0, 37 | LAYOUT_4POINT1 = AV_CH_LAYOUT_4POINT1, 38 | LAYOUT_2_2 = AV_CH_LAYOUT_2_2, 39 | LAYOUT_QUAD = AV_CH_LAYOUT_QUAD, 40 | LAYOUT_5POINT0 = AV_CH_LAYOUT_5POINT0, 41 | LAYOUT_5POINT1 = AV_CH_LAYOUT_5POINT1, 42 | LAYOUT_5POINT0_BACK = AV_CH_LAYOUT_5POINT0_BACK, 43 | LAYOUT_5POINT1_BACK = AV_CH_LAYOUT_5POINT1_BACK, 44 | LAYOUT_6POINT0 = AV_CH_LAYOUT_6POINT0, 45 | LAYOUT_6POINT0_FRONT = AV_CH_LAYOUT_6POINT0_FRONT, 46 | LAYOUT_HEXAGONAL = AV_CH_LAYOUT_HEXAGONAL, 47 | LAYOUT_6POINT1 = AV_CH_LAYOUT_6POINT1, 48 | LAYOUT_6POINT1_BACK = AV_CH_LAYOUT_6POINT1_BACK, 49 | LAYOUT_6POINT1_FRONT = AV_CH_LAYOUT_6POINT1_FRONT, 50 | LAYOUT_7POINT0 = AV_CH_LAYOUT_7POINT0, 51 | LAYOUT_7POINT0_FRONT = AV_CH_LAYOUT_7POINT0_FRONT, 52 | LAYOUT_7POINT1 = AV_CH_LAYOUT_7POINT1, 53 | LAYOUT_7POINT1_WIDE = AV_CH_LAYOUT_7POINT1_WIDE, 54 | LAYOUT_7POINT1_WIDE_BACK = AV_CH_LAYOUT_7POINT1_WIDE_BACK, 55 | LAYOUT_OCTAGONAL = AV_CH_LAYOUT_OCTAGONAL, 56 | LAYOUT_STEREO_DOWNMIX = AV_CH_LAYOUT_STEREO_DOWNMIX 57 | }; 58 | 59 | 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/ClipProcessingJobs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header for ClipProcessingJobs class 4 | * @author Jonathan Thomas 5 | * @author Brenno Caldato 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifdef USE_OPENCV 15 | #define int64 opencv_broken_int 16 | #define uint64 opencv_broken_uint 17 | #include 18 | #include 19 | #undef uint64 20 | #undef int64 21 | 22 | #include "CVStabilization.h" 23 | #include "CVTracker.h" 24 | #include "CVObjectDetection.h" 25 | #endif 26 | 27 | #include 28 | #include "ProcessingController.h" 29 | #include "Clip.h" 30 | 31 | namespace openshot { 32 | 33 | // Constructor responsible to choose processing type and apply to clip 34 | class ClipProcessingJobs{ 35 | private: 36 | std::string processInfoJson; 37 | std::string processingType; 38 | 39 | bool processingDone = false; 40 | bool stopProcessing = false; 41 | uint processingProgress = 0; 42 | 43 | std::thread t; 44 | 45 | /// Will handle a Thread safely comutication between ClipProcessingJobs and the processing effect classes 46 | ProcessingController processingController; 47 | 48 | // Apply object tracking to clip 49 | void trackClip(Clip& clip, ProcessingController& controller); 50 | // Apply stabilization to clip 51 | void stabilizeClip(Clip& clip, ProcessingController& controller); 52 | // Apply object detection to clip 53 | void detectObjectsClip(Clip& clip, ProcessingController& controller); 54 | 55 | 56 | public: 57 | // Constructor 58 | ClipProcessingJobs(std::string processingType, std::string processInfoJson); 59 | // Process clip accordingly to processingType 60 | void processClip(Clip& clip, std::string json); 61 | 62 | // Thread related variables and methods 63 | int GetProgress(); 64 | bool IsDone(); 65 | void CancelProcessing(); 66 | bool GetError(); 67 | std::string GetErrorMessage(); 68 | }; 69 | 70 | } // namespace openshot 71 | -------------------------------------------------------------------------------- /src/Color.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Color class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_COLOR_H 14 | #define OPENSHOT_COLOR_H 15 | 16 | #include "KeyFrame.h" 17 | #include 18 | 19 | namespace openshot { 20 | 21 | /** 22 | * @brief This class represents a color (used on the timeline and clips) 23 | * 24 | * Colors are represented by 4 curves, representing red, green, blue, and alpha. The curves 25 | * can be used to animate colors over time. 26 | */ 27 | class Color{ 28 | 29 | public: 30 | openshot::Keyframe red; /// GetColorRGBA(int64_t frame_number); 56 | 57 | /// Get the distance between 2 RGB pairs. (0=identical colors, 10=very close colors, 760=very different colors) 58 | static long GetDistance(long R1, long G1, long B1, long R2, long G2, long B2); 59 | 60 | // Get and Set JSON methods 61 | std::string Json() const; ///< Generate JSON string of this object 62 | Json::Value JsonValue() const; ///< Generate Json::Value for this object 63 | void SetJson(const std::string value); ///< Load JSON string into this object 64 | void SetJsonValue(const Json::Value root); ///< Load Json::Value into this object 65 | }; 66 | 67 | } // namespace openshot 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/Coordinate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for Coordinate class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "Coordinate.h" 14 | #include "Exceptions.h" 15 | 16 | using namespace openshot; 17 | 18 | // Default constructor for a coordinate, delegating to the full signature 19 | Coordinate::Coordinate() : Coordinate::Coordinate(0, 0) {} 20 | 21 | // Constructor which also allows the user to set the X and Y 22 | Coordinate::Coordinate(double x, double y) : X(x), Y(y) {} 23 | 24 | // Constructor which accepts a std::pair for (X, Y) 25 | Coordinate::Coordinate(const std::pair& co) 26 | : X(co.first), Y(co.second) {} 27 | 28 | // Generate JSON string of this object 29 | std::string Coordinate::Json() const { 30 | 31 | // Return formatted string 32 | return JsonValue().toStyledString(); 33 | } 34 | 35 | // Generate Json::Value for this object 36 | Json::Value Coordinate::JsonValue() const { 37 | 38 | // Create root json object 39 | Json::Value root; 40 | root["X"] = X; 41 | root["Y"] = Y; 42 | //root["increasing"] = increasing; 43 | //root["repeated"] = Json::Value(Json::objectValue); 44 | //root["repeated"]["num"] = repeated.num; 45 | //root["repeated"]["den"] = repeated.den; 46 | //root["delta"] = delta; 47 | 48 | // return JsonValue 49 | return root; 50 | } 51 | 52 | // Load JSON string into this object 53 | void Coordinate::SetJson(const std::string value) { 54 | 55 | // Parse JSON string into JSON objects 56 | try 57 | { 58 | const Json::Value root = openshot::stringToJson(value); 59 | // Set all values that match 60 | SetJsonValue(root); 61 | } 62 | catch (const std::exception& e) 63 | { 64 | // Error parsing JSON (or missing keys) 65 | throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); 66 | } 67 | } 68 | 69 | // Load Json::Value into this object 70 | void Coordinate::SetJsonValue(const Json::Value root) { 71 | 72 | // Set data from Json (if key is found) 73 | if (!root["X"].isNull()) 74 | X = root["X"].asDouble(); 75 | if (!root["Y"].isNull()) 76 | Y = root["Y"].asDouble(); 77 | } 78 | -------------------------------------------------------------------------------- /src/Coordinate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Coordinate class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_COORDINATE_H 14 | #define OPENSHOT_COORDINATE_H 15 | 16 | #include 17 | #include "Fraction.h" 18 | #include "Json.h" 19 | 20 | namespace openshot { 21 | 22 | /** 23 | * @brief A Cartesian coordinate (X, Y) used in the Keyframe animation system. 24 | * 25 | * Animation involves the changing (i.e. interpolation) of numbers over time. 26 | * A series of Coordinate objects allows us to plot a specific curve or line 27 | * used during interpolation. In other words, it helps us control how a 28 | * value changes over time — whether it's increasing or decreasing 29 | * (the direction of the slope) and how quickly (the steepness of the curve). 30 | * 31 | * Please see the following Example Code: 32 | * \code 33 | * Coordinate c1(2,4); 34 | * assert(c1.X == 2.0f); 35 | * assert(c1.Y == 4.0f); 36 | * \endcode 37 | */ 38 | class Coordinate { 39 | public: 40 | double X; ///< The X value of the coordinate (usually representing the frame #) 41 | double Y; ///< The Y value of the coordinate (usually representing the value of the property being animated) 42 | 43 | /// The default constructor, which defaults to (0,0) 44 | Coordinate(); 45 | 46 | /// @brief Constructor which also sets the X and Y 47 | /// @param x The X coordinate (usually representing the frame #) 48 | /// @param y The Y coordinate (usually representing the value of the property being animated) 49 | Coordinate(double x, double y); 50 | 51 | /// @brief Constructor which accepts a std::pair tuple for {X, Y} 52 | /// @param co A std::pair tuple containing (X, Y) 53 | Coordinate(const std::pair& co); 54 | 55 | // Get and Set JSON methods 56 | std::string Json() const; ///< Generate JSON string of this object 57 | Json::Value JsonValue() const; ///< Generate Json::Value for this object 58 | void SetJson(const std::string value); ///< Load JSON string into this object 59 | void SetJsonValue(const Json::Value root); ///< Load Json::Value into this object 60 | }; 61 | 62 | /// Stream output operator for openshot::Coordinate 63 | template 64 | std::basic_ostream& 65 | operator<<(std::basic_ostream& o, const openshot::Coordinate& co) { 66 | std::basic_ostringstream s; 67 | s.flags(o.flags()); 68 | s.imbue(o.getloc()); 69 | s.precision(o.precision()); 70 | s << "(" << co.X << ", " << co.Y << ")"; 71 | return o << s.str(); 72 | } 73 | 74 | } 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/CrashHandler.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for CrashHandler class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_CRASH_HANDLER_H 14 | #define OPENSHOT_CRASH_HANDLER_H 15 | 16 | #include 17 | #include 18 | #include 19 | #ifdef __MINGW32__ 20 | #include 21 | #include 22 | #include 23 | #else 24 | #include 25 | #endif 26 | #include 27 | #include 28 | #include "ZmqLogger.h" 29 | 30 | namespace openshot { 31 | 32 | /** 33 | * @brief This class is designed to catch exceptions thrown by libc (SIGABRT, SIGSEGV, SIGILL, SIGFPE) 34 | * 35 | * This class is a singleton which only needs to be instantiated 1 time, and it will register as a signal 36 | * handler with libc, and log errors using the ZmqLogger class. 37 | */ 38 | class CrashHandler { 39 | private: 40 | /// Default constructor 41 | CrashHandler(){return;}; // Don't allow user to create an instance of this singleton 42 | 43 | /// Default copy method 44 | //CrashHandler(CrashHandler const&){}; // Don't allow the user to copy this instance 45 | CrashHandler(CrashHandler const&) = delete; // Don't allow the user to copy this instance 46 | 47 | /// Default assignment operator 48 | CrashHandler & operator=(CrashHandler const&) = delete; // Don't allow the user to assign this instance 49 | 50 | /// Private variable to keep track of singleton instance 51 | static CrashHandler *m_pInstance; 52 | 53 | public: 54 | /// Create or get an instance of this crash handler singleton (invoke the class with this method). This also 55 | /// registers the instance as a signal handler for libc 56 | static CrashHandler *Instance(); 57 | 58 | #ifdef __MINGW32__ 59 | // TODO: Windows exception handling methods 60 | static void abortHandler(int signum); 61 | #else 62 | /// Method which handles crashes and logs error 63 | static void abortHandler(int signum, siginfo_t* si, void* unused); 64 | #endif 65 | 66 | /// Method which prints a stacktrace 67 | static void printStackTrace(FILE *out, unsigned int max_frames); 68 | }; 69 | 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/EffectInfo.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for the EffectInfo class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_EFFECT_INFO_H 14 | #define OPENSHOT_EFFECT_INFO_H 15 | 16 | #include "Json.h" 17 | 18 | namespace openshot 19 | { 20 | class Clip; 21 | class EffectBase; 22 | /** 23 | * @brief This class returns a listing of all effects supported by libopenshot 24 | * 25 | * Use this class to return a listing of all supported effects, and their 26 | * descriptions. 27 | */ 28 | class EffectInfo 29 | { 30 | public: 31 | /// Create an instance of an effect (factory style) 32 | EffectBase* CreateEffect(std::string effect_type); 33 | 34 | // JSON methods 35 | static std::string Json(); ///< Generate JSON string of this object 36 | static Json::Value JsonValue(); ///< Generate Json::Value for this object 37 | 38 | }; 39 | 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/Effects.h: -------------------------------------------------------------------------------- 1 | #ifndef OPENSHOT_EFFECTS_H 2 | #define OPENSHOT_EFFECTS_H 3 | 4 | /** 5 | * @file 6 | * @brief This header includes all commonly used effects for libopenshot, for ease-of-use. 7 | * @author Jonathan Thomas 8 | * 9 | * @ref License 10 | */ 11 | 12 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 13 | // 14 | // SPDX-License-Identifier: LGPL-3.0-or-later 15 | 16 | /* Effects */ 17 | #include "effects/Bars.h" 18 | #include "effects/Blur.h" 19 | #include "effects/Brightness.h" 20 | #include "effects/Caption.h" 21 | #include "effects/ChromaKey.h" 22 | #include "effects/ColorMap.h" 23 | #include "effects/ColorShift.h" 24 | #include "effects/Crop.h" 25 | #include "effects/Deinterlace.h" 26 | #include "effects/Hue.h" 27 | #include "effects/LensFlare.h" 28 | #include "effects/Mask.h" 29 | #include "effects/Negate.h" 30 | #include "effects/Pixelate.h" 31 | #include "effects/Saturation.h" 32 | #include "effects/Sharpen.h" 33 | #include "effects/SphericalProjection.h" 34 | #include "effects/Shift.h" 35 | #include "effects/Wave.h" 36 | 37 | /* Audio Effects */ 38 | #include "audio_effects/Noise.h" 39 | #include "audio_effects/Delay.h" 40 | #include "audio_effects/Echo.h" 41 | #include "audio_effects/Distortion.h" 42 | #include "audio_effects/ParametricEQ.h" 43 | #include "audio_effects/Compressor.h" 44 | #include "audio_effects/Expander.h" 45 | #include "audio_effects/Robotization.h" 46 | #include "audio_effects/Whisperization.h" 47 | 48 | /* OpenCV Effects */ 49 | #ifdef USE_OPENCV 50 | #include "effects/Outline.h" 51 | #include "effects/ObjectDetection.h" 52 | #include "effects/Tracker.h" 53 | #include "effects/Stabilizer.h" 54 | #endif 55 | 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/Fraction.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for Fraction class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "Fraction.h" 14 | #include 15 | 16 | using namespace openshot; 17 | 18 | // Delegating constructors 19 | Fraction::Fraction() : Fraction::Fraction(1, 1) {} 20 | 21 | Fraction::Fraction(std::pair pair) 22 | : Fraction::Fraction(pair.first, pair.second) {} 23 | 24 | Fraction::Fraction(std::map mapping) 25 | : Fraction::Fraction(mapping["num"], mapping["den"]) {} 26 | 27 | Fraction::Fraction(std::vector vector) 28 | : Fraction::Fraction(vector[0], vector[1]) {} 29 | 30 | // Full constructor 31 | Fraction::Fraction(int num, int den) : 32 | num(num), den(den) {} 33 | 34 | // Return this fraction as a float (i.e. 1/2 = 0.5) 35 | float Fraction::ToFloat() { 36 | return float(num) / float(den); 37 | } 38 | 39 | // Return this fraction as a double (i.e. 1/2 = 0.5) 40 | double Fraction::ToDouble() const { 41 | return double(num) / double(den); 42 | } 43 | 44 | // Return a rounded integer of the frame rate (for example 30000/1001 returns 30 fps) 45 | int Fraction::ToInt() { 46 | return round((double) num / den); 47 | } 48 | 49 | // Calculate the greatest common denominator 50 | int Fraction::GreatestCommonDenominator() { 51 | int first = num; 52 | int second = den; 53 | 54 | // Find the biggest whole number that will divide into both the numerator 55 | // and denominator 56 | int t; 57 | while (second != 0) { 58 | t = second; 59 | second = first % second; 60 | first = t; 61 | } 62 | return first; 63 | } 64 | 65 | void Fraction::Reduce() { 66 | // Get the greatest common denominator 67 | int GCD = GreatestCommonDenominator(); 68 | if (GCD == 0) { 69 | return; 70 | } 71 | 72 | // Reduce this fraction to the smallest possible whole numbers 73 | num = num / GCD; 74 | den = den / GCD; 75 | } 76 | 77 | // Return the reciprocal as a new Fraction 78 | Fraction Fraction::Reciprocal() const 79 | { 80 | // flip the fraction 81 | return Fraction(den, num); 82 | } 83 | -------------------------------------------------------------------------------- /src/ImageReader.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for ImageReader class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_IMAGE_READER_H 14 | #define OPENSHOT_IMAGE_READER_H 15 | 16 | // Require ImageMagick support 17 | #ifdef USE_IMAGEMAGICK 18 | 19 | #include 20 | #include 21 | 22 | #include "ReaderBase.h" 23 | #include "Json.h" 24 | 25 | // Forward decls 26 | namespace Magick { 27 | class Image; 28 | } 29 | namespace openshot { 30 | class CacheBase; 31 | class Frame; 32 | } 33 | 34 | namespace openshot 35 | { 36 | /** 37 | * @brief This class uses the ImageMagick++ libraries, to open image files, and return 38 | * openshot::Frame objects containing the image. 39 | * 40 | * @code 41 | * // Create a reader for a video 42 | * ImageReader r("MyAwesomeImage.jpeg"); 43 | * r.Open(); // Open the reader 44 | * 45 | * // Get frame number 1 from the video 46 | * std::shared_ptr f = r.GetFrame(1); 47 | * 48 | * // Now that we have an openshot::Frame object, lets have some fun! 49 | * f->Display(); // Display the frame on the screen 50 | * 51 | * // Close the reader 52 | * r.Close(); 53 | * @endcode 54 | */ 55 | class ImageReader : public ReaderBase 56 | { 57 | private: 58 | std::string path; 59 | std::shared_ptr image; 60 | bool is_open; 61 | 62 | public: 63 | /// @brief Constructor for ImageReader. 64 | /// 65 | /// Opens the media file to inspect its properties and loads frame 1, 66 | /// iff inspect_reader == true (the default). Pass a false value in 67 | /// the optional parameter to defer this initial Open()/Close() cycle. 68 | /// 69 | /// When not inspecting the media file, it's much faster, and useful 70 | /// when you are inflating the object using JSON after instantiation. 71 | ImageReader(const std::string& path, bool inspect_reader=true); 72 | 73 | /// Close File 74 | void Close() override; 75 | 76 | /// Get the cache object used by this reader (always returns NULL for this object) 77 | CacheBase* GetCache() override { return NULL; }; 78 | 79 | /// Get an openshot::Frame object for a specific frame number of this reader. All numbers 80 | /// return the same Frame, since they all share the same image data. 81 | /// 82 | /// @returns The requested frame (containing the image) 83 | /// @param requested_frame The frame number that is requested. 84 | std::shared_ptr GetFrame(int64_t requested_frame) override; 85 | 86 | /// Determine if reader is open or closed 87 | bool IsOpen() override { return is_open; }; 88 | 89 | /// Return the type name of the class 90 | std::string Name() override { return "ImageReader"; }; 91 | 92 | // Get and Set JSON methods 93 | std::string Json() const override; ///< Generate JSON string of this object 94 | void SetJson(const std::string value) override; ///< Load JSON string into this object 95 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 96 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 97 | 98 | /// Open File - which is called by the constructor automatically 99 | void Open() override; 100 | }; 101 | 102 | } 103 | 104 | #endif //USE_IMAGEMAGICK 105 | #endif //OPENSHOT_IMAGE_READER_H 106 | -------------------------------------------------------------------------------- /src/Json.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Helper functions for Json parsing 4 | * @author FeRD (Frank Dana) 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "Json.h" 14 | #include "Exceptions.h" 15 | 16 | const Json::Value openshot::stringToJson(const std::string value) { 17 | 18 | // Parse JSON string into JSON objects 19 | Json::Value root; 20 | Json::CharReaderBuilder rbuilder; 21 | Json::CharReader* reader(rbuilder.newCharReader()); 22 | 23 | std::string errors; 24 | bool success = reader->parse( value.c_str(), value.c_str() + value.size(), 25 | &root, &errors ); 26 | delete reader; 27 | 28 | if (!success) 29 | // Raise exception 30 | throw openshot::InvalidJSON("JSON could not be parsed (or is invalid)"); 31 | 32 | return root; 33 | } 34 | -------------------------------------------------------------------------------- /src/Json.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for JSON class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_JSON_H 14 | #define OPENSHOT_JSON_H 15 | 16 | #include 17 | #include "json/json.h" 18 | 19 | 20 | namespace openshot { 21 | const Json::Value stringToJson(const std::string value); 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/MagickUtilities.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Implementation for MagickUtilities (conversions) 4 | * @author Jonathan Thomas 5 | * @author FeRD (Frank Dana) 6 | */ 7 | 8 | // Copyright (c) 2008-2021 OpenShot Studios, LLC 9 | // 10 | // SPDX-License-Identifier: LGPL-3.0-or-later 11 | 12 | #ifdef USE_IMAGEMAGICK 13 | 14 | #include "MagickUtilities.h" 15 | #include "QtUtilities.h" 16 | 17 | #include 18 | 19 | // Get pointer to Magick::Image conversion of a QImage 20 | std::shared_ptr 21 | openshot::QImage2Magick(std::shared_ptr image) 22 | { 23 | // Check for blank image 24 | if (!image || image->isNull()) 25 | return nullptr; 26 | 27 | // Get the pixels from the frame image 28 | const QRgb *tmpBits = (const QRgb*)image->constBits(); 29 | 30 | // Create new image object, and fill with pixel data 31 | auto magick_image = std::make_shared( 32 | image->width(), image->height(), 33 | "RGBA", Magick::CharPixel, tmpBits); 34 | 35 | // Give image a transparent background color 36 | magick_image->backgroundColor(Magick::Color("none")); 37 | magick_image->virtualPixelMethod( 38 | Magick::TransparentVirtualPixelMethod); 39 | MAGICK_IMAGE_ALPHA(magick_image, true); 40 | 41 | return magick_image; 42 | } 43 | 44 | // Get pointer to QImage conversion of a Magick::Image 45 | std::shared_ptr 46 | openshot::Magick2QImage(std::shared_ptr image) 47 | { 48 | if (!image) 49 | return nullptr; 50 | 51 | const int BPP = 4; 52 | const std::size_t size = image->columns() * image->rows() * BPP; 53 | 54 | auto* qbuffer = new unsigned char[size](); 55 | 56 | MagickCore::ExceptionInfo exception; 57 | // TODO: Actually do something, if we get an exception here 58 | MagickCore::ExportImagePixels( 59 | image->constImage(), 0, 0, 60 | image->columns(), image->rows(), 61 | "RGBA", Magick::CharPixel, 62 | qbuffer, &exception); 63 | 64 | auto qimage = std::make_shared( 65 | qbuffer, image->columns(), image->rows(), 66 | image->columns() * BPP, 67 | QImage::Format_RGBA8888_Premultiplied, 68 | (QImageCleanupFunction) &openshot::cleanUpBuffer, 69 | (void*) qbuffer); 70 | return qimage; 71 | } 72 | 73 | #endif // USE_IMAGEMAGICK 74 | -------------------------------------------------------------------------------- /src/MagickUtilities.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for MagickUtilities (IM6/IM7 compatibility overlay) 4 | * @author Jonathan Thomas 5 | * @author FeRD (Frank Dana) 6 | */ 7 | 8 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 9 | // 10 | // SPDX-License-Identifier: LGPL-3.0-or-later 11 | 12 | #ifndef OPENSHOT_MAGICK_UTILITIES_H 13 | #define OPENSHOT_MAGICK_UTILITIES_H 14 | 15 | #ifdef USE_IMAGEMAGICK 16 | 17 | // Avoid a bug in the interaction between ImageMagick 18 | // and the standard C insertion headers, which can 19 | // cause functions used by macros in the standard C 20 | // assertion code to be put in an ImageMagick library 21 | // namespace instead of the global namespace 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | // Exclude a warning message with IM6 headers 28 | #pragma GCC diagnostic push 29 | #pragma GCC diagnostic ignored "-Wignored-qualifiers" 30 | #include "Magick++.h" 31 | #pragma GCC diagnostic pop 32 | 33 | // Determine ImageMagick version, as IM7 isn't fully 34 | // backwards compatible 35 | #ifndef NEW_MAGICK 36 | #define NEW_MAGICK (MagickLibVersion >= 0x700) 37 | #endif 38 | 39 | // IM7: ->alpha(bool) 40 | // IM6: ->matte(bool) 41 | #if NEW_MAGICK 42 | #define MAGICK_IMAGE_ALPHA(im, a) im->alpha((a)) 43 | #else 44 | #define MAGICK_IMAGE_ALPHA(im, a) im->matte((a)) 45 | #endif 46 | 47 | // IM7: vector 48 | // IM6: list 49 | // (both have the push_back() method which is all we use) 50 | #if NEW_MAGICK 51 | #define MAGICK_DRAWABLE std::vector 52 | #else 53 | #define MAGICK_DRAWABLE std::list 54 | #endif 55 | 56 | namespace openshot { 57 | 58 | /// Convert QImage to Magick::Image 59 | std::shared_ptr 60 | QImage2Magick(std::shared_ptr); 61 | 62 | /// Convert Magick::Image to QImage 63 | std::shared_ptr 64 | Magick2QImage(std::shared_ptr); 65 | 66 | } // namespace 67 | 68 | #endif // USE_IMAGEMAGICK 69 | #endif // OPENSHOT_MAGICK_UTILITIES_H 70 | -------------------------------------------------------------------------------- /src/OpenCVUtilities.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for OpenCVUtilities (set some common macros) 4 | * @author FeRD (Frank Dana) 5 | * @author Jonathan Thomas 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2021 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_OPENCV_UTILITIES_H 15 | #define OPENSHOT_OPENCV_UTILITIES_H 16 | 17 | #define int64 int64_t 18 | #define uint64 uint64_t 19 | #if USE_LEGACY_TRACKER 20 | #include 21 | #include 22 | #define OPENCV_TRACKER_TYPE cv::legacy::Tracker 23 | #define OPENCV_TRACKER_NS cv::legacy 24 | #else 25 | #include 26 | #define OPENCV_TRACKER_TYPE cv::Tracker 27 | #define OPENCV_TRACKER_NS cv 28 | #endif 29 | #undef int64 30 | #undef uint64 31 | 32 | #endif // OPENSHOT_OPENCV_UTILITIES_H 33 | -------------------------------------------------------------------------------- /src/OpenMPUtilities.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for OpenMPUtilities (set some common macros) 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_OPENMP_UTILITIES_H 14 | #define OPENSHOT_OPENMP_UTILITIES_H 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "Settings.h" 21 | 22 | // Calculate the # of OpenMP Threads to allow 23 | #define OPEN_MP_NUM_PROCESSORS std::min(omp_get_num_procs(), std::max(2, openshot::Settings::Instance()->OMP_THREADS)) 24 | #define FF_VIDEO_NUM_PROCESSORS std::min(omp_get_num_procs(), std::max(2, openshot::Settings::Instance()->FF_THREADS)) 25 | #define FF_AUDIO_NUM_PROCESSORS std::min(omp_get_num_procs(), std::max(2, openshot::Settings::Instance()->FF_THREADS)) 26 | 27 | // Set max-active-levels to the max supported, if possible 28 | // (supported_active_levels is OpenMP 5.0 (November 2018) or later, only.) 29 | #if (_OPENMP >= 201811) 30 | #define OPEN_MP_MAX_ACTIVE omp_get_supported_active_levels() 31 | #else 32 | #define OPEN_MP_MAX_ACTIVE OPEN_MP_NUM_PROCESSORS 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/OpenShotVersion.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for GetVersion function 4 | * @author Jonathan Thomas 5 | * @author FeRD (Frank Dana) 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #include "OpenShotVersion.h" 15 | 16 | namespace openshot { 17 | OpenShotVersion GetVersion() { 18 | return openshot::Version; 19 | } 20 | } -------------------------------------------------------------------------------- /src/OpenShotVersion.h.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file that includes the version number of libopenshot 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_VERSION_H 14 | #define OPENSHOT_VERSION_H 15 | 16 | #define OPENSHOT_VERSION_ALL "@PROJECT_VERSION@" /// A string of the entire version "Major.Minor.Build" 17 | #define OPENSHOT_VERSION_FULL "@PROJECT_VERSION_FULL@" /// A string of the full version identifier, including suffixes (e.g. "0.0.0-dev0") 18 | #define OPENSHOT_VERSION_MAJOR_MINOR "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@" /// A string of the "Major.Minor" version 19 | 20 | #define OPENSHOT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ /// Major version number is incremented when huge features are added or improved. 21 | #define OPENSHOT_VERSION_MINOR @PROJECT_VERSION_MINOR@ /// Minor version is incremented when smaller (but still very important) improvements are added. 22 | #define OPENSHOT_VERSION_BUILD @PROJECT_VERSION_PATCH@ /// Build number is incremented when minor bug fixes and less important improvements are added. 23 | #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) 24 | 25 | // Useful dependency versioning / feature availability 26 | #cmakedefine QT_VERSION_STR "@QT_VERSION_STR@" 27 | #cmakedefine AVCODEC_VERSION_STR "@AVCODEC_VERSION_STR@" 28 | #cmakedefine AVFORMAT_VERSION_STR "@AVFORMAT_VERSION_STR@" 29 | #cmakedefine AVUTIL_VERSION_STR "@AVUTIL_VERSION_STR@" 30 | #cmakedefine OPENCV_VERSION_STR "@OPENCV_VERSION_STR@" 31 | #cmakedefine01 HAVE_BABL 32 | #cmakedefine01 HAVE_IMAGEMAGICK 33 | #cmakedefine01 HAVE_RESVG 34 | #cmakedefine01 HAVE_OPENCV 35 | #cmakedefine01 FFMPEG_USE_SWRESAMPLE 36 | #cmakedefine01 APPIMAGE_BUILD 37 | 38 | #include 39 | 40 | namespace openshot 41 | { 42 | /// This struct holds version number information. Use the GetVersion() method to access the current version of libopenshot. 43 | struct OpenShotVersion { 44 | static const int Major = OPENSHOT_VERSION_MAJOR; /// Major version number 45 | static const int Minor = OPENSHOT_VERSION_MINOR; /// Minor version number 46 | static const int Build = OPENSHOT_VERSION_BUILD; /// Build number 47 | static const int So = OPENSHOT_VERSION_SO; /// Shared Object Number (incremented when API or ABI changes) 48 | 49 | /// Get a string version of the version (i.e. "Major.Minor.Build") 50 | inline static std::string ToString() { 51 | return std::to_string(Major) + "." + std::to_string(Minor) + "." + std::to_string(Build); 52 | } 53 | }; 54 | 55 | static const openshot::OpenShotVersion Version; 56 | 57 | /// Get the current version number of libopenshot (major, minor, and build number) 58 | openshot::OpenShotVersion GetVersion(); 59 | } 60 | 61 | #endif // OPENSHOT_VERSION_H 62 | -------------------------------------------------------------------------------- /src/PlayerBase.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for PlayerBase class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "PlayerBase.h" 14 | 15 | using namespace openshot; 16 | 17 | // Display a loading animation 18 | void PlayerBase::Loading() { 19 | mode = PLAYBACK_LOADING; 20 | } 21 | 22 | // Play the video 23 | void PlayerBase::Play() { 24 | mode = PLAYBACK_PLAY; 25 | } 26 | 27 | // Pause the video 28 | void PlayerBase::Pause() { 29 | mode = PLAYBACK_PAUSED; 30 | } 31 | 32 | // Get the Playback speed 33 | float PlayerBase::Speed() { 34 | return speed; 35 | } 36 | 37 | // Set the Playback speed multiplier (1.0 = normal speed, <1.0 = slower, >1.0 faster) 38 | void PlayerBase::Speed(float new_speed) { 39 | speed = new_speed; 40 | } 41 | 42 | // Stop the video player and clear the cached frames 43 | void PlayerBase::Stop() { 44 | mode = PLAYBACK_STOPPED; 45 | } 46 | 47 | // Get the current reader, such as a FFmpegReader 48 | openshot::ReaderBase* PlayerBase::Reader() { 49 | return reader; 50 | } 51 | 52 | // Set the current reader, such as a FFmpegReader 53 | void PlayerBase::Reader(openshot::ReaderBase *new_reader) { 54 | reader = new_reader; 55 | } 56 | 57 | // Get the Volume 58 | float PlayerBase::Volume() { 59 | return volume; 60 | } 61 | 62 | // Set the Volume multiplier (1.0 = normal volume, <1.0 = quieter, >1.0 louder) 63 | void PlayerBase::Volume(float new_volume) { 64 | volume = new_volume; 65 | } 66 | -------------------------------------------------------------------------------- /src/PlayerBase.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for PlayerBase class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_PLAYER_BASE_H 14 | #define OPENSHOT_PLAYER_BASE_H 15 | 16 | #include 17 | #include "ReaderBase.h" 18 | 19 | namespace openshot 20 | { 21 | /** 22 | * @brief This enumeration determines the mode of the video player (i.e. playing, paused, etc...) 23 | * 24 | * A player can be in one of the following modes, which controls how it behaves. 25 | */ 26 | enum PlaybackMode 27 | { 28 | PLAYBACK_PLAY, ///< Play the video normally 29 | PLAYBACK_PAUSED, ///< Pause the video (holding the last displayed frame) 30 | PLAYBACK_LOADING, ///< Loading the video (display a loading animation) 31 | PLAYBACK_STOPPED, ///< Stop playing the video (clear cache, done with player) 32 | }; 33 | 34 | /** 35 | * @brief This is the base class of all Players in libopenshot. 36 | * 37 | * Players are responsible for displaying images and playing back audio samples with specific 38 | * frame rates and sample rates. All Players must be based on this class, and include these 39 | * methods. 40 | */ 41 | class PlayerBase 42 | { 43 | protected: 44 | float speed; 45 | float volume; 46 | openshot::ReaderBase *reader; 47 | PlaybackMode mode; 48 | 49 | public: 50 | 51 | /// Display a loading animation 52 | virtual void Loading() = 0; 53 | 54 | /// Get the current mode 55 | virtual PlaybackMode Mode() = 0; 56 | 57 | /// Play the video 58 | virtual void Play() = 0; 59 | 60 | /// Pause the video 61 | virtual void Pause() = 0; 62 | 63 | /// Get the current frame number being played 64 | virtual int64_t Position() = 0; 65 | 66 | /// Seek to a specific frame in the player 67 | virtual void Seek(int64_t new_frame) = 0; 68 | 69 | /// Get the Playback speed 70 | virtual float Speed() = 0; 71 | 72 | /// Set the Playback speed (1.0 = normal speed, <1.0 = slower, >1.0 faster) 73 | virtual void Speed(float new_speed) = 0; 74 | 75 | /// Stop the video player and clear the cached frames 76 | virtual void Stop() = 0; 77 | 78 | /// Get the current reader, such as a FFmpegReader 79 | virtual openshot::ReaderBase* Reader() = 0; 80 | 81 | /// Set the current reader, such as a FFmpegReader 82 | virtual void Reader(openshot::ReaderBase *new_reader) = 0; 83 | 84 | /// Get the Volume 85 | virtual float Volume() = 0; 86 | 87 | /// Set the Volume (1.0 = normal volume, <1.0 = quieter, >1.0 louder) 88 | virtual void Volume(float new_volume) = 0; 89 | 90 | virtual ~PlayerBase() = default; 91 | }; 92 | 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /src/ProcessingController.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief This is a message class for thread safe comunication between ClipProcessingJobs and OpenCV classes 4 | * @author Jonathan Thomas 5 | * @author Brenno Caldato 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_PROCESSINGCONTROLLER_H 15 | #define OPENSHOT_PROCESSINGCONTROLLER_H 16 | 17 | #include 18 | #include 19 | 20 | class ProcessingController{ 21 | private: 22 | uint processingProgress; 23 | bool processingFinished; 24 | bool stopProcessing; 25 | bool error = true; 26 | std::string error_message; 27 | 28 | std::mutex mtxProgress; 29 | std::mutex mtxFinished; 30 | std::mutex mtxStop; 31 | std::mutex mtxerror; 32 | 33 | public: 34 | 35 | ProcessingController(){ 36 | processingProgress = 0; 37 | stopProcessing = false; 38 | processingFinished = false; 39 | } 40 | 41 | int GetFinished(){ 42 | std::lock_guard lck (mtxFinished); 43 | bool f = processingFinished; 44 | return f; 45 | } 46 | 47 | void SetFinished(bool f){ 48 | std::lock_guard lck (mtxFinished); 49 | processingFinished = f; 50 | } 51 | 52 | void SetProgress(uint p){ 53 | std::lock_guard lck (mtxProgress); 54 | processingProgress = p; 55 | } 56 | 57 | int GetProgress(){ 58 | std::lock_guard lck (mtxProgress); 59 | uint p = processingProgress; 60 | return p; 61 | } 62 | 63 | void CancelProcessing(){ 64 | std::lock_guard lck (mtxStop); 65 | stopProcessing = true; 66 | } 67 | 68 | bool ShouldStop(){ 69 | std::lock_guard lck (mtxStop); 70 | bool s = stopProcessing; 71 | return s; 72 | } 73 | 74 | void SetError(bool err, std::string message){ 75 | std::lock_guard lck (mtxerror); 76 | error = err; 77 | error_message = message; 78 | } 79 | 80 | bool GetError(){ 81 | std::lock_guard lck (mtxerror); 82 | bool e = error; 83 | return e; 84 | } 85 | 86 | std::string GetErrorMessage(){ 87 | std::lock_guard lck (mtxerror); 88 | std::string message = error_message; 89 | return message; 90 | } 91 | 92 | }; 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /src/Qt/PlayerDemo.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for demo application for QtPlayer class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_PLAYER_DEMO_H 14 | #define OPENSHOT_PLAYER_DEMO_H 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "VideoRenderWidget.h" 24 | 25 | // Define the QtPlayer without including it (due to build issues with Qt moc / Qt macros) 26 | namespace openshot 27 | { 28 | class QtPlayer; 29 | } 30 | 31 | class PlayerDemo : public QWidget 32 | { 33 | Q_OBJECT 34 | 35 | public: 36 | PlayerDemo(QWidget *parent = 0); 37 | ~PlayerDemo(); 38 | 39 | protected: 40 | void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; 41 | void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; 42 | 43 | private slots: 44 | void open(bool checked); 45 | 46 | private: 47 | QVBoxLayout *vbox; 48 | QMenuBar *menu; 49 | VideoRenderWidget *video; 50 | openshot::QtPlayer *player; 51 | }; 52 | 53 | #endif // OPENSHOT_PLAYER_H 54 | -------------------------------------------------------------------------------- /src/Qt/PlayerPrivate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for PlayerPrivate class 4 | * @author Duzy Chan 5 | * @author Jonathan Thomas 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_PLAYER_PRIVATE_H 15 | #define OPENSHOT_PLAYER_PRIVATE_H 16 | 17 | #include "../ReaderBase.h" 18 | #include "../RendererBase.h" 19 | #include "../AudioReaderSource.h" 20 | #include "../Qt/AudioPlaybackThread.h" 21 | #include "../Qt/VideoPlaybackThread.h" 22 | #include "../Qt/VideoCacheThread.h" 23 | 24 | namespace openshot 25 | { 26 | /** 27 | * @brief The private part of QtPlayer class, which contains an audio thread and video thread, 28 | * and controls the video timing and audio synchronization code. 29 | */ 30 | class PlayerPrivate : juce::Thread 31 | { 32 | std::shared_ptr frame; /// The current frame 33 | int64_t playback_frames; /// The # of frames since playback started 34 | int64_t video_position; /// The current frame position. 35 | int64_t audio_position; /// The current frame position. 36 | openshot::ReaderBase *reader; /// The reader which powers this player 37 | openshot::AudioPlaybackThread *audioPlayback; /// The audio thread 38 | openshot::VideoPlaybackThread *videoPlayback; /// The video thread 39 | openshot::VideoCacheThread *videoCache; /// The cache thread 40 | int speed; /// The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...) 41 | int last_speed; /// The previous speed and direction (used to detect a change) 42 | openshot::RendererBase *renderer; 43 | int64_t last_video_position; /// The last frame actually displayed 44 | int max_sleep_ms; /// The max milliseconds to sleep (when syncing audio and video) 45 | bool is_dirty; /// Detect if a frame needs to be refreshed (calls to Seek() set this to true) 46 | 47 | /// Constructor 48 | PlayerPrivate(openshot::RendererBase *rb); 49 | /// Destructor 50 | virtual ~PlayerPrivate(); 51 | 52 | /// Start thread 53 | void run(); 54 | 55 | /// Start the video/audio playback 56 | bool startPlayback(); 57 | 58 | /// Seek to a new frame # 59 | void Seek(int64_t new_position); 60 | 61 | /// Stop the video/audio playback 62 | void stopPlayback(); 63 | 64 | /// Get the next frame (based on speed and direction) 65 | std::shared_ptr getFrame(); 66 | 67 | /// The parent class of PlayerPrivate 68 | friend class QtPlayer; 69 | }; 70 | 71 | } 72 | 73 | #endif // OPENSHOT_PLAYER_PRIVATE_H 74 | -------------------------------------------------------------------------------- /src/Qt/VideoPlaybackThread.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for VideoPlaybackThread class 4 | * @author Duzy Chan 5 | * @author Jonathan Thomas 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #include "VideoPlaybackThread.h" 15 | #include "ZmqLogger.h" 16 | 17 | #include "Frame.h" 18 | #include "RendererBase.h" 19 | #include "ZmqLogger.h" 20 | 21 | namespace openshot 22 | { 23 | // Constructor 24 | VideoPlaybackThread::VideoPlaybackThread(RendererBase *rb) 25 | : Thread("video-playback"), renderer(rb) 26 | , render(), reset(false) 27 | { 28 | } 29 | 30 | // Destructor 31 | VideoPlaybackThread::~VideoPlaybackThread() 32 | { 33 | } 34 | 35 | // Get the currently playing frame number (if any) 36 | int64_t VideoPlaybackThread::getCurrentFramePosition() 37 | { 38 | if (frame) 39 | return frame->number; 40 | else 41 | return 0; 42 | } 43 | 44 | // Start the thread 45 | void VideoPlaybackThread::run() 46 | { 47 | while (!threadShouldExit()) { 48 | // Make other threads wait on the render event 49 | bool need_render = render.wait(500); 50 | 51 | if (need_render && frame) 52 | { 53 | // Debug 54 | ZmqLogger::Instance()->AppendDebugMethod( 55 | "VideoPlaybackThread::run (before render)", 56 | "frame->number", frame->number, 57 | "need_render", need_render); 58 | 59 | // Render the frame to the screen 60 | renderer->paint(frame); 61 | } 62 | 63 | // Signal to other threads that the rendered event has completed 64 | rendered.signal(); 65 | } 66 | 67 | return; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Qt/VideoPlaybackThread.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for VideoPlaybackThread class 4 | * @author Duzy Chan 5 | * @author Jonathan Thomas 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_VIDEO_PLAYBACK_THREAD_H 15 | #define OPENSHOT_VIDEO_PLAYBACK_THREAD_H 16 | 17 | #include 18 | #include 19 | 20 | namespace openshot 21 | { 22 | class Frame; 23 | class RendererBase; 24 | using juce::Thread; 25 | using juce::WaitableEvent; 26 | 27 | /** 28 | * @brief The video playback class. 29 | */ 30 | class VideoPlaybackThread : Thread 31 | { 32 | RendererBase *renderer; 33 | std::shared_ptr frame; 34 | WaitableEvent render; 35 | WaitableEvent rendered; 36 | bool reset; 37 | 38 | /// Constructor 39 | VideoPlaybackThread(RendererBase *rb); 40 | /// Destructor 41 | ~VideoPlaybackThread(); 42 | 43 | /// Get the currently playing frame number (if any) 44 | int64_t getCurrentFramePosition(); 45 | 46 | /// Start the thread 47 | void run(); 48 | 49 | /// Parent class of VideoPlaybackThread 50 | friend class PlayerPrivate; 51 | friend class QtPlayer; 52 | }; 53 | 54 | } 55 | 56 | #endif // OPENSHOT_VIDEO_PLAYBACK_THREAD_H 57 | -------------------------------------------------------------------------------- /src/Qt/VideoRenderWidget.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for Video RendererWidget class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "VideoRenderWidget.h" 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | VideoRenderWidget::VideoRenderWidget(QWidget *parent) 23 | : QWidget(parent), renderer(new VideoRenderer(this)) 24 | { 25 | QPalette p = palette(); 26 | p.setColor(QPalette::Window, Qt::black); 27 | setPalette(p); 28 | setAttribute(Qt::WA_OpaquePaintEvent); 29 | setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 30 | 31 | // init aspect ratio settings (default values) 32 | aspect_ratio.num = 16; 33 | aspect_ratio.den = 9; 34 | pixel_ratio.num = 1; 35 | pixel_ratio.den = 1; 36 | 37 | connect(renderer, SIGNAL(present(const QImage &)), this, SLOT(present(const QImage &))); 38 | } 39 | 40 | VideoRenderWidget::~VideoRenderWidget() 41 | { 42 | } 43 | 44 | VideoRenderer *VideoRenderWidget::GetRenderer() const 45 | { 46 | return renderer; 47 | } 48 | 49 | void VideoRenderWidget::SetAspectRatio(openshot::Fraction new_aspect_ratio, openshot::Fraction new_pixel_ratio) 50 | { 51 | aspect_ratio = new_aspect_ratio; 52 | pixel_ratio = new_pixel_ratio; 53 | } 54 | 55 | QRect VideoRenderWidget::centeredViewport(int width, int height) 56 | { 57 | // calculate aspect ratio 58 | float aspectRatio = aspect_ratio.ToFloat() * pixel_ratio.ToFloat(); 59 | int heightFromWidth = (int) (width / aspectRatio); 60 | int widthFromHeight = (int) (height * aspectRatio); 61 | 62 | if (heightFromWidth <= height) { 63 | return QRect(0,(height - heightFromWidth) / 2, width, heightFromWidth); 64 | } else { 65 | return QRect((width - widthFromHeight) / 2.0, 0, widthFromHeight, height); 66 | } 67 | } 68 | 69 | void VideoRenderWidget::paintEvent(QPaintEvent *event) 70 | { 71 | QPainter painter(this); 72 | 73 | // maintain aspect ratio 74 | painter.fillRect(event->rect(), palette().window()); 75 | painter.setViewport(centeredViewport(width(), height())); 76 | painter.drawImage(QRect(0, 0, width(), height()), image); 77 | 78 | } 79 | 80 | void VideoRenderWidget::present(const QImage &m) 81 | { 82 | image = m; 83 | repaint(); 84 | } 85 | -------------------------------------------------------------------------------- /src/Qt/VideoRenderWidget.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Video RendererWidget class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_VIDEO_RENDERER_WIDGET_H 14 | #define OPENSHOT_VIDEO_RENDERER_WIDGET_H 15 | 16 | #include "../Fraction.h" 17 | #include "VideoRenderer.h" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | class VideoRenderWidget : public QWidget 25 | { 26 | Q_OBJECT 27 | 28 | private: 29 | VideoRenderer *renderer; 30 | QImage image; 31 | openshot::Fraction aspect_ratio; 32 | openshot::Fraction pixel_ratio; 33 | 34 | public: 35 | VideoRenderWidget(QWidget *parent = 0); 36 | ~VideoRenderWidget(); 37 | 38 | VideoRenderer *GetRenderer() const; 39 | void SetAspectRatio(openshot::Fraction new_aspect_ratio, openshot::Fraction new_pixel_ratio); 40 | 41 | protected: 42 | void paintEvent(QPaintEvent *event); 43 | 44 | QRect centeredViewport(int width, int height); 45 | 46 | private slots: 47 | void present(const QImage &image); 48 | 49 | }; 50 | 51 | #endif // OPENSHOT_VIDEO_RENDERER_WIDGET_H 52 | -------------------------------------------------------------------------------- /src/Qt/VideoRenderer.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for VideoRenderer class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "VideoRenderer.h" 14 | 15 | 16 | VideoRenderer::VideoRenderer(QObject *parent) 17 | : QObject(parent) 18 | { 19 | } 20 | 21 | VideoRenderer::~VideoRenderer() 22 | { 23 | } 24 | 25 | /// Override QWidget which needs to be painted 26 | void VideoRenderer::OverrideWidget(int64_t qwidget_address) 27 | { 28 | // re-cast QWidget pointer (long) as an actual QWidget 29 | override_widget = reinterpret_cast(qwidget_address); 30 | 31 | } 32 | 33 | void VideoRenderer::render(std::shared_ptr image) 34 | { 35 | if (image) 36 | emit present(*image); 37 | } 38 | -------------------------------------------------------------------------------- /src/Qt/VideoRenderer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Video Renderer class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_VIDEO_RENDERER_H 14 | #define OPENSHOT_VIDEO_RENDERER_H 15 | 16 | #include "../RendererBase.h" 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | class QPainter; 23 | 24 | class VideoRenderer : public QObject, public openshot::RendererBase 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | VideoRenderer(QObject *parent = 0); 30 | ~VideoRenderer(); 31 | 32 | /// Override QWidget which needs to be painted 33 | void OverrideWidget(int64_t qwidget_address); 34 | 35 | signals: 36 | void present(const QImage &image); 37 | 38 | protected: 39 | //void render(openshot::OSPixelFormat format, int width, int height, int bytesPerLine, unsigned char *data); 40 | void render(std::shared_ptr image); 41 | 42 | private slots: 43 | 44 | private: 45 | QWidget* override_widget; 46 | }; 47 | 48 | #endif //OPENSHOT_VIDEO_RENDERER_H 49 | -------------------------------------------------------------------------------- /src/QtPlayer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for QtPlayer class 4 | * @author Duzy Chan 5 | * @author Jonathan Thomas 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_QT_PLAYER_H 15 | #define OPENSHOT_QT_PLAYER_H 16 | 17 | #include 18 | #include 19 | 20 | #include "PlayerBase.h" 21 | #include "Qt/PlayerPrivate.h" 22 | #include "RendererBase.h" 23 | 24 | namespace openshot 25 | { 26 | using AudioDeviceList = std::vector>; 27 | 28 | /** 29 | * @brief This class is used to playback a video from a reader. 30 | * 31 | */ 32 | class QtPlayer : public openshot::PlayerBase 33 | { 34 | openshot::PlayerPrivate *p; 35 | bool threads_started; 36 | 37 | public: 38 | /// Default constructor 39 | explicit QtPlayer(); 40 | explicit QtPlayer(openshot::RendererBase *rb); 41 | 42 | /// Default destructor 43 | virtual ~QtPlayer(); 44 | 45 | /// Close audio device 46 | void CloseAudioDevice(); 47 | 48 | /// Get Error (if any) 49 | std::string GetError(); 50 | 51 | /// Return the default audio sample rate (from the system) 52 | double GetDefaultSampleRate(); 53 | 54 | /// Get Audio Devices from JUCE 55 | AudioDeviceList GetAudioDeviceNames(); 56 | 57 | /// Get current audio device or last attempted 58 | AudioDeviceInfo GetCurrentAudioDevice(); 59 | 60 | /// Play the video 61 | void Play(); 62 | 63 | /// Display a loading animation 64 | void Loading(); 65 | 66 | /// Get the current mode 67 | openshot::PlaybackMode Mode(); 68 | 69 | /// Pause the video 70 | void Pause(); 71 | 72 | /// Get the current frame number being played 73 | int64_t Position(); 74 | 75 | /// Seek to a specific frame in the player 76 | void Seek(int64_t new_frame); 77 | 78 | /// Set the source URL/path of this player (which will create an internal Reader) 79 | void SetSource(const std::string &source); 80 | 81 | /// Set the source JSON of an openshot::Timelime 82 | void SetTimelineSource(const std::string &json); 83 | 84 | /// Set the QWidget which will be used as the display (note: QLabel works well). This does not take a 85 | /// normal pointer, but rather a LONG pointer id (and it re-casts the QWidget pointer inside libopenshot). 86 | /// This is required due to SIP and SWIG incompatibility in the Python bindings. 87 | void SetQWidget(int64_t qwidget_address); 88 | 89 | /// Get the Renderer pointer address (for Python to cast back into a QObject) 90 | int64_t GetRendererQObject(); 91 | 92 | /// Get the Playback speed 93 | float Speed(); 94 | 95 | /// Set the Playback speed (1.0 = normal speed, <1.0 = slower, >1.0 faster) 96 | void Speed(float new_speed); 97 | 98 | /// Stop the video player and clear the cached frames 99 | void Stop(); 100 | 101 | /// Set the current reader 102 | void Reader(openshot::ReaderBase *new_reader); 103 | 104 | /// Get the current reader, such as a FFmpegReader 105 | openshot::ReaderBase* Reader(); 106 | 107 | /// Get the Volume 108 | float Volume(); 109 | 110 | /// Set the Volume (1.0 = normal volume, <1.0 = quieter, >1.0 louder) 111 | void Volume(float new_volume); 112 | }; 113 | } 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /src/QtUtilities.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for QtUtilities (compatibiity overlay) 4 | * @author FeRD (Frank Dana) 5 | */ 6 | 7 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 8 | // 9 | // SPDX-License-Identifier: LGPL-3.0-or-later 10 | 11 | #ifndef OPENSHOT_QT_UTILITIES_H 12 | #define OPENSHOT_QT_UTILITIES_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | // Fix Qt::endl for older Qt versions 20 | // From: https://bugreports.qt.io/browse/QTBUG-82680 21 | #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 22 | namespace Qt { 23 | using TextStreamFunction = QTextStream& (*)(QTextStream&); 24 | constexpr TextStreamFunction endl = ::endl; 25 | } 26 | #endif 27 | 28 | 29 | namespace openshot { 30 | 31 | // Cross-platform aligned free function 32 | inline void aligned_free(void* ptr) 33 | { 34 | #if defined(_WIN32) 35 | _aligned_free(ptr); 36 | #else 37 | free(ptr); 38 | #endif 39 | } 40 | 41 | // Clean up buffer after QImage is deleted 42 | static inline void cleanUpBuffer(void *info) 43 | { 44 | if (!info) 45 | return; 46 | 47 | // Free the aligned memory buffer 48 | aligned_free(info); 49 | } 50 | } // namespace 51 | 52 | #endif // OPENSHOT_QT_UTILITIES_H 53 | -------------------------------------------------------------------------------- /src/RendererBase.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for RendererBase class 4 | * @author Duzy Chan 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "RendererBase.h" 14 | using namespace openshot; 15 | 16 | RendererBase::RendererBase() 17 | { 18 | } 19 | 20 | RendererBase::~RendererBase() 21 | { 22 | } 23 | 24 | void RendererBase::paint(const std::shared_ptr & frame) 25 | { 26 | if (frame) 27 | this->render(frame->GetImage()); 28 | } 29 | -------------------------------------------------------------------------------- /src/RendererBase.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for RendererBase class 4 | * @author Duzy Chan 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_RENDERER_BASE_H 14 | #define OPENSHOT_RENDERER_BASE_H 15 | 16 | #include "Frame.h" 17 | #include // for realloc 18 | #include 19 | 20 | namespace openshot 21 | { 22 | class Frame; 23 | 24 | /** 25 | * @brief This is the base class of all Renderers in libopenshot. 26 | * 27 | * Renderers are responsible for rendering images of a video onto a 28 | * display device. 29 | */ 30 | class RendererBase 31 | { 32 | public: 33 | 34 | /// Paint(render) a video Frame. 35 | void paint(const std::shared_ptr & frame); 36 | 37 | /// Allow manual override of the QWidget that is used to display 38 | virtual void OverrideWidget(int64_t qwidget_address) = 0; 39 | 40 | protected: 41 | RendererBase(); 42 | virtual ~RendererBase(); 43 | 44 | virtual void render(std::shared_ptr image) = 0; 45 | }; 46 | 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/Settings.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for global Settings class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include 14 | #include 15 | #include "Settings.h" 16 | 17 | using namespace openshot; 18 | 19 | // Global reference to Settings 20 | Settings *Settings::m_pInstance = nullptr; 21 | 22 | // Create or Get an instance of the settings singleton 23 | Settings *Settings::Instance() 24 | { 25 | if (!m_pInstance) { 26 | // Create the actual instance of Settings only once 27 | m_pInstance = new Settings; 28 | m_pInstance->OMP_THREADS = omp_get_num_procs(); 29 | m_pInstance->FF_THREADS = omp_get_num_procs(); 30 | auto env_debug = std::getenv("LIBOPENSHOT_DEBUG"); 31 | if (env_debug != nullptr) 32 | m_pInstance->DEBUG_TO_STDERR = true; 33 | } 34 | 35 | return m_pInstance; 36 | } 37 | -------------------------------------------------------------------------------- /src/TimelineBase.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for Timeline class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "TimelineBase.h" 14 | 15 | using namespace openshot; 16 | 17 | /// Constructor for the base timeline 18 | TimelineBase::TimelineBase() 19 | : preview_width(1920), 20 | preview_height(1080) { } 21 | 22 | -------------------------------------------------------------------------------- /src/TimelineBase.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Timeline class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_TIMELINE_BASE_H 14 | #define OPENSHOT_TIMELINE_BASE_H 15 | 16 | #include 17 | #include 18 | 19 | 20 | namespace openshot { 21 | // Forward decl 22 | class Clip; 23 | 24 | /** 25 | * @brief This struct contains info about the current Timeline clip instance 26 | * 27 | * When the Timeline requests an openshot::Frame instance from a Clip, it passes 28 | * this struct along, with some additional details from the Timeline, such as if this clip is 29 | * above or below overlapping clips, etc... This info can help determine if a Clip should apply 30 | * global effects from the Timeline, such as a global Transition/Mask effect. 31 | */ 32 | struct TimelineInfoStruct 33 | { 34 | bool is_top_clip; ///< Is clip on top (if overlapping another clip) 35 | bool is_before_clip_keyframes; ///< Is this before clip keyframes are applied 36 | }; 37 | 38 | /** 39 | * @brief This class represents a timeline (used for building generic timeline implementations) 40 | */ 41 | class TimelineBase { 42 | 43 | public: 44 | int preview_width; ///< Optional preview width of timeline image. If your preview window is smaller than the timeline, it's recommended to set this. 45 | int preview_height; ///< Optional preview width of timeline image. If your preview window is smaller than the timeline, it's recommended to set this. 46 | 47 | /// Constructor for the base timeline 48 | TimelineBase(); 49 | 50 | /// This function will be overloaded in the Timeline class passing no arguments 51 | /// so we'll be able to access the Timeline::Clips() function from a pointer object of 52 | /// the TimelineBase class 53 | virtual std::list Clips() = 0; 54 | 55 | virtual ~TimelineBase() = default; 56 | }; 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/TrackedObjectBase.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for the TrackedObjectBase class 4 | * @author Jonathan Thomas 5 | * @author Brenno Caldato 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #include "TrackedObjectBase.h" 15 | 16 | #include "Json.h" 17 | 18 | namespace openshot 19 | { 20 | 21 | // Default constructor, delegating 22 | TrackedObjectBase::TrackedObjectBase() : TrackedObjectBase("") {} 23 | 24 | // Constructor 25 | TrackedObjectBase::TrackedObjectBase(std::string _id) 26 | : visible(1.0), draw_box(1), id(_id) {} 27 | 28 | Json::Value TrackedObjectBase::add_property_choice_json( 29 | std::string name, int value, int selected_value) const 30 | { 31 | // Create choice 32 | Json::Value new_choice = Json::Value(Json::objectValue); 33 | new_choice["name"] = name; 34 | new_choice["value"] = value; 35 | new_choice["selected"] = (value == selected_value); 36 | 37 | // return JsonValue 38 | return new_choice; 39 | } 40 | } // namespace openshot 41 | -------------------------------------------------------------------------------- /src/TrackedObjectBase.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for the TrackedObjectBase class 4 | * @author Jonathan Thomas 5 | * @author Brenno Caldato 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_TRACKEDOBJECTBASE_H 15 | #define OPENSHOT_TRACKEDOBJECTBASE_H 16 | 17 | #include 18 | #include 19 | 20 | #include "KeyFrame.h" 21 | #include "Json.h" 22 | 23 | namespace openshot { 24 | 25 | // Forward decls 26 | class ClipBase; 27 | 28 | /** 29 | * @brief This abstract class is the base class of all Tracked Objects. 30 | * 31 | * A Tracked Object is an object or a desired set of pixels in a digital image 32 | * which properties (such as position, width and height) can be detected and 33 | * predicted along the frames of a clip. 34 | */ 35 | class TrackedObjectBase { 36 | protected: 37 | std::string id; 38 | ClipBase* parentClip; 39 | 40 | public: 41 | 42 | /// Keyframe to track if a box is visible in the current frame (read-only) 43 | Keyframe visible; 44 | 45 | /// Keyframe to determine if a specific box is drawn (or hidden) 46 | Keyframe draw_box; 47 | 48 | /// Default constructor 49 | TrackedObjectBase(); 50 | 51 | /// Constructor which takes an object ID 52 | TrackedObjectBase(std::string _id); 53 | 54 | /// Destructor 55 | virtual ~TrackedObjectBase() = default; 56 | 57 | /// Get the id of this object 58 | std::string Id() const { return id; } 59 | /// Set the id of this object 60 | void Id(std::string _id) { id = _id; } 61 | /// Get and set the parentClip of this object 62 | ClipBase* ParentClip() const { return parentClip; } 63 | void ParentClip(ClipBase* clip) { parentClip = clip; } 64 | 65 | /// Check if there is data for the exact frame number 66 | virtual bool ExactlyContains(int64_t frame_number) const { return {}; }; 67 | 68 | /// Scale an object's property 69 | virtual void ScalePoints(double scale) { return; }; 70 | /// Return the main properties of a TrackedObjectBBox instance - such as position, size and rotation 71 | virtual std::map GetBoxValues(int64_t frame_number) const { std::map ret; return ret; }; 72 | /// Add a bounding box to the tracked object's BoxVec map 73 | virtual void AddBox(int64_t _frame_num, float _cx, float _cy, float _width, float _height, float _angle) { return; }; 74 | 75 | 76 | /// Get and Set JSON methods 77 | virtual std::string Json() const = 0; ///< Generate JSON string of this object 78 | virtual Json::Value JsonValue() const = 0; ///< Generate Json::Value for this object 79 | virtual void SetJson(const std::string value) = 0; ///< Load JSON string into this object 80 | virtual void SetJsonValue(const Json::Value root) = 0; ///< Load Json::Value into this object 81 | 82 | /// Get all properties for a specific frame (perfect for a UI to display the current state 83 | /// of all properties at any time) 84 | virtual Json::Value PropertiesJSON(int64_t requested_frame) const = 0; 85 | /// Generate JSON choice for a property (dropdown properties) 86 | Json::Value add_property_choice_json(std::string name, int value, int selected_value) const; 87 | }; 88 | } // Namespace openshot 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /src/ZmqLogger.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for ZeroMQ-based Logger class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_LOGGER_H 14 | #define OPENSHOT_LOGGER_H 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | namespace openshot { 25 | 26 | /** 27 | * @brief This class is used for logging and sending those logs over a ZemoMQ socket to a listener 28 | * 29 | * OpenShot desktop editor listens to this port, to receive libopenshot debug output. It both logs to 30 | * a file and sends the stdout over a socket. 31 | */ 32 | class ZmqLogger { 33 | private: 34 | std::recursive_mutex loggerMutex; 35 | std::string connection; 36 | 37 | // Logfile related vars 38 | std::string file_path; 39 | std::ofstream log_file; 40 | bool enabled; 41 | 42 | /// ZMQ Context 43 | zmq::context_t *context; 44 | 45 | /// ZMQ Socket 46 | zmq::socket_t *publisher; 47 | 48 | /// Default constructor 49 | ZmqLogger(){}; // Don't allow user to create an instance of this singleton 50 | 51 | #if __GNUC__ >=7 52 | /// Default copy method 53 | ZmqLogger(ZmqLogger const&) = delete; // Don't allow the user to assign this instance 54 | 55 | /// Default assignment operator 56 | ZmqLogger & operator=(ZmqLogger const&) = delete; // Don't allow the user to assign this instance 57 | #else 58 | /// Default copy method 59 | ZmqLogger(ZmqLogger const&) {}; // Don't allow the user to assign this instance 60 | 61 | /// Default assignment operator 62 | ZmqLogger & operator=(ZmqLogger const&); // Don't allow the user to assign this instance 63 | #endif 64 | 65 | /// Private variable to keep track of singleton instance 66 | static ZmqLogger * m_pInstance; 67 | 68 | public: 69 | /// Create or get an instance of this logger singleton (invoke the class with this method) 70 | static ZmqLogger * Instance(); 71 | 72 | /// Append debug information 73 | void AppendDebugMethod( 74 | std::string method_name, 75 | std::string arg1_name="", float arg1_value=-1.0, 76 | std::string arg2_name="", float arg2_value=-1.0, 77 | std::string arg3_name="", float arg3_value=-1.0, 78 | std::string arg4_name="", float arg4_value=-1.0, 79 | std::string arg5_name="", float arg5_value=-1.0, 80 | std::string arg6_name="", float arg6_value=-1.0 81 | ); 82 | 83 | /// Close logger (sockets and/or files) 84 | void Close(); 85 | 86 | /// Set or change connection info for logger (i.e. tcp://*:5556) 87 | void Connection(std::string new_connection); 88 | 89 | /// Enable/Disable logging 90 | void Enable(bool is_enabled) { enabled = is_enabled;}; 91 | 92 | /// Set or change the file path (optional) 93 | void Path(std::string new_path); 94 | 95 | /// Log message to all subscribers of this logger (if any) 96 | void Log(std::string message); 97 | 98 | /// Log message to a file (if path set) 99 | void LogToFile(std::string message); 100 | }; 101 | 102 | } 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /src/audio_effects/Compressor.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Compressor audio effect class 4 | * @author 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_COMPRESSOR_AUDIO_EFFECT_H 14 | #define OPENSHOT_COMPRESSOR_AUDIO_EFFECT_H 15 | 16 | #include "EffectBase.h" 17 | 18 | #include "Json.h" 19 | #include "KeyFrame.h" 20 | #include "Enums.h" 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | namespace openshot 29 | { 30 | class Frame; 31 | /** 32 | * @brief This class adds a compressor into the audio 33 | * 34 | */ 35 | class Compressor : public EffectBase 36 | { 37 | private: 38 | /// Init effect settings 39 | void init_effect_details(); 40 | 41 | 42 | public: 43 | Keyframe threshold; 44 | Keyframe ratio; 45 | Keyframe attack; 46 | Keyframe release; 47 | Keyframe makeup_gain; 48 | Keyframe bypass; 49 | 50 | juce::AudioBuffer mixed_down_input; 51 | float xl; 52 | float yl; 53 | float xg; 54 | float yg; 55 | float control; 56 | 57 | float input_level; 58 | float yl_prev; 59 | 60 | float inverse_sample_rate; 61 | float inverseE; 62 | 63 | /// Default constructor 64 | Compressor(); 65 | 66 | /// Constructor 67 | Compressor(Keyframe threshold, Keyframe ratio, Keyframe attack, 68 | Keyframe release, Keyframe makeup_gain, Keyframe bypass); 69 | 70 | float calculateAttackOrRelease(float value); 71 | 72 | std::shared_ptr GetFrame(int64_t frame_number) override { 73 | return GetFrame(std::make_shared(), frame_number); 74 | } 75 | 76 | std::shared_ptr 77 | GetFrame(std::shared_ptr frame, int64_t frame_number) override; 78 | 79 | // Get and Set JSON methods 80 | std::string Json() const override; ///< Generate JSON string of this object 81 | void SetJson(const std::string value) override; ///< Load JSON string into this object 82 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 83 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 84 | 85 | std::string PropertiesJSON(int64_t requested_frame) const override; 86 | }; 87 | 88 | } 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /src/audio_effects/Delay.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Delay audio effect class 4 | * @author 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_DELAY_AUDIO_EFFECT_H 14 | #define OPENSHOT_DELAY_AUDIO_EFFECT_H 15 | 16 | #include "EffectBase.h" 17 | 18 | #include "Json.h" 19 | #include "KeyFrame.h" 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace openshot 28 | { 29 | class Frame; 30 | 31 | /** 32 | * @brief This class adds a delay into the audio 33 | * 34 | */ 35 | class Delay : public EffectBase 36 | { 37 | private: 38 | /// Init effect settings 39 | void init_effect_details(); 40 | 41 | public: 42 | Keyframe delay_time; 43 | 44 | juce::AudioBuffer delay_buffer; 45 | int delay_buffer_samples; 46 | int delay_buffer_channels; 47 | int delay_write_position; 48 | bool initialized; 49 | 50 | /// Default constructor 51 | Delay(); 52 | 53 | /// Constructor 54 | Delay(Keyframe new_delay_time); 55 | 56 | std::shared_ptr GetFrame(int64_t frame_number) override { 57 | return GetFrame(std::make_shared(), frame_number); 58 | } 59 | 60 | void setup(std::shared_ptr frame); 61 | 62 | std::shared_ptr 63 | GetFrame(std::shared_ptr frame, int64_t frame_number) override; 64 | 65 | // Get and Set JSON methods 66 | std::string Json() const override; ///< Generate JSON string of this object 67 | void SetJson(const std::string value) override; ///< Load JSON string into this object 68 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 69 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 70 | 71 | std::string PropertiesJSON(int64_t requested_frame) const override; 72 | }; 73 | 74 | } 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/audio_effects/Distortion.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Distortion audio effect class 4 | * @author 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_DISTORTION_AUDIO_EFFECT_H 14 | #define OPENSHOT_DISTORTION_AUDIO_EFFECT_H 15 | #define _USE_MATH_DEFINES 16 | 17 | #include "EffectBase.h" 18 | 19 | #include "Json.h" 20 | #include "KeyFrame.h" 21 | #include "Enums.h" 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace openshot 31 | { 32 | class Frame; 33 | /** 34 | * @brief This class adds a distortion into the audio 35 | * 36 | */ 37 | class Distortion : public EffectBase 38 | { 39 | private: 40 | /// Init effect settings 41 | void init_effect_details(); 42 | 43 | public: 44 | openshot::DistortionType distortion_type; 45 | Keyframe input_gain; 46 | Keyframe output_gain; 47 | Keyframe tone; 48 | 49 | /// Default constructor 50 | Distortion(); 51 | 52 | /// Constructor 53 | Distortion(openshot::DistortionType distortion_type, 54 | Keyframe input_gain, Keyframe output_gain, Keyframe tone); 55 | 56 | std::shared_ptr GetFrame(int64_t frame_number) override { 57 | return GetFrame(std::make_shared(), frame_number); 58 | } 59 | 60 | std::shared_ptr GetFrame(std::shared_ptr frame, int64_t frame_number) override; 61 | 62 | // Get and Set JSON methods 63 | std::string Json() const override; ///< Generate JSON string of this object 64 | void SetJson(const std::string value) override; ///< Load JSON string into this object 65 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 66 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 67 | 68 | std::string PropertiesJSON(int64_t requested_frame) const override; 69 | 70 | class Filter : public juce::IIRFilter 71 | { 72 | public: 73 | void updateCoefficients(const double discrete_frequency, const double gain); 74 | }; 75 | 76 | juce::OwnedArray filters; 77 | 78 | void updateFilters(int64_t frame_number); 79 | }; 80 | 81 | } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/audio_effects/Echo.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Echo audio effect class 4 | * @author 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_ECHO_AUDIO_EFFECT_H 14 | #define OPENSHOT_ECHO_AUDIO_EFFECT_H 15 | 16 | #include "EffectBase.h" 17 | 18 | #include "Json.h" 19 | #include "KeyFrame.h" 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace openshot 28 | { 29 | class Frame; 30 | 31 | /** 32 | * @brief This class adds a echo into the audio 33 | * 34 | */ 35 | class Echo : public EffectBase 36 | { 37 | private: 38 | /// Init effect settings 39 | void init_effect_details(); 40 | 41 | public: 42 | Keyframe echo_time; 43 | Keyframe feedback; 44 | Keyframe mix; 45 | 46 | juce::AudioBuffer echo_buffer; 47 | int echo_buffer_samples; 48 | int echo_buffer_channels; 49 | int echo_write_position; 50 | bool initialized; 51 | 52 | /// Default constructor 53 | Echo(); 54 | 55 | /// Constructor 56 | Echo(Keyframe echo_time, Keyframe feedback, Keyframe mix); 57 | 58 | std::shared_ptr GetFrame(int64_t frame_number) override { 59 | return GetFrame(std::make_shared(), frame_number); 60 | } 61 | 62 | void setup(std::shared_ptr frame); 63 | 64 | std::shared_ptr 65 | GetFrame(std::shared_ptr frame, int64_t frame_number) override; 66 | 67 | // Get and Set JSON methods 68 | std::string Json() const override; ///< Generate JSON string of this object 69 | void SetJson(const std::string value) override; ///< Load JSON string into this object 70 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 71 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 72 | 73 | std::string PropertiesJSON(int64_t requested_frame) const override; 74 | }; 75 | 76 | } 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/audio_effects/Expander.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Expander audio effect class 4 | * @author 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_EXPANDER_AUDIO_EFFECT_H 14 | #define OPENSHOT_EXPANDER_AUDIO_EFFECT_H 15 | 16 | #include "EffectBase.h" 17 | 18 | #include "Json.h" 19 | #include "KeyFrame.h" 20 | #include "Enums.h" 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | namespace openshot 29 | { 30 | class Frame; 31 | 32 | /** 33 | * @brief This class adds a expander (or noise gate) into the audio 34 | * 35 | */ 36 | class Expander : public EffectBase 37 | { 38 | private: 39 | /// Init effect settings 40 | void init_effect_details(); 41 | 42 | 43 | public: 44 | Keyframe threshold; 45 | Keyframe ratio; 46 | Keyframe attack; 47 | Keyframe release; 48 | Keyframe makeup_gain; 49 | Keyframe bypass; 50 | 51 | juce::AudioBuffer mixed_down_input; 52 | float xl; 53 | float yl; 54 | float xg; 55 | float yg; 56 | float control; 57 | 58 | float input_level; 59 | float yl_prev; 60 | 61 | float inverse_sample_rate; 62 | float inverseE; 63 | 64 | /// Default constructor 65 | Expander(); 66 | 67 | /// Constructor 68 | Expander(Keyframe threshold, Keyframe ratio, Keyframe attack, 69 | Keyframe release, Keyframe makeup_gain, Keyframe bypass); 70 | 71 | float calculateAttackOrRelease(float value); 72 | 73 | std::shared_ptr GetFrame(int64_t frame_number) override { 74 | return GetFrame(std::make_shared(), frame_number); 75 | } 76 | 77 | std::shared_ptr 78 | GetFrame(std::shared_ptr frame, int64_t frame_number) override; 79 | 80 | // Get and Set JSON methods 81 | std::string Json() const override; ///< Generate JSON string of this object 82 | void SetJson(const std::string value) override; ///< Load JSON string into this object 83 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 84 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 85 | 86 | std::string PropertiesJSON(int64_t requested_frame) const override; 87 | }; 88 | 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/audio_effects/Noise.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Noise audio effect class 4 | * @author 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_NOISE_AUDIO_EFFECT_H 14 | #define OPENSHOT_NOISE_AUDIO_EFFECT_H 15 | 16 | #include "../EffectBase.h" 17 | 18 | #include "../Frame.h" 19 | #include "../Json.h" 20 | #include "../KeyFrame.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | 28 | namespace openshot 29 | { 30 | 31 | /** 32 | * @brief This class adds a noise into the audio 33 | * 34 | */ 35 | class Noise : public EffectBase 36 | { 37 | private: 38 | /// Init effect settings 39 | void init_effect_details(); 40 | 41 | public: 42 | Keyframe level; ///< Noise level keyframe. The amount of noise inserted on the audio. 43 | 44 | /// Default constructor 45 | Noise(); 46 | 47 | /// Constructor 48 | /// 49 | /// @param level The audio default noise level (between 1 and 100) 50 | Noise(Keyframe level); 51 | 52 | std::shared_ptr GetFrame(int64_t frame_number) override { 53 | return GetFrame(std::make_shared(), frame_number); 54 | } 55 | 56 | std::shared_ptr 57 | GetFrame(std::shared_ptr frame, int64_t frame_number) override; 58 | 59 | // Get and Set JSON methods 60 | std::string Json() const override; ///< Generate JSON string of this object 61 | void SetJson(const std::string value) override; ///< Load JSON string into this object 62 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 63 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 64 | 65 | std::string PropertiesJSON(int64_t requested_frame) const override; 66 | }; 67 | 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/audio_effects/ParametricEQ.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Parametric EQ audio effect class 4 | * @author 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_PARAMETRIC_EQ_AUDIO_EFFECT_H 14 | #define OPENSHOT_PARAMETRIC_EQ_AUDIO_EFFECT_H 15 | #define _USE_MATH_DEFINES 16 | 17 | #include "EffectBase.h" 18 | 19 | #include "Json.h" 20 | #include "KeyFrame.h" 21 | #include "Enums.h" 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | namespace openshot 30 | { 31 | class Frame; 32 | 33 | /** 34 | * @brief This class adds a equalization into the audio 35 | * 36 | */ 37 | class ParametricEQ : public EffectBase 38 | { 39 | private: 40 | /// Init effect settings 41 | void init_effect_details(); 42 | 43 | public: 44 | openshot::FilterType filter_type; 45 | Keyframe frequency; 46 | Keyframe q_factor; 47 | Keyframe gain; 48 | bool initialized; 49 | 50 | /// Blank constructor, useful when using Json to load the effect properties 51 | ParametricEQ(); 52 | 53 | /// Constructor 54 | ParametricEQ(openshot::FilterType filter_type, Keyframe frequency, 55 | Keyframe gain, Keyframe q_factor); 56 | 57 | std::shared_ptr GetFrame(int64_t frame_number) override { 58 | return GetFrame(std::make_shared(), frame_number); 59 | } 60 | 61 | std::shared_ptr 62 | GetFrame(std::shared_ptr frame, int64_t frame_number) override; 63 | 64 | // Get and Set JSON methods 65 | std::string Json() const override; ///< Generate JSON string of this object 66 | void SetJson(const std::string value) override; ///< Load JSON string into this object 67 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 68 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 69 | 70 | std::string PropertiesJSON(int64_t requested_frame) const override; 71 | 72 | class Filter : public juce::IIRFilter 73 | { 74 | public: 75 | void updateCoefficients (const double discrete_frequency, 76 | const double q_factor, 77 | const double gain, 78 | const int filter_type); 79 | }; 80 | 81 | juce::OwnedArray filters; 82 | 83 | void updateFilters(int64_t frame_number, double sample_rate); 84 | }; 85 | 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/audio_effects/Robotization.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Robotization audio effect class 4 | * @author 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_ROBOTIZATION_AUDIO_EFFECT_H 14 | #define OPENSHOT_ROBOTIZATION_AUDIO_EFFECT_H 15 | #define _USE_MATH_DEFINES 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "EffectBase.h" 22 | 23 | #include "STFT.h" 24 | 25 | #include "Json.h" 26 | #include "KeyFrame.h" 27 | #include "Enums.h" 28 | 29 | namespace juce { 30 | namespace dsp { 31 | class FFT; 32 | } 33 | } 34 | namespace openshot 35 | { 36 | class Frame; 37 | 38 | /** 39 | * @brief This class adds a robotization effect into the audio 40 | * 41 | */ 42 | class Robotization : public EffectBase 43 | { 44 | private: 45 | /// Init effect settings 46 | void init_effect_details(); 47 | 48 | public: 49 | openshot::FFTSize fft_size; 50 | openshot::HopSize hop_size; 51 | openshot::WindowType window_type; 52 | 53 | /// Default constructor 54 | Robotization(); 55 | 56 | /// Constructor 57 | Robotization(openshot::FFTSize fft_size, 58 | openshot::HopSize hop_size, 59 | openshot::WindowType window_type); 60 | 61 | std::shared_ptr GetFrame(int64_t frame_number) override { 62 | return GetFrame(std::make_shared(), frame_number); 63 | } 64 | 65 | std::shared_ptr 66 | GetFrame(std::shared_ptr frame, int64_t frame_number) override; 67 | 68 | // Get and Set JSON methods 69 | std::string Json() const override; ///< Generate JSON string of this object 70 | void SetJson(const std::string value) override; ///< Load JSON string into this object 71 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 72 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 73 | 74 | std::string PropertiesJSON(int64_t requested_frame) const override; 75 | 76 | 77 | class RobotizationEffect : public STFT 78 | { 79 | public: 80 | RobotizationEffect (Robotization& p) : parent (p) { } 81 | 82 | private: 83 | void modification(const int channel) override; 84 | 85 | Robotization &parent; 86 | }; 87 | 88 | std::recursive_mutex mutex; 89 | RobotizationEffect stft; 90 | std::unique_ptr fft; 91 | }; 92 | 93 | } // namespace 94 | 95 | #endif // OPENSHOT_ROBOTIZATION_AUDIO_EFFECT_H 96 | -------------------------------------------------------------------------------- /src/audio_effects/STFT.h: -------------------------------------------------------------------------------- 1 | // © OpenShot Studios, LLC 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #pragma once 6 | 7 | #ifndef OPENSHOT_STFT_AUDIO_EFFECT_H 8 | #define OPENSHOT_STFT_AUDIO_EFFECT_H 9 | #define _USE_MATH_DEFINES 10 | 11 | #include "EffectBase.h" 12 | #include "Enums.h" 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | namespace openshot 19 | { 20 | 21 | class STFT 22 | { 23 | public: 24 | STFT() : num_channels (1) { } 25 | 26 | virtual ~STFT() { } 27 | 28 | void setup(const int num_input_channels); 29 | 30 | void process(juce::AudioBuffer &block); 31 | 32 | void updateParameters(const int new_fft_size, const int new_overlap, const int new_window_type); 33 | 34 | virtual void updateFftSize(const int new_fft_size); 35 | 36 | virtual void updateHopSize(const int new_overlap); 37 | 38 | virtual void updateWindow(const int new_window_type); 39 | 40 | private: 41 | 42 | virtual void modification(const int channel); 43 | 44 | virtual void analysis(const int channel); 45 | 46 | virtual void synthesis(const int channel); 47 | 48 | protected: 49 | int num_channels; 50 | int num_samples; 51 | 52 | int fft_size; 53 | std::unique_ptr fft; 54 | 55 | int input_buffer_length; 56 | juce::AudioBuffer input_buffer; 57 | 58 | int output_buffer_length; 59 | juce::AudioBuffer output_buffer; 60 | 61 | juce::HeapBlock fft_window; 62 | juce::HeapBlock> time_domain_buffer; 63 | juce::HeapBlock> frequency_domain_buffer; 64 | 65 | int overlap; 66 | int hop_size; 67 | int window_type; 68 | float window_scale_factor; 69 | 70 | int input_buffer_write_position; 71 | int output_buffer_write_position; 72 | int output_buffer_read_position; 73 | int samples_since_last_FFT; 74 | 75 | int current_input_buffer_write_position; 76 | int current_output_buffer_write_position; 77 | int current_output_buffer_read_position; 78 | int current_samples_since_last_FFT; 79 | }; 80 | } 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/audio_effects/Whisperization.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for whisperization audio effect class 4 | * @author 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_WHISPERIZATION_AUDIO_EFFECT_H 14 | #define OPENSHOT_WHISPERIZATION_AUDIO_EFFECT_H 15 | #define _USE_MATH_DEFINES 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "../EffectBase.h" 22 | 23 | #include "../Json.h" 24 | #include "../KeyFrame.h" 25 | #include "../Enums.h" 26 | #include "STFT.h" 27 | 28 | namespace juce { 29 | namespace dsp { 30 | class FFT; 31 | } 32 | } 33 | 34 | namespace openshot 35 | { 36 | class Frame; 37 | /** 38 | * @brief This class adds a whisperization effect into the audio 39 | * 40 | */ 41 | class Whisperization : public EffectBase 42 | { 43 | private: 44 | /// Init effect settings 45 | void init_effect_details(); 46 | 47 | public: 48 | openshot::FFTSize fft_size; 49 | openshot::HopSize hop_size; 50 | openshot::WindowType window_type; 51 | 52 | /// Default constructor 53 | Whisperization(); 54 | 55 | /// Constructor 56 | Whisperization(openshot::FFTSize fft_size, 57 | openshot::HopSize hop_size, 58 | openshot::WindowType window_type); 59 | 60 | std::shared_ptr GetFrame(int64_t frame_number) override { 61 | return GetFrame(std::make_shared(), frame_number); 62 | } 63 | 64 | std::shared_ptr 65 | GetFrame(std::shared_ptr frame, int64_t frame_number) override; 66 | 67 | // Get and Set JSON methods 68 | std::string Json() const override; ///< Generate JSON string of this object 69 | void SetJson(const std::string value) override; ///< Load JSON string into this object 70 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 71 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 72 | 73 | std::string PropertiesJSON(int64_t requested_frame) const override; 74 | 75 | 76 | class WhisperizationEffect : public STFT 77 | { 78 | public: 79 | WhisperizationEffect(Whisperization& p) : parent (p) { } 80 | 81 | private: 82 | void modification(const int channel) override; 83 | 84 | Whisperization &parent; 85 | }; 86 | 87 | std::recursive_mutex mutex; 88 | WhisperizationEffect stft; 89 | std::unique_ptr fft; 90 | }; 91 | 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /src/effects/Brightness.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Brightness class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_BRIGHTNESS_EFFECT_H 14 | #define OPENSHOT_BRIGHTNESS_EFFECT_H 15 | 16 | #include "../EffectBase.h" 17 | 18 | #include "../Frame.h" 19 | #include "../Json.h" 20 | #include "../KeyFrame.h" 21 | 22 | #include 23 | #include 24 | 25 | namespace openshot 26 | { 27 | 28 | /** 29 | * @brief This class adjusts the brightness and contrast of an image, and can be animated 30 | * with openshot::Keyframe curves over time. 31 | * 32 | * Adjusting the brightness and contrast over time can create many different powerful effects. 33 | */ 34 | class Brightness : public EffectBase 35 | { 36 | private: 37 | /// Init effect settings 38 | void init_effect_details(); 39 | 40 | public: 41 | Keyframe brightness; ///< Brightness keyframe. A constant value here will prevent animation. 42 | Keyframe contrast; ///< Contrast keyframe. 43 | 44 | /// Blank constructor, useful when using Json to load the effect properties 45 | Brightness(); 46 | 47 | /// Default constructor, which takes 2 curves. The curves adjust the brightness and 48 | // contrast of a frame's image. 49 | /// 50 | /// @param new_brightness The curve to adjust the brightness (from -1 to +1, 0 is default/"off") 51 | /// @param new_contrast The curve to adjust the contrast (3 is typical, 20 is a lot, 100 is max. 0 is invalid) 52 | Brightness(Keyframe new_brightness, Keyframe new_contrast); 53 | 54 | /// @brief This method is required for all derived classes of ClipBase, and returns a 55 | /// new openshot::Frame object. All Clip keyframes and effects are resolved into 56 | /// pixels. 57 | /// 58 | /// @returns A new openshot::Frame object 59 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 60 | std::shared_ptr GetFrame(int64_t frame_number) override { return GetFrame(std::make_shared(), frame_number); } 61 | 62 | /// @brief This method is required for all derived classes of ClipBase, and returns a 63 | /// modified openshot::Frame object 64 | /// 65 | /// The frame object is passed into this method and used as a starting point (pixels and audio). 66 | /// All Clip keyframes and effects are resolved into pixels. 67 | /// 68 | /// @returns The modified openshot::Frame object 69 | /// @param frame The frame object that needs the clip or effect applied to it 70 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 71 | std::shared_ptr GetFrame(std::shared_ptr frame, int64_t frame_number) override; 72 | 73 | // Get and Set JSON methods 74 | std::string Json() const override; ///< Generate JSON string of this object 75 | void SetJson(const std::string value) override; ///< Load JSON string into this object 76 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 77 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 78 | 79 | /// Get all properties for a specific frame (perfect for a UI to display the current state 80 | /// of all properties at any time) 81 | std::string PropertiesJSON(int64_t requested_frame) const override; 82 | }; 83 | 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /src/effects/ColorMap.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for ColorMap (LUT) effect 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_COLORMAP_EFFECT_H 14 | #define OPENSHOT_COLORMAP_EFFECT_H 15 | 16 | #include "../EffectBase.h" 17 | #include "../Json.h" 18 | #include "../KeyFrame.h" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace openshot 26 | { 27 | 28 | /** 29 | * @brief Applies a 3D LUT (.cube) color transform to each frame. 30 | * 31 | * Loads a .cube file (LUT_3D_SIZE N × N × N) into memory, then for each pixel 32 | * uses nearest‐neighbor lookup and blends the result by keyframable per‐channel intensities. 33 | */ 34 | class ColorMap : public EffectBase 35 | { 36 | private: 37 | std::string lut_path; ///< Filesystem path to .cube LUT file 38 | int lut_size; ///< Dimension N of the cube (LUT_3D_SIZE) 39 | std::vector lut_data; ///< Flat array [N³ × 3] RGB lookup table 40 | bool needs_refresh; ///< Reload LUT on next frame 41 | 42 | /// Populate info fields (class_name, name, description) 43 | void init_effect_details(); 44 | 45 | /// Parse the .cube file into lut_size & lut_data 46 | void load_cube_file(); 47 | 48 | public: 49 | Keyframe intensity; ///< Overall intensity 0–1 (affects all channels) 50 | Keyframe intensity_r; ///< Blend 0–1 for red channel 51 | Keyframe intensity_g; ///< Blend 0–1 for green channel 52 | Keyframe intensity_b; ///< Blend 0–1 for blue channel 53 | 54 | /// Blank constructor (used by JSON loader) 55 | ColorMap(); 56 | 57 | /** 58 | * @brief Constructor with LUT path and per‐channel intensities 59 | * 60 | * @param path Filesystem path to .cube file 61 | * @param i Keyframe for overall intensity (0–1) 62 | * @param iR Keyframe for red blend (0–1) 63 | * @param iG Keyframe for green blend (0–1) 64 | * @param iB Keyframe for blue blend (0–1) 65 | */ 66 | ColorMap(const std::string &path, 67 | const Keyframe &i = Keyframe(1.0), 68 | const Keyframe &iR = Keyframe(1.0), 69 | const Keyframe &iG = Keyframe(1.0), 70 | const Keyframe &iB = Keyframe(1.0)); 71 | 72 | /// Apply effect to a new frame 73 | std::shared_ptr 74 | GetFrame(int64_t frame_number) override 75 | { return GetFrame(std::make_shared(), frame_number); } 76 | 77 | /// Apply effect to an existing frame 78 | std::shared_ptr 79 | GetFrame(std::shared_ptr frame, 80 | int64_t frame_number) override; 81 | 82 | // JSON serialization 83 | std::string Json() const override; 84 | Json::Value JsonValue() const override; 85 | void SetJson(const std::string value) override; 86 | void SetJsonValue(const Json::Value root) override; 87 | 88 | /// Expose properties (for UI) 89 | std::string PropertiesJSON(int64_t requested_frame) const override; 90 | }; 91 | 92 | } // namespace openshot 93 | 94 | #endif // OPENSHOT_COLORMAP_EFFECT_H 95 | -------------------------------------------------------------------------------- /src/effects/Deinterlace.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for De-interlace class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_DEINTERLACE_EFFECT_H 14 | #define OPENSHOT_DEINTERLACE_EFFECT_H 15 | 16 | #include "../EffectBase.h" 17 | 18 | #include 19 | #include 20 | #include "../Frame.h" 21 | #include "../Json.h" 22 | #include "../KeyFrame.h" 23 | 24 | namespace openshot 25 | { 26 | 27 | /** 28 | * @brief This class uses the ImageMagick++ libraries, to de-interlace the image, which 29 | * removes the EVEN or ODD horizontal lines (which represent different points of time). 30 | * 31 | * This is most useful when converting video made for traditional TVs to computers, 32 | * which are not interlaced. 33 | */ 34 | class Deinterlace : public EffectBase 35 | { 36 | private: 37 | bool isOdd; 38 | 39 | /// Init effect settings 40 | void init_effect_details(); 41 | 42 | public: 43 | 44 | /// Default constructor, useful when using Json to load the effect properties 45 | Deinterlace(); 46 | 47 | /// Constructor 48 | Deinterlace(bool isOdd); 49 | 50 | /// @brief This method is required for all derived classes of ClipBase, and returns a 51 | /// new openshot::Frame object. All Clip keyframes and effects are resolved into 52 | /// pixels. 53 | /// 54 | /// @returns A new openshot::Frame object 55 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 56 | std::shared_ptr GetFrame(int64_t frame_number) override { return GetFrame(std::make_shared(), frame_number); } 57 | 58 | /// @brief This method is required for all derived classes of ClipBase, and returns a 59 | /// modified openshot::Frame object 60 | /// 61 | /// The frame object is passed into this method and used as a starting point (pixels and audio). 62 | /// All Clip keyframes and effects are resolved into pixels. 63 | /// 64 | /// @returns The modified openshot::Frame object 65 | /// @param frame The frame object that needs the clip or effect applied to it 66 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 67 | std::shared_ptr GetFrame(std::shared_ptr frame, int64_t frame_number) override; 68 | 69 | // Get and Set JSON methods 70 | std::string Json() const override; ///< Generate JSON string of this object 71 | void SetJson(const std::string value) override; ///< Load JSON string into this object 72 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 73 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 74 | 75 | // Get all properties for a specific frame 76 | std::string PropertiesJSON(int64_t requested_frame) const override; 77 | }; 78 | 79 | } 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/effects/Hue.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Hue effect class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_HUE_EFFECT_H 14 | #define OPENSHOT_HUE_EFFECT_H 15 | 16 | #include "../EffectBase.h" 17 | 18 | #include "../Frame.h" 19 | #include "../Json.h" 20 | #include "../KeyFrame.h" 21 | 22 | #include 23 | #include 24 | 25 | 26 | namespace openshot 27 | { 28 | 29 | /** 30 | * @brief This class shifts the hue of an image, and can be animated with openshot::Keyframe curves over time. 31 | * 32 | * Shifting hue can adjust the colors in an image towards red, blue, green, or anywhere in between. Animating hue 33 | * can create some fun and interesting effects, but can also be used to change the mood of a scene, etc... 34 | */ 35 | class Hue : public EffectBase 36 | { 37 | private: 38 | /// Init effect settings 39 | void init_effect_details(); 40 | 41 | 42 | public: 43 | Keyframe hue; ///< Shift the hue coordinates (left or right) 44 | 45 | /// Default constructor, useful when using Json to load the effect properties 46 | Hue(); 47 | 48 | /// Constructor which takes 1 curve. The curves will shift the hue of the image. 49 | /// 50 | /// @param hue The curve to adjust the hue shift (between 0 and 1) 51 | Hue(Keyframe hue); 52 | 53 | /// @brief This method is required for all derived classes of ClipBase, and returns a 54 | /// new openshot::Frame object. All Clip keyframes and effects are resolved into 55 | /// pixels. 56 | /// 57 | /// @returns A new openshot::Frame object 58 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 59 | std::shared_ptr GetFrame(int64_t frame_number) override { return GetFrame(std::make_shared(), frame_number); } 60 | 61 | /// @brief This method is required for all derived classes of ClipBase, and returns a 62 | /// modified openshot::Frame object 63 | /// 64 | /// The frame object is passed into this method and used as a starting point (pixels and audio). 65 | /// All Clip keyframes and effects are resolved into pixels. 66 | /// 67 | /// @returns The modified openshot::Frame object 68 | /// @param frame The frame object that needs the clip or effect applied to it 69 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 70 | std::shared_ptr GetFrame(std::shared_ptr frame, int64_t frame_number) override; 71 | 72 | // Get and Set JSON methods 73 | std::string Json() const override; ///< Generate JSON string of this object 74 | void SetJson(const std::string value) override; ///< Load JSON string into this object 75 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 76 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 77 | 78 | /// Get all properties for a specific frame (perfect for a UI to display the current state 79 | /// of all properties at any time) 80 | std::string PropertiesJSON(int64_t requested_frame) const override; 81 | }; 82 | 83 | } 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/effects/LensFlare.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for LensFlare class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_LENSFLARE_EFFECT_H 14 | #define OPENSHOT_LENSFLARE_EFFECT_H 15 | 16 | #include "../EffectBase.h" 17 | #include "../KeyFrame.h" 18 | #include "../Color.h" 19 | #include 20 | #include 21 | 22 | namespace openshot 23 | { 24 | class LensFlare : public EffectBase 25 | { 26 | private: 27 | void init_effect_details(); 28 | 29 | public: 30 | Keyframe x; 31 | Keyframe y; 32 | Keyframe brightness; 33 | Keyframe size; 34 | Keyframe spread; 35 | Color color; 36 | 37 | LensFlare(); 38 | ~LensFlare() override; 39 | LensFlare(const Keyframe &xPos, 40 | const Keyframe &yPos, 41 | const Keyframe &intensity, 42 | const Keyframe &scale, 43 | const Keyframe &spreadVal, 44 | const Keyframe &bladeCount, 45 | const Keyframe &shapeType, 46 | const Color &tint = Color("#ffffff")); 47 | 48 | std::shared_ptr GetFrame(int64_t frame_number) override; 49 | std::shared_ptr GetFrame(std::shared_ptr frame, 50 | int64_t frame_number) override; 51 | 52 | std::string Json() const override; 53 | Json::Value JsonValue() const override; 54 | void SetJson(const std::string value) override; 55 | void SetJsonValue(const Json::Value root) override; 56 | 57 | std::string PropertiesJSON(int64_t requested_frame) const override; 58 | }; 59 | 60 | } // namespace openshot 61 | 62 | #endif // OPENSHOT_LENSFLARE_EFFECT_H 63 | -------------------------------------------------------------------------------- /src/effects/Negate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source file for Negate class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "Negate.h" 14 | #include "Exceptions.h" 15 | 16 | using namespace openshot; 17 | 18 | // Default constructor 19 | Negate::Negate() 20 | { 21 | /// Initialize the values of the EffectInfo struct. 22 | InitEffectInfo(); 23 | 24 | /// Set the effect info 25 | info.class_name = "Negate"; 26 | info.name = "Negative"; 27 | info.description = "Negates the colors, producing a negative of the image."; 28 | info.has_audio = false; 29 | info.has_video = true; 30 | } 31 | 32 | // This method is required for all derived classes of EffectBase, and returns a 33 | // modified openshot::Frame object 34 | std::shared_ptr Negate::GetFrame(std::shared_ptr frame, int64_t frame_number) 35 | { 36 | // Make a negative of the images pixels 37 | frame->GetImage()->invertPixels(); 38 | 39 | // return the modified frame 40 | return frame; 41 | } 42 | 43 | // Generate JSON string of this object 44 | std::string Negate::Json() const { 45 | 46 | // Return formatted string 47 | return JsonValue().toStyledString(); 48 | } 49 | 50 | // Generate Json::Value for this object 51 | Json::Value Negate::JsonValue() const { 52 | 53 | // Create root json object 54 | Json::Value root = EffectBase::JsonValue(); // get parent properties 55 | root["type"] = info.class_name; 56 | 57 | // return JsonValue 58 | return root; 59 | } 60 | 61 | // Load JSON string into this object 62 | void Negate::SetJson(const std::string value) { 63 | 64 | // Parse JSON string into JSON objects 65 | try 66 | { 67 | const Json::Value root = openshot::stringToJson(value); 68 | // Set all values that match 69 | SetJsonValue(root); 70 | } 71 | catch (const std::exception& e) 72 | { 73 | // Error parsing JSON (or missing keys) 74 | throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); 75 | } 76 | } 77 | 78 | // Load Json::Value into this object 79 | void Negate::SetJsonValue(const Json::Value root) { 80 | 81 | // Set parent data 82 | EffectBase::SetJsonValue(root); 83 | 84 | } 85 | 86 | // Get all properties for a specific frame 87 | std::string Negate::PropertiesJSON(int64_t requested_frame) const { 88 | 89 | // Generate JSON properties list 90 | Json::Value root = BasePropertiesJSON(requested_frame); 91 | 92 | // Return formatted string 93 | return root.toStyledString(); 94 | } 95 | -------------------------------------------------------------------------------- /src/effects/Negate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Negate class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_NEGATE_EFFECT_H 14 | #define OPENSHOT_NEGATE_EFFECT_H 15 | 16 | #include "../EffectBase.h" 17 | 18 | #include "../Frame.h" 19 | #include "../KeyFrame.h" 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | namespace openshot 27 | { 28 | 29 | /** 30 | * @brief This class uses the ImageMagick++ libraries, to negate image (i.e. negative) 31 | * 32 | * This produces a common negative effect popular in photography. 33 | */ 34 | class Negate : public EffectBase 35 | { 36 | public: 37 | 38 | /// Default constructor 39 | Negate(); 40 | 41 | /// @brief This method is required for all derived classes of ClipBase, and returns a 42 | /// new openshot::Frame object. All Clip keyframes and effects are resolved into 43 | /// pixels. 44 | /// 45 | /// @returns A new openshot::Frame object 46 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 47 | std::shared_ptr GetFrame(int64_t frame_number) override { return GetFrame(std::make_shared(), frame_number); } 48 | 49 | /// @brief This method is required for all derived classes of ClipBase, and returns a 50 | /// modified openshot::Frame object 51 | /// 52 | /// The frame object is passed into this method and used as a starting point (pixels and audio). 53 | /// All Clip keyframes and effects are resolved into pixels. 54 | /// 55 | /// @returns The modified openshot::Frame object 56 | /// @param frame The frame object that needs the clip or effect applied to it 57 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 58 | std::shared_ptr GetFrame(std::shared_ptr frame, int64_t frame_number) override; 59 | 60 | // Get and Set JSON methods 61 | std::string Json() const override; ///< Generate JSON string of this object 62 | void SetJson(const std::string value) override; ///< Load JSON string into this object 63 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 64 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 65 | 66 | // Get all properties for a specific frame 67 | std::string PropertiesJSON(int64_t requested_frame) const override; 68 | }; 69 | 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/effects/Sharpen.h: -------------------------------------------------------------------------------- 1 | // Sharpen.h 2 | /** 3 | * @file 4 | * @brief Header file for Sharpen effect class 5 | * @author Jonathan Thomas 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_SHARPEN_EFFECT_H 15 | #define OPENSHOT_SHARPEN_EFFECT_H 16 | 17 | #include "EffectBase.h" 18 | #include "KeyFrame.h" 19 | #include "Json.h" 20 | 21 | #include 22 | 23 | namespace openshot { 24 | 25 | /** 26 | * @brief This class provides a sharpen effect for video frames. 27 | * 28 | * The sharpen effect enhances the edges and details in a video frame, making it appear sharper. 29 | * It uses an unsharp mask or high-pass blend technique with adjustable parameters. 30 | */ 31 | class Sharpen : public EffectBase { 32 | private: 33 | /// Initialize the effect details 34 | void init_effect_details(); 35 | 36 | public: 37 | /// Amount of sharpening to apply (0 to 2) 38 | Keyframe amount; 39 | 40 | /// Radius of the blur used in sharpening (0 to 10 pixels for 1080p) 41 | Keyframe radius; 42 | 43 | /// Threshold for applying sharpening (0 to 1) 44 | Keyframe threshold; 45 | 46 | /// Sharpening mode (0 = UnsharpMask, 1 = HighPassBlend) 47 | int mode; 48 | 49 | /// Channel to apply sharpening to (0 = All, 1 = Luma, 2 = Chroma) 50 | int channel; 51 | 52 | /// Default constructor 53 | Sharpen(); 54 | 55 | /// Constructor with initial values 56 | Sharpen(Keyframe new_amount, Keyframe new_radius, Keyframe new_threshold); 57 | 58 | /// @brief This method is required for all derived classes of EffectBase, and returns a 59 | /// modified openshot::Frame object 60 | /// 61 | /// The frame object is passed into this method, and a frame_number is passed in which 62 | /// tells the effect which settings to use from its keyframes (starting at 1). 63 | /// 64 | /// @returns The modified openshot::Frame object 65 | /// @param frame The frame object that needs the effect applied to it 66 | /// @param frame_number The frame number (starting at 1) of the effect on the timeline. 67 | std::shared_ptr GetFrame(std::shared_ptr frame, int64_t frame_number) override; 68 | std::shared_ptr GetFrame(int64_t n) override 69 | { return GetFrame(std::make_shared(), n); } 70 | 71 | /// Get and Set JSON methods 72 | std::string Json() const override; ///< Generate JSON string of this object 73 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 74 | void SetJson(const std::string value) override; ///< Load JSON string into this object 75 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 76 | 77 | /// Get all properties for a specific frame (perfect for a UI to display the current state 78 | /// of all properties at any time) 79 | std::string PropertiesJSON(int64_t requested_frame) const override; 80 | }; 81 | 82 | } // namespace openshot 83 | 84 | #endif // OPENSHOT_SHARPEN_EFFECT_H -------------------------------------------------------------------------------- /src/effects/Shift.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Shift effect class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_SHIFT_EFFECT_H 14 | #define OPENSHOT_SHIFT_EFFECT_H 15 | 16 | #include "../EffectBase.h" 17 | 18 | #include "../Frame.h" 19 | #include "../Json.h" 20 | #include "../KeyFrame.h" 21 | 22 | #include 23 | #include 24 | 25 | 26 | namespace openshot 27 | { 28 | 29 | /** 30 | * @brief This class shifts the pixels of an image up, down, left, or right, and can be animated 31 | * with openshot::Keyframe curves over time. 32 | * 33 | * Shifting pixels can be used in many interesting ways, especially when animating the movement of the pixels. 34 | * The pixels wrap around the image (the pixels drop off one side and appear on the other side of the image). 35 | */ 36 | class Shift : public EffectBase 37 | { 38 | private: 39 | /// Init effect settings 40 | void init_effect_details(); 41 | 42 | 43 | public: 44 | Keyframe x; ///< Shift the X coordinates (left or right) 45 | Keyframe y; ///< Shift the Y coordinates (up or down) 46 | 47 | /// Blank constructor, useful when using Json to load the effect properties 48 | Shift(); 49 | 50 | /// Default constructor, which takes 2 curve. The curves will shift the pixels up, down, left, or right 51 | /// 52 | /// @param x The curve to adjust the x shift (between -1 and 1, percentage) 53 | /// @param y The curve to adjust the y shift (between -1 and 1, percentage) 54 | Shift(Keyframe x, Keyframe y); 55 | 56 | /// @brief This method is required for all derived classes of ClipBase, and returns a 57 | /// new openshot::Frame object. All Clip keyframes and effects are resolved into 58 | /// pixels. 59 | /// 60 | /// @returns A new openshot::Frame object 61 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 62 | std::shared_ptr GetFrame(int64_t frame_number) override { return GetFrame(std::make_shared(), frame_number); } 63 | 64 | /// @brief This method is required for all derived classes of ClipBase, and returns a 65 | /// modified openshot::Frame object 66 | /// 67 | /// The frame object is passed into this method and used as a starting point (pixels and audio). 68 | /// All Clip keyframes and effects are resolved into pixels. 69 | /// 70 | /// @returns The modified openshot::Frame object 71 | /// @param frame The frame object that needs the clip or effect applied to it 72 | /// @param frame_number The frame number (starting at 1) of the clip or effect on the timeline. 73 | std::shared_ptr GetFrame(std::shared_ptr frame, int64_t frame_number) override; 74 | 75 | // Get and Set JSON methods 76 | std::string Json() const override; ///< Generate JSON string of this object 77 | void SetJson(const std::string value) override; ///< Load JSON string into this object 78 | Json::Value JsonValue() const override; ///< Generate Json::Value for this object 79 | void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object 80 | 81 | /// Get all properties for a specific frame (perfect for a UI to display the current state 82 | /// of all properties at any time) 83 | std::string PropertiesJSON(int64_t requested_frame) const override; 84 | }; 85 | 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/effects/SphericalProjection.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for SphericalProjection effect class 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifndef OPENSHOT_SPHERICAL_PROJECTION_EFFECT_H 14 | #define OPENSHOT_SPHERICAL_PROJECTION_EFFECT_H 15 | 16 | #include "../EffectBase.h" 17 | #include "../Frame.h" 18 | #include "../Json.h" 19 | #include "../KeyFrame.h" 20 | 21 | #include 22 | #include 23 | 24 | namespace openshot 25 | { 26 | 27 | /** 28 | * @brief Projects 360° or fisheye video through a virtual camera. 29 | * Supports yaw, pitch, roll, FOV, sphere/hemisphere/fisheye modes, 30 | * optional inversion, and nearest/bilinear sampling. 31 | */ 32 | class SphericalProjection : public EffectBase 33 | { 34 | private: 35 | void init_effect_details(); 36 | 37 | public: 38 | Keyframe yaw; ///< Yaw around up-axis (degrees) 39 | Keyframe pitch; ///< Pitch around right-axis (degrees) 40 | Keyframe roll; ///< Roll around forward-axis (degrees) 41 | Keyframe fov; ///< Field-of-view (horizontal, degrees) 42 | 43 | int projection_mode; ///< 0=Sphere, 1=Hemisphere, 2=Fisheye 44 | int invert; ///< 0=Normal, 1=Invert (back lens / +180°) 45 | int interpolation; ///< 0=Nearest, 1=Bilinear 46 | 47 | /// Blank ctor (for JSON deserialization) 48 | SphericalProjection(); 49 | 50 | /// Ctor with custom curves 51 | SphericalProjection(Keyframe new_yaw, 52 | Keyframe new_pitch, 53 | Keyframe new_roll, 54 | Keyframe new_fov); 55 | 56 | /// ClipBase override: create a fresh Frame then call the main GetFrame 57 | std::shared_ptr GetFrame(int64_t frame_number) override 58 | { return GetFrame(std::make_shared(), frame_number); } 59 | 60 | /// EffectBase override: reproject the QImage 61 | std::shared_ptr GetFrame(std::shared_ptr frame, 62 | int64_t frame_number) override; 63 | 64 | // JSON serialization 65 | std::string Json() const override; 66 | void SetJson(std::string value) override; 67 | Json::Value JsonValue() const override; 68 | void SetJsonValue(Json::Value root) override; 69 | std::string PropertiesJSON(int64_t requested_frame) const override; 70 | }; 71 | 72 | } // namespace openshot 73 | 74 | #endif // OPENSHOT_SPHERICAL_PROJECTION_EFFECT_H 75 | -------------------------------------------------------------------------------- /src/effects/Tracker.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header file for Tracker effect class 4 | * @author Jonathan Thomas 5 | * @author Brenno Caldato 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_TRACKER_EFFECT_H 15 | #define OPENSHOT_TRACKER_EFFECT_H 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "EffectBase.h" 22 | 23 | #include "Json.h" 24 | #include "KeyFrame.h" 25 | 26 | #include "TrackedObjectBBox.h" 27 | 28 | namespace openshot 29 | { 30 | // Forwards decls 31 | class Frame; 32 | class TrackedObjectBBox; 33 | 34 | /** 35 | * @brief This class tracks a given object through the clip, draws a box around it and allow 36 | * the user to attach another clip (image or video) to the tracked object. 37 | * 38 | * Tracking is useful to better visualize, follow the movement of an object through video 39 | * and attach an image or video to it. 40 | */ 41 | class Tracker : public EffectBase 42 | { 43 | private: 44 | /// Init effect settings 45 | void init_effect_details(); 46 | 47 | Fraction BaseFPS; 48 | double TimeScale; 49 | 50 | public: 51 | std::string protobuf_data_path; ///< Path to the protobuf file that holds the bounding-box data 52 | std::shared_ptr trackedData; ///< Pointer to an object that holds the bounding-box data and it's Keyframes 53 | 54 | /// Default constructor 55 | Tracker(); 56 | 57 | Tracker(std::string clipTrackerDataPath); 58 | 59 | /// @brief Apply this effect to an openshot::Frame 60 | /// 61 | /// @returns The modified openshot::Frame object 62 | /// @param frame The frame object that needs the effect applied to it 63 | /// @param frame_number The frame number (starting at 1) of the effect on the timeline. 64 | std::shared_ptr GetFrame(std::shared_ptr frame, int64_t frame_number) override; 65 | 66 | std::shared_ptr 67 | GetFrame(int64_t frame_number) override { 68 | return GetFrame(std::shared_ptr(new Frame()), frame_number); 69 | } 70 | 71 | /// Get the indexes and IDs of all visible objects in the given frame 72 | std::string GetVisibleObjects(int64_t frame_number) const override; 73 | 74 | // Get and Set JSON methods 75 | 76 | /// Generate JSON string of this object 77 | std::string Json() const override; 78 | /// Load JSON string into this object 79 | void SetJson(const std::string value) override; 80 | /// Generate Json::Value for this object 81 | Json::Value JsonValue() const override; 82 | /// Load Json::Value into this object 83 | void SetJsonValue(const Json::Value root) override; 84 | 85 | /// Get all properties for a specific frame 86 | /// 87 | /// (perfect for a UI to display the current state 88 | /// of all properties at any time) 89 | std::string PropertiesJSON(int64_t requested_frame) const override; 90 | }; 91 | 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /src/objdetectdata.proto: -------------------------------------------------------------------------------- 1 | // © OpenShot Studios, LLC 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | // [START declaration] 6 | syntax = "proto3"; 7 | package pb_objdetect; 8 | 9 | import "google/protobuf/timestamp.proto"; 10 | // [END declaration] 11 | 12 | // [START messages] 13 | message Frame { 14 | int32 id = 1; // Frame ID. 15 | 16 | message Box{ 17 | float x = 1; 18 | float y = 2; 19 | float w = 3; 20 | float h = 4; 21 | int32 classId = 5; 22 | float confidence = 6; 23 | int32 objectId = 7; 24 | } 25 | 26 | repeated Box bounding_box = 2; 27 | } 28 | 29 | message ObjDetect { 30 | repeated Frame frame = 1; 31 | 32 | google.protobuf.Timestamp last_updated = 2; 33 | 34 | repeated string classNames = 3; 35 | } 36 | // [END messages] 37 | -------------------------------------------------------------------------------- /src/sort_filter/Hungarian.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2016 Cong Ma 2 | // 3 | // SPDX-License-Identifier: BSD-3-Clause 4 | 5 | /////////////////////////////////////////////////////////////////////////////// 6 | // Hungarian.h: Header file for Class HungarianAlgorithm. 7 | // 8 | // This is a C++ wrapper with slight modification of a hungarian algorithm implementation by Markus Buehren. 9 | // The original implementation is a few mex-functions for use in MATLAB, found here: 10 | // http://www.mathworks.com/matlabcentral/fileexchange/6543-functions-for-the-rectangular-assignment-problem 11 | // 12 | // Both this code and the orignal code are published under the BSD license. 13 | // by Cong Ma, 2016 14 | // 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | class HungarianAlgorithm 23 | { 24 | public: 25 | HungarianAlgorithm(); 26 | ~HungarianAlgorithm(); 27 | double Solve(std::vector> &DistMatrix, std::vector &Assignment); 28 | 29 | private: 30 | void assignmentoptimal(int *assignment, double *cost, double *distMatrix, int nOfRows, int nOfColumns); 31 | void buildassignmentvector(int *assignment, bool *starMatrix, int nOfRows, int nOfColumns); 32 | void computeassignmentcost(int *assignment, double *cost, double *distMatrix, int nOfRows); 33 | void step2a(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); 34 | void step2b(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); 35 | void step3(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); 36 | void step4(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim, int row, int col); 37 | void step5(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); 38 | }; 39 | -------------------------------------------------------------------------------- /src/sort_filter/KalmanTracker.cpp: -------------------------------------------------------------------------------- 1 | // © OpenShot Studios, LLC 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | /////////////////////////////////////////////////////////////////////////////// 6 | // KalmanTracker.cpp: KalmanTracker Class Implementation Declaration 7 | 8 | #include "KalmanTracker.h" 9 | #include 10 | 11 | using namespace std; 12 | using namespace cv; 13 | 14 | // initialize Kalman filter 15 | void KalmanTracker::init_kf( 16 | StateType stateMat) 17 | { 18 | int stateNum = 7; 19 | int measureNum = 4; 20 | kf = KalmanFilter(stateNum, measureNum, 0); 21 | 22 | measurement = Mat::zeros(measureNum, 1, CV_32F); 23 | 24 | kf.transitionMatrix = (Mat_(7, 7) << 1, 0, 0, 0, 1, 0, 0, 25 | 26 | 0, 1, 0, 0, 0, 1, 0, 27 | 0, 0, 1, 0, 0, 0, 1, 28 | 0, 0, 0, 1, 0, 0, 0, 29 | 0, 0, 0, 0, 1, 0, 0, 30 | 0, 0, 0, 0, 0, 1, 0, 31 | 0, 0, 0, 0, 0, 0, 1); 32 | 33 | setIdentity(kf.measurementMatrix); 34 | setIdentity(kf.processNoiseCov, Scalar::all(1e-1)); 35 | setIdentity(kf.measurementNoiseCov, Scalar::all(1e-4)); 36 | setIdentity(kf.errorCovPost, Scalar::all(1e-2)); 37 | 38 | // initialize state vector with bounding box in [cx,cy,s,r] style 39 | kf.statePost.at(0, 0) = stateMat.x + stateMat.width / 2; 40 | kf.statePost.at(1, 0) = stateMat.y + stateMat.height / 2; 41 | kf.statePost.at(2, 0) = stateMat.area(); 42 | kf.statePost.at(3, 0) = stateMat.width / stateMat.height; 43 | } 44 | 45 | // Predict the estimated bounding box. 46 | StateType KalmanTracker::predict() 47 | { 48 | // predict 49 | Mat p = kf.predict(); 50 | m_age += 1; 51 | 52 | if (m_time_since_update > 0) 53 | m_hit_streak = 0; 54 | m_time_since_update += 1; 55 | 56 | StateType predictBox = get_rect_xysr(p.at(0, 0), p.at(1, 0), p.at(2, 0), p.at(3, 0)); 57 | 58 | m_history.push_back(predictBox); 59 | return m_history.back(); 60 | } 61 | 62 | StateType KalmanTracker::predict2() 63 | { 64 | // predict 65 | Mat p = kf.predict(); 66 | 67 | StateType predictBox = get_rect_xysr(p.at(0, 0), p.at(1, 0), p.at(2, 0), p.at(3, 0)); 68 | 69 | return predictBox; 70 | } 71 | 72 | // Update the state vector with observed bounding box. 73 | void KalmanTracker::update( 74 | StateType stateMat) 75 | { 76 | m_time_since_update = 0; 77 | m_history.clear(); 78 | m_hits += 1; 79 | m_hit_streak += 1; 80 | 81 | // measurement 82 | measurement.at(0, 0) = stateMat.x + stateMat.width / 2; 83 | measurement.at(1, 0) = stateMat.y + stateMat.height / 2; 84 | measurement.at(2, 0) = stateMat.area(); 85 | measurement.at(3, 0) = stateMat.width / stateMat.height; 86 | 87 | // update 88 | kf.correct(measurement); 89 | // time_t now = time(0); 90 | // convert now to string form 91 | 92 | // detect_times.push_back(dt); 93 | } 94 | 95 | // Return the current state vector 96 | StateType KalmanTracker::get_state() 97 | { 98 | Mat s = kf.statePost; 99 | return get_rect_xysr(s.at(0, 0), s.at(1, 0), s.at(2, 0), s.at(3, 0)); 100 | } 101 | 102 | // Convert bounding box from [cx,cy,s,r] to [x,y,w,h] style. 103 | StateType KalmanTracker::get_rect_xysr( 104 | float cx, 105 | float cy, 106 | float s, 107 | float r) 108 | { 109 | float w = sqrt(s * r); 110 | float h = s / w; 111 | float x = (cx - w / 2); 112 | float y = (cy - h / 2); 113 | 114 | if (x < 0 && cx > 0) 115 | x = 0; 116 | if (y < 0 && cy > 0) 117 | y = 0; 118 | 119 | return StateType(x, y, w, h); 120 | } 121 | -------------------------------------------------------------------------------- /src/sort_filter/KalmanTracker.h: -------------------------------------------------------------------------------- 1 | // © OpenShot Studios, LLC 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | /////////////////////////////////////////////////////////////////////////////// 6 | // KalmanTracker.h: KalmanTracker Class Declaration 7 | 8 | #ifndef KALMAN_H 9 | #define KALMAN_H 2 10 | 11 | #include "opencv2/video/tracking.hpp" 12 | #include "opencv2/highgui/highgui.hpp" 13 | 14 | 15 | #define StateType cv::Rect_ 16 | 17 | /// This class represents the internel state of individual tracked objects observed as bounding box. 18 | class KalmanTracker 19 | { 20 | public: 21 | KalmanTracker() 22 | { 23 | init_kf(StateType()); 24 | m_time_since_update = 0; 25 | m_hits = 0; 26 | m_hit_streak = 0; 27 | m_age = 0; 28 | m_id = 0; 29 | } 30 | KalmanTracker(StateType initRect, float confidence, int classId, int objectId) : confidence(confidence), classId(classId) 31 | { 32 | init_kf(initRect); 33 | m_time_since_update = 0; 34 | m_hits = 0; 35 | m_hit_streak = 0; 36 | m_age = 0; 37 | m_id = objectId; 38 | } 39 | 40 | ~KalmanTracker() 41 | { 42 | m_history.clear(); 43 | } 44 | 45 | StateType predict(); 46 | StateType predict2(); 47 | void update(StateType stateMat); 48 | 49 | StateType get_state(); 50 | StateType get_rect_xysr(float cx, float cy, float s, float r); 51 | 52 | int m_time_since_update; 53 | int m_hits; 54 | int m_hit_streak; 55 | int m_age; 56 | int m_id; 57 | float confidence; 58 | int classId; 59 | 60 | private: 61 | void init_kf(StateType stateMat); 62 | 63 | cv::KalmanFilter kf; 64 | cv::Mat measurement; 65 | 66 | std::vector m_history; 67 | }; 68 | 69 | #endif -------------------------------------------------------------------------------- /src/sort_filter/sort.hpp: -------------------------------------------------------------------------------- 1 | // © OpenShot Studios, LLC 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "KalmanTracker.h" 6 | #include "Hungarian.h" 7 | 8 | #include 9 | #include 10 | #include // to format image names using setw() and setfill() 11 | #include 12 | 13 | #include "opencv2/video/tracking.hpp" 14 | #include "opencv2/highgui/highgui.hpp" 15 | 16 | #ifndef _OPENCV_KCFTRACKER_HPP_ 17 | #define _OPENCV_KCFTRACKER_HPP_ 18 | #endif 19 | #pragma once 20 | 21 | typedef struct TrackingBox 22 | { 23 | int frame = 0; 24 | float confidence = 0; 25 | int classId = 0; 26 | int id = 0; 27 | cv::Rect_ box = cv::Rect_(0.0, 0.0, 0.0, 0.0); 28 | TrackingBox() {} 29 | TrackingBox(int _frame, float _confidence, int _classId, int _id) : frame(_frame), confidence(_confidence), classId(_classId), id(_id) {} 30 | } TrackingBox; 31 | 32 | class SortTracker 33 | { 34 | public: 35 | // Constructor 36 | SortTracker(int max_age = 7, int min_hits = 2); 37 | // Initialize tracker 38 | 39 | // Update position based on the new frame 40 | void update(std::vector detection, int frame_count, double image_diagonal, std::vector confidences, std::vector classIds); 41 | double GetIOU(cv::Rect_ bb_test, cv::Rect_ bb_gt); 42 | double GetCentroidsDistance(cv::Rect_ bb_test, cv::Rect_ bb_gt); 43 | std::vector trackers; 44 | 45 | double max_centroid_dist_norm = 0.05; 46 | 47 | std::vector> predictedBoxes; 48 | std::vector> centroid_dist_matrix; 49 | std::vector assignment; 50 | std::set unmatchedDetections; 51 | std::set unmatchedTrajectories; 52 | std::set allItems; 53 | std::set matchedItems; 54 | std::vector matchedPairs; 55 | 56 | std::vector frameTrackingResult; 57 | std::vector dead_trackers_id; 58 | 59 | unsigned int trkNum = 0; 60 | unsigned int detNum = 0; 61 | int _min_hits; 62 | int _max_age; 63 | bool alive_tracker; 64 | }; 65 | -------------------------------------------------------------------------------- /src/stabilizedata.proto: -------------------------------------------------------------------------------- 1 | // © OpenShot Studios, LLC 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | // [START declaration] 6 | syntax = "proto3"; 7 | package pb_stabilize; 8 | 9 | import "google/protobuf/timestamp.proto"; 10 | // [END declaration] 11 | 12 | // [START messages] 13 | message Frame { 14 | int32 id = 1; // Frame ID. 15 | 16 | // TransformParam: frame smothed transformation 17 | float dx = 2; 18 | float dy = 3; 19 | float da = 4; 20 | 21 | // CamTrajectory: Shaky camera trajectory. 22 | // Can be used to run different smoothing techniques. 23 | float x = 5; 24 | float y = 6; 25 | float a = 7; 26 | 27 | } 28 | 29 | message Stabilization { 30 | repeated Frame frame = 1; 31 | 32 | google.protobuf.Timestamp last_updated = 2; 33 | } 34 | // [END messages] 35 | -------------------------------------------------------------------------------- /src/trackerdata.proto: -------------------------------------------------------------------------------- 1 | // © OpenShot Studios, LLC 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | // [START declaration] 6 | syntax = "proto3"; 7 | package pb_tracker; 8 | 9 | import "google/protobuf/timestamp.proto"; 10 | // [END declaration] 11 | 12 | // [START messages] 13 | message Frame { 14 | int32 id = 1; // Frame ID. 15 | float rotation = 2; 16 | 17 | message Box { 18 | float x1 = 1; 19 | float y1 = 2; 20 | float x2 = 3; 21 | float y2 = 4; 22 | } 23 | 24 | Box bounding_box = 3; 25 | } 26 | 27 | message Tracker { 28 | repeated Frame frame = 1; 29 | 30 | google.protobuf.Timestamp last_updated = 2; 31 | } 32 | // [END messages] 33 | -------------------------------------------------------------------------------- /tests/AudioDeviceManager.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Unit tests for openshot::AudioDeviceManagerSingleton 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2022 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "openshot_catch.h" 14 | #include "Settings.h" 15 | #include "Qt/AudioPlaybackThread.h" 16 | 17 | 18 | using namespace openshot; 19 | 20 | TEST_CASE( "Initialize Audio Device Manager Singleton", "[libopenshot][AudioDeviceManagerSingleton]" ) 21 | { 22 | Settings::Instance()->PLAYBACK_AUDIO_DEVICE_TYPE = ""; 23 | Settings::Instance()->PLAYBACK_AUDIO_DEVICE_NAME = ""; 24 | 25 | // Invalid sample rate 26 | AudioDeviceManagerSingleton *mng = AudioDeviceManagerSingleton::Instance(12300, 2); 27 | double detected_sample_rate = mng->defaultSampleRate; 28 | 29 | // Ignore systems that fail to find a valid audio device (i.e. build servers w/no sound card) 30 | if (mng->initialise_error.empty() && detected_sample_rate >= 44100.0) { 31 | // Verify invalid sample rate not found 32 | CHECK(detected_sample_rate != 12300); // verify common rate is returned 33 | mng->CloseAudioDevice(); 34 | 35 | // Valid sample rate 36 | mng = AudioDeviceManagerSingleton::Instance(44100, 2); 37 | CHECK(mng->defaultSampleRate == 44100); 38 | mng->CloseAudioDevice(); 39 | 40 | // Valid device type (for Linux) 41 | Settings::Instance()->PLAYBACK_AUDIO_DEVICE_TYPE = "ALSA"; 42 | Settings::Instance()->PLAYBACK_AUDIO_DEVICE_NAME = "Playback/recording through the PulseAudio sound server"; 43 | mng = AudioDeviceManagerSingleton::Instance(44100, 2); 44 | if (mng->currentAudioDevice.get_name() == Settings::Instance()->PLAYBACK_AUDIO_DEVICE_NAME && 45 | mng->currentAudioDevice.get_type() == Settings::Instance()->PLAYBACK_AUDIO_DEVICE_TYPE) { 46 | // Only check this device if it exists (i.e. we are on Linux with ALSA and PulseAudio) 47 | CHECK(mng->defaultSampleRate == 44100); 48 | mng->CloseAudioDevice(); 49 | } 50 | 51 | // Invalid device type (for Linux) 52 | Settings::Instance()->PLAYBACK_AUDIO_DEVICE_TYPE = "Fake Type"; 53 | Settings::Instance()->PLAYBACK_AUDIO_DEVICE_NAME = "Fake Device"; 54 | mng = AudioDeviceManagerSingleton::Instance(44100, 2); 55 | CHECK(mng->defaultSampleRate == 44100); 56 | mng->CloseAudioDevice(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/CVOutline.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Unit tests for OpenCV Outline effect 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2025 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include "openshot_catch.h" 18 | 19 | #include "Clip.h" 20 | #include "effects/Outline.h" 21 | 22 | using namespace openshot; 23 | 24 | TEST_CASE( "Outline_Tests", "[libopenshot][opencv][outline]" ) 25 | { 26 | // Create a video clip 27 | std::stringstream path; 28 | path << TEST_MEDIA_PATH << "1F0CF.svg"; 29 | 30 | // Open clip 31 | openshot::Clip c(path.str()); 32 | c.Open(); 33 | auto f = c.GetFrame(1); 34 | 35 | // Create effect constructor (default values) 36 | openshot::Outline e1{}; 37 | 38 | // Get frame from effect 39 | auto f1 = e1.GetFrame(f, 1); 40 | std::shared_ptr i1 = f1->GetImage(); 41 | 42 | // Check effect colors 43 | QColor pix1 = i1->pixelColor(3, 32); 44 | QColor compare1{0, 0, 0, 0}; 45 | CHECK(pix1 == compare1); 46 | 47 | // Test another effect constructor 48 | openshot::Outline e2(Keyframe(3.0), Color(0, 0, 255, 128)); 49 | 50 | // Get frame from effect 51 | auto f2 = e2.GetFrame(f, 1); 52 | std::shared_ptr i2 = f2->GetImage(); 53 | 54 | // Check effect colors 55 | QColor pix2 = i2->pixelColor(11, 35); 56 | QColor compare2{0, 0, 255, 128}; 57 | CHECK(pix2 == compare2); 58 | 59 | // Close clip 60 | c.Close(); 61 | } 62 | -------------------------------------------------------------------------------- /tests/ChromaKey.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Unit tests for openshot::ChromaKey effect 4 | * @author Jonathan Thomas 5 | * @author FeRD (Frank Dana) 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2021 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #include 15 | #include 16 | 17 | #include "Frame.h" 18 | #include "effects/ChromaKey.h" 19 | 20 | #include 21 | #include 22 | 23 | // Stream output formatter for QColor, needed so Catch2 can display 24 | // values when CHECK(qcolor1 == qcolor2) comparisons fail 25 | std::ostream& operator << ( std::ostream& os, QColor const& value ) { 26 | os << "QColor(" << value.red() << ", " << value.green() << ", " 27 | << value.blue() << ", " << value.alpha() << ")"; 28 | return os; 29 | } 30 | 31 | #include "openshot_catch.h" 32 | 33 | using namespace openshot; 34 | 35 | TEST_CASE( "basic keying", "[libopenshot][effect][chromakey]" ) 36 | { 37 | // solid green frame 38 | auto f = std::make_shared(1, 1280, 720, "#00ff00"); 39 | 40 | // Create a ChromaKey effect to key on solid green ± 5 values 41 | openshot::Color key(0, 255, 0, 255); 42 | openshot::Keyframe fuzz(5); 43 | openshot::ChromaKey e(key, fuzz); 44 | 45 | auto f_out = e.GetFrame(f, 1); 46 | std::shared_ptr i = f_out->GetImage(); 47 | 48 | // Check color fill (should be transparent) 49 | QColor pix = i->pixelColor(10, 10); 50 | QColor trans{Qt::transparent}; 51 | CHECK(pix == trans); 52 | } 53 | 54 | TEST_CASE( "threshold", "[libopenshot][effect][chromakey]" ) 55 | { 56 | auto frame = std::make_shared(1, 1280, 720, "#00cc00"); 57 | 58 | // Create a ChromaKey effect to key on solid green ± 5 values 59 | openshot::Color key(0, 255, 0, 255); 60 | openshot::Keyframe fuzz(5); 61 | openshot::ChromaKey e(key, fuzz); 62 | 63 | auto frame_out = e.GetFrame(frame, 1); 64 | std::shared_ptr i = frame_out->GetImage(); 65 | 66 | // Output should be the same, no ChromaKey 67 | QColor pix_e = i->pixelColor(10, 10); 68 | QColor expected(0, 204, 0, 255); 69 | CHECK(pix_e == expected); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /tests/Coordinate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Unit tests for openshot::Coordinate 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "openshot_catch.h" 14 | 15 | #include "Coordinate.h" 16 | #include "Exceptions.h" 17 | 18 | using namespace openshot; 19 | 20 | TEST_CASE( "default constructor", "[libopenshot][coordinate]" ) 21 | { 22 | // Create an empty coordinate 23 | Coordinate c1; 24 | 25 | CHECK(c1.X == Approx(0.0f).margin(0.00001)); 26 | CHECK(c1.Y == Approx(0.0f).margin(0.00001)); 27 | } 28 | 29 | TEST_CASE( "XY constructor", "[libopenshot][coordinate]" ) 30 | { 31 | // Create an empty coordinate 32 | Coordinate c1(2,8); 33 | 34 | CHECK(c1.X == Approx(2.0f).margin(0.00001)); 35 | CHECK(c1.Y == Approx(8.0f).margin(0.00001)); 36 | } 37 | 38 | TEST_CASE( "std::pair constructor", "[libopenshot][coordinate]" ) 39 | { 40 | Coordinate c1(std::pair(12, 10)); 41 | CHECK(c1.X == Approx(12.0f).margin(0.00001)); 42 | CHECK(c1.Y == Approx(10.0f).margin(0.00001)); 43 | } 44 | 45 | TEST_CASE( "Json", "[libopenshot][coordinate]" ) 46 | { 47 | openshot::Coordinate c(100, 200); 48 | openshot::Coordinate c1; 49 | c1.X = 100; 50 | c1.Y = 200; 51 | // Check that JSON produced is identical 52 | auto j = c.Json(); 53 | auto j1 = c1.Json(); 54 | CHECK(j1 == j); 55 | // Check Json::Value representation 56 | auto jv = c.JsonValue(); 57 | auto jv_string = jv.toStyledString(); 58 | CHECK(j1 == jv_string); 59 | } 60 | 61 | TEST_CASE( "SetJson", "[libopenshot][coordinate]" ) { 62 | // Construct our input Json representation 63 | const std::string json_input = R"json( 64 | { 65 | "X": 100.0, 66 | "Y": 50.0 67 | } 68 | )json"; 69 | openshot::Coordinate c; 70 | CHECK_THROWS_AS(c.SetJson("}{"), openshot::InvalidJSON); 71 | // Check that values set via SetJson() are correct 72 | c.SetJson(json_input); 73 | CHECK(c.X == Approx(100.0).margin(0.01)); 74 | CHECK(c.Y == Approx(50.0).margin(0.01)); 75 | } 76 | -------------------------------------------------------------------------------- /tests/ImageWriter.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Unit tests for openshot::ImageWriter 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #ifdef USE_IMAGEMAGICK 14 | 15 | #include 16 | #include 17 | 18 | #include "openshot_catch.h" 19 | 20 | #include "ImageWriter.h" 21 | #include "Exceptions.h" 22 | #include "ImageReader.h" 23 | #include "FFmpegReader.h" 24 | #include "Frame.h" 25 | 26 | using namespace openshot; 27 | 28 | TEST_CASE( "conversions", "[libopenshot][imagewriter]" ) 29 | { 30 | auto magick1 = openshot::QImage2Magick(nullptr); 31 | CHECK_FALSE(magick1); 32 | 33 | auto qimage1 = openshot::Magick2QImage(nullptr); 34 | CHECK_FALSE(qimage1); 35 | 36 | std::stringstream path_overlay; 37 | path_overlay << TEST_MEDIA_PATH << "front3.png"; 38 | openshot::Clip overlay(path_overlay.str()); 39 | overlay.Open(); 40 | auto frame = overlay.Reader()->GetFrame(1); 41 | auto qimage = frame->GetImage(); 42 | 43 | auto magick = openshot::QImage2Magick(qimage); 44 | auto qimage_out = openshot::Magick2QImage(magick); 45 | CHECK(qimage->pixelColor(100, 100) == qimage_out->pixelColor(100, 100)); 46 | } 47 | 48 | TEST_CASE( "Gif", "[libopenshot][imagewriter]" ) 49 | { 50 | // Reader --------------- 51 | 52 | // Bad path 53 | FFmpegReader bad_r("/tmp/bleeblorp.xls", false); 54 | CHECK_THROWS_AS(bad_r.Open(), InvalidFile); 55 | 56 | // Good path 57 | std::stringstream path; 58 | path << TEST_MEDIA_PATH << "sintel_trailer-720p.mp4"; 59 | FFmpegReader r(path.str()); 60 | 61 | // Read-before-open error 62 | CHECK_THROWS_AS(r.GetFrame(1), ReaderClosed); 63 | 64 | r.Open(); 65 | 66 | /* WRITER ---------------- */ 67 | ImageWriter w("ImageWriter-Gif-output1.gif"); 68 | 69 | CHECK_FALSE(w.IsOpen()); 70 | 71 | // Check for exception on write-before-open 72 | CHECK_THROWS_AS(w.WriteFrame(&r, 500, 509), WriterClosed); 73 | 74 | // Set the image output settings 75 | // (format, fps, width, height, quality, loops, combine) 76 | // loops=0 == infinite looping 77 | w.SetVideoOptions("GIF", r.info.fps, r.info.width, r.info.height, 70, 0, true); 78 | 79 | // Open writer 80 | w.Open(); 81 | 82 | // Write some frames 83 | w.WriteFrame(&r, 500, 509); 84 | 85 | // Close writer & reader 86 | w.Close(); 87 | r.Close(); 88 | 89 | // Open up the 5th frame from the newly created GIF 90 | ImageReader r1("ImageWriter-Gif-output1.gif[4]"); 91 | 92 | // Basic Reader state queries 93 | CHECK(r1.Name() == "ImageReader"); 94 | 95 | CacheBase* c = r1.GetCache(); 96 | CHECK(c == nullptr); 97 | 98 | CHECK_FALSE(r1.IsOpen()); 99 | r1.Open(); 100 | CHECK(r1.IsOpen() == true); 101 | 102 | // Verify various settings 103 | CHECK(r1.info.width == r.info.width); 104 | CHECK(r1.info.height == r.info.height); 105 | 106 | // Get a specific frame 107 | std::shared_ptr f = r1.GetFrame(8); 108 | 109 | // Get the image data for row 500 110 | const unsigned char* pixels = f->GetPixels(500); 111 | int pixel_index = 230 * 4; // pixel 230 (4 bytes per pixel) 112 | 113 | // Check image properties 114 | CHECK((int)pixels[pixel_index] == Approx(20).margin(5)); 115 | CHECK((int)pixels[pixel_index + 1] == Approx(18).margin(5)); 116 | CHECK((int)pixels[pixel_index + 2] == Approx(11).margin(5)); 117 | CHECK((int)pixels[pixel_index + 3] == Approx(255).margin(5)); 118 | } 119 | #endif // USE_IMAGEMAGICK 120 | -------------------------------------------------------------------------------- /tests/QtImageReader.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Unit tests for openshot::QtImageReader 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "openshot_catch.h" 14 | 15 | #include 16 | 17 | #include "QtImageReader.h" 18 | #include "Clip.h" 19 | #include "Exceptions.h" 20 | #include "Frame.h" 21 | #include "Timeline.h" 22 | 23 | using namespace openshot; 24 | 25 | TEST_CASE( "Default_Constructor", "[libopenshot][qtimagereader]" ) 26 | { 27 | // Check invalid path 28 | CHECK_THROWS_AS(QtImageReader(""), InvalidFile); 29 | } 30 | 31 | TEST_CASE( "GetFrame_Before_Opening", "[libopenshot][qtimagereader]" ) 32 | { 33 | // Create a reader 34 | std::stringstream path; 35 | path << TEST_MEDIA_PATH << "front.png"; 36 | QtImageReader r(path.str()); 37 | 38 | // Check invalid path 39 | CHECK_THROWS_AS(r.GetFrame(1), ReaderClosed); 40 | } 41 | 42 | TEST_CASE( "Check_SVG_Loading", "[libopenshot][qtimagereader]" ) 43 | { 44 | // Create a reader 45 | std::stringstream path; 46 | path << TEST_MEDIA_PATH << "1F0CF.svg"; 47 | QtImageReader r(path.str()); 48 | r.Open(); 49 | 50 | // Get frame, with no Timeline or Clip 51 | // Size should be equal to default SVG size 52 | std::shared_ptr f = r.GetFrame(1); 53 | CHECK(f->GetImage()->width() == 72); 54 | CHECK(f->GetImage()->height() == 72); 55 | 56 | Fraction fps(30000,1000); 57 | Timeline t1(640, 480, fps, 44100, 2, LAYOUT_STEREO); 58 | 59 | Clip clip1(path.str()); 60 | clip1.Layer(1); 61 | clip1.Position(0.0); // Delay the overlay by 0.05 seconds 62 | clip1.End(10.0); // Make the duration of the overlay 1/2 second 63 | 64 | // Add clips 65 | t1.AddClip(&clip1); 66 | t1.Open(); 67 | 68 | // Get frame, with 640x480 Timeline 69 | // Should scale to 480 70 | clip1.Reader()->Open(); 71 | f = clip1.Reader()->GetFrame(2); 72 | CHECK(f->GetImage()->width() == 480); 73 | CHECK(f->GetImage()->height() == 480); 74 | 75 | // Add scale_x and scale_y. Should scale the square SVG 76 | // by the largest scale keyframe (i.e. 4) 77 | clip1.scale_x.AddPoint(1.0, 2.0, openshot::LINEAR); 78 | clip1.scale_y.AddPoint(1.0, 2.0, openshot::LINEAR); 79 | f = clip1.Reader()->GetFrame(3); 80 | CHECK(f->GetImage()->width() == 480 * 2); 81 | CHECK(f->GetImage()->height() == 480 * 2); 82 | 83 | // Close reader 84 | t1.Close(); 85 | r.Close(); 86 | } 87 | -------------------------------------------------------------------------------- /tests/ReaderBase.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Unit tests for openshot::ReaderBase 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include 14 | #include 15 | 16 | #include "openshot_catch.h" 17 | 18 | #include "ReaderBase.h" 19 | #include "CacheBase.h" 20 | #include "Frame.h" 21 | #include "Json.h" 22 | 23 | using namespace openshot; 24 | 25 | // Since it is not possible to instantiate an abstract class, this test creates 26 | // a new derived class, in order to test the base class file info struct. 27 | TEST_CASE( "derived class", "[libopenshot][readerbase]" ) 28 | { 29 | // Create a new derived class from type ReaderBase 30 | class TestReader : public ReaderBase 31 | { 32 | public: 33 | TestReader() { }; 34 | CacheBase* GetCache() { return nullptr; }; 35 | std::shared_ptr GetFrame(int64_t number) { std::shared_ptr f(new Frame()); return f; } 36 | void Close() { }; 37 | void Open() { }; 38 | std::string Json() const { return ""; }; 39 | void SetJson(std::string value) { }; 40 | Json::Value JsonValue() const { return Json::Value("{}"); }; 41 | void SetJsonValue(Json::Value root) { }; 42 | bool IsOpen() { return true; }; 43 | std::string Name() { return "TestReader"; }; 44 | }; 45 | 46 | // Create an instance of the derived class 47 | TestReader t1; 48 | 49 | // Validate the new class 50 | CHECK(t1.Name() == "TestReader"); 51 | 52 | t1.Close(); 53 | t1.Open(); 54 | CHECK(t1.IsOpen() == true); 55 | 56 | CHECK(t1.GetCache() == nullptr); 57 | 58 | t1.SetJson("{ }"); 59 | t1.SetJsonValue(Json::Value("{}")); 60 | CHECK(t1.Json() == ""); 61 | auto json = t1.JsonValue(); 62 | CHECK(Json::Value("{}") == json); 63 | 64 | auto f = t1.GetFrame(1); 65 | 66 | REQUIRE(f != nullptr); 67 | CHECK(f->number == 1); 68 | 69 | // Check some of the default values of the FileInfo struct on the base class 70 | CHECK_FALSE(t1.info.has_audio); 71 | CHECK_FALSE(t1.info.has_audio); 72 | CHECK(t1.info.duration == Approx(0.0f).margin(0.00001)); 73 | CHECK(t1.info.height == 0); 74 | CHECK(t1.info.width == 0); 75 | CHECK(t1.info.fps.num == 1); 76 | CHECK(t1.info.fps.den == 1); 77 | } 78 | -------------------------------------------------------------------------------- /tests/Settings.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Unit tests for openshot::Color 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #include "openshot_catch.h" 14 | 15 | #include "Settings.h" 16 | #include 17 | 18 | 19 | using namespace openshot; 20 | 21 | TEST_CASE( "Constructor", "[libopenshot][settings]" ) 22 | { 23 | // Get system cpu count 24 | int cpu_count = omp_get_num_procs(); 25 | 26 | // Create an empty color 27 | Settings *s = Settings::Instance(); 28 | 29 | CHECK(s->OMP_THREADS == cpu_count); 30 | CHECK(s->FF_THREADS == cpu_count); 31 | CHECK_FALSE(s->HIGH_QUALITY_SCALING); 32 | } 33 | 34 | TEST_CASE( "Change settings", "[libopenshot][settings]" ) 35 | { 36 | // Create an empty color 37 | Settings *s = Settings::Instance(); 38 | s->OMP_THREADS = 13; 39 | s->HIGH_QUALITY_SCALING = true; 40 | 41 | CHECK(s->OMP_THREADS == 13); 42 | CHECK(s->HIGH_QUALITY_SCALING == true); 43 | 44 | CHECK(Settings::Instance()->OMP_THREADS == 13); 45 | CHECK(Settings::Instance()->HIGH_QUALITY_SCALING == true); 46 | } 47 | 48 | TEST_CASE( "Debug logging", "[libopenshot][settings][environment]") 49 | { 50 | // Check the environment 51 | auto envvar = std::getenv("LIBOPENSHOT_DEBUG"); 52 | const auto is_enabled = bool(envvar != nullptr); 53 | 54 | CHECK(Settings::Instance()->DEBUG_TO_STDERR == is_enabled); 55 | } 56 | -------------------------------------------------------------------------------- /tests/catch2v2.h.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header (template) for tests built with Catch2 v2 4 | * @author Jonathan Thomas 5 | * @author FeRD (Frank Dana) 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2022 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_CATCH2_H 15 | #define OPENSHOT_CATCH2_H 16 | 17 | #include 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /tests/catch2v3.h.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Header (template) for tests built with Catch2 v3.0 or later 4 | * @author Jonathan Thomas 5 | * @author FeRD (Frank Dana) 6 | * 7 | * @ref License 8 | */ 9 | 10 | // Copyright (c) 2008-2022 OpenShot Studios, LLC 11 | // 12 | // SPDX-License-Identifier: LGPL-3.0-or-later 13 | 14 | #ifndef OPENSHOT_CATCH2_H 15 | #define OPENSHOT_CATCH2_H 16 | 17 | #include 18 | using namespace Catch; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tests/catch_main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Source code for Unit test executable (runs all tests and reports successes and failures) 4 | * @author Jonathan Thomas 5 | * 6 | * @ref License 7 | */ 8 | 9 | // Copyright (c) 2008-2019 OpenShot Studios, LLC 10 | // 11 | // SPDX-License-Identifier: LGPL-3.0-or-later 12 | 13 | #define CATCH_CONFIG_MAIN 14 | #include "openshot_catch.h" 15 | 16 | -------------------------------------------------------------------------------- /thirdparty/jsoncpp/LICENSE: -------------------------------------------------------------------------------- 1 | The JsonCpp library's source code, including accompanying documentation, 2 | tests and demonstration applications, are licensed under the following 3 | conditions... 4 | 5 | Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all 6 | jurisdictions which recognize such a disclaimer. In such jurisdictions, 7 | this software is released into the Public Domain. 8 | 9 | In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 10 | 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and 11 | The JsonCpp Authors, and is released under the terms of the MIT License (see below). 12 | 13 | In jurisdictions which recognize Public Domain property, the user of this 14 | software may choose to accept it either as 1) Public Domain, 2) under the 15 | conditions of the MIT License (see below), or 3) under the terms of dual 16 | Public Domain/MIT License conditions described here, as they choose. 17 | 18 | The MIT License is about as close to Public Domain as a license can get, and is 19 | described in clear, concise terms at: 20 | 21 | http://en.wikipedia.org/wiki/MIT_License 22 | 23 | The full text of the MIT License follows: 24 | 25 | ======================================================================== 26 | Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 27 | 28 | Permission is hereby granted, free of charge, to any person 29 | obtaining a copy of this software and associated documentation 30 | files (the "Software"), to deal in the Software without 31 | restriction, including without limitation the rights to use, copy, 32 | modify, merge, publish, distribute, sublicense, and/or sell copies 33 | of the Software, and to permit persons to whom the Software is 34 | furnished to do so, subject to the following conditions: 35 | 36 | The above copyright notice and this permission notice shall be 37 | included in all copies or substantial portions of the Software. 38 | 39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 40 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 41 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 42 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 43 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 44 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 45 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 46 | SOFTWARE. 47 | ======================================================================== 48 | (END LICENSE TEXT) 49 | 50 | The MIT license is compatible with both the GPL and commercial 51 | software, affording one all of the rights of Public Domain with the 52 | minor nuisance of being required to keep the above copyright notice 53 | and license text in the source code. Note also that by accepting the 54 | Public Domain "license" you can re-license your copy using whatever 55 | license you like. 56 | -------------------------------------------------------------------------------- /version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # © OpenShot Studios, LLC 4 | # 5 | # SPDX-License-Identifier: LGPL-3.0-or-later 6 | 7 | grep 'set.*(.*PROJECT_VERSION_FULL' CMakeLists.txt\ 8 | |sed -e 's#set(PROJECT_VERSION_FULL.*"\(.*\)\")#\1#;q' 9 | 10 | --------------------------------------------------------------------------------