Merge branch 'develop' into timeline-inheritance

This commit is contained in:
Frank Dana
2021-09-27 10:56:21 -04:00
committed by GitHub
76 changed files with 5038 additions and 980 deletions

View File

@@ -6,35 +6,43 @@ jobs:
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-20.04]
compiler: [gcc, clang]
compiler:
- { cc: gcc, cpp: g++ }
- { cc: clang, cpp: clang++ }
env:
CC: ${{ matrix.compiler }}
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cpp }}
CODECOV_TOKEN: 'dc94d508-39d3-4369-b1c6-321749f96f7c'
steps:
- uses: actions/checkout@v2
# Work around a codecov issue detecting commit SHAs
# see: https://community.codecov.io/t/issue-detecting-commit-sha-please-run-actions-checkout-with-fetch-depth-1-or-set-to-0/2571
with:
# Work around a codecov issue detecting commit SHAs
# see: https://community.codecov.io/t/issue-detecting-commit-sha-please-run-actions-checkout-with-fetch-depth-1-or-set-to-0/2571
fetch-depth: 0
- name: Checkout OpenShotAudio
uses: actions/checkout@v2
with:
repository: OpenShot/libopenshot-audio
path: audio
- uses: haya14busa/action-cond@v1
id: coverage
with:
cond: ${{ matrix.compiler == 'clang' }}
cond: ${{ matrix.compiler.cc == 'gcc' }}
if_true: "-DENABLE_COVERAGE:BOOL=1"
if_false: "-DENABLE_COVERAGE:BOOL=0"
- name: Install dependencies
shell: bash
run: |
sudo add-apt-repository ppa:openshot.developers/libopenshot-daily
sudo apt update
sudo apt remove libzmq5 # See actions/virtual-environments#3317
sudo apt install \
cmake swig doxygen graphviz curl lcov \
libopenshot-audio-dev libasound2-dev \
qtbase5-dev qtbase5-dev-tools \
libasound2-dev \
qtbase5-dev qtbase5-dev-tools libqt5svg5-dev \
libfdk-aac-dev libavcodec-dev libavformat-dev libavdevice-dev libavutil-dev libavfilter-dev libswscale-dev libpostproc-dev libswresample-dev \
libzmq3-dev libmagick++-dev \
libopencv-dev libprotobuf-dev protobuf-compiler
@@ -43,13 +51,30 @@ jobs:
wget https://launchpad.net/ubuntu/+archive/primary/+files/catch2_2.13.0-1_all.deb
sudo dpkg -i catch2_2.13.0-1_all.deb
- uses: actions/cache@v2
id: cache
with:
path: audio/build
key: audio-${{ matrix.os }}-${{ matrix.compiler.cpp }}-${{ hashFiles('audio/CMakeLists.txt') }}
- name: Build OpenShotAudio (if not cached)
if: steps.cache.outputs.cache-hit != 'true'
shell: bash
run: |
pushd audio
if [ ! -d build ]; then
mkdir build
cmake -B build -S .
fi
cmake --build build
popd
- name: Build libopenshot
shell: bash
run: |
mkdir build
pushd build
cmake -B . -S .. -DCMAKE_INSTALL_PREFIX:PATH="dist" -DCMAKE_BUILD_TYPE="Debug" "${{ steps.coverage.outputs.value }}"
cmake -B . -S .. -DCMAKE_INSTALL_PREFIX:PATH="dist" -DCMAKE_BUILD_TYPE="Debug" -DOpenShotAudio_ROOT="../audio/build" "${{ steps.coverage.outputs.value }}"
cmake --build . -- VERBOSE=1
popd
@@ -67,7 +92,7 @@ jobs:
cmake --build . --target install -- VERBOSE=1
popd
- uses: codecov/codecov-action@v1
if: ${{ matrix.compiler == 'clang' }}
- uses: codecov/codecov-action@v2.1.0
if: ${{ matrix.compiler.cc == 'gcc' }}
with:
file: build/coverage.info

View File

@@ -40,8 +40,8 @@ For more information, please visit <http://www.openshot.org/>.
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules")
################ PROJECT VERSION ####################
set(PROJECT_VERSION_FULL "0.2.5-dev3")
set(PROJECT_SO_VERSION 19)
set(PROJECT_VERSION_FULL "0.2.7-dev")
set(PROJECT_SO_VERSION 21)
# Remove the dash and anything following, to get the #.#.# version for project()
STRING(REGEX REPLACE "\-.*$" "" VERSION_NUM "${PROJECT_VERSION_FULL}")
@@ -99,6 +99,12 @@ if(ENABLE_TESTS)
set(BUILD_TESTING ${ENABLE_TESTS})
endif()
### JUCE requires one of -DDEBUG or -DNDEBUG set on the
### compile command line. CMake automatically sets -DNDEBUG
### on all non-debug configs, so we'll just add -DDEBUG to
### the debug build flags
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
#### Work around a GCC < 9 bug with handling of _Pragma() in macros
#### See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578
if ((${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") AND
@@ -200,6 +206,7 @@ if(BUILD_TESTING)
if(VERBOSE_TESTS)
list(APPEND CTEST_OPTIONS "-VV")
endif()
list(APPEND CTEST_OPTIONS "--output-on-failure")
add_subdirectory(tests)
endif()
add_feature_info("Unit tests" ${BUILD_TESTING} "Compile unit tests for library functions")
@@ -211,6 +218,7 @@ if (ENABLE_COVERAGE AND DEFINED UNIT_TEST_TARGETS)
"examples/*"
"${CMAKE_CURRENT_BINARY_DIR}/bindings/*"
"${CMAKE_CURRENT_BINARY_DIR}/src/*_autogen/*"
"audio/*"
)
setup_target_for_coverage_lcov(
NAME coverage

View File

@@ -95,6 +95,12 @@ if (DEFINED _inc)
set_property(SOURCE openshot.i PROPERTY INCLUDE_DIRECTORIES ${_inc})
endif()
### (FINALLY!)
### Properly manage dependencies (regenerate bindings after changes)
if (CMAKE_VERSION VERSION_GREATER 3.20)
set_property(SOURCE openshot.i PROPERTY USE_SWIG_DEPENDENCIES TRUE)
endif()
### Add the SWIG interface file (which defines all the SWIG methods)
if (CMAKE_VERSION VERSION_LESS 3.8.0)
swig_add_module(pyopenshot python openshot.i)

View File

@@ -111,6 +111,12 @@ if (DEFINED _inc)
set_property(SOURCE openshot.i PROPERTY INCLUDE_DIRECTORIES ${_inc})
endif()
### (FINALLY!)
### Properly manage dependencies (regenerate bindings after changes)
if (CMAKE_VERSION VERSION_GREATER 3.20)
set_property(SOURCE openshot.i PROPERTY USE_SWIG_DEPENDENCIES TRUE)
endif()
### Add the SWIG interface file (which defines all the SWIG methods)
if (CMAKE_VERSION VERSION_LESS 3.8.0)
swig_add_module(rbopenshot ruby openshot.i)

View File

@@ -34,21 +34,23 @@ This module defines the following variables:
::
FFMPEG_FOUND - System has the all required components.
FFMPEG_INCLUDE_DIRS - Include directory necessary for using the required components headers.
FFMPEG_LIBRARIES - Link these to use the required ffmpeg components.
FFMPEG_DEFINITIONS - Compiler switches required for using the required ffmpeg components.
FFmpeg_FOUND - System has the all required components.
FFmpeg_INCLUDE_DIRS - Include directory necessary for using the required components headers.
FFmpeg_LIBRARIES - Link these to use the required ffmpeg components.
FFmpeg_DEFINITIONS - Compiler switches required for using the required ffmpeg components.
FFmpeg_VERSION - The FFmpeg package version found.
For each component, ``<component>_FOUND`` will be set if the component is available.
For each ``<component>_FOUND``, the following variables will be defined:
For each component, ``FFmpeg_<component>_FOUND`` will be set if the component is available.
For each ``FFmpeg_<component>_FOUND``, the following variables will be defined:
::
<component>_INCLUDE_DIRS - Include directory necessary for using the <component> headers
<component>_LIBRARIES - Link these to use <component>
<component>_DEFINITIONS - Compiler switches required for using <component>
<component>_VERSION - The components version
FFmpeg_<component>_INCLUDE_DIRS - Include directory necessary for using the
<component> headers
FFmpeg_<component>_LIBRARIES - Link these to use <component>
FFmpeg_<component>_DEFINITIONS - Compiler switches required for <component>
FFmpeg_<component>_VERSION - The components version
Backwards compatibility
^^^^^^^^^^^^^^^^^^^^^^^
@@ -57,10 +59,20 @@ For compatibility with previous versions of this module, uppercase names
for FFmpeg and for all components are also recognized, and all-uppercase
versions of the cache variables are also created.
Revision history
^^^^^^^^^^^^^^^^
ca. 2019 - Create CMake targets for discovered components
2019-06-25 - No longer probe for non-requested components
- Added fallback version.h parsing for components, when
pkgconfig is missing
- Added parsing of libavutil/ffversion.h for FFmpeg_VERSION
- Adopt standard FFmpeg_<component>_<property> variable names
- Switch to full signature for FPHSA, use HANDLE_COMPONENTS
Copyright (c) 2006, Matthias Kretz, <kretz@kde.org>
Copyright (c) 2008, Alexander Neundorf, <neundorf@kde.org>
Copyright (c) 2011, Michael Jansen, <kde@michael-jansen.biz>
Copyright (c) 2019, FeRD (Frank Dana) <ferdnyc@gmail.com>
Copyright (c) 2019-2021, FeRD (Frank Dana) <ferdnyc@gmail.com>
Redistribution and use is allowed according to the terms of the BSD license.
For details see the accompanying COPYING-CMAKE-SCRIPTS file.
@@ -84,16 +96,44 @@ endif ()
# Marks the given component as found if both *_LIBRARIES AND *_INCLUDE_DIRS is present.
#
macro(set_component_found _component )
if (${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS)
if (FFmpeg_${_component}_LIBRARIES AND FFmpeg_${_component}_INCLUDE_DIRS)
# message(STATUS "FFmpeg - ${_component} found.")
set(${_component}_FOUND TRUE)
else ()
if (NOT FFmpeg_FIND_QUIETLY AND NOT FFMPEG_FIND_QUIETLY)
message(STATUS "FFmpeg - ${_component} not found.")
endif ()
set(FFmpeg_${_component}_FOUND TRUE)
#else ()
# if (NOT FFmpeg_FIND_QUIETLY AND NOT FFMPEG_FIND_QUIETLY)
# message(STATUS "FFmpeg - ${_component} not found.")
# endif ()
endif ()
endmacro()
#
### Macro: parse_lib_version
#
# Reads the file '${_pkgconfig}/version.h' in the component's _INCLUDE_DIR,
# and parses #define statements for COMPONENT_VERSION_(MAJOR|MINOR|PATCH)
# into a dotted string ${_component}_VERSION.
#
# Needed if the version is not supplied via pkgconfig's PC_${_component}_VERSION
macro(parse_lib_version _component _libname )
set(_version_h "${FFmpeg_${_component}_INCLUDE_DIRS}/${_libname}/version.h")
if(EXISTS "${_version_h}")
#message(STATUS "Parsing ${_component} version from ${_version_h}")
string(TOUPPER "${_libname}" _prefix)
set(_parts)
foreach(_lvl MAJOR MINOR MICRO)
file(STRINGS "${_version_h}" _lvl_version
REGEX "^[ \t]*#define[ \t]+${_prefix}_VERSION_${_lvl}[ \t]+[0-9]+[ \t]*$")
string(REGEX REPLACE
"^.*${_prefix}_VERSION_${_lvl}[ \t]+([0-9]+)[ \t]*$"
"\\1"
_lvl_match "${_lvl_version}")
list(APPEND _parts "${_lvl_match}")
endforeach()
list(JOIN _parts "." FFmpeg_${_component}_VERSION)
message(STATUS "Found ${_component} version: ${FFmpeg_${_component}_VERSION}")
endif()
endmacro()
#
### Macro: find_component
#
@@ -109,9 +149,9 @@ macro(find_component _component _pkgconfig _library _header)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_${_component} ${_pkgconfig})
endif ()
endif (NOT WIN32)
endif()
find_path(${_component}_INCLUDE_DIRS ${_header}
find_path(FFmpeg_${_component}_INCLUDE_DIRS ${_header}
HINTS
/opt/
/opt/include/
@@ -123,7 +163,7 @@ macro(find_component _component _pkgconfig _library _header)
ffmpeg
)
find_library(${_component}_LIBRARIES NAMES ${_library}
find_library(FFmpeg_${_component}_LIBRARIES NAMES ${_library}
HINTS
${PC_${_component}_LIBDIR}
${PC_${_component}_LIBRARY_DIRS}
@@ -132,56 +172,86 @@ macro(find_component _component _pkgconfig _library _header)
$ENV{FFMPEGDIR}/bin/
)
set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.")
set(${_component}_VERSION ${PC_${_component}_VERSION} CACHE STRING "The ${_component} version number.")
set(FFmpeg_${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.")
# Take version from PkgConfig, or parse from its version.h header
if (PC_${_component}_VERSION)
set(FFmpeg_${_component}_VERSION ${PC_${_component}_VERSION})
else()
parse_lib_version(${_component} ${_pkgconfig})
endif()
set(FFmpeg_${_component}_VERSION ${FFmpeg_${_component}_VERSION} CACHE STRING "The ${_component} version number.")
set_component_found(${_component})
mark_as_advanced(
${_component}_INCLUDE_DIRS
${_component}_LIBRARIES
${_component}_DEFINITIONS
${_component}_VERSION
FFmpeg_${_component}_INCLUDE_DIRS
FFmpeg_${_component}_LIBRARIES
FFmpeg_${_component}_DEFINITIONS
FFmpeg_${_component}_VERSION
)
endmacro()
#
### Macro: parse_ff_version
#
# Read the libavutil/ffversion.h file and extract the definition
# for FFMPEG_VERSION, to use as our version string.
macro (parse_ff_version)
set(_header "${FFmpeg_avutil_INCLUDE_DIRS}/libavutil/ffversion.h")
if(EXISTS "${_header}")
#message(STATUS "Parsing ffmpeg version from ${_header}")
file(STRINGS "${_header}" _version_def
REGEX "^#define[ \t]+FFMPEG_VERSION[ \t]+\".*\"[ \t]*$")
string(REGEX REPLACE
"^.*FFMPEG_VERSION[ \t]+\"(.*)\".*$"
"\\1"
FFmpeg_VERSION "${_version_def}")
#message(STATUS "Found FFmpeg version: ${FFmpeg_VERSION}")
endif()
endmacro()
# Check for cached results. If there are skip the costly part.
if (NOT FFmpeg_LIBRARIES)
# Configs for all possible component.
set(avcodec_params libavcodec avcodec libavcodec/avcodec.h)
set(avdevice_params libavdevice avdevice libavdevice/avdevice.h)
set(avformat_params libavformat avformat libavformat/avformat.h)
set(avfilter_params libavfilter avfilter libavfilter/avfilter.h)
set(avutil_params libavutil avutil libavutil/avutil.h)
set(postproc_params libpostproc postproc libpostproc/postprocess.h)
set(swscale_params libswscale swscale libswscale/swscale.h)
set(swresample_params libswresample swresample libswresample/swresample.h)
set(avresample_params libavresample avresample libavresample/avresample.h)
# Check for all possible component.
find_component(avcodec libavcodec avcodec libavcodec/avcodec.h)
find_component(avdevice libavdevice avdevice libavdevice/avdevice.h)
find_component(avformat libavformat avformat libavformat/avformat.h)
find_component(avfilter libavfilter avfilter libavfilter/avfilter.h)
find_component(avutil libavutil avutil libavutil/avutil.h)
find_component(postproc libpostproc postproc libpostproc/postprocess.h)
find_component(swscale libswscale swscale libswscale/swscale.h)
find_component(swresample libswresample swresample libswresample/swresample.h)
find_component(avresample libavresample avresample libavresample/avresample.h)
else()
# Just set the noncached _FOUND vars for the components.
foreach(_component ${FFmpeg_ALL_COMPONENTS})
set_component_found(${_component})
endforeach ()
endif()
# Check if the requested components were found and add their stuff to the FFmpeg_* vars.
foreach (_component ${FFmpeg_FIND_COMPONENTS})
# Gather configs for each requested component
foreach(_component ${FFmpeg_FIND_COMPONENTS})
string(TOLOWER "${_component}" _component)
if (${_component}_FOUND)
# Only probe if not already _FOUND (expensive)
if (NOT FFmpeg_${_component}_FOUND)
find_component(${_component} ${${_component}_params})
endif()
# Add the component's configs to the FFmpeg_* variables
if (FFmpeg_${_component}_FOUND)
# message(STATUS "Requested component ${_component} present.")
set(FFmpeg_LIBRARIES ${FFmpeg_LIBRARIES} ${${_component}_LIBRARIES})
set(FFmpeg_DEFINITIONS ${FFmpeg_DEFINITIONS} ${${_component}_DEFINITIONS})
list(APPEND FFmpeg_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS})
set(FFmpeg_LIBRARIES ${FFmpeg_LIBRARIES} ${FFmpeg_${_component}_LIBRARIES})
set(FFmpeg_DEFINITIONS ${FFmpeg_DEFINITIONS} ${FFmpeg_${_component}_DEFINITIONS})
list(APPEND FFmpeg_INCLUDE_DIRS ${FFmpeg_${_component}_INCLUDE_DIRS})
else ()
# message(STATUS "Requested component ${_component} missing.")
endif ()
endforeach ()
endforeach()
# Make sure we've probed for avutil
if (NOT FFmpeg_avutil_FOUND)
find_component(avutil libavutil avutil libavutil/avutil.h)
endif()
# Get the overall FFmpeg version from libavutil/ffversion.h
parse_ff_version()
# Build the result lists with duplicates removed, in case of repeated
# invocations.
# invocations or component redundancy.
if (FFmpeg_INCLUDE_DIRS)
list(REMOVE_DUPLICATES FFmpeg_INCLUDE_DIRS)
endif()
@@ -196,57 +266,68 @@ endif ()
set(FFmpeg_INCLUDE_DIRS ${FFmpeg_INCLUDE_DIRS} CACHE STRING "The FFmpeg include directories." FORCE)
set(FFmpeg_LIBRARIES ${FFmpeg_LIBRARIES} CACHE STRING "The FFmpeg libraries." FORCE)
set(FFmpeg_DEFINITIONS ${FFmpeg_DEFINITIONS} CACHE STRING "The FFmpeg cflags." FORCE)
set(FFmpeg_VERSION ${FFmpeg_VERSION} CACHE STRING "The overall FFmpeg version.")
mark_as_advanced(FFmpeg_INCLUDE_DIRS
mark_as_advanced(
FFmpeg_INCLUDE_DIRS
FFmpeg_LIBRARIES
FFmpeg_DEFINITIONS)
FFmpeg_DEFINITIONS
FFmpeg_VERSION
)
# Backwards compatibility
foreach(_suffix INCLUDE_DIRS LIBRARIES DEFINITIONS)
foreach(_suffix INCLUDE_DIRS LIBRARIES DEFINITIONS VERSION)
get_property(_help CACHE FFmpeg_${_suffix} PROPERTY HELPSTRING)
set(FFMPEG_${_suffix} ${FFmpeg_${_suffix}} CACHE STRING "${_help}" FORCE)
mark_as_advanced(FFMPEG_${_suffix})
endforeach()
foreach(_component ${FFmpeg_ALL_COMPONENTS})
if(${_component}_FOUND)
if(FFmpeg_${_component}_FOUND)
string(TOUPPER "${_component}" _uc_component)
set(${_uc_component}_FOUND TRUE)
set(FFMPEG_${_uc_component}_FOUND TRUE)
foreach(_suffix INCLUDE_DIRS LIBRARIES DEFINITIONS VERSION)
get_property(_help CACHE ${_component}_${_suffix} PROPERTY HELPSTRING)
set(${_uc_component}_${_suffix} ${${_component}_${_suffix}} CACHE STRING "${_help}" FORCE)
mark_as_advanced(${_uc_component}_${_suffix})
get_property(_help CACHE FFmpeg_${_component}_${_suffix} PROPERTY HELPSTRING)
set(FFMPEG_${_uc_component}_${_suffix} ${FFmpeg_${_component}_${_suffix}} CACHE STRING "${_help}" FORCE)
mark_as_advanced(FFMPEG_${_uc_component}_${_suffix})
endforeach()
endif()
endforeach()
# Compile the list of required vars
set(_FFmpeg_REQUIRED_VARS FFmpeg_LIBRARIES FFmpeg_INCLUDE_DIRS)
foreach (_component ${FFmpeg_FIND_COMPONENTS})
list(APPEND _FFmpeg_REQUIRED_VARS
${_component}_LIBRARIES
${_component}_INCLUDE_DIRS)
endforeach ()
# XXX: HANDLE_COMPONENTS should take care of this, maybe? -FeRD
# foreach (_component ${FFmpeg_FIND_COMPONENTS})
# list(APPEND _FFmpeg_REQUIRED_VARS
# FFmpeg_${_component}_LIBRARIES
# FFmpeg_${_component}_INCLUDE_DIRS)
# endforeach ()
# Give a nice error message if some of the required vars are missing.
find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${_FFmpeg_REQUIRED_VARS})
find_package_handle_standard_args(FFmpeg
REQUIRED_VARS ${_FFmpeg_REQUIRED_VARS}
VERSION_VAR FFmpeg_VERSION
HANDLE_COMPONENTS
)
# Export targets for each found component
foreach (_component ${FFmpeg_ALL_COMPONENTS})
foreach (_component ${FFmpeg_FIND_COMPONENTS})
if(${_component}_FOUND)
# message(STATUS "Creating IMPORTED target FFmpeg::${_component}")
if(FFmpeg_${_component}_FOUND)
#message(STATUS "Creating IMPORTED target FFmpeg::${_component}")
if(NOT TARGET FFmpeg::${_component})
add_library(FFmpeg::${_component} UNKNOWN IMPORTED)
set_target_properties(FFmpeg::${_component} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${${_component}_INCLUDE_DIRS}")
INTERFACE_INCLUDE_DIRECTORIES
"${FFmpeg_${_component}_INCLUDE_DIRS}")
set_property(TARGET FFmpeg::${_component} APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS "${${_component}_DEFINITIONS}")
INTERFACE_COMPILE_DEFINITIONS
"${FFmpeg_${_component}_DEFINITIONS}")
set_property(TARGET FFmpeg::${_component} APPEND PROPERTY
IMPORTED_LOCATION "${${_component}_LIBRARIES}")
IMPORTED_LOCATION "${FFmpeg_${_component}_LIBRARIES}")
endif()
endif()

View File

@@ -35,21 +35,25 @@ using namespace std;
using namespace openshot;
// Constructor that reads samples from a reader
AudioReaderSource::AudioReaderSource(ReaderBase *audio_reader, int64_t starting_frame_number, int buffer_size)
: reader(audio_reader), frame_number(starting_frame_number),
size(buffer_size), position(0), frame_position(0), estimated_frame(0), speed(1) {
// Initialize an audio buffer (based on reader)
buffer = new juce::AudioSampleBuffer(reader->info.channels, size);
// initialize the audio samples to zero (silence)
AudioReaderSource::AudioReaderSource(
ReaderBase *audio_reader, int64_t starting_frame_number, int buffer_size
) :
position(0),
size(buffer_size),
buffer(new juce::AudioSampleBuffer(audio_reader->info.channels, buffer_size)),
speed(1),
reader(audio_reader),
frame_number(starting_frame_number),
frame_position(0),
estimated_frame(0)
{
// Zero the buffer contents
buffer->clear();
}
// Destructor
AudioReaderSource::~AudioReaderSource()
{
// Clear and delete the buffer
delete buffer;
buffer = NULL;
}

View File

@@ -130,7 +130,17 @@ set(EFFECTS_SOURCES
effects/Pixelate.cpp
effects/Saturation.cpp
effects/Shift.cpp
effects/Wave.cpp)
effects/Wave.cpp
audio_effects/STFT.cpp
audio_effects/Noise.cpp
audio_effects/Delay.cpp
audio_effects/Echo.cpp
audio_effects/Distortion.cpp
audio_effects/ParametricEQ.cpp
audio_effects/Compressor.cpp
audio_effects/Expander.cpp
audio_effects/Robotization.cpp
audio_effects/Whisperization.cpp)
# Qt video player components
set(QT_PLAYER_SOURCES
@@ -186,56 +196,57 @@ target_link_libraries(openshot PUBLIC OpenShot::Audio)
###
# Find the ImageMagick++ library
find_package(ImageMagick COMPONENTS Magick++ MagickCore)
if (ENABLE_MAGICK)
find_package(ImageMagick COMPONENTS Magick++ MagickCore)
if(ImageMagick_FOUND)
if(NOT TARGET ImageMagick::Magick++ AND NOT TARGET Magick++_TARGET)
add_library(Magick++_TARGET INTERFACE)
if(ImageMagick_FOUND)
if(NOT TARGET ImageMagick::Magick++ AND NOT TARGET Magick++_TARGET)
add_library(Magick++_TARGET INTERFACE)
# Include ImageMagick++ headers (needed for compile)
set_property(TARGET Magick++_TARGET APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${ImageMagick_INCLUDE_DIRS})
# Include ImageMagick++ headers (needed for compile)
set_property(TARGET Magick++_TARGET APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${ImageMagick_INCLUDE_DIRS})
# Set the Quantum Depth that ImageMagick was built with (default to 16 bits)
if(NOT DEFINED MAGICKCORE_QUANTUM_DEPTH)
set(MAGICKCORE_QUANTUM_DEPTH 16)
endif()
if(NOT DEFINED MAGICKCORE_HDRI_ENABLE)
set(MAGICKCORE_HDRI_ENABLE 0)
endif()
set_property(TARGET Magick++_TARGET APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS
MAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH})
set_property(TARGET Magick++_TARGET APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS
MAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE})
target_link_libraries(Magick++_TARGET INTERFACE
${ImageMagick_LIBRARIES})
# Alias to our namespaced name
add_library(ImageMagick::Magick++ ALIAS Magick++_TARGET)
# Set the Quantum Depth that ImageMagick was built with (default to 16 bits)
if(NOT DEFINED MAGICKCORE_QUANTUM_DEPTH)
set(MAGICKCORE_QUANTUM_DEPTH 16)
endif()
if(NOT DEFINED MAGICKCORE_HDRI_ENABLE)
set(MAGICKCORE_HDRI_ENABLE 0)
endif()
set_property(TARGET Magick++_TARGET APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS
MAGICKCORE_QUANTUM_DEPTH=${MAGICKCORE_QUANTUM_DEPTH})
set_property(TARGET Magick++_TARGET APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS
MAGICKCORE_HDRI_ENABLE=${MAGICKCORE_HDRI_ENABLE})
# Add optional ImageMagic-dependent sources
target_sources(openshot PRIVATE
ImageReader.cpp
ImageWriter.cpp
TextReader.cpp)
target_link_libraries(Magick++_TARGET INTERFACE
${ImageMagick_LIBRARIES})
# define a preprocessor macro (used in the C++ source)
target_compile_definitions(openshot PUBLIC USE_IMAGEMAGICK=1)
# Alias to our namespaced name
add_library(ImageMagick::Magick++ ALIAS Magick++_TARGET)
# Link with ImageMagick library
target_link_libraries(openshot PUBLIC ImageMagick::Magick++)
set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE)
mark_as_advanced(HAVE_IMAGEMAGICK)
endif()
# Add optional ImageMagic-dependent sources
target_sources(openshot PRIVATE
ImageReader.cpp
ImageWriter.cpp
TextReader.cpp)
# define a preprocessor macro (used in the C++ source)
target_compile_definitions(openshot PUBLIC USE_IMAGEMAGICK=1)
# Link with ImageMagick library
target_link_libraries(openshot PUBLIC ImageMagick::Magick++)
set(HAVE_IMAGEMAGICK TRUE CACHE BOOL "Building with ImageMagick support" FORCE)
mark_as_advanced(HAVE_IMAGEMAGICK)
endif()
################### JSONCPP #####################
# Include jsoncpp headers (needed for JSON parsing)
if (USE_SYSTEM_JSONCPP)
@@ -273,7 +284,7 @@ endif ()
################# QT5 ###################
# Find QT5 libraries
set(_qt_components Core Gui Widgets)
set(_qt_components Core Gui Widgets Svg)
find_package(Qt5 COMPONENTS ${_qt_components} REQUIRED)
foreach(_qt_comp IN LISTS _qt_components)
@@ -288,31 +299,45 @@ mark_as_advanced(QT_VERSION_STR)
################### FFMPEG #####################
# Find FFmpeg libraries (used for video encoding / decoding)
find_package(FFmpeg REQUIRED COMPONENTS avcodec avformat avutil swscale)
find_package(FFmpeg REQUIRED
COMPONENTS avcodec avformat avutil swscale
OPTIONAL_COMPONENTS swresample avresample
)
set(all_comps avcodec avformat avutil swscale)
if(TARGET FFmpeg::swresample)
list(APPEND all_comps swresample)
else()
list(APPEND all_comps avresample)
endif()
set(version_comps avcodec avformat avutil)
# Pick a resampler. Prefer swresample if possible
if(TARGET FFmpeg::swresample AND ${FFmpeg_avformat_VERSION} VERSION_GREATER "57.0.0")
set(resample_lib swresample)
set(USE_SW TRUE)
else()
set(resample_lib avresample)
set(USE_SW FALSE)
endif()
list(APPEND all_comps ${resample_lib})
foreach(ff_comp IN LISTS all_comps)
if(TARGET FFmpeg::${ff_comp})
target_link_libraries(openshot PUBLIC FFmpeg::${ff_comp})
# Keep track of some FFmpeg lib versions, to embed in our version header
if(${ff_comp} IN_LIST version_comps AND ${ff_comp}_VERSION)
if(${ff_comp} IN_LIST version_comps AND FFmpeg_${ff_comp}_VERSION)
string(TOUPPER ${ff_comp} v_name)
set(${v_name}_VERSION_STR ${${ff_comp}_VERSION} CACHE STRING "${ff_comp} version used" FORCE)
set(${v_name}_VERSION_STR ${FFmpeg_${ff_comp}_VERSION} CACHE STRING "${ff_comp} version used" FORCE)
mark_as_advanced(${v_name}_VERSION_STR)
endif()
endif()
endforeach()
# Indicate which resampler we linked with, and set a config header flag
add_feature_info("FFmpeg ${resample_lib}" TRUE "Audio resampling uses ${resample_lib}")
# Set the appropriate flag in OpenShotVersion.h
set(FFMPEG_USE_SWRESAMPLE ${USE_SW} CACHE BOOL "libswresample used for audio resampling" FORCE)
mark_as_advanced(FFMPEG_USE_SWRESAMPLE)
# Version check for hardware-acceleration code
if(USE_HW_ACCEL AND avcodec_VERSION)
if(${avcodec_VERSION} VERSION_GREATER 57.107.100)
if(USE_HW_ACCEL AND FFmpeg_avcodec_VERSION)
if(${FFmpeg_avcodec_VERSION} VERSION_GREATER "57.106")
set(HAVE_HW_ACCEL TRUE)
endif()
endif()
@@ -537,4 +562,3 @@ endif()
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Jonathan Thomas") #required
include(CPack)

View File

@@ -207,7 +207,7 @@ cv::Rect2d CVTracker::filter_box_jitter(size_t frameId){
float curr_box_height = bbox.height;
// keep the last width and height if the difference is less than 1%
float threshold = 0.01;
cv::Rect2d filtered_box = bbox;
if(std::abs(1-(curr_box_width/last_box_width)) <= threshold){
filtered_box.width = last_box_width;
@@ -299,13 +299,13 @@ void CVTracker::SetJson(const std::string value) {
// Load Json::Value into this object
void CVTracker::SetJsonValue(const Json::Value root) {
// Set data from Json (if key is found)
if (!root["protobuf_data_path"].isNull()){
protobuf_data_path = (root["protobuf_data_path"].asString());
}
// Set data from Json (if key is found)
if (!root["protobuf_data_path"].isNull()){
protobuf_data_path = (root["protobuf_data_path"].asString());
}
if (!root["tracker-type"].isNull()){
trackerType = (root["tracker-type"].asString());
}
trackerType = (root["tracker-type"].asString());
}
if (!root["region"].isNull()){
double x = root["region"]["normalized_x"].asDouble();
@@ -314,20 +314,22 @@ void CVTracker::SetJsonValue(const Json::Value root) {
double h = root["region"]["normalized_height"].asDouble();
cv::Rect2d prev_bbox(x,y,w,h);
bbox = prev_bbox;
if (!root["region"]["first-frame"].isNull()){
start = root["region"]["first-frame"].asInt64();
json_interval = true;
}
else{
processingController->SetError(true, "No first-frame");
error = true;
}
}
else{
processingController->SetError(true, "No initial bounding box selected");
error = true;
}
if (!root["region"]["first-frame"].isNull()){
start = root["region"]["first-frame"].asInt64();
json_interval = true;
}
else{
processingController->SetError(true, "No first-frame");
error = true;
}
}
/*

View File

@@ -121,12 +121,8 @@ void Clip::init_reader_settings() {
// Init reader's rotation (if any)
void Clip::init_reader_rotation() {
// Only init rotation from reader when needed
if (rotation.GetCount() > 1)
// Do nothing if more than 1 rotation Point
return;
else if (rotation.GetCount() == 1 && rotation.GetValue(1) != 0.0)
// Do nothing if 1 Point, and it's not the default value
// Dont init rotation if clip has keyframes
if (rotation.GetCount() > 0)
return;
// Init rotation
@@ -1384,13 +1380,9 @@ QTransform Clip::get_transform(std::shared_ptr<Frame> frame, int width, int heig
break;
}
case (SCALE_NONE): {
// Calculate ratio of source size to project size
// Even with no scaling, previews need to be adjusted correctly
// (otherwise NONE scaling draws the frame image outside of the preview)
float source_width_ratio = source_size.width() / float(width);
float source_height_ratio = source_size.height() / float(height);
source_size.scale(width * source_width_ratio, height * source_height_ratio, Qt::KeepAspectRatio);
// Image is already the original size (i.e. no scaling mode) relative
// to the preview window size (i.e. timeline / preview ratio). No further
// scaling is needed here.
// Debug output
ZmqLogger::Instance()->AppendDebugMethod("Clip::get_transform (Scale: SCALE_NONE)", "frame->number", frame->number, "source_width", source_size.width(), "source_height", source_size.height());
break;

View File

@@ -68,15 +68,13 @@ namespace openshot {
CacheMemory cache;
/// Constructor for the base clip
ClipBase() {
// Initialize values
position = 0.0;
layer = 0;
start = 0.0;
end = 0.0;
previous_properties = "";
timeline = NULL;
};
ClipBase() :
position(0.0),
layer(0),
start(0.0),
end(0.0),
previous_properties(""),
timeline(nullptr) {}
// Compare a clip using the Position() property
bool operator< ( ClipBase& a) { return (Position() < a.Position()); }

View File

@@ -28,6 +28,8 @@
* along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cmath>
#include "Color.h"
#include "Exceptions.h"

View File

@@ -34,14 +34,14 @@
using namespace openshot;
// Default constructor for a coordinate, delegating to the full signature
Coordinate::Coordinate() : Coordinate::Coordinate(0, 0) {};
Coordinate::Coordinate() : Coordinate::Coordinate(0, 0) {}
// Constructor which also allows the user to set the X and Y
Coordinate::Coordinate(double x, double y) : X(x), Y(y) {};
Coordinate::Coordinate(double x, double y) : X(x), Y(y) {}
// Constructor which accepts a std::pair for (X, Y)
Coordinate::Coordinate(const std::pair<double, double>& co)
: X(co.first), Y(co.second) {};
: X(co.first), Y(co.second) {}
// Generate JSON string of this object
std::string Coordinate::Json() const {

View File

@@ -37,43 +37,57 @@
namespace openshot {
/**
* @brief This class represents a Cartesian coordinate (X, Y) used in the Keyframe animation system.
*
* Animation involves the changing (i.e. interpolation) of numbers over time. A series of Coordinate
* objects allows us to plot a specific curve or line used during interpolation. In other words, it helps us
* control how a number changes over time (quickly or slowly).
*
* Please see the following <b>Example Code</b>:
* \code
* Coordinate c1(2,4);
* assert(c1.X == 2.0f);
* assert(c1.Y == 4.0f);
* \endcode
*/
class Coordinate {
public:
double X; ///< The X value of the coordinate (usually representing the frame #)
double Y; ///< The Y value of the coordinate (usually representing the value of the property being animated)
/**
* @brief A Cartesian coordinate (X, Y) used in the Keyframe animation system.
*
* Animation involves the changing (i.e. interpolation) of numbers over time.
* A series of Coordinate objects allows us to plot a specific curve or line
* used during interpolation. In other words, it helps us control how a
* value changes over time — whether it's increasing or decreasing
* (the direction of the slope) and how quickly (the steepness of the curve).
*
* Please see the following <b>Example Code</b>:
* \code
* Coordinate c1(2,4);
* assert(c1.X == 2.0f);
* assert(c1.Y == 4.0f);
* \endcode
*/
class Coordinate {
public:
double X; ///< The X value of the coordinate (usually representing the frame #)
double Y; ///< The Y value of the coordinate (usually representing the value of the property being animated)
/// The default constructor, which defaults to (0,0)
Coordinate();
/// The default constructor, which defaults to (0,0)
Coordinate();
/// @brief Constructor which also sets the X and Y
/// @param x The X coordinate (usually representing the frame #)
/// @param y The Y coordinate (usually representing the value of the property being animated)
Coordinate(double x, double y);
/// @brief Constructor which also sets the X and Y
/// @param x The X coordinate (usually representing the frame #)
/// @param y The Y coordinate (usually representing the value of the property being animated)
Coordinate(double x, double y);
/// @brief Constructor which accepts a std::pair tuple for {X, Y}
/// @param co A std::pair<double, double> tuple containing (X, Y)
Coordinate(const std::pair<double, double>& co);
/// @brief Constructor which accepts a std::pair tuple for {X, Y}
/// @param co A std::pair<double, double> tuple containing (X, Y)
Coordinate(const std::pair<double, double>& co);
// Get and Set JSON methods
std::string Json() const; ///< Generate JSON string of this object
Json::Value JsonValue() const; ///< Generate Json::Value for this object
void SetJson(const std::string value); ///< Load JSON string into this object
void SetJsonValue(const Json::Value root); ///< Load Json::Value into this object
};
// Get and Set JSON methods
std::string Json() const; ///< Generate JSON string of this object
Json::Value JsonValue() const; ///< Generate Json::Value for this object
void SetJson(const std::string value); ///< Load JSON string into this object
void SetJsonValue(const Json::Value root); ///< Load Json::Value into this object
};
/// Stream output operator for openshot::Coordinate
template<class charT, class traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& o, const openshot::Coordinate& co) {
std::basic_ostringstream<charT, traits> s;
s.flags(o.flags());
s.imbue(o.getloc());
s.precision(o.precision());
s << "(" << co.X << ", " << co.Y << ")";
return o << s.str();
}
}

View File

@@ -28,6 +28,9 @@
* along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <iomanip>
#include "EffectBase.h"
#include "Exceptions.h"
@@ -57,16 +60,16 @@ void EffectBase::InitEffectInfo()
}
// Display file information
void EffectBase::DisplayInfo() {
std::cout << std::fixed << std::setprecision(2) << std::boolalpha;
std::cout << "----------------------------" << std::endl;
std::cout << "----- Effect Information -----" << std::endl;
std::cout << "----------------------------" << std::endl;
std::cout << "--> Name: " << info.name << std::endl;
std::cout << "--> Description: " << info.description << std::endl;
std::cout << "--> Has Video: " << info.has_video << std::endl;
std::cout << "--> Has Audio: " << info.has_audio << std::endl;
std::cout << "----------------------------" << std::endl;
void EffectBase::DisplayInfo(std::ostream* out) {
*out << std::fixed << std::setprecision(2) << std::boolalpha;
*out << "----------------------------" << std::endl;
*out << "----- Effect Information -----" << std::endl;
*out << "----------------------------" << std::endl;
*out << "--> Name: " << info.name << std::endl;
*out << "--> Description: " << info.description << std::endl;
*out << "--> Has Video: " << info.has_video << std::endl;
*out << "--> Has Audio: " << info.has_audio << std::endl;
*out << "----------------------------" << std::endl;
}
// Constrain a color value from 0 to 255

View File

@@ -87,7 +87,7 @@ namespace openshot
EffectInfoStruct info;
/// Display effect information in the standard output stream (stdout)
void DisplayInfo();
void DisplayInfo(std::ostream* out=&std::cout);
/// Constrain a color value from 0 to 255
int constrain(int color_value);

View File

@@ -88,6 +88,33 @@ EffectBase* EffectInfo::CreateEffect(std::string effect_type) {
else if (effect_type == "Wave")
return new Wave();
else if(effect_type == "Noise")
return new Noise();
else if(effect_type == "Delay")
return new Delay();
else if(effect_type == "Echo")
return new Echo();
else if(effect_type == "Distortion")
return new Distortion();
else if(effect_type == "ParametricEQ")
return new ParametricEQ();
else if(effect_type == "Compressor")
return new Compressor();
else if(effect_type == "Expander")
return new Expander();
else if(effect_type == "Robotization")
return new Robotization();
else if(effect_type == "Whisperization")
return new Whisperization();
#ifdef USE_OPENCV
else if(effect_type == "Stabilizer")
return new Stabilizer();
@@ -124,6 +151,16 @@ Json::Value EffectInfo::JsonValue() {
root.append(Saturation().JsonInfo());
root.append(Shift().JsonInfo());
root.append(Wave().JsonInfo());
/* Audio */
root.append(Noise().JsonInfo());
root.append(Delay().JsonInfo());
root.append(Echo().JsonInfo());
root.append(Distortion().JsonInfo());
root.append(ParametricEQ().JsonInfo());
root.append(Compressor().JsonInfo());
root.append(Expander().JsonInfo());
root.append(Robotization().JsonInfo());
root.append(Whisperization().JsonInfo());
#ifdef USE_OPENCV
root.append(Stabilizer().JsonInfo());

View File

@@ -48,6 +48,18 @@
#include "effects/Shift.h"
#include "effects/Wave.h"
/* Audio Effects */
#include "audio_effects/Noise.h"
#include "audio_effects/Delay.h"
#include "audio_effects/Echo.h"
#include "audio_effects/Distortion.h"
#include "audio_effects/ParametricEQ.h"
#include "audio_effects/Compressor.h"
#include "audio_effects/Expander.h"
#include "audio_effects/Robotization.h"
#include "audio_effects/Whisperization.h"
/* OpenCV Effects */
#ifdef USE_OPENCV
#include "effects/ObjectDetection.h"
#include "effects/Tracker.h"

View File

@@ -80,5 +80,58 @@ namespace openshot
VOLUME_MIX_AVERAGE, ///< Evenly divide the overlapping clips volume keyframes, so that the sum does not exceed 100%
VOLUME_MIX_REDUCE ///< Reduce volume by about %25, and then mix (louder, but could cause pops if the sum exceeds 100%)
};
/// This enumeration determines the distortion type of Distortion Effect.
enum DistortionType
{
HARD_CLIPPING,
SOFT_CLIPPING,
EXPONENTIAL,
FULL_WAVE_RECTIFIER,
HALF_WAVE_RECTIFIER,
};
/// This enumeration determines the filter type of ParametricEQ Effect.
enum FilterType
{
LOW_PASS,
HIGH_PASS,
LOW_SHELF,
HIGH_SHELF,
BAND_PASS,
BAND_STOP,
PEAKING_NOTCH,
};
/// This enumeration determines the FFT size.
enum FFTSize
{
FFT_SIZE_32,
FFT_SIZE_64,
FFT_SIZE_128,
FFT_SIZE_256,
FFT_SIZE_512,
FFT_SIZE_1024,
FFT_SIZE_2048,
FFT_SIZE_4096,
FFT_SIZE_8192,
};
/// This enumeration determines the hop size.
enum HopSize {
HOP_SIZE_2,
HOP_SIZE_4,
HOP_SIZE_8,
};
/// This enumeration determines the window type.
enum WindowType {
RECTANGULAR,
BART_LETT,
HANN,
HAMMING,
};
}
#endif

View File

@@ -33,6 +33,7 @@
#include "FFmpegReader.h"
#include "Exceptions.h"
#include "Timeline.h"
#include <thread> // for std::this_thread::sleep_for
#include <chrono> // for std::chrono::milliseconds
@@ -768,12 +769,12 @@ void FFmpegReader::UpdateVideoInfo() {
// Check for valid duration (if found)
if (info.duration <= 0.0f && pFormatCtx->duration >= 0)
// Use the format's duration
info.duration = pFormatCtx->duration / AV_TIME_BASE;
info.duration = float(pFormatCtx->duration) / AV_TIME_BASE;
// Calculate duration from filesize and bitrate (if any)
if (info.duration <= 0.0f && info.video_bit_rate > 0 && info.file_size > 0)
// Estimate from bitrate, total bytes, and framerate
info.duration = (info.file_size / info.video_bit_rate);
info.duration = float(info.file_size) / info.video_bit_rate;
// No duration found in stream of file
if (info.duration <= 0.0f) {
@@ -1285,9 +1286,18 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame) {
}
} else {
// No scaling, use original image size (slower)
max_width = info.width;
max_height = info.height;
// Scale video to equivalent unscaled size
// Since the preview window can change sizes, we want to always
// scale against the ratio of original video size to timeline size
float preview_ratio = 1.0;
if (parent->ParentTimeline()) {
Timeline *t = (Timeline *) parent->ParentTimeline();
preview_ratio = t->preview_width / float(t->info.width);
}
float max_scale_x = parent->scale_x.GetMaxPoint().co.Y;
float max_scale_y = parent->scale_y.GetMaxPoint().co.Y;
max_width = info.width * max_scale_x * preview_ratio;
max_height = info.height * max_scale_y * preview_ratio;
}
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More