diff --git a/.cproject b/.cproject
deleted file mode 100644
index 1028fe17..00000000
--- a/.cproject
+++ /dev/null
@@ -1,405 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- cmake
- -G "Unix Makefiles" ../ -D"CMAKE_BUILD_TYPE:STRING=Release"
- true
- false
- true
-
-
- cmake
- -G "Unix Makefiles" ../ -D"MAGICKCORE_HDRI_ENABLE=0" -D"MAGICKCORE_QUANTUM_DEPTH=16" -D"OPENSHOT_IMAGEMAGICK_COMPATIBILITY=0" -D"ENABLE_BLACKMAGIC=1" -D"CMAKE_BUILD_TYPE:STRING=Debug" -D"DISABLE_TESTS=0"
-
- true
- false
- true
-
-
- make
- test
- true
- false
- true
-
-
- make
- help
- true
- false
- true
-
-
- make
- doc
- true
- false
- true
-
-
- cmake
- -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc48/bin/g++-4.8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc48/bin/gcc-4.8 -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.1.1/ -DPYTHON_INCLUDE_DIR=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/include/python3.3m/ -DPYTHON_LIBRARY=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/lib/libpython3.3.dylib -DPython_FRAMEWORKS=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/ ../ -D"CMAKE_BUILD_TYPE:STRING=Debug"
- true
- false
- true
-
-
- cmake
- -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc48/bin/g++-4.8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc48/bin/gcc-4.8 -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.1.1/ -DPYTHON_INCLUDE_DIR=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/include/python3.3m/ -DPYTHON_LIBRARY=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/lib/libpython3.3.dylib -DPython_FRAMEWORKS=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/ ../ -D"CMAKE_BUILD_TYPE:STRING=Release"
- true
- false
- true
-
-
- cmake
- -G "MinGW Makefiles" ../ -D"CMAKE_BUILD_TYPE:STRING=Debug"
- true
- false
- true
-
-
- cmake
- -G "MinGW Makefiles" ../ -D"CMAKE_BUILD_TYPE:STRING=Release"
- true
- false
- true
-
-
-
-
diff --git a/.gitignore b/.gitignore
index e7f24925..022991be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,8 @@ build/*
*.DS_Store
.pydevproject
.settings
-.idea/*
\ No newline at end of file
+.idea/*
+.project
+.cproject
+/.metadata/
+*~
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3059ee9d..d74c1ef6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -20,9 +20,14 @@ linux-builder:
- cmake -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -D"CMAKE_BUILD_TYPE:STRING=Release" ../
- make
- make install
- - mv /usr/local/lib/python3.4/dist-packages/*openshot* install-x64/python
+ - make doc
+ - ~/auto-update-docs "$CI_PROJECT_DIR/build" "$CI_COMMIT_REF_NAME"
+ - mv install-x64/lib/python3.4/site-packages/*openshot* install-x64/python
- echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME"
+ - git log $(git describe --tags --abbrev=0)..HEAD --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log"
when: always
+ except:
+ - tags
tags:
- linux
@@ -44,38 +49,15 @@ mac-builder:
- cmake -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR/build/install-x64" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc48/bin/g++-4.8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc48/bin/gcc-4.8 -DCMAKE_PREFIX_PATH=/usr/local/qt5/5.5/clang_64 -DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -DPYTHON_LIBRARY=/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib -DPython_FRAMEWORKS=/Library/Frameworks/Python.framework/ -D"CMAKE_BUILD_TYPE:STRING=Debug" -D"CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" -D"CMAKE_OSX_DEPLOYMENT_TARGET=10.9" -D"CMAKE_INSTALL_RPATH_USE_LINK_PATH=1" -D"ENABLE_RUBY=0" ../
- make
- make install
- - mv /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/*openshot* install-x64/python
+ - mv install-x64/lib/python3.6/site-packages/*openshot* install-x64/python
- echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME"
+ - git log $(git describe --tags --abbrev=0)..HEAD --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log"
when: always
+ except:
+ - tags
tags:
- mac
-windows-builder-x86:
- stage: build-libopenshot
- artifacts:
- expire_in: 6 months
- paths:
- - build\install-x86\*
- script:
- - try { Invoke-WebRequest -Uri "http://gitlab.openshot.org/OpenShot/libopenshot-audio/-/jobs/artifacts/$CI_COMMIT_REF_NAME/download?job=windows-builder-x86" -Headers @{"PRIVATE-TOKEN"="$ACCESS_TOKEN"} -OutFile "artifacts.zip" } catch { $_.Exception.Response.StatusCode.Value__ }
- - if (-not (Test-Path "artifacts.zip")) { Invoke-WebRequest -Uri "http://gitlab.openshot.org/OpenShot/libopenshot-audio/-/jobs/artifacts/develop/download?job=windows-builder-x86" -Headers @{"PRIVATE-TOKEN"="$ACCESS_TOKEN"} -OutFile "artifacts.zip" }
- - Expand-Archive -Path artifacts.zip -DestinationPath .
- - $env:LIBOPENSHOT_AUDIO_DIR = "$CI_PROJECT_DIR\build\install-x86"
- - $env:UNITTEST_DIR = "C:\msys32\usr"
- - $env:ZMQDIR = "C:\msys32\usr"
- - $env:Path = "C:\msys32\mingw32\bin;C:\msys32\mingw32\lib;C:\msys32\usr\lib\cmake\UnitTest++;C:\msys32\home\jonathan\depot_tools;C:\msys32\usr;C:\msys32\usr\lib;" + $env:Path;
- - New-Item -ItemType Directory -Force -Path build
- - New-Item -ItemType Directory -Force -Path build\install-x86\python
- - cd build
- - cmake -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR\build\install-x86" -G "MinGW Makefiles" -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_CXX_FLAGS=-m32" -D"CMAKE_EXE_LINKER_FLAGS=-Wl,--large-address-aware" -D"CMAKE_C_FLAGS=-m32" ../
- - mingw32-make install
- - Move-Item -Force -path "C:\msys32\mingw32\lib\python3.6\site-packages\*openshot*" -destination "install-x86\python\"
- - cp src\libopenshot.dll install-x86\lib
- - New-Item -path "install-x86/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force
- when: always
- tags:
- - windows
-
windows-builder-x64:
stage: build-libopenshot
artifacts:
@@ -95,10 +77,45 @@ windows-builder-x64:
- cd build
- cmake -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR\build\install-x64" -G "MinGW Makefiles" -D"CMAKE_BUILD_TYPE:STRING=Release" ../
- mingw32-make install
- - Move-Item -Force -path "C:\msys64\mingw64\lib\python3.6\site-packages\*openshot*" -destination "install-x64\python\"
+ - Move-Item -Force -path "install-x64\lib\python3.6\site-packages\*openshot*" -destination "install-x64\python\"
- cp src\libopenshot.dll install-x64\lib
- New-Item -path "install-x64/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force
+ - $PREV_GIT_LABEL=(git describe --tags --abbrev=0)
+ - git log "$PREV_GIT_LABEL..HEAD" --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log"
when: always
+ except:
+ - tags
+ tags:
+ - windows
+
+windows-builder-x86:
+ stage: build-libopenshot
+ artifacts:
+ expire_in: 6 months
+ paths:
+ - build\install-x86\*
+ script:
+ - try { Invoke-WebRequest -Uri "http://gitlab.openshot.org/OpenShot/libopenshot-audio/-/jobs/artifacts/$CI_COMMIT_REF_NAME/download?job=windows-builder-x86" -Headers @{"PRIVATE-TOKEN"="$ACCESS_TOKEN"} -OutFile "artifacts.zip" } catch { $_.Exception.Response.StatusCode.Value__ }
+ - if (-not (Test-Path "artifacts.zip")) { Invoke-WebRequest -Uri "http://gitlab.openshot.org/OpenShot/libopenshot-audio/-/jobs/artifacts/develop/download?job=windows-builder-x86" -Headers @{"PRIVATE-TOKEN"="$ACCESS_TOKEN"} -OutFile "artifacts.zip" }
+ - Expand-Archive -Path artifacts.zip -DestinationPath .
+ - $env:LIBOPENSHOT_AUDIO_DIR = "$CI_PROJECT_DIR\build\install-x86"
+ - $env:UNITTEST_DIR = "C:\msys32\usr"
+ - $env:RESVGDIR = "C:\msys32\usr\local"
+ - $env:ZMQDIR = "C:\msys32\usr"
+ - $env:Path = "C:\msys32\mingw32\bin;C:\msys32\mingw32\lib;C:\msys32\usr\lib\cmake\UnitTest++;C:\msys32\home\jonathan\depot_tools;C:\msys32\usr;C:\msys32\usr\lib;" + $env:Path;
+ - New-Item -ItemType Directory -Force -Path build
+ - New-Item -ItemType Directory -Force -Path build\install-x86\python
+ - cd build
+ - cmake -D"CMAKE_INSTALL_PREFIX:PATH=$CI_PROJECT_DIR\build\install-x86" -G "MinGW Makefiles" -D"CMAKE_BUILD_TYPE:STRING=Release" -D"CMAKE_CXX_FLAGS=-m32" -D"CMAKE_EXE_LINKER_FLAGS=-Wl,--large-address-aware" -D"CMAKE_C_FLAGS=-m32" ../
+ - mingw32-make install
+ - Move-Item -Force -path "install-x86\lib\python3.6\site-packages\*openshot*" -destination "install-x86\python\"
+ - cp src\libopenshot.dll install-x86\lib
+ - New-Item -path "install-x86/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force
+ - $PREV_GIT_LABEL=(git describe --tags --abbrev=0)
+ - git log "$PREV_GIT_LABEL..HEAD" --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x86/share/$CI_PROJECT_NAME.log"
+ when: always
+ except:
+ - tags
tags:
- windows
@@ -108,5 +125,7 @@ trigger-pipeline:
- "curl -X POST -F token=$OPENSHOT_QT_PIPELINE_TOKEN -F ref=$CI_COMMIT_REF_NAME http://gitlab.openshot.org/api/v4/projects/3/trigger/pipeline"
when: always
dependencies: []
+ except:
+ - tags
tags:
- gitlab
diff --git a/.project b/.project
deleted file mode 100644
index 5e324854..00000000
--- a/.project
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
- libopenshot
-
-
-
-
-
- com.aptana.ide.core.unifiedBuilder
-
-
-
-
- org.python.pydev.PyDevBuilder
-
-
-
-
- org.eclipse.cdt.managedbuilder.core.genmakebuilder
- clean,full,incremental,
-
-
- ?name?
-
-
-
- org.eclipse.cdt.make.core.append_environment
- true
-
-
- org.eclipse.cdt.make.core.autoBuildTarget
- all
-
-
- org.eclipse.cdt.make.core.buildArguments
-
-
-
- org.eclipse.cdt.make.core.buildCommand
- make
-
-
- org.eclipse.cdt.make.core.buildLocation
- ${workspace_loc:/libopenshot/build}
-
-
- org.eclipse.cdt.make.core.cleanBuildTarget
- clean
-
-
- org.eclipse.cdt.make.core.contents
- org.eclipse.cdt.make.core.activeConfigSettings
-
-
- org.eclipse.cdt.make.core.enableAutoBuild
- false
-
-
- org.eclipse.cdt.make.core.enableCleanBuild
- true
-
-
- org.eclipse.cdt.make.core.enableFullBuild
- true
-
-
- org.eclipse.cdt.make.core.fullBuildTarget
- all
-
-
- org.eclipse.cdt.make.core.stopOnError
- true
-
-
- org.eclipse.cdt.make.core.useDefaultBuildCmd
- true
-
-
-
-
- org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
-
-
-
-
-
- org.eclipse.cdt.core.cnature
- org.eclipse.cdt.core.ccnature
- org.eclipse.cdt.managedbuilder.core.managedBuildNature
- org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
- org.python.pydev.pythonNature
- com.aptana.ruby.core.rubynature
-
-
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..2e7db59d
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,53 @@
+dist: xenial
+sudo: required
+
+matrix:
+ include:
+ - language: cpp
+ name: "FFmpeg 2"
+ before_script:
+ - sudo add-apt-repository ppa:openshot.developers/libopenshot-daily -y
+ - sudo add-apt-repository ppa:beineri/opt-qt-5.10.0-xenial -y
+ - sudo apt-get update -qq
+ - sudo apt-get install gcc-4.8 cmake libavcodec-dev libavformat-dev libswscale-dev libavresample-dev libavutil-dev libopenshot-audio-dev libopenshot-dev libfdk-aac-dev libfdk-aac-dev libjsoncpp-dev libmagick++-dev libopenshot-audio-dev libunittest++-dev libzmq3-dev pkg-config python3-dev qtbase5-dev qtmultimedia5-dev swig -y
+ - sudo apt autoremove -y
+ script:
+ - mkdir -p build; cd build;
+ - cmake -D"CMAKE_BUILD_TYPE:STRING=Debug" ../
+ - make VERBOSE=1
+ - make os_test
+ - make install DESTDIR=dist/
+
+ - language: cpp
+ name: "FFmpeg 3"
+ before_script:
+ - sudo add-apt-repository ppa:openshot.developers/libopenshot-daily -y
+ - sudo add-apt-repository ppa:beineri/opt-qt-5.10.0-xenial -y
+ - sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y
+ - sudo apt-get update -qq
+ - sudo apt-get install gcc-4.8 cmake libavcodec-dev libavformat-dev libswscale-dev libavresample-dev libavutil-dev libopenshot-audio-dev libopenshot-dev libfdk-aac-dev libfdk-aac-dev libjsoncpp-dev libmagick++-dev libopenshot-audio-dev libunittest++-dev libzmq3-dev pkg-config python3-dev qtbase5-dev qtmultimedia5-dev swig -y
+ - sudo apt autoremove -y
+ script:
+ - mkdir -p build; cd build;
+ - cmake -D"CMAKE_BUILD_TYPE:STRING=Debug" ../
+ - make VERBOSE=1
+ - make os_test
+ - make install DESTDIR=dist/
+
+ - language: cpp
+ name: "FFmpeg 4"
+ before_script:
+ - sudo add-apt-repository ppa:openshot.developers/libopenshot-daily -y
+ - sudo add-apt-repository ppa:beineri/opt-qt-5.10.0-xenial -y
+ - sudo add-apt-repository ppa:jonathonf/ffmpeg -y
+ - sudo add-apt-repository ppa:jonathonf/ffmpeg-4 -y
+ - sudo add-apt-repository ppa:jonathonf/backports -y
+ - sudo apt-get update -qq
+ - sudo apt-get install gcc-4.8 cmake libavcodec58 libavformat58 libavcodec-dev libavformat-dev libswscale-dev libavresample-dev libavutil-dev libopenshot-audio-dev libopenshot-dev libfdk-aac-dev libfdk-aac-dev libjsoncpp-dev libmagick++-dev libopenshot-audio-dev libunittest++-dev libzmq3-dev pkg-config python3-dev qtbase5-dev qtmultimedia5-dev swig -y
+ - sudo apt autoremove -y
+ script:
+ - mkdir -p build; cd build;
+ - cmake -D"CMAKE_BUILD_TYPE:STRING=Debug" ../
+ - make VERBOSE=1
+ - make os_test
+ - make install DESTDIR=dist/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index eaf7d65f..ede6ebbf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,10 +4,10 @@
#
# @section LICENSE
#
-# Copyright (c) 2008-2014 OpenShot Studios, LLC
+# Copyright (c) 2008-2019 OpenShot Studios, LLC
# . This file is part of
-# OpenShot Library (libopenshot), an open-source project dedicated to
-# delivering high quality video editing and animation solutions to the
+# OpenShot Library (libopenshot), an open-source project dedicated to
+# delivering high quality video editing and animation solutions to the
# world. For more information visit .
#
# OpenShot Library (libopenshot) is free software: you can redistribute it
@@ -24,25 +24,31 @@
# along with OpenShot Library. If not, see .
################################################################################
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 3.1...3.14 FATAL_ERROR)
-MESSAGE("--------------------------------------------------------------")
-MESSAGE("Welcome to the OpenShot Build System! CMake will now check for all required build")
-MESSAGE("dependencies and notify you of any missing files or other issues. If you have any")
-MESSAGE("questions or issues, please visit .")
+message("\
+-----------------------------------------------------------------
+ Welcome to the OpenShot Build System!
+
+CMake will now check libopenshot's build dependencies and inform
+you of any missing files or other issues.
+
+For more information, please visit .
+-----------------------------------------------------------------")
################ ADD CMAKE MODULES ##################
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules")
################ GET VERSION INFORMATION FROM VERSION.H ##################
-MESSAGE("--------------------------------------------------------------")
-MESSAGE("Determining Version Number (from Version.h file)")
+message(STATUS "Determining Version Number (from Version.h file)")
#### Get the lines related to libopenshot version from the Version.h header
-file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/include/Version.h OPENSHOT_VERSION_LINES
- REGEX "#define[ ]+OPENSHOT_VERSION_.*[0-9]+;.*")
-
-#### Set each line into it's own variable
+file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/include/Version.h
+ OPENSHOT_VERSION_LINES
+ REGEX "#define[ ]+OPENSHOT_VERSION_.*[0-9]+;.*")
+
+#### Set each line into its own variable
+
list (GET OPENSHOT_VERSION_LINES 0 LINE_MAJOR)
list (GET OPENSHOT_VERSION_LINES 1 LINE_MINOR)
list (GET OPENSHOT_VERSION_LINES 2 LINE_BUILD)
@@ -53,22 +59,34 @@ STRING(REGEX REPLACE "#define[ ]+OPENSHOT_VERSION_MAJOR[ ]+([0-9]+);(.*)" "\\1"
STRING(REGEX REPLACE "#define[ ]+OPENSHOT_VERSION_MINOR[ ]+([0-9]+);(.*)" "\\1" MINOR_VERSION "${LINE_MINOR}")
STRING(REGEX REPLACE "#define[ ]+OPENSHOT_VERSION_BUILD[ ]+([0-9]+);(.*)" "\\1" BUILD_VERSION "${LINE_BUILD}")
STRING(REGEX REPLACE "#define[ ]+OPENSHOT_VERSION_SO[ ]+([0-9]+);(.*)" "\\1" SO_VERSION "${LINE_SO}")
-set(PROJECT_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${BUILD_VERSION}")
-MESSAGE("--> MAJOR Version: ${MAJOR_VERSION}")
-MESSAGE("--> MINOR Version: ${MINOR_VERSION}")
-MESSAGE("--> BUILD Version: ${BUILD_VERSION}")
-MESSAGE("--> SO/API/ABI Version: ${SO_VERSION}")
-MESSAGE("--> VERSION: ${PROJECT_VERSION}")
-MESSAGE("")
+message(STATUS "MAJOR Version: ${MAJOR_VERSION}")
+message(STATUS "MINOR Version: ${MINOR_VERSION}")
+message(STATUS "BUILD Version: ${BUILD_VERSION}")
+message(STATUS "SO/API/ABI Version: ${SO_VERSION}")
+message(STATUS "Determining Version Number - done")
################### SETUP PROJECT ###################
-PROJECT(openshot)
-MESSAGE("--------------------------------------------------------------")
-MESSAGE("Generating build files for ${PROJECT_NAME} (${PROJECT_VERSION})")
+PROJECT(libopenshot LANGUAGES C CXX
+ VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${BUILD_VERSION})
+
+message("
+Generating build files for OpenShot
+ Building ${PROJECT_NAME} (version ${PROJECT_VERSION})
+ SO/API/ABI Version: ${SO_VERSION}
+")
+
+#### 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
+ (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS "9.0.0"))
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-integrated-cpp")
+endif()
#### Enable C++11 (for std::shared_ptr support)
-set(CMAKE_CXX_FLAGS "-std=c++11")
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
IF (WIN32)
SET_PROPERTY(GLOBAL PROPERTY WIN32 "WIN32")
diff --git a/Doxyfile.in b/Doxyfile.in
index 7cf50631..7b54a9c0 100644
--- a/Doxyfile.in
+++ b/Doxyfile.in
@@ -1,4 +1,4 @@
-# Doxyfile 1.8.6
+# Doxyfile 1.8.15
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -17,11 +17,11 @@
# Project related configuration options
#---------------------------------------------------------------------------
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all text
-# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
-# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
-# for the list of possible encodings.
+# This tag specifies the encoding used for all characters in the configuration
+# file that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
# The default value is: UTF-8.
DOXYFILE_ENCODING = UTF-8
@@ -46,10 +46,10 @@ PROJECT_NUMBER = "@PROJECT_VERSION@"
PROJECT_BRIEF =
-# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
-# the documentation. The maximum height of the logo should not exceed 55 pixels
-# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
-# to the output directory.
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
PROJECT_LOGO =
@@ -60,7 +60,7 @@ PROJECT_LOGO =
OUTPUT_DIRECTORY = "@DOXYFILE_OUTPUT_DIR@"
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
# will distribute the generated files over these directories. Enabling this
# option can be useful when feeding doxygen a huge amount of source files, where
@@ -70,6 +70,14 @@ OUTPUT_DIRECTORY = "@DOXYFILE_OUTPUT_DIR@"
CREATE_SUBDIRS = NO
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
@@ -85,14 +93,22 @@ CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
-# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all generated output in the proper direction.
+# Possible values are: None, LTR, RTL and Context.
+# The default value is: None.
+
+OUTPUT_TEXT_DIRECTION = None
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
# The default value is: YES.
BRIEF_MEMBER_DESC = YES
-# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
# description of a member or function before the detailed description
#
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
@@ -127,7 +143,7 @@ ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
-# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
# before files name in the file list and in the header files. If set to NO the
# shortest path that makes the file name unique will be used
# The default value is: YES.
@@ -197,9 +213,9 @@ MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
-# new page for each member. If set to NO, the documentation of a member will be
-# part of the file/class/namespace that contains it.
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
# The default value is: NO.
SEPARATE_MEMBER_PAGES = NO
@@ -218,7 +234,12 @@ TAB_SIZE = 8
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines.
+# newlines (in the resulting output). You can put ^^ in the value part of an
+# alias to insert a newline as if a physical newline was in the original file.
+# When you need a literal { or } or , in the value part of an alias you have to
+# escape them by means of a backslash (\), this can lead to conflicts with the
+# commands \{ and \} for these it is advised to use the version @{ and @} or use
+# a double escape (\\{ and \\})
ALIASES =
@@ -256,16 +277,28 @@ OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
+# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
+# sources only. Doxygen will then generate output that is more tailored for that
+# language. For instance, namespaces will be presented as modules, types will be
+# separated into more groups, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_SLICE = NO
+
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
-# (default is Fortran), use: inc=Fortran f=C.
+# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
+# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
+# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
+# tries to guess whether the code is fixed or free formatted code, this is the
+# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is
+# Fortran), use: inc=Fortran f=C.
#
-# Note For files without extension you can use no_extension as a placeholder.
+# Note: For files without extension you can use no_extension as a placeholder.
#
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen.
@@ -274,7 +307,7 @@ EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# documentation. See https://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
@@ -282,10 +315,19 @@ EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
# When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by by putting a % sign in front of the word
-# or globally by setting AUTOLINK_SUPPORT to NO.
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
# The default value is: YES.
AUTOLINK_SUPPORT = YES
@@ -307,7 +349,7 @@ BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
# will parse them like normal C++ but will assume all classes use public instead
# of private inheritance when no explicit protection keyword is present.
# The default value is: NO.
@@ -325,13 +367,20 @@ SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
+# tag is set to YES then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
# The default value is: NO.
DISTRIBUTE_GROUP_DOC = NO
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
# Set the SUBGROUPING tag to YES to allow class member groups of the same type
# (for instance a group of public functions) to be put as a subgroup of that
# type (e.g. under the Public Functions section). Set it to NO to prevent
@@ -390,7 +439,7 @@ LOOKUP_CACHE_SIZE = 0
# Build related configuration options
#---------------------------------------------------------------------------
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
# documentation are documented, even if no documentation was available. Private
# class members and static file members will be hidden unless the
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
@@ -400,35 +449,35 @@ LOOKUP_CACHE_SIZE = 0
EXTRACT_ALL = YES
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
# be included in the documentation.
# The default value is: NO.
EXTRACT_PRIVATE = NO
-# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
# scope will be included in the documentation.
# The default value is: NO.
EXTRACT_PACKAGE = NO
-# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
# included in the documentation.
# The default value is: NO.
EXTRACT_STATIC = NO
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
# only classes defined in header files are included. Does not have any effect
# for Java sources.
# The default value is: YES.
EXTRACT_LOCAL_CLASSES = YES
-# This flag is only useful for Objective-C code. When set to YES local methods,
+# This flag is only useful for Objective-C code. If set to YES, local methods,
# which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO only methods in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
# included.
# The default value is: NO.
@@ -453,21 +502,21 @@ HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy. If set
-# to NO these classes will be included in the various overviews. This option has
-# no effect if EXTRACT_ALL is enabled.
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
# The default value is: NO.
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO these declarations will be
+# (class|struct|union) declarations. If set to NO, these declarations will be
# included in the documentation.
# The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO
# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO these
+# documentation blocks found inside the body of a function. If set to NO, these
# blocks will be appended to the function's detailed documentation block.
# The default value is: NO.
@@ -481,7 +530,7 @@ HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES upper-case letters are also
+# names in lower-case letters. If set to YES, upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
@@ -490,12 +539,19 @@ INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES the
+# their full class and namespace scopes in the documentation. If set to YES, the
# scope will be hidden.
# The default value is: NO.
HIDE_SCOPE_NAMES = NO
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
# the files that are included by a file in the documentation of that file.
# The default value is: YES.
@@ -523,14 +579,14 @@ INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
# (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO the members will appear in declaration order.
+# name. If set to NO, the members will appear in declaration order.
# The default value is: YES.
SORT_MEMBER_DOCS = YES
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
# descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO the members will appear in declaration order. Note that
+# name. If set to NO, the members will appear in declaration order. Note that
# this will also influence the order of the classes in the class list.
# The default value is: NO.
@@ -575,27 +631,25 @@ SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
-# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
-# todo list. This list is created by putting \todo commands in the
-# documentation.
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
# The default value is: YES.
GENERATE_TODOLIST = YES
-# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
-# test list. This list is created by putting \test commands in the
-# documentation.
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
# The default value is: YES.
GENERATE_TESTLIST = YES
-# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
# list. This list is created by putting \bug commands in the documentation.
# The default value is: YES.
GENERATE_BUGLIST = YES
-# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
# the deprecated list. This list is created by putting \deprecated commands in
# the documentation.
# The default value is: YES.
@@ -620,8 +674,8 @@ ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES the list
-# will mention the files that were used to generate the documentation.
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
# The default value is: YES.
SHOW_USED_FILES = YES
@@ -666,11 +720,10 @@ LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. Do not use file names with spaces, bibtex cannot handle them. See
-# also \cite for info how to create references.
+# search path. See also \cite for info how to create references.
CITE_BIB_FILES =
@@ -686,7 +739,7 @@ CITE_BIB_FILES =
QUIET = YES
# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
# this implies that the warnings are on.
#
# Tip: Turn warnings on while writing the documentation.
@@ -694,7 +747,7 @@ QUIET = YES
WARNINGS = YES
-# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
# will automatically be disabled.
# The default value is: YES.
@@ -711,12 +764,19 @@ WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
-# value. If set to NO doxygen will only warn about wrong or incomplete parameter
-# documentation, but not about the absence of documentation.
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation. If
+# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# The default value is: NO.
WARN_NO_PARAMDOC = NO
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
# will be replaced by the file and line number from which the warning originated
@@ -740,16 +800,18 @@ WARN_LOGFILE =
# The INPUT tag is used to specify the files and/or directories that contain
# documented source files. You may enter file names like myfile.cpp or
# directories like /usr/src/myproject. Separate the files or directories with
-# spaces.
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = "@CMAKE_CURRENT_SOURCE_DIR@/include" \
- "@CMAKE_CURRENT_SOURCE_DIR@/src"
+ "@CMAKE_CURRENT_SOURCE_DIR@/src" \
+ "@CMAKE_CURRENT_SOURCE_DIR@/doc"
+
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
# possible encodings.
# The default value is: UTF-8.
@@ -757,12 +819,17 @@ INPUT_ENCODING = UTF-8
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank the
-# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
-# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
-# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
-# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
-# *.qsf, *.as and *.js.
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS =
@@ -797,8 +864,9 @@ EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = "*/.*" \
"*/.*/*" \
- "*/src/Main.cpp*" \
- "*/src/Main_Blackmagic.cpp*"
+ "*/src/examples/*" \
+ "*/src/bindings/*" \
+ "*.py"
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -851,6 +919,10 @@ IMAGE_PATH = "@CMAKE_CURRENT_SOURCE_DIR@"
# Note that the filter must not add or remove lines; it is applied before the
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
INPUT_FILTER =
@@ -860,11 +932,15 @@ INPUT_FILTER =
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
FILTER_PATTERNS =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER ) will also be used to filter the input files that are used for
+# INPUT_FILTER) will also be used to filter the input files that are used for
# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
# The default value is: NO.
@@ -912,10 +988,10 @@ INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = NO
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# function all documented functions referencing it will be listed.
+# entity all documented functions referencing it will be listed.
# The default value is: NO.
-REFERENCED_BY_RELATION = NO
+REFERENCED_BY_RELATION = YES
# If the REFERENCES_RELATION tag is set to YES then for each documented function
# all documented entities called/used by that function will be listed.
@@ -924,7 +1000,7 @@ REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
# link to the documentation.
# The default value is: YES.
@@ -944,12 +1020,12 @@ SOURCE_TOOLTIPS = YES
# If the USE_HTAGS tag is set to YES then the references to source code will
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
# source browser. The htags tool is part of GNU's global source tagging system
-# (see http://www.gnu.org/software/global/global.html). You will need version
+# (see https://www.gnu.org/software/global/global.html). You will need version
# 4.8.6 or higher.
#
# To use it do the following:
# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
# - Make sure the INPUT points to the root of the source tree
# - Run doxygen as normal
#
@@ -1001,7 +1077,7 @@ IGNORE_PREFIX =
# Configuration options related to the HTML output
#---------------------------------------------------------------------------
-# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
# The default value is: YES.
GENERATE_HTML = YES
@@ -1063,13 +1139,15 @@ HTML_FOOTER =
HTML_STYLESHEET =
-# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
-# defined cascading style sheet that is included after the standard style sheets
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefor more robust against future updates.
-# Doxygen will copy the style sheet file to the output directory. For an example
-# see the documentation.
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET =
@@ -1082,12 +1160,12 @@ HTML_EXTRA_STYLESHEET =
# files will be copied as-is; there are no commands or markers available.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_EXTRA_FILES = "doc/InstallationGuide.pdf"
+HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the stylesheet and background images according to
+# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
# Minimum value: 0, maximum value: 359, default value: 220.
@@ -1116,12 +1194,24 @@ HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: YES.
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = YES
+# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
+# documentation will contain a main index with vertical navigation menus that
+# are dynamically created via Javascript. If disabled, the navigation index will
+# consists of multiple levels of tabs that are statically embedded in every HTML
+# page. Disable this option to support browsers that do not have Javascript,
+# like the Qt help browser.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_MENUS = YES
+
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded.
@@ -1145,13 +1235,13 @@ HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# environment (see: https://developer.apple.com/xcode/), introduced with OSX
+# 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
+# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
+# genXcode/_index.html for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1190,7 +1280,7 @@ DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
@@ -1213,28 +1303,29 @@ GENERATE_HTMLHELP = NO
CHM_FILE =
# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
# doxygen will try to run the HTML help compiler on the generated index.hhp.
# The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
HHC_LOCATION =
-# The GENERATE_CHI flag controls if a separate .chi index file is generated (
-# YES) or that it should be included in the master .chm file ( NO).
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
GENERATE_CHI = NO
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
# and project file content.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_INDEX_ENCODING =
-# The BINARY_TOC flag controls whether a binary table of contents is generated (
-# YES) or a normal table of contents ( NO) in the .chm file.
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
@@ -1265,7 +1356,7 @@ QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1273,7 +1364,7 @@ QHP_NAMESPACE =
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
# folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1282,7 +1373,7 @@ QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1290,7 +1381,7 @@ QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1298,7 +1389,7 @@ QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
@@ -1347,7 +1438,7 @@ DISABLE_INDEX = NO
# index structure (just like the one that is generated for HTML Help). For this
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
# further fine-tune the look of the index. As an example, the default style
# sheet generated by doxygen has an example that shows how to put an image at
# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
@@ -1375,7 +1466,7 @@ ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
# external symbols imported via tag files in a separate window.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1391,7 +1482,7 @@ EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are not
# supported properly for IE 6.0, but are supported on all modern browsers.
#
@@ -1403,8 +1494,8 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# https://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
# to it using the MATHJAX_RELPATH option.
@@ -1430,8 +1521,8 @@ MATHJAX_FORMAT = HTML-CSS
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# MathJax from https://www.mathjax.org before deployment.
+# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
@@ -1474,11 +1565,11 @@ SEARCHENGINE = NO
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There
-# are two flavours of web server based searching depending on the
-# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
-# searching and an index file used by the script. When EXTERNAL_SEARCH is
-# enabled the indexing and searching needs to be provided by external tools. See
-# the section "External Indexing and Searching" for details.
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
# The default value is: NO.
# This tag requires that the tag SEARCHENGINE is set to YES.
@@ -1490,9 +1581,9 @@ SERVER_BASED_SEARCH = NO
# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
# search results.
#
-# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/).
+# Xapian (see: https://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
@@ -1503,9 +1594,9 @@ EXTERNAL_SEARCH = NO
# The SEARCHENGINE_URL should point to a search engine hosted by a web server
# which will return the search results when EXTERNAL_SEARCH is enabled.
#
-# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Xapian (see: https://xapian.org/). See the section "External Indexing and
# Searching" for details.
# This tag requires that the tag SEARCHENGINE is set to YES.
@@ -1541,7 +1632,7 @@ EXTRA_SEARCH_MAPPINGS =
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
-# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES.
GENERATE_LATEX = @DOXYFILE_GENERATE_LATEX@
@@ -1557,22 +1648,35 @@ LATEX_OUTPUT = "@DOXYFILE_LATEX_DIR@"
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked.
#
-# Note that when enabling USE_PDFLATEX this option is only used for generating
-# bitmaps for formulas in the HTML output, but not in the Makefile that is
-# written to the output directory.
-# The default file is: latex.
+# Note that when not enabling USE_PDFLATEX the default is latex when enabling
+# USE_PDFLATEX the default is pdflatex and when in the later case latex is
+# chosen this is overwritten by pdflatex. For specific output languages the
+# default can have been set differently, this depends on the implementation of
+# the output language.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_CMD_NAME = "@LATEX_COMPILER@"
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
# index for LaTeX.
+# Note: This tag is used in the Makefile / make.bat.
+# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
+# (.tex).
# The default file is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
MAKEINDEX_CMD_NAME = "@MAKEINDEX_COMPILER@"
-# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
+# generate index for LaTeX.
+# Note: This tag is used in the generated output file (.tex).
+# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
+# The default value is: \makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_MAKEINDEX_CMD = \makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
# documents. This may be useful for small projects and may help to save some
# trees in general.
# The default value is: NO.
@@ -1590,9 +1694,12 @@ COMPACT_LATEX = NO
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. To get the times font for
-# instance you can specify
-# EXTRA_PACKAGES=times
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
# If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1606,23 +1713,36 @@ EXTRA_PACKAGES =
#
# Note: Only use a user-defined header if you know what you are doing! The
# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
-# replace them by respectively the title of the page, the current date and time,
-# only the current date, the version number of doxygen, the project name (see
-# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer.
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
#
# Note: Only use a user-defined footer if you know what you are doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER =
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the LATEX_OUTPUT output
# directory. Note that the files will be copied as-is; there are no commands or
@@ -1640,8 +1760,8 @@ LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
-# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
# higher quality PDF documentation.
# The default value is: YES.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1676,17 +1796,33 @@ LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# The default value is: plain.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_BIB_STYLE = plain
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP = NO
+
+# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
+# path from which the emoji images will be read. If a relative path is entered,
+# it will be relative to the LATEX_OUTPUT directory. If left blank the
+# LATEX_OUTPUT directory will be used.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EMOJI_DIRECTORY =
+
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
-# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
# RTF output is optimized for Word 97 and may not look too pretty with other RTF
# readers/editors.
# The default value is: NO.
@@ -1701,7 +1837,7 @@ GENERATE_RTF = NO
RTF_OUTPUT = rtf
-# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
# documents. This may be useful for small projects and may help to save some
# trees in general.
# The default value is: NO.
@@ -1721,9 +1857,9 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
-# Load stylesheet definitions from file. Syntax is similar to doxygen's config
-# file, i.e. a series of assignments. You only have to provide replacements,
-# missing definitions are set to their default value.
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# configuration file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
#
# See also section "Doxygen usage" for information on how to generate the
# default style sheet that doxygen normally uses.
@@ -1732,17 +1868,27 @@ RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's config file. A template extensions file can be generated
-# using doxygen -e rtf extensionFile.
+# similar to doxygen's configuration file. A template extensions file can be
+# generated using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE = NO
+
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
-# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
# classes and files.
# The default value is: NO.
@@ -1766,6 +1912,13 @@ MAN_OUTPUT = man
MAN_EXTENSION = .3
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
# will generate one additional man file for each entity documented in the real
# man page(s). These additional files only source the real man page, but without
@@ -1779,7 +1932,7 @@ MAN_LINKS = NO
# Configuration options related to the XML output
#---------------------------------------------------------------------------
-# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
# captures the structure of the code including all documentation.
# The default value is: NO.
@@ -1793,19 +1946,7 @@ GENERATE_XML = NO
XML_OUTPUT = xml
-# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
-# validating XML parser to check the syntax of the XML files.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
-# validating XML parser to check the syntax of the XML files.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
# listings (including syntax highlighting and cross-referencing information) to
# the XML output. Note that enabling this will significantly increase the size
# of the XML output.
@@ -1814,11 +1955,18 @@ XML_DTD =
XML_PROGRAMLISTING = YES
+# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
+# namespace members in file scope as well, matching the HTML output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_NS_MEMB_FILE_SCOPE = NO
+
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
-# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
# that can be used to generate PDF.
# The default value is: NO.
@@ -1832,14 +1980,23 @@ GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
-# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
-# Definitions (see http://autogen.sf.net) file that captures the structure of
-# the code including all documentation. Note that this feature is still
-# experimental and incomplete at the moment.
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
+# the structure of the code including all documentation. Note that this feature
+# is still experimental and incomplete at the moment.
# The default value is: NO.
GENERATE_AUTOGEN_DEF = NO
@@ -1848,7 +2005,7 @@ GENERATE_AUTOGEN_DEF = NO
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
-# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
# file that captures the structure of the code including all documentation.
#
# Note that this feature is still experimental and incomplete at the moment.
@@ -1856,7 +2013,7 @@ GENERATE_AUTOGEN_DEF = NO
GENERATE_PERLMOD = NO
-# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
# output from the Perl module output.
# The default value is: NO.
@@ -1864,9 +2021,9 @@ GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
# formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO the
+# understand what is going on. On the other hand, if this tag is set to NO, the
# size of the Perl module output will be much smaller and Perl will parse it
# just the same.
# The default value is: YES.
@@ -1886,14 +2043,14 @@ PERLMOD_MAKEVAR_PREFIX =
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
-# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
# C-preprocessor directives found in the sources and include files.
# The default value is: YES.
ENABLE_PREPROCESSING = YES
-# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
-# in the source code. If set to NO only conditional compilation will be
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
# performed. Macro expansion can be done in a controlled way by setting
# EXPAND_ONLY_PREDEF to YES.
# The default value is: NO.
@@ -1909,7 +2066,7 @@ MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
-# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
# The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
@@ -1951,9 +2108,9 @@ PREDEFINED =
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all refrences to function-like macros that are alone on a line, have an
-# all uppercase name, and do not end with a semicolon. Such function macros are
-# typically used for boiler-plate code, and will confuse the parser if not
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
# removed.
# The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
@@ -1973,7 +2130,7 @@ SKIP_FUNCTION_MACROS = YES
# where loc1 and loc2 can be relative or absolute paths or URLs. See the
# section "Linking to external documentation" for more information about the use
# of tag files.
-# Note: Each tag file must have an unique name (where the name does NOT include
+# Note: Each tag file must have a unique name (where the name does NOT include
# the path). If a tag file is not located in the directory in which doxygen is
# run, you must also specify the path to the tagfile here.
@@ -1985,20 +2142,21 @@ TAGFILES =
GENERATE_TAGFILE =
-# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
-# class index. If set to NO only the inherited external classes will be listed.
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
# The default value is: NO.
ALLEXTERNALS = NO
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
-# the modules index. If set to NO, only the current project's groups will be
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
# listed.
# The default value is: YES.
EXTERNAL_GROUPS = YES
-# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
# the related pages index. If set to NO, only the current project's pages will
# be listed.
# The default value is: YES.
@@ -2015,7 +2173,7 @@ PERL_PATH = /usr/bin/perl
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
-# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more
@@ -2040,7 +2198,7 @@ MSCGEN_PATH =
DIA_PATH =
-# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# If set to YES the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class.
# The default value is: YES.
@@ -2065,7 +2223,7 @@ HAVE_DOT = @DOXYFILE_DOT@
DOT_NUM_THREADS = 0
-# When you want a differently looking font n the dot files that doxygen
+# When you want a differently looking font in the dot files that doxygen
# generates you can specify the font name using DOT_FONTNAME. You need to make
# sure dot is able to find the font, which can be done by putting it in a
# standard location or by setting the DOTFONTPATH environment variable or by
@@ -2073,7 +2231,7 @@ DOT_NUM_THREADS = 0
# The default value is: Helvetica.
# This tag requires that the tag HAVE_DOT is set to YES.
-DOT_FONTNAME =
+DOT_FONTNAME =
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
# dot graphs.
@@ -2113,7 +2271,7 @@ COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
# collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language.
# The default value is: NO.
@@ -2165,7 +2323,8 @@ INCLUDED_BY_GRAPH = YES
#
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2176,7 +2335,8 @@ CALL_GRAPH = NO
#
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command.
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2199,15 +2359,19 @@ GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot.
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
-# Possible values are: png, jpg, gif and svg.
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
# The default value is: png.
# This tag requires that the tag HAVE_DOT is set to YES.
-DOT_IMAGE_FORMAT = png
+DOT_IMAGE_FORMAT = svg
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
# enable generation of interactive SVG images that allow zooming and panning.
@@ -2219,7 +2383,7 @@ DOT_IMAGE_FORMAT = png
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
-INTERACTIVE_SVG = NO
+INTERACTIVE_SVG = YES
# The DOT_PATH tag can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
@@ -2246,6 +2410,24 @@ MSCFILE_DIRS =
DIAFILE_DIRS =
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH =
+
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
# that will be shown in the graph. If the number of nodes in a graph becomes
# larger than this value, doxygen will truncate the graph, which is visualized
@@ -2282,7 +2464,7 @@ MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = YES
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
# this, this feature is disabled by default.
@@ -2299,7 +2481,7 @@ DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
-# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
# files that are used to generate the various graphs.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644
index 00000000..474fb9c2
--- /dev/null
+++ b/INSTALL.md
@@ -0,0 +1,153 @@
+## Detailed Install Instructions
+
+Operating system specific install instructions are located in:
+
+* doc/INSTALL-LINUX.md
+* doc/INSTALL-MAC.md
+* doc/INSTALL-WINDOWS.md
+
+## Getting Started
+
+The best way to get started with libopenshot, is to learn about our build system, obtain all the source code,
+install a development IDE and tools, and better understand our dependencies. So, please read through the
+following sections, and follow the instructions. And keep in mind, that your computer is likely different
+than the one used when writing these instructions. Your file paths and versions of applications might be
+slightly different, so keep an eye out for subtle file path differences in the commands you type.
+
+## Build Tools
+
+CMake is the backbone of our build system. It is a cross-platform build system, which checks for dependencies,
+locates header files and libraries, generates makefiles, and supports the cross-platform compiling of
+libopenshot and libopenshot-audio. CMake uses an out-of-source build concept, where all temporary build
+files, such as makefiles, object files, and even the final binaries, are created outside of the source
+code folder, inside a /build/ sub-folder. This prevents the build process from cluttering up the source
+code. These instructions have only been tested with the GNU compiler (including MSYS2/MinGW for Windows).
+
+## Dependencies
+
+The following libraries are required to build libopenshot. Instructions on how to install these
+dependencies vary for each operating system. Libraries and Executables have been labeled in the
+list below to help distinguish between them.
+
+* ### FFmpeg (libavformat, libavcodec, libavutil, libavdevice, libavresample, libswscale)
+ * http://www.ffmpeg.org/ `(Library)`
+ * This library is used to decode and encode video, audio, and image files. It is also used to obtain information about media files, such as frame rate, sample rate, aspect ratio, and other common attributes.
+
+* ### ImageMagick++ (libMagick++, libMagickWand, libMagickCore)
+ * http://www.imagemagick.org/script/magick++.php `(Library)`
+ * This library is **optional**, and used to decode and encode images.
+
+* ### OpenShot Audio Library (libopenshot-audio)
+ * https://github.com/OpenShot/libopenshot-audio/ `(Library)`
+ * This library is used to mix, resample, host plug-ins, and play audio. It is based on the JUCE project, which is an outstanding audio library used by many different applications
+
+* ### Qt 5 (libqt5)
+ * http://www.qt.io/qt5/ `(Library)`
+ * Qt5 is used to display video, store image data, composite images, apply image effects, and many other utility functions, such as file system manipulation, high resolution timers, etc...
+
+* ### CMake (cmake)
+ * http://www.cmake.org/ `(Executable)`
+ * This executable is used to automate the generation of Makefiles, check for dependencies, and is the backbone of libopenshot’s cross-platform build process.
+
+* ### SWIG (swig)
+ * http://www.swig.org/ `(Executable)`
+ * This executable is used to generate the Python and Ruby bindings for libopenshot. It is a simple and powerful wrapper for C++ libraries, and supports many languages.
+
+* ### Python 3 (libpython)
+ * http://www.python.org/ `(Executable and Library)`
+ * This library is used by swig to create the Python (version 3+) bindings for libopenshot. This is also the official language used by OpenShot Video Editor (a graphical interface to libopenshot).
+
+* ### Doxygen (doxygen)
+ * http://www.stack.nl/~dimitri/doxygen/ `(Executable)`
+ * This executable is used to auto-generate the documentation used by libopenshot.
+
+* ### UnitTest++ (libunittest++)
+ * https://github.com/unittest-cpp/ `(Library)`
+ * This library is used to execute unit tests for libopenshot. It contains many macros used to keep our unit testing code very clean and simple.
+
+* ### ZeroMQ (libzmq)
+ * http://zeromq.org/ `(Library)`
+ * This library is used to communicate between libopenshot and other applications (publisher / subscriber). Primarily used to send debug data from libopenshot.
+
+* ### OpenMP (-fopenmp)
+ * http://openmp.org/wp/ `(Compiler Flag)`
+ * If your compiler supports this flag (GCC, Clang, and most other compilers), it provides libopenshot with easy methods of using parallel programming techniques to improve performance and take advantage of multi-core processors.
+
+## CMake Flags (Optional)
+There are many different build flags that can be passed to cmake to adjust how libopenshot is compiled. Some of these flags might be required when compiling on certain OSes, just depending on how your build environment is setup. To add a build flag, follow this general syntax: $ cmake -DMAGICKCORE_HDRI_ENABLE=1 -DENABLE_TESTS=1 ../
+
+* MAGICKCORE_HDRI_ENABLE (default 0)
+* MAGICKCORE_QUANTUM_DEPTH (default 0)
+* OPENSHOT_IMAGEMAGICK_COMPATIBILITY (default 0)
+* DISABLE_TESTS (default 0)
+* CMAKE_PREFIX_PATH (`/location/to/missing/library/`)
+* PYTHON_INCLUDE_DIR (`/location/to/python/include/`)
+* PYTHON_LIBRARY (`/location/to/python/lib.a`)
+* PYTHON_FRAMEWORKS (`/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/`)
+* CMAKE_CXX_COMPILER (`/location/to/mingw/g++`)
+* CMAKE_C_COMPILER (`/location/to/mingw/gcc`)
+
+## Obtaining Source Code
+
+The first step in installing libopenshot is to obtain the most recent source code. The source code is available on [GitHub](https://github.com/OpenShot/libopenshot). Use the following command to obtain the latest libopenshot source code.
+
+```
+git clone https://github.com/OpenShot/libopenshot.git
+git clone https://github.com/OpenShot/libopenshot-audio.git
+```
+
+## Folder Structure (libopenshot)
+
+The source code is divided up into the following folders.
+
+* ### build/
+ * This folder needs to be manually created, and is used by cmake to store the temporary build files, such as makefiles, as well as the final binaries (library and test executables).
+
+* ### cmake/
+ * This folder contains custom modules not included by default in cmake, used to find dependency libraries and headers and determine if these libraries are installed.
+
+* ### doc/
+ * This folder contains documentation and related files, such as logos and images required by the doxygen auto-generated documentation.
+
+* ### include/
+ * This folder contains all headers (*.h) used by libopenshot.
+
+* ### src/
+ * This folder contains all source code (*.cpp) used by libopenshot.
+
+* ### tests/
+ * This folder contains all unit test code. Each class has it’s own test file (*.cpp), and uses UnitTest++ macros to keep the test code simple and manageable.
+
+* ### thirdparty/
+ * This folder contains code not written by the OpenShot team. For example, jsoncpp, an open-source JSON parser.
+
+## Linux Build Instructions (libopenshot-audio)
+To compile libopenshot-audio, we need to go through a few additional steps to manually build and install it. Launch a terminal and enter:
+
+```
+cd [libopenshot-audio repo folder]
+mkdir build
+cd build
+cmake ../
+make
+make install
+./src/openshot-audio-test-sound (This should play a test sound)
+```
+
+## Linux Build Instructions (libopenshot)
+Run the following commands to compile libopenshot:
+
+```
+cd [libopenshot repo directory]
+mkdir -p build
+cd build
+cmake ../
+make
+make install
+```
+
+For more detailed instructions, please see:
+
+* doc/INSTALL-LINUX.md
+* doc/INSTALL-MAC.md
+* doc/INSTALL-WINDOWS.md
diff --git a/README b/README
deleted file mode 100644
index 8c05f753..00000000
--- a/README
+++ /dev/null
@@ -1,66 +0,0 @@
-####################################################################
- OpenShot Library
-####################################################################
-
-OpenShot Library (libopenshot) is an open-source project dedicated to
-delivering high quality video editing, animation, and playback solutions
-to the world. For more information visit .
-
-####################################################################
- License
-####################################################################
-
-Copyright (c) 2008-2014 OpenShot Studios, LLC
-.
-
-OpenShot Library (libopenshot) is free software: you can redistribute it
-and/or modify it under the terms of the GNU Lesser General Public License
-as published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-OpenShot Library (libopenshot) is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with OpenShot Library. If not, see .
-
-####################################################################
-
- To release a closed-source product which uses libopenshot (i.e. video
- editing and playback), commercial licenses are available: contact
- sales@openshot.org for more information.
-
-
-####################################################################
- Install
-####################################################################
-
-Please see /doc/InstallationGuide.pdf for a very detailed
-Linux, Mac, and Windows compiling instruction guide. An online version
-is also available:
-https://docs.google.com/document/d/1V6nq-IuS9zxqO1-OSt8iTS_cw_HMCpsUNofHLYtUNjM/pub
-
-
-####################################################################
- Documentation
-####################################################################
-
-Documentation is auto-generated by Doxygen, and can be created with
-$ make doc (Also available online: )
-
-
-####################################################################
- Authors
-####################################################################
-
-Please see AUTHORS file for a full list of authors.
-
-
-####################################################################
- www.openshot.org | www.openshotstudios.com
-####################################################################
-
- Copyright (c) 2008-2014 OpenShot Studios, LLC
- .
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..cf69c1cf
--- /dev/null
+++ b/README.md
@@ -0,0 +1,92 @@
+OpenShot Video Library (libopenshot) is a free, open-source C++ library dedicated to
+delivering high quality video editing, animation, and playback solutions to the
+world.
+
+## Build Status
+
+[](https://travis-ci.org/OpenShot/libopenshot) [](https://travis-ci.org/OpenShot/libopenshot-audio)
+
+## Features
+
+* Cross-Platform (Linux, Mac, and Windows)
+* Multi-Layer Compositing
+* Video and Audio Effects (Chroma Key, Color Adjustment, Grayscale, etc…)
+* Animation Curves (Bézier, Linear, Constant)
+* Time Mapping (Curve-based Slow Down, Speed Up, Reverse)
+* Audio Mixing & Resampling (Curve-based)
+* Audio Plug-ins (VST & AU)
+* Audio Drivers (ASIO, WASAPI, DirectSound, CoreAudio, iPhone Audio, ALSA, JACK, and Android)
+* Telecine and Inverse Telecine (Film to TV, TV to Film)
+* Frame Rate Conversions
+* Multi-Processor Support (Performance)
+* Python and Ruby Bindings (All Features Supported)
+* Qt Video Player Included (Ability to display video on any QWidget)
+* Unit Tests (Stability)
+* All FFmpeg Formats and Codecs Supported (Images, Videos, and Audio files)
+* Full Documentation with Examples (Doxygen Generated)
+
+## Install
+
+Detailed instructions for building libopenshot and libopenshot-audio for each OS. These instructions
+are also available in the /docs/ source folder.
+
+ * [Linux](https://github.com/OpenShot/libopenshot/wiki/Linux-Build-Instructions)
+ * [Mac](https://github.com/OpenShot/libopenshot/wiki/Mac-Build-Instructions)
+ * [Windows](https://github.com/OpenShot/libopenshot/wiki/Windows-Build-Instructions)
+
+## Hardware Acceleration
+
+OpenShot now supports experimental hardware acceleration, both for encoding and
+decoding videos. When enabled, this can either speed up those operations or slow
+them down, depending on the power and features supported by your graphics card.
+Please see [doc/HW-ACCELL.md](doc/HW-ACCEL.md) for more information.
+
+## Documentation
+
+Beautiful HTML documentation can be generated using Doxygen.
+```
+make doc
+```
+(Also available online: http://openshot.org/files/libopenshot/)
+
+## Developers
+
+Are you interested in becoming more involved in the development of
+OpenShot? Build exciting new features, fix bugs, make friends, and become a hero!
+Please read the [step-by-step](https://github.com/OpenShot/openshot-qt/wiki/Become-a-Developer)
+instructions for getting source code, configuring dependencies, and building OpenShot.
+
+## Report a bug
+
+You can report a new libopenshot issue directly on GitHub:
+
+https://github.com/OpenShot/libopenshot/issues
+
+## Websites
+
+- https://www.openshot.org/ (Official website and blog)
+- https://github.com/OpenShot/libopenshot/ (source code and issue tracker)
+- https://github.com/OpenShot/libopenshot-audio/ (source code for audio library)
+- https://github.com/OpenShot/openshot-qt/ (source code for Qt client)
+- https://launchpad.net/openshot/
+
+### License
+
+Copyright (c) 2008-2019 OpenShot Studios, LLC.
+
+OpenShot Library (libopenshot) is free software: you can redistribute it
+and/or modify it under the terms of the GNU Lesser General Public License
+as published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+OpenShot Library (libopenshot) is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with OpenShot Library. If not, see http://www.gnu.org/licenses/.
+
+To release a closed-source product which uses libopenshot (i.e. video
+editing and playback), commercial licenses are also available: contact
+sales@openshot.org for more information.
diff --git a/cmake/Modules/FindFFmpeg.cmake b/cmake/Modules/FindFFmpeg.cmake
index 4af6cc93..c4eb7ca3 100644
--- a/cmake/Modules/FindFFmpeg.cmake
+++ b/cmake/Modules/FindFFmpeg.cmake
@@ -1,151 +1,161 @@
-# - Try to find FFMPEG
+# vim: ts=2 sw=2
+# - Try to find the required ffmpeg components(default: AVFORMAT, AVUTIL, AVCODEC)
+#
# Once done this will define
-#
-# FFMPEG_FOUND - system has FFMPEG
-# FFMPEG_INCLUDE_DIR - the include directory
-# FFMPEG_LIBRARY_DIR - the directory containing the libraries
-# FFMPEG_LIBRARIES - Link these to use FFMPEG
-#
-
-# FindAvformat
-FIND_PATH( AVFORMAT_INCLUDE_DIR libavformat/avformat.h
- PATHS /usr/include/
- /usr/include/ffmpeg/
- $ENV{FFMPEGDIR}/include/
- $ENV{FFMPEGDIR}/include/ffmpeg/ )
-
-FIND_LIBRARY( AVFORMAT_LIBRARY avformat avformat-55 avformat-57
- PATHS /usr/lib/
- /usr/lib/ffmpeg/
- $ENV{FFMPEGDIR}/lib/
- $ENV{FFMPEGDIR}/lib/ffmpeg/
- $ENV{FFMPEGDIR}/bin/ )
-
-#FindAvcodec
-FIND_PATH( AVCODEC_INCLUDE_DIR libavcodec/avcodec.h
- PATHS /usr/include/
- /usr/include/ffmpeg/
- $ENV{FFMPEGDIR}/include/
- $ENV{FFMPEGDIR}/include/ffmpeg/ )
-
-FIND_LIBRARY( AVCODEC_LIBRARY avcodec avcodec-55 avcodec-57
- PATHS /usr/lib/
- /usr/lib/ffmpeg/
- $ENV{FFMPEGDIR}/lib/
- $ENV{FFMPEGDIR}/lib/ffmpeg/
- $ENV{FFMPEGDIR}/bin/ )
-
-#FindAvutil
-FIND_PATH( AVUTIL_INCLUDE_DIR libavutil/avutil.h
- PATHS /usr/include/
- /usr/include/ffmpeg/
- $ENV{FFMPEGDIR}/include/
- $ENV{FFMPEGDIR}/include/ffmpeg/ )
-
-FIND_LIBRARY( AVUTIL_LIBRARY avutil avutil-52 avutil-55
- PATHS /usr/lib/
- /usr/lib/ffmpeg/
- $ENV{FFMPEGDIR}/lib/
- $ENV{FFMPEGDIR}/lib/ffmpeg/
- $ENV{FFMPEGDIR}/bin/ )
-
-#FindAvdevice
-FIND_PATH( AVDEVICE_INCLUDE_DIR libavdevice/avdevice.h
- PATHS /usr/include/
- /usr/include/ffmpeg/
- $ENV{FFMPEGDIR}/include/
- $ENV{FFMPEGDIR}/include/ffmpeg/ )
-
-FIND_LIBRARY( AVDEVICE_LIBRARY avdevice avdevice-55 avdevice-56
- PATHS /usr/lib/
- /usr/lib/ffmpeg/
- $ENV{FFMPEGDIR}/lib/
- $ENV{FFMPEGDIR}/lib/ffmpeg/
- $ENV{FFMPEGDIR}/bin/ )
-
-#FindSwscale
-FIND_PATH( SWSCALE_INCLUDE_DIR libswscale/swscale.h
- PATHS /usr/include/
- /usr/include/ffmpeg/
- $ENV{FFMPEGDIR}/include/
- $ENV{FFMPEGDIR}/include/ffmpeg/ )
-
-FIND_LIBRARY( SWSCALE_LIBRARY swscale swscale-2 swscale-4
- PATHS /usr/lib/
- /usr/lib/ffmpeg/
- $ENV{FFMPEGDIR}/lib/
- $ENV{FFMPEGDIR}/lib/ffmpeg/
- $ENV{FFMPEGDIR}/bin/ )
-
-#FindAvresample
-FIND_PATH( AVRESAMPLE_INCLUDE_DIR libavresample/avresample.h
- PATHS /usr/include/
- /usr/include/ffmpeg/
- $ENV{FFMPEGDIR}/include/
- $ENV{FFMPEGDIR}/include/ffmpeg/ )
-
-FIND_LIBRARY( AVRESAMPLE_LIBRARY avresample avresample-2 avresample-3
- PATHS /usr/lib/
- /usr/lib/ffmpeg/
- $ENV{FFMPEGDIR}/lib/
- $ENV{FFMPEGDIR}/lib/ffmpeg/
- $ENV{FFMPEGDIR}/bin/ )
-
-SET( FFMPEG_FOUND FALSE )
-
-IF ( AVFORMAT_INCLUDE_DIR AND AVFORMAT_LIBRARY )
- SET ( AVFORMAT_FOUND TRUE )
-ENDIF ( AVFORMAT_INCLUDE_DIR AND AVFORMAT_LIBRARY )
-
-IF ( AVCODEC_INCLUDE_DIR AND AVCODEC_LIBRARY )
- SET ( AVCODEC_FOUND TRUE)
-ENDIF ( AVCODEC_INCLUDE_DIR AND AVCODEC_LIBRARY )
-
-IF ( AVUTIL_INCLUDE_DIR AND AVUTIL_LIBRARY )
- SET ( AVUTIL_FOUND TRUE )
-ENDIF ( AVUTIL_INCLUDE_DIR AND AVUTIL_LIBRARY )
-
-IF ( AVDEVICE_INCLUDE_DIR AND AVDEVICE_LIBRARY )
- SET ( AVDEVICE_FOUND TRUE )
-ENDIF ( AVDEVICE_INCLUDE_DIR AND AVDEVICE_LIBRARY )
-
-IF ( SWSCALE_INCLUDE_DIR AND SWSCALE_LIBRARY )
- SET ( SWSCALE_FOUND TRUE )
-ENDIF ( SWSCALE_INCLUDE_DIR AND SWSCALE_LIBRARY )
-
-IF ( AVRESAMPLE_INCLUDE_DIR AND AVRESAMPLE_LIBRARY )
- SET ( AVRESAMPLE_FOUND TRUE )
-ENDIF ( AVRESAMPLE_INCLUDE_DIR AND AVRESAMPLE_LIBRARY )
-
-IF ( AVFORMAT_INCLUDE_DIR OR AVCODEC_INCLUDE_DIR OR AVUTIL_INCLUDE_DIR OR AVDEVICE_FOUND OR SWSCALE_FOUND OR AVRESAMPLE_FOUND )
-
- SET ( FFMPEG_FOUND TRUE )
-
- SET ( FFMPEG_INCLUDE_DIR
- ${AVFORMAT_INCLUDE_DIR}
- ${AVCODEC_INCLUDE_DIR}
- ${AVUTIL_INCLUDE_DIR}
- ${AVDEVICE_INCLUDE_DIR}
- ${SWSCALE_INCLUDE_DIR}
- ${AVRESAMPLE_INCLUDE_DIR} )
-
- SET ( FFMPEG_LIBRARIES
- ${AVFORMAT_LIBRARY}
- ${AVCODEC_LIBRARY}
- ${AVUTIL_LIBRARY}
- ${AVDEVICE_LIBRARY}
- ${SWSCALE_LIBRARY}
- ${AVRESAMPLE_LIBRARY} )
-
-ENDIF ( AVFORMAT_INCLUDE_DIR OR AVCODEC_INCLUDE_DIR OR AVUTIL_INCLUDE_DIR OR AVDEVICE_FOUND OR SWSCALE_FOUND OR AVRESAMPLE_FOUND )
-
-MARK_AS_ADVANCED(
- FFMPEG_LIBRARY_DIR
- FFMPEG_INCLUDE_DIR
-)
+# FFMPEG_FOUND - System has the all required components.
+# FFMPEG_INCLUDE_DIRS - Include directory necessary for using the required components headers.
+# FFMPEG_LIBRARIES - Link these to use the required ffmpeg components.
+# FFMPEG_DEFINITIONS - Compiler switches required for using the required ffmpeg components.
+#
+# For each of the components it will additionally set.
+# - AVCODEC
+# - AVDEVICE
+# - AVFORMAT
+# - AVFILTER
+# - AVUTIL
+# - POSTPROC
+# - SWSCALE
+# - SWRESAMPLE
+# - AVRESAMPLE
+# the following variables will be defined
+# _FOUND - System has
+# _INCLUDE_DIRS - Include directory necessary for using the headers
+# _LIBRARIES - Link these to use
+# _DEFINITIONS - Compiler switches required for using
+# _VERSION - The components version
+#
+# Copyright (c) 2006, Matthias Kretz,
+# Copyright (c) 2008, Alexander Neundorf,
+# Copyright (c) 2011, Michael Jansen,
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
include(FindPackageHandleStandardArgs)
-# handle the QUIETLY and REQUIRED arguments and set FFMPEG_FOUND to TRUE
-# if all listed variables are TRUE
-find_package_handle_standard_args(FFMPEG DEFAULT_MSG
- FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIR)
+
+# The default components were taken from a survey over other FindFFMPEG.cmake files
+if (NOT FFmpeg_FIND_COMPONENTS)
+ set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL)
+endif ()
+
+#
+### Macro: set_component_found
+#
+# Marks the given component as found if both *_LIBRARIES AND *_INCLUDE_DIRS is present.
+#
+macro(set_component_found _component )
+ if (${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS)
+ # message(STATUS " - ${_component} found.")
+ set(${_component}_FOUND TRUE)
+ else ()
+ # message(STATUS " - ${_component} not found.")
+ endif ()
+endmacro()
+
+#
+### Macro: find_component
+#
+# Checks for the given component by invoking pkgconfig and then looking up the libraries and
+# include directories.
+#
+macro(find_component _component _pkgconfig _library _header)
+
+ if (NOT WIN32)
+ # use pkg-config to get the directories and then use these values
+ # in the FIND_PATH() and FIND_LIBRARY() calls
+ find_package(PkgConfig)
+ if (PKG_CONFIG_FOUND)
+ pkg_check_modules(PC_${_component} ${_pkgconfig})
+ endif ()
+ endif (NOT WIN32)
+
+ find_path(${_component}_INCLUDE_DIRS ${_header}
+ HINTS
+ /opt/
+ /opt/include/
+ ${PC_LIB${_component}_INCLUDEDIR}
+ ${PC_LIB${_component}_INCLUDE_DIRS}
+ $ENV{FFMPEGDIR}/include/
+ $ENV{FFMPEGDIR}/include/ffmpeg/
+ PATH_SUFFIXES
+ ffmpeg
+ )
+
+ find_library(${_component}_LIBRARIES NAMES ${_library}
+ HINTS
+ ${PC_LIB${_component}_LIBDIR}
+ ${PC_LIB${_component}_LIBRARY_DIRS}
+ $ENV{FFMPEGDIR}/lib/
+ $ENV{FFMPEGDIR}/lib/ffmpeg/
+ $ENV{FFMPEGDIR}/bin/
+ )
+
+ set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.")
+ set(${_component}_VERSION ${PC_${_component}_VERSION} CACHE STRING "The ${_component} version number.")
+
+ set_component_found(${_component})
+
+ mark_as_advanced(
+ ${_component}_INCLUDE_DIRS
+ ${_component}_LIBRARIES
+ ${_component}_DEFINITIONS
+ ${_component}_VERSION)
+
+endmacro()
+
+
+# Check for cached results. If there are skip the costly part.
+if (NOT FFMPEG_LIBRARIES)
+
+ # Check for all possible component.
+ find_component(AVCODEC libavcodec avcodec libavcodec/avcodec.h)
+ find_component(AVFORMAT libavformat avformat libavformat/avformat.h)
+ find_component(AVDEVICE libavdevice avdevice libavdevice/avdevice.h)
+ find_component(AVUTIL libavutil avutil libavutil/avutil.h)
+ find_component(AVFILTER libavfilter avfilter libavfilter/avfilter.h)
+ find_component(SWSCALE libswscale swscale libswscale/swscale.h)
+ find_component(POSTPROC libpostproc postproc libpostproc/postprocess.h)
+ find_component(SWRESAMPLE libswresample swresample libswresample/swresample.h)
+ find_component(AVRESAMPLE libavresample avresample libavresample/avresample.h)
+
+ # Check if the required components were found and add their stuff to the FFMPEG_* vars.
+ foreach (_component ${FFmpeg_FIND_COMPONENTS})
+ if (${_component}_FOUND)
+ # message(STATUS "Required component ${_component} present.")
+ set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${${_component}_LIBRARIES})
+ set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} ${${_component}_DEFINITIONS})
+ list(APPEND FFMPEG_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS})
+ else ()
+ # message(STATUS "Required component ${_component} missing.")
+ endif ()
+ endforeach ()
+
+ # Build the include path with duplicates removed.
+ if (FFMPEG_INCLUDE_DIRS)
+ list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS)
+ endif ()
+
+ # cache the vars.
+ set(FFMPEG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIRS} CACHE STRING "The FFmpeg include directories." FORCE)
+ set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} CACHE STRING "The FFmpeg libraries." FORCE)
+ set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} CACHE STRING "The FFmpeg cflags." FORCE)
+
+ mark_as_advanced(FFMPEG_INCLUDE_DIRS
+ FFMPEG_LIBRARIES
+ FFMPEG_DEFINITIONS)
+
+endif ()
+
+# Now set the noncached _FOUND vars for the components.
+foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE SWRESAMPLE AVRESAMPLE)
+ set_component_found(${_component})
+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 ()
+
+# Give a nice error message if some of the required vars are missing.
+find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${_FFmpeg_REQUIRED_VARS})
diff --git a/cmake/Modules/FindOpenShotAudio.cmake b/cmake/Modules/FindOpenShotAudio.cmake
index 1de4529b..0aeb0e1f 100644
--- a/cmake/Modules/FindOpenShotAudio.cmake
+++ b/cmake/Modules/FindOpenShotAudio.cmake
@@ -7,31 +7,12 @@
message("$ENV{LIBOPENSHOT_AUDIO_DIR}")
-# Find the base directory of juce includes
-find_path(LIBOPENSHOT_AUDIO_BASE_DIR JuceHeader.h
+# Find the libopenshot-audio header files
+find_path(LIBOPENSHOT_AUDIO_INCLUDE_DIR JuceHeader.h
PATHS $ENV{LIBOPENSHOT_AUDIO_DIR}/include/libopenshot-audio/
/usr/include/libopenshot-audio/
/usr/local/include/libopenshot-audio/ )
-# Get a list of all header file paths
-FILE(GLOB_RECURSE JUCE_HEADER_FILES
- ${LIBOPENSHOT_AUDIO_BASE_DIR}/*.h
-)
-
-# Loop through each header file
-FOREACH(HEADER_PATH ${JUCE_HEADER_FILES})
- # Get the directory of each header file
- get_filename_component(HEADER_DIRECTORY ${HEADER_PATH}
- PATH
- )
-
- # Append each directory into the HEADER_DIRECTORIES list
- LIST(APPEND HEADER_DIRECTORIES ${HEADER_DIRECTORY})
-ENDFOREACH(HEADER_PATH)
-
-# Remove duplicates from the header directories list
-LIST(REMOVE_DUPLICATES HEADER_DIRECTORIES)
-
# Find the libopenshot-audio.so (check env var first)
find_library(LIBOPENSHOT_AUDIO_LIBRARY
NAMES libopenshot-audio openshot-audio
@@ -48,9 +29,7 @@ find_library(LIBOPENSHOT_AUDIO_LIBRARY
set(LIBOPENSHOT_AUDIO_LIBRARIES ${LIBOPENSHOT_AUDIO_LIBRARY})
set(LIBOPENSHOT_AUDIO_LIBRARY ${LIBOPENSHOT_AUDIO_LIBRARIES})
-# Seems to work fine with just the base dir (rather than all the actual include folders)
-set(LIBOPENSHOT_AUDIO_INCLUDE_DIR ${LIBOPENSHOT_AUDIO_BASE_DIR} )
-set(LIBOPENSHOT_AUDIO_INCLUDE_DIRS ${LIBOPENSHOT_AUDIO_BASE_DIR} )
+set(LIBOPENSHOT_AUDIO_INCLUDE_DIRS ${LIBOPENSHOT_AUDIO_INCLUDE_DIR} )
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBOPENSHOT_AUDIO_FOUND to TRUE
diff --git a/cmake/Modules/FindRESVG.cmake b/cmake/Modules/FindRESVG.cmake
new file mode 100644
index 00000000..b03a0667
--- /dev/null
+++ b/cmake/Modules/FindRESVG.cmake
@@ -0,0 +1,28 @@
+# - Try to find RESVG
+# Once done this will define
+# RESVG_FOUND - System has RESVG
+# RESVG_INCLUDE_DIRS - The RESVG include directories
+# RESVG_LIBRARIES - The libraries needed to use RESVG
+find_path ( RESVG_INCLUDE_DIR ResvgQt.h
+ PATHS ${RESVGDIR}/include/resvg
+ $ENV{RESVGDIR}/include/resvg
+ $ENV{RESVGDIR}/include
+ /usr/include/resvg
+ /usr/include
+ /usr/local/include/resvg
+ /usr/local/include )
+
+find_library ( RESVG_LIBRARY NAMES resvg
+ PATHS /usr/lib
+ /usr/local/lib
+ $ENV{RESVGDIR}
+ $ENV{RESVGDIR}/lib )
+
+set ( RESVG_LIBRARIES ${RESVG_LIBRARY} )
+set ( RESVG_INCLUDE_DIRS ${RESVG_INCLUDE_DIR} )
+
+include ( FindPackageHandleStandardArgs )
+# handle the QUIETLY and REQUIRED arguments and set RESVG_FOUND to TRUE
+# if all listed variables are TRUE
+find_package_handle_standard_args ( RESVG "Could NOT find RESVG, using Qt SVG parsing instead" RESVG_LIBRARY RESVG_INCLUDE_DIR )
+mark_as_advanced( RESVG_LIBRARY RESVG_INCLUDE_DIR )
diff --git a/cmake/Modules/UseDoxygen.cmake b/cmake/Modules/UseDoxygen.cmake
index 48480e4d..807dbac6 100644
--- a/cmake/Modules/UseDoxygen.cmake
+++ b/cmake/Modules/UseDoxygen.cmake
@@ -1,4 +1,30 @@
-# - Run Doxygen
+# Redistribution and use is allowed according to the terms of the New
+# BSD license:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+
+# - Run Doxygen
#
# Adds a doxygen target that runs doxygen to generate the html
# and optionally the LaTeX API documentation.
@@ -48,7 +74,6 @@
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
-# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
macro(usedoxygen_set_default name value type docstring)
@@ -80,12 +105,18 @@ if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
STRING "Additional source files/directories separated by space")
set(DOXYFILE_SOURE_DIRS "\"${DOXYFILE_SOURCE_DIR}\" ${DOXYFILE_EXTRA_SOURCES}")
- usedoxygen_set_default(DOXYFILE_LATEX YES BOOL "Generate LaTeX API documentation" OFF)
+ usedoxygen_set_default(DOXYFILE_LATEX OFF BOOL "Generate LaTeX API documentation")
usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex" STRING "LaTex output directory")
mark_as_advanced(DOXYFILE_OUTPUT_DIR DOXYFILE_HTML_DIR DOXYFILE_LATEX_DIR
DOXYFILE_SOURCE_DIR DOXYFILE_EXTRA_SOURCE_DIRS DOXYFILE_IN)
+ ## Dot
+ usedoxygen_set_default(DOXYFILE_USE_DOT ON BOOL "Use dot (part of graphviz) to generate graphs")
+ set(DOXYFILE_DOT "NO")
+ if(DOXYFILE_USE_DOT AND DOXYGEN_DOT_EXECUTABLE)
+ set(DOXYFILE_DOT "YES")
+ endif()
set_property(DIRECTORY
APPEND PROPERTY
@@ -100,13 +131,12 @@ if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
## LaTeX
set(DOXYFILE_PDFLATEX "NO")
- set(DOXYFILE_DOT "NO")
set_property(DIRECTORY APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
- if(DOXYFILE_LATEX STREQUAL "ON")
+ if(DOXYFILE_LATEX)
set(DOXYFILE_GENERATE_LATEX "YES")
find_package(LATEX)
find_program(DOXYFILE_MAKE make)
@@ -115,9 +145,6 @@ if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
if(PDFLATEX_COMPILER)
set(DOXYFILE_PDFLATEX "YES")
endif()
- if(DOXYGEN_DOT_EXECUTABLE)
- set(DOXYFILE_DOT "YES")
- endif()
add_custom_command(TARGET doxygen
POST_BUILD
@@ -134,7 +161,9 @@ if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
configure_file("${DOXYFILE_IN}" "${DOXYFILE}" @ONLY)
- get_target_property(DOC_TARGET doc TYPE)
+ if(TARGET doc)
+ get_target_property(DOC_TARGET doc TYPE)
+ endif()
if(NOT DOC_TARGET)
add_custom_target(doc)
endif()
diff --git a/cmake/Windows/README b/cmake/Windows/README
deleted file mode 100644
index 44dd56d7..00000000
--- a/cmake/Windows/README
+++ /dev/null
@@ -1,85 +0,0 @@
-####################################################################
- Install Dependencies for Windows
-####################################################################
-
-Most Windows dependencies needed for libopenshot-audio, libopenshot, and openshot-qt
-can be installed easily with MSYS2 and the pacman package manager. Follow these
-directions to setup a Windows build environment for OpenShot:
-
-####################################################################
-
-1) Install MSYS2 (http://www.msys2.org/)
-
-2) Run MSYS2 command prompt (for example: C:\msys64\msys2_shell.cmd)
-
-3) Append PATH (so MSYS2 can find executables and libraries):
- $ PATH=$PATH:/c/msys64/mingw64/bin:/c/msys64/mingw64/lib (64-bit PATH)
- or
- $ PATH=$PATH:/c/msys32/mingw32/bin:/c/msys32/mingw32/lib (32-bit PATH)
-
-4) Update and upgrade all packages
- $ pacman -Syu
-
-5a) Install the following packages:
-*** for 64-BIT support ***
-
- $ pacman -S --needed base-devel mingw-w64-x86_64-toolchain
- $ pacman -S mingw64/mingw-w64-x86_64-ffmpeg
- $ pacman -S mingw64/mingw-w64-x86_64-python3-pyqt5
- $ pacman -S mingw64/mingw-w64-x86_64-swig
- $ pacman -S mingw64/mingw-w64-x86_64-cmake
- $ pacman -S mingw64/mingw-w64-x86_64-doxygen
- $ pacman -S mingw64/mingw-w64-x86_64-python3-pip
- $ pacman -S mingw32/mingw-w64-i686-zeromq
- $ pacman -S mingw64/mingw-w64-x86_64-python3-pyzmq
- $ pacman -S mingw64/mingw-w64-x86_64-python3-cx_Freeze
- $ pacman -S git
-
- Install ImageMagick if needed (OPTIONAL and NOT NEEDED)
- $ pacman -S mingw64/mingw-w64-x86_64-imagemagick
-
-5b) Install the following packages:
-*** for 32-BIT support ***
-
- $ pacman -S --needed base-devel mingw32/mingw-w64-i686-toolchain
- $ pacman -S mingw32/mingw-w64-i686-ffmpeg
- $ pacman -S mingw32/mingw-w64-i686-python3-pyqt5
- $ pacman -S mingw32/mingw-w64-i686-swig
- $ pacman -S mingw32/mingw-w64-i686-cmake
- $ pacman -S mingw32/mingw-w64-i686-doxygen
- $ pacman -S mingw32/mingw-w64-i686-python3-pip
- $ pacman -S mingw32/mingw-w64-i686-zeromq
- $ pacman -S mingw32/mingw-w64-i686-python3-pyzmq
- $ pacman -S mingw32/mingw-w64-i686-python3-cx_Freeze
- $ pacman -S git
-
- Install ImageMagick if needed (OPTIONAL and NOT NEEDED)
- $ pacman -S mingw32/mingw-w32-x86_32-imagemagick
-
-6) Install Python PIP Dependencies
- $ pip3 install httplib2
- $ pip3 install slacker
- $ pip3 install tinys3
- $ pip3 install github3.py
- $ pip3 install requests
-
-7) Download Unittest++ (https://github.com/unittest-cpp/unittest-cpp) into /c/home/USER/unittest-cpp-master/
- Configure Unittest++:
- $ cmake -G "MSYS Makefiles" ../ -DCMAKE_MAKE_PROGRAM=mingw32-make -DCMAKE_INSTALL_PREFIX:PATH=/usr
- Build Unittest++
- $ mingw32-make install
-
-8) ZMQ++ Header (This might not be needed anymore)
- NOTE: Download and copy zmq.hpp into the /c/msys64/mingw64/include/ folder
-
-
-####################################################################
- OPTIONAL: Installing ImageMagick on Windows
-####################################################################
-
-If you would rather install ImageMagick from source code yourself, follow these steps:
-
-Step 1) Copy [build-imagemagick.sh and urls.txt] into your local MSYS2 environment
-Step 2) Run MSYS2 Shell
-Step 3) Execute this command
- $ ./build-imagemagick.sh
\ No newline at end of file
diff --git a/cmake/Windows/build-imagemagick.sh b/cmake/Windows/build-imagemagick.sh
deleted file mode 100644
index b3814dd9..00000000
--- a/cmake/Windows/build-imagemagick.sh
+++ /dev/null
@@ -1,274 +0,0 @@
-#!/bin/bash
-# xml2 build ok but failed test
-# libfpx build error
-
-function ised() {
- IN=$1
- shift
- tmp=$RANDOM.$$
- <$IN sed "$@" >$tmp && cat $tmp > $IN
- rm $tmp
-}
-
-function ask() {
- read -p "${1:-Are you sure?]} [Y/n] " response
- case $response in
- y|Y|"")
- true;;
- *)
- false;;
- esac
-}
-
-function download() {
- while IFS=\; read url md5 <&3; do
- fileName=${url##*/}
-
- echo "Downloading ${fileName}..."
- while true; do
- if [[ ! -e $fileName ]]; then
- wget ${url} -O ${fileName}
- else
- echo "File exists!"
- fi
-
- localMd5=$(md5sum ${fileName} | cut -d\ -f1)
-
- if [[ ${localMd5} != ${md5} ]]; then
- ask "Checksum failed. Do you want to download this file again? [Y/n] "
- if [[ $? -ne 0 ]]; then
- exit 1
- fi
- rm ${fileName}
- else
- break
- fi
- done
- done 3< urls.txt
-}
-
-function extract() {
- file=$1
- if [[ ! -e ${file} ]]; then
- return
- fi
-
- case $file in
- *.tar.gz)
- tar xzf $file
- ;;
- *.tar.xz|*.tar.lzma)
- tar xJf $file
- ;;
- *.tar.bz2)
- tar xjf $file
- ;;
- *)
- "Don't know how to extract $file"
- esac
-}
-
-function isLibsInstalled() {
- libs="$@"
- notfound=false
- for l in "${libs}"; do
- ld -L/usr/local/lib -l"${l}" 2>/dev/null
- if [[ $? -ne 0 ]]; then
- notfound=true
- fi
- done
-
- ! ${notfound}
-}
-
-function isDirExists() {
- dir="$@"
- found=false
- for d in ${dir}; do
- if [[ -d "${d}" ]]; then
- found=true
- break
- fi
- done
-
- ${found}
-}
-
-function extractIfNeeded() {
- file=$1
- isDirExists ${file%%-*}-*
- if [[ $? -ne 0 ]]; then
- echo "Extracting $file"
- extract $file
- fi
-}
-
-function buildbzip2() {
- if isLibsInstalled "bz2"; then
- if ask "Found bzip2 installed. Do you want to reinstall it?"; then :
- else
- return 0
- fi
- fi
-
- extractIfNeeded bzip2-*.tar.lzma
-
- cd bzip2-*/
- tar xzf bzip2-1.0.6.tar.gz
- tar xzf cygming-autotools-buildfiles.tar.gz
- cd bzip2-*/
- autoconf
- mkdir ../build
- cd ../build
- ../bzip2-*/configure
- make
- make install
- cd ../..
-}
-
-function buildzlib() {
- if isLibsInstalled "z"; then
- if ask "Found zlib installed. Do you want to reinstall it?"; then :
- else
- return 0
- fi
- fi
-
- extractIfNeeded zlib-*.tar.xz
-
- cd zlib-*/
- INCLUDE_PATH=/usr/local/include LIBRARY_PATH=/usr/local/lib BINARY_PATH=/usr/local/bin make install -f win32/Makefile.gcc SHARED_MODE=1
- cd ..
-}
-
-function buildlibxml2() {
- if isLibsInstalled "xml2"; then
- if ask "Found libxml2 installed. Do you want to reinstall it?"; then :
- else
- return 0
- fi
- fi
- extractIfNeeded libxml2-*.tar.gz
- cd libxml2-*/win32/
- ised configure.js 's/dirSep = "\\\\";/dirSep = "\/";/'
- cscript.exe configure.js compiler=mingw prefix=/usr/local
- # ised ../dict.c '/typedef.*uint32_t;$/d'
- ised Makefile.mingw 's/cmd.exe \/C "\?if not exist \(.*\) mkdir \1"\?/mkdir -p \1/'
- ised Makefile.mingw 's/cmd.exe \/C "copy\(.*\)"/cp\1/'
- ised Makefile.mingw '/cp/{y/\\/\//;}'
- ised Makefile.mingw '/PREFIX/{y/\\/\//;}'
- make -f Makefile.mingw
- make -f Makefile.mingw install
- cd ../../
-}
-
-function buildlibpng() {
- if isLibsInstalled "png"; then
- if ask "Found libpng installed. Do you want to reinstall it?"; then :
- else
- return 0
- fi
- fi
-
- extractIfNeeded libpng-*.tar.xz
-
- cd libpng-*/
- make -f scripts/makefile.msys
- make install -f scripts/makefile.msys
- cd ..
-}
-
-function buildjpegsrc() {
- if isLibsInstalled "jpeg"; then
- if ask "Found jpegsrc installed. Do you want to reinstall it?"; then :
- else
- return 0
- fi
- fi
-
- extract jpegsrc*.tar.gz
-
- cd jpeg-*/
- ./configure
- make
- make install
- cd ..
-}
-
-function buildfreetype() {
- if isLibsInstalled "freetype"; then
- if ask "Found freetype installed. Do you want to reinstall it?"; then :
- else
- return 0
- fi
- fi
- extract freetype*.tar.bz2
-
- INCLUDE_PATH=/usr/local/include
- LIBRARY_PATH=/usr/local/lib
- BINARY_PATH=/usr/local/bin
- cd freetype-*/
- ./configure
- make
- make install
- cd ..
-}
-
-function buildlibwmf() {
- if isLibsInstalled "wmf"; then
- if ask "Found libwmf installed. Do you want to reinstall it?"; then :
- else
- return 0
- fi
- fi
- extract libwmf*.tar.gz
-
- cd libwmf-*/
- ./configure CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib"
- make
- make install
- cd ..
-}
-
-function buildlibwebp() {
- if isLibsInstalled "webp"; then
- if ask "Found libwebp installed. Do you want to reinstall it?"; then :
- else
- return 0
- fi
- fi
- extract libwebp*.tar.gz
-
- cd libwebp-*/
- ./configure CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib"
- make
- make install
- cd ..
-}
-
-function buildDelegate() {
- delegates="bzip2 zlib libxml2 libpng jpegsrc freetype libwmf libwebp"
- for d in ${delegates}; do
- echo "**********************************************************"
- echo "Building $d"
- build${d}
- done
-}
-
-function build() {
- extractIfNeeded ImageMagick-*.tar.xz
-
- local oldPwd=$(pwd -L)
- cd ImageMagick-*/
- # patch configure
- #sed -i 's/${GDI32_LIBS}x" !=/${GDI32_LIBS} ==/' configure
- ised configure 's/${GDI32_LIBS}x" !=/${GDI32_LIBS} ==/'
- ./configure --enable-shared --disable-static --enable-delegate-build --without-modules CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib"
- make
- make install
- cd ${oldPwd}
-}
-
-download
-buildDelegate
-build
diff --git a/cmake/Windows/urls.txt b/cmake/Windows/urls.txt
deleted file mode 100644
index 0a45d8af..00000000
--- a/cmake/Windows/urls.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-ftp://ftp.imagemagick.org/pub/ImageMagick/releases/ImageMagick-6.8.8-10.tar.xz;ab9b397c1d4798a9f6ae6cc94aa292fe
-ftp://ftp.imagemagick.org/pub/ImageMagick/delegates/libpng-1.6.20.tar.xz;3968acb7c66ef81a9dab867f35d0eb4b
-ftp://ftp.imagemagick.org/pub/ImageMagick/delegates/libwebp-0.4.4.tar.gz;b737062cf688e502b940b460ddc3015f
-ftp://ftp.imagemagick.org/pub/ImageMagick/delegates/libwmf-0.2.8.4.tar.gz;d1177739bf1ceb07f57421f0cee191e0
-ftp://ftp.imagemagick.org/pub/ImageMagick/delegates/libxml2-2.9.3.tar.gz;daece17e045f1c107610e137ab50c179
-ftp://ftp.imagemagick.org/pub/ImageMagick/delegates/zlib-1.2.8.tar.xz;28f1205d8dd2001f26fec1e8c2cebe37
-ftp://ftp.imagemagick.org/pub/ImageMagick/delegates/freetype-2.6.2.tar.bz2;86109d0c998787d81ac582bad9adf82e
-http://ncu.dl.sourceforge.net/project/mingw/MinGW/Extension/bzip2/bzip2-1.0.6-4/bzip2-1.0.6-4-mingw32-src.tar.lzma;2a25de4331d1e6e1458d8632dff55fad
-ftp://ftp.imagemagick.org/pub/ImageMagick/delegates/libfpx-1.3.1-4.tar.xz;65e2cf8dcf230ad0b90aead35553bbda
-ftp://ftp.imagemagick.org/pub/ImageMagick/delegates/jpegsrc.v9a.tar.gz;3353992aecaee1805ef4109aadd433e7
diff --git a/doc/HW-ACCEL.md b/doc/HW-ACCEL.md
new file mode 100644
index 00000000..b8ee7b4e
--- /dev/null
+++ b/doc/HW-ACCEL.md
@@ -0,0 +1,134 @@
+## Hardware Acceleration
+
+OpenShot now has experimental support for hardware acceleration, which uses 1 (or more)
+graphics cards to offload some of the work for both decoding and encoding. This is
+very new and experimental (as of May 2019), but we look forward to "accelerating"
+our support for this in the future!
+
+The following table summarizes our current level of support:
+
+| | Linux Decode | Linux Encode | Mac Decode | Mac Encode |Windows Decode| Windows Encode | Notes |
+|--------------------|------------------------|----------------------|------------------|----------------|--------------|------------------|------------------|
+| VA-API | :heavy_check_mark: | :heavy_check_mark: | - | - | - | - | *Linux Only* |
+| VDPAU | :heavy_check_mark:(+) |:white_check_mark:(++)| - | - | - | - | *Linux Only* |
+| CUDA (NVDEC/NVENC) | :x:(+++) | :heavy_check_mark: | - | - | - |:heavy_check_mark:| *Cross Platform* |
+| VideoToolBox | - | - |:heavy_check_mark:| :x:(++++) | - | - | *Mac Only* |
+| DXVA2 | - | - | - | - | :x:(+++) | - | *Windows Only* |
+| D3D11VA | - | - | - | - | :x:(+++) | - | *Windows Only* |
+| QSV | :x:(+++) | :x: | :x: | :x: | :x: | :x: | *Cross Platform* |
+
+* *(+) VDPAU for some reason needs a card number one higher than it really is*
+* *(++) VDPAU is a decoder only.*
+* *(+++) Green frames (pixel data not correctly tranferred back to system memory)*
+* *(++++) Crashes and burns*
+
+## Supported FFmpeg Versions
+
+* HW accel is supported from FFmpeg version 3.2 (3.3 for nVidia drivers)
+* HW accel was removed for nVidia drivers in Ubuntu for FFmpeg 4+
+
+**Notice:** The FFmpeg versions of Ubuntu and PPAs for Ubuntu show the
+same behaviour. FFmpeg 3 has working nVidia hardware acceleration while
+FFmpeg 4+ has no support for nVidia hardware acceleration
+included.
+
+## OpenShot Settings
+
+The following settings are use by libopenshot to enable, disable, and control
+the various hardware acceleration features.
+
+```
+/// Use video codec for faster video decoding (if supported)
+int HARDWARE_DECODER = 0;
+
+/* 0 - No acceleration
+ 1 - Linux VA-API
+ 2 - nVidia NVDEC
+ 3 - Windows D3D9
+ 4 - Windows D3D11
+ 5 - MacOS / VideoToolBox
+ 6 - Linux VDPAU
+ 7 - Intel QSV */
+
+/// Number of threads of OpenMP
+int OMP_THREADS = 12;
+
+/// Number of threads that FFmpeg uses
+int FF_THREADS = 8;
+
+/// Maximum rows that hardware decode can handle
+int DE_LIMIT_HEIGHT_MAX = 1100;
+
+/// Maximum columns that hardware decode can handle
+int DE_LIMIT_WIDTH_MAX = 1950;
+
+/// Which GPU to use to decode (0 is the first, LINUX ONLY)
+int HW_DE_DEVICE_SET = 0;
+
+/// Which GPU to use to encode (0 is the first, LINUX ONLY)
+int HW_EN_DEVICE_SET = 0;
+```
+
+## Libva / VA-API (Video Acceleration API)
+
+The correct version of libva is needed (libva in Ubuntu 16.04 or libva2
+in Ubuntu 18.04) for the AppImage to work with hardware acceleration.
+An AppImage that works on both systems (supporting libva and libva2),
+might be possible when no libva is included in the AppImage.
+
+* vaapi is working for intel and AMD
+* vaapi is working for decode only for nouveau
+* nVidia driver is working for export only
+
+## AMD Graphics Cards (RadeonOpenCompute/ROCm)
+
+Decoding and encoding on the (AMD) GPU is possible with the default drivers.
+On systems where ROCm is installed and run a future use for GPU acceleration
+of effects could be implemented (contributions welcome).
+
+## Multiple Graphics Cards
+
+If the computer has multiple graphics cards installed, you can choose which
+should be used by libopenshot. Also, you can optionally use one card for
+decoding and the other for encoding (if both cards support acceleration).
+This is currently only supported on Linux, due to the device name FFmpeg
+expects (i.e. **/dev/dri/render128**). Contributions welcome if anyone can
+determine what string format to pass for Windows and Mac.
+
+## Help Us Improve Hardware Support
+
+This information might be wrong, and we would love to continue improving
+our support for hardware acceleration in OpenShot. Please help us update
+this document if you find an error or discover new and/or useful information.
+
+**FFmpeg 4 + nVidia** The manual at:
+https://www.tal.org/tutorials/ffmpeg_nvidia_encode
+works pretty well. We could compile and install a version of FFmpeg 4.1.3
+on Mint 19.1 that supports the GPU on nVidia cards. A version of openshot
+with hardware support using these libraries could use the nVidia GPU.
+
+**BUG:** Hardware supported decoding still has some bugs (as you can see from
+the chart above). Also, the speed gains with decoding are not as great
+as with encoding. Currently, if hardware decoding fails, there is no
+fallback (you either get green frames or an "invalid file" error in OpenShot).
+This needs to be improved to successfully fall-back to software decoding.
+
+**Needed:**
+ * A way to get options and limits of the GPU, such as
+ supported dimensions (width and height).
+ * A way to list the actual Graphic Cards available to FFmpeg (for the
+ user to choose which card for decoding and encoding, as opposed
+ to "Graphics Card X")
+
+**Further improvement:** Right now the frame can be decoded on the GPU, but the
+frame is then copied to CPU memory for modifications. It is then copied back to
+GPU memory for encoding. Using the GPU for both decoding and modifications
+will make it possible to do away with these two copies. A possible solution would
+be to use Vulkan compute which would be available on Linux and Windows natively
+and on MacOS via MoltenVK.
+
+## Credit
+
+A big thanks to Peter M (https://github.com/eisneinechse) for all his work
+on integrating hardware acceleration into libopenshot! The community thanks
+you for this major contribution!
diff --git a/doc/INSTALL-LINUX.md b/doc/INSTALL-LINUX.md
new file mode 100644
index 00000000..2a0bbe1b
--- /dev/null
+++ b/doc/INSTALL-LINUX.md
@@ -0,0 +1,227 @@
+# Building libopenshot for Linux
+
+## Getting Started
+
+The best way to get started with libopenshot, is to learn about our build system, obtain all the source code,
+install a development IDE and tools, and better understand our dependencies. So, please read through the
+following sections, and follow the instructions. And keep in mind, that your computer is likely different
+than the one used when writing these instructions. Your file paths and versions of applications might be
+slightly different, so keep an eye out for subtle file path differences in the commands you type.
+
+## Build Tools
+
+CMake is the backbone of our build system. It is a cross-platform build system, which checks for
+dependencies, locates header files and libraries, generates makefiles, and supports the cross-platform
+compiling of libopenshot and libopenshot-audio. CMake uses an out-of-source build concept, where
+all temporary build files, such as makefiles, object files, and even the final binaries, are created
+outside of the source code folder, inside a /build/ sub-folder. This prevents the build process
+from cluttering up the source code. These instructions have only been tested with the GNU compiler
+(including MSYS2/MinGW for Windows).
+
+## Dependencies
+
+The following libraries are required to build libopenshot. Instructions on how to install these
+dependencies vary for each operating system. Libraries and Executables have been labeled in the
+list below to help distinguish between them.
+
+### FFmpeg (libavformat, libavcodec, libavutil, libavdevice, libavresample, libswscale)
+ * http://www.ffmpeg.org/ `(Library)`
+ * This library is used to decode and encode video, audio, and image files. It is also used to obtain information about media files, such as frame rate, sample rate, aspect ratio, and other common attributes.
+
+### ImageMagick++ (libMagick++, libMagickWand, libMagickCore)
+ * http://www.imagemagick.org/script/magick++.php `(Library)`
+ * This library is **optional**, and used to decode and encode images.
+
+### OpenShot Audio Library (libopenshot-audio)
+ * https://github.com/OpenShot/libopenshot-audio/ `(Library)`
+ * This library is used to mix, resample, host plug-ins, and play audio. It is based on the JUCE project, which is an outstanding audio library used by many different applications
+
+### Qt 5 (libqt5)
+ * http://www.qt.io/qt5/ `(Library)`
+ * Qt5 is used to display video, store image data, composite images, apply image effects, and many other utility functions, such as file system manipulation, high resolution timers, etc...
+
+### CMake (cmake)
+ * http://www.cmake.org/ `(Executable)`
+ * This executable is used to automate the generation of Makefiles, check for dependencies, and is the backbone of libopenshot’s cross-platform build process.
+
+### SWIG (swig)
+ * http://www.swig.org/ `(Executable)`
+ * This executable is used to generate the Python and Ruby bindings for libopenshot. It is a simple and powerful wrapper for C++ libraries, and supports many languages.
+
+### Python 3 (libpython)
+ * http://www.python.org/ `(Executable and Library)`
+ * This library is used by swig to create the Python (version 3+) bindings for libopenshot. This is also the official language used by OpenShot Video Editor (a graphical interface to libopenshot).
+
+### Doxygen (doxygen)
+ * http://www.stack.nl/~dimitri/doxygen/ `(Executable)`
+ * This executable is used to auto-generate the documentation used by libopenshot.
+
+### UnitTest++ (libunittest++)
+ * https://github.com/unittest-cpp/ `(Library)`
+ * This library is used to execute unit tests for libopenshot. It contains many macros used to keep our unit testing code very clean and simple.
+
+### ZeroMQ (libzmq)
+ * http://zeromq.org/ `(Library)`
+ * This library is used to communicate between libopenshot and other applications (publisher / subscriber). Primarily used to send debug data from libopenshot.
+
+### OpenMP (-fopenmp)
+ * http://openmp.org/wp/ `(Compiler Flag)`
+ * If your compiler supports this flag (GCC, Clang, and most other compilers), it provides libopenshot with easy methods of using parallel programming techniques to improve performance and take advantage of multi-core processors.
+
+
+## CMake Flags (Optional)
+There are many different build flags that can be passed to cmake to adjust how libopenshot is
+compiled. Some of these flags might be required when compiling on certain OSes, just depending
+on how your build environment is setup. To add a build flag, follow this general syntax:
+`cmake -DMAGICKCORE_HDRI_ENABLE=1 -DENABLE_TESTS=1 ../`
+
+* MAGICKCORE_HDRI_ENABLE (default 0)
+* MAGICKCORE_QUANTUM_DEPTH (default 0)
+* OPENSHOT_IMAGEMAGICK_COMPATIBILITY (default 0)
+* DISABLE_TESTS (default 0)
+* CMAKE_PREFIX_PATH (`/location/to/missing/library/`)
+* PYTHON_INCLUDE_DIR (`/location/to/python/include/`)
+* PYTHON_LIBRARY (`/location/to/python/lib.a`)
+* PYTHON_FRAMEWORKS (`/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/`)
+* CMAKE_CXX_COMPILER (`/location/to/mingw/g++`)
+* CMAKE_C_COMPILER (`/location/to/mingw/gcc`)
+
+## Obtaining Source Code
+
+The first step in installing libopenshot is to obtain the most recent source code. The source code is
+available on [GitHub](https://github.com/OpenShot/libopenshot). Use the following command
+to obtain the latest libopenshot source code.
+
+```
+git clone https://github.com/OpenShot/libopenshot.git
+git clone https://github.com/OpenShot/libopenshot-audio.git
+```
+
+## Folder Structure (libopenshot)
+
+The source code is divided up into the following folders.
+
+### build/
+ * This folder needs to be manually created, and is used by cmake to store the temporary build files, such as makefiles, as well as the final binaries (library and test executables).
+
+### cmake/
+ * This folder contains custom modules not included by default in cmake, used to find dependency libraries and headers and determine if these libraries are installed.
+
+### doc/
+ * This folder contains documentation and related files, such as logos and images required by the doxygen auto-generated documentation.
+
+### include/
+ * This folder contains all headers (*.h) used by libopenshot.
+
+### src/
+ * This folder contains all source code (*.cpp) used by libopenshot.
+
+### tests/
+ * This folder contains all unit test code. Each class has it’s own test file (*.cpp), and uses UnitTest++ macros to keep the test code simple and manageable.
+
+### thirdparty/
+ * This folder contains code not written by the OpenShot team. For example, jsoncpp, an open-source JSON parser.
+
+## Install Dependencies
+
+In order to actually compile libopenshot, we need to install some dependencies on your system. The easiest
+way to accomplish this is with our Daily PPA. A PPA is an unofficial Ubuntu repository, which has our
+software packages available to download and install.
+
+```
+ sudo add-apt-repository ppa:openshot.developers/libopenshot-daily
+ sudo apt-get update
+ sudo apt-get install openshot-qt \
+ cmake \
+ libx11-dev \
+ libasound2-dev \
+ libavcodec-dev \
+ libavdevice-dev \
+ libavfilter-dev \
+ libavformat-dev \
+ libavresample-dev \
+ libavutil-dev \
+ libfdk-aac-dev \
+ libfreetype6-dev \
+ libjsoncpp-dev \
+ libmagick++-dev \
+ libopenshot-audio-dev \
+ libswscale-dev \
+ libunittest++-dev \
+ libxcursor-dev \
+ libxinerama-dev \
+ libxrandr-dev \
+ libzmq3-dev \
+ pkg-config \
+ python3-dev \
+ qtbase5-dev \
+ qtmultimedia5-dev \
+ swig
+```
+
+## Linux Build Instructions (libopenshot-audio)
+To compile libopenshot-audio, we need to go through a few additional steps to manually build and
+install it. Launch a terminal and enter:
+
+```
+cd [libopenshot-audio repo folder]
+mkdir build
+cd build
+cmake ../
+make
+make install
+./src/openshot-audio-test-sound (This should play a test sound)
+```
+
+## Linux Build Instructions (libopenshot)
+Run the following commands to compile libopenshot:
+
+```
+cd [libopenshot repo directory]
+mkdir -p build
+cd build
+cmake ../
+make
+```
+
+If you are missing any dependencies for libopenshot, you might receive error messages at this point.
+Just install the missing packages (usually with a -dev suffix), and run the above commands again.
+Repeat until no error messages are displayed, and the build process completes. Also, if you manually
+install Qt 5, you might need to specify the location for cmake:
+
+```
+cmake -DCMAKE_PREFIX_PATH=/qt5_path/qt5/5.2.0/ ../
+```
+
+To run all unit tests (and verify everything is working correctly), launch a terminal, and enter:
+
+```
+make test
+```
+
+To auto-generate documentation for libopenshot, launch a terminal, and enter:
+
+```
+make doc
+```
+
+This will use doxygen to generate a folder of HTML files, with all classes and methods documented. The
+folder is located at **build/doc/html/**. Once libopenshot has been successfully built, we need to
+install it (i.e. copy it to the correct folder, so other libraries can find it).
+
+```
+make install
+```
+
+This will copy the binary files to /usr/local/lib/, and the header files to /usr/local/include/openshot/...
+This is where other projects will look for the libopenshot files when building. Python 3 bindings are
+also installed at this point. let's verify the python bindings work:
+
+```
+python3
+>>> import openshot
+```
+
+If no errors are displayed, you have successfully compiled and installed libopenshot on your system.
+Congratulations and be sure to read our wiki on [Becoming an OpenShot Developer](https://github.com/OpenShot/openshot-qt/wiki/Become-a-Developer)!
+Welcome to the OpenShot developer community! We look forward to meeting you!
diff --git a/doc/INSTALL-MAC.md b/doc/INSTALL-MAC.md
new file mode 100644
index 00000000..ac0c7f7c
--- /dev/null
+++ b/doc/INSTALL-MAC.md
@@ -0,0 +1,220 @@
+# Building libopenshot for MacOS
+
+## Getting Started
+
+The best way to get started with libopenshot, is to learn about our build system, obtain all the source code,
+install a development IDE and tools, and better understand our dependencies. So, please read through the
+following sections, and follow the instructions. And keep in mind, that your computer is likely different
+than the one used when writing these instructions. Your file paths and versions of applications might be
+slightly different, so keep an eye out for subtle file path differences in the commands you type.
+
+## Build Tools
+
+CMake is the backbone of our build system. It is a cross-platform build system, which checks for
+dependencies, locates header files and libraries, generates makefiles, and supports the cross-platform
+compiling of libopenshot and libopenshot-audio. CMake uses an out-of-source build concept, where
+all temporary build files, such as makefiles, object files, and even the final binaries, are created
+outside of the source code folder, inside a /build/ sub-folder. This prevents the build process
+from cluttering up the source code. These instructions have only been tested with the GNU compiler
+(including MSYS2/MinGW for Windows).
+
+## Dependencies
+
+The following libraries are required to build libopenshot. Instructions on how to install these
+dependencies vary for each operating system. Libraries and Executables have been labeled in the
+list below to help distinguish between them.
+
+### FFmpeg (libavformat, libavcodec, libavutil, libavdevice, libavresample, libswscale)
+ * http://www.ffmpeg.org/ `(Library)`
+ * This library is used to decode and encode video, audio, and image files. It is also used to obtain information about media files, such as frame rate, sample rate, aspect ratio, and other common attributes.
+
+### ImageMagick++ (libMagick++, libMagickWand, libMagickCore)
+ * http://www.imagemagick.org/script/magick++.php `(Library)`
+ * This library is **optional**, and used to decode and encode images.
+
+### OpenShot Audio Library (libopenshot-audio)
+ * https://github.com/OpenShot/libopenshot-audio/ `(Library)`
+ * This library is used to mix, resample, host plug-ins, and play audio. It is based on the JUCE project, which is an outstanding audio library used by many different applications
+
+### Qt 5 (libqt5)
+ * http://www.qt.io/qt5/ `(Library)`
+ * Qt5 is used to display video, store image data, composite images, apply image effects, and many other utility functions, such as file system manipulation, high resolution timers, etc...
+
+### CMake (cmake)
+ * http://www.cmake.org/ `(Executable)`
+ * This executable is used to automate the generation of Makefiles, check for dependencies, and is the backbone of libopenshot’s cross-platform build process.
+
+### SWIG (swig)
+ * http://www.swig.org/ `(Executable)`
+ * This executable is used to generate the Python and Ruby bindings for libopenshot. It is a simple and powerful wrapper for C++ libraries, and supports many languages.
+
+### Python 3 (libpython)
+ * http://www.python.org/ `(Executable and Library)`
+ * This library is used by swig to create the Python (version 3+) bindings for libopenshot. This is also the official language used by OpenShot Video Editor (a graphical interface to libopenshot).
+
+### Doxygen (doxygen)
+ * http://www.stack.nl/~dimitri/doxygen/ `(Executable)`
+ * This executable is used to auto-generate the documentation used by libopenshot.
+
+### UnitTest++ (libunittest++)
+ * https://github.com/unittest-cpp/ `(Library)`
+ * This library is used to execute unit tests for libopenshot. It contains many macros used to keep our unit testing code very clean and simple.
+
+### ZeroMQ (libzmq)
+ * http://zeromq.org/ `(Library)`
+ * This library is used to communicate between libopenshot and other applications (publisher / subscriber). Primarily used to send debug data from libopenshot.
+
+### OpenMP (-fopenmp)
+ * http://openmp.org/wp/ `(Compiler Flag)`
+ * If your compiler supports this flag (GCC, Clang, and most other compilers), it provides libopenshot with easy methods of using parallel programming techniques to improve performance and take advantage of multi-core processors.
+
+## CMake Flags (Optional)
+There are many different build flags that can be passed to cmake to adjust how libopenshot is compiled.
+Some of these flags might be required when compiling on certain OSes, just depending on how your build
+environment is setup. To add a build flag, follow this general syntax:
+`cmake -DMAGICKCORE_HDRI_ENABLE=1 -DENABLE_TESTS=1 ../`
+
+* MAGICKCORE_HDRI_ENABLE (default 0)
+* MAGICKCORE_QUANTUM_DEPTH (default 0)
+* OPENSHOT_IMAGEMAGICK_COMPATIBILITY (default 0)
+* DISABLE_TESTS (default 0)
+* CMAKE_PREFIX_PATH (`/location/to/missing/library/`)
+* PYTHON_INCLUDE_DIR (`/location/to/python/include/`)
+* PYTHON_LIBRARY (`/location/to/python/lib.a`)
+* PYTHON_FRAMEWORKS (`/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/`)
+* CMAKE_CXX_COMPILER (`/location/to/mingw/g++`)
+* CMAKE_C_COMPILER (`/location/to/mingw/gcc`)
+
+## Obtaining Source Code
+
+The first step in installing libopenshot is to obtain the most recent source code. The source code
+is available on [GitHub](https://github.com/OpenShot/libopenshot). Use the following command to
+obtain the latest libopenshot source code.
+
+```
+git clone https://github.com/OpenShot/libopenshot.git
+git clone https://github.com/OpenShot/libopenshot-audio.git
+```
+
+## Folder Structure (libopenshot)
+
+The source code is divided up into the following folders.
+
+### build/
+ * This folder needs to be manually created, and is used by cmake to store the temporary build files, such as makefiles, as well as the final binaries (library and test executables).
+
+### cmake/
+ * This folder contains custom modules not included by default in cmake, used to find dependency libraries and headers and determine if these libraries are installed.
+
+### doc/
+ * This folder contains documentation and related files, such as logos and images required by the doxygen auto-generated documentation.
+
+### include/
+ * This folder contains all headers (*.h) used by libopenshot.
+
+### src/
+ * This folder contains all source code (*.cpp) used by libopenshot.
+
+### tests/
+ * This folder contains all unit test code. Each class has it’s own test file (*.cpp), and uses UnitTest++ macros to keep the test code simple and manageable.
+
+### thirdparty/
+ * This folder contains code not written by the OpenShot team. For example, jsoncpp, an open-source JSON parser.
+
+## Install Dependencies
+
+In order to actually compile libopenshot and libopenshot-audio, we need to install some dependencies on
+your system. Most packages needed by libopenshot can be installed easily with Homebrew. However, first
+install Xcode with the following options ("UNIX Development", "System Tools", "Command Line Tools", or
+"Command Line Support"). Be sure to refresh your list of Homebrew packages with the “brew update” command.
+
+**NOTE:** Homebrew seems to work much better for most users (compared to MacPorts), so I am going to
+focus on brew for this guide.
+
+Install the following packages using the Homebrew package installer (http://brew.sh/). Pay close attention
+to any warnings or errors during these brew installs. NOTE: You might have some conflicting libraries in
+your /usr/local/ folders, so follow the directions from brew if these are detected.
+
+```
+brew install gcc48 --enable-all-languages
+brew install ffmpeg
+brew install librsvg
+brew install swig
+brew install doxygen
+brew install unittest-cpp --cc=gcc-4.8. You must specify the c++ compiler with the --cc flag to be 4.7 or 4.8.
+brew install qt5
+brew install cmake
+brew install zeromq
+```
+
+## Mac Build Instructions (libopenshot-audio)
+Since libopenshot-audio is not available in a Homebrew or MacPorts package, we need to go through a
+few additional steps to manually build and install it. Launch a terminal and enter:
+
+```
+cd [libopenshot-audio repo folder]
+mkdir build
+cd build
+cmake -d -G "Unix Makefiles" -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang ../ (CLang must be used due to GNU incompatible Objective-C code in some of the Apple frameworks)
+make
+make install
+./src/openshot-audio-test-sound (This should play a test sound)
+```
+
+## Mac Build Instructions (libopenshot)
+Run the following commands to build libopenshot:
+
+```
+$ cd [libopenshot repo folder]
+$ mkdir build
+$ cd build
+$ cmake -G "Unix Makefiles" -DCMAKE_CXX_COMPILER=/usr/local/opt/gcc48/bin/g++-4.8 -DCMAKE_C_COMPILER=/usr/local/opt/gcc48/bin/gcc-4.8 -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.4.2/ -DPYTHON_INCLUDE_DIR=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/include/python3.3m/ -DPYTHON_LIBRARY=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/lib/libpython3.3.dylib -DPython_FRAMEWORKS=/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/ ../ -D"CMAKE_BUILD_TYPE:STRING=Debug"
+```
+
+The extra arguments on the cmake command make sure the compiler will be gcc4.8 and that cmake
+knows where to look for the Qt header files and Python library. Double check these file paths,
+as yours will likely be different.
+
+```
+make
+```
+
+If you are missing any dependencies for libopenshot, you will receive error messages at this point.
+Just install the missing dependencies, and run the above commands again. Repeat until no error
+messages are displayed and the build process completes.
+
+Also, if you are having trouble building, please see the CMake Flags section above, as it might
+provide a solution for finding a missing folder path, missing Python 3 library, etc...
+
+To run all unit tests (and verify everything is working correctly), launch a terminal, and enter:
+
+```
+make test
+```
+
+To auto-generate the documentation for libopenshot, launch a terminal, and enter:
+
+```
+make doc
+```
+
+This will use doxygen to generate a folder of HTML files, with all classes and methods documented.
+The folder is located at build/doc/html/. Once libopenshot has been successfully built, we need
+to install it (i.e. copy it to the correct folder, so other libraries can find it).
+
+```
+make install
+```
+
+This should copy the binary files to /usr/local/lib/, and the header files to /usr/local/include/openshot/...
+This is where other projects will look for the libopenshot files when building. Python 3 bindings are
+also installed at this point. let's verify the python bindings work:
+
+```
+python3 (or python)
+>>> import openshot
+```
+
+If no errors are displayed, you have successfully compiled and installed libopenshot on your
+system. Congratulations and be sure to read our wiki on [Becoming an OpenShot Developer](https://github.com/OpenShot/openshot-qt/wiki/Become-a-Developer)!
+Welcome to the OpenShot developer community! We look forward to meeting you!
diff --git a/doc/INSTALL-WINDOWS.md b/doc/INSTALL-WINDOWS.md
new file mode 100644
index 00000000..2b17569b
--- /dev/null
+++ b/doc/INSTALL-WINDOWS.md
@@ -0,0 +1,331 @@
+# Building libopenshot for Windows
+
+## Getting Started
+
+The best way to get started with libopenshot, is to learn about our build system, obtain all the
+source code, install a development IDE and tools, and better understand our dependencies. So,
+please read through the following sections, and follow the instructions. And keep in mind,
+that your computer is likely different than the one used when writing these instructions.
+Your file paths and versions of applications might be slightly different, so keep an eye out
+for subtle file path differences in the commands you type.
+
+## Build Tools
+
+CMake is the backbone of our build system. It is a cross-platform build system, which
+checks for dependencies, locates header files and libraries, generates makefiles, and
+supports the cross-platform compiling of libopenshot and libopenshot-audio. CMake uses
+an out-of-source build concept, where all temporary build files, such as makefiles,
+object files, and even the final binaries, are created outside of the source code
+folder, inside a /build/ sub-folder. This prevents the build process from cluttering
+up the source code. These instructions have only been tested with the GNU compiler
+(including MSYS2/MinGW for Windows).
+
+## Dependencies
+
+The following libraries are required to build libopenshot. Instructions on how to
+install these dependencies vary for each operating system. Libraries and Executables
+have been labeled in the list below to help distinguish between them.
+
+### FFmpeg (libavformat, libavcodec, libavutil, libavdevice, libavresample, libswscale)
+ * http://www.ffmpeg.org/ `(Library)`
+ * This library is used to decode and encode video, audio, and image files. It is also used to obtain information about media files, such as frame rate, sample rate, aspect ratio, and other common attributes.
+
+### ImageMagick++ (libMagick++, libMagickWand, libMagickCore)
+ * http://www.imagemagick.org/script/magick++.php `(Library)`
+ * This library is **optional**, and used to decode and encode images.
+
+### OpenShot Audio Library (libopenshot-audio)
+ * https://github.com/OpenShot/libopenshot-audio/ `(Library)`
+ * This library is used to mix, resample, host plug-ins, and play audio. It is based on the JUCE project, which is an outstanding audio library used by many different applications
+
+### Qt 5 (libqt5)
+ * http://www.qt.io/qt5/ `(Library)`
+ * Qt5 is used to display video, store image data, composite images, apply image effects, and many other utility functions, such as file system manipulation, high resolution timers, etc...
+
+### CMake (cmake)
+ * http://www.cmake.org/ `(Executable)`
+ * This executable is used to automate the generation of Makefiles, check for dependencies, and is the backbone of libopenshot’s cross-platform build process.
+
+### SWIG (swig)
+ * http://www.swig.org/ `(Executable)`
+ * This executable is used to generate the Python and Ruby bindings for libopenshot. It is a simple and powerful wrapper for C++ libraries, and supports many languages.
+
+### Python 3 (libpython)
+ * http://www.python.org/ `(Executable and Library)`
+ * This library is used by swig to create the Python (version 3+) bindings for libopenshot. This is also the official language used by OpenShot Video Editor (a graphical interface to libopenshot).
+
+### Doxygen (doxygen)
+ * http://www.stack.nl/~dimitri/doxygen/ `(Executable)`
+ * This executable is used to auto-generate the documentation used by libopenshot.
+
+### UnitTest++ (libunittest++)
+ * https://github.com/unittest-cpp/ `(Library)`
+ * This library is used to execute unit tests for libopenshot. It contains many macros used to keep our unit testing code very clean and simple.
+
+### ZeroMQ (libzmq)
+ * http://zeromq.org/ `(Library)`
+ * This library is used to communicate between libopenshot and other applications (publisher / subscriber). Primarily used to send debug data from libopenshot.
+
+### OpenMP (-fopenmp)
+ * http://openmp.org/wp/ `(Compiler Flag)`
+ * If your compiler supports this flag (GCC, Clang, and most other compilers), it provides libopenshot with easy methods of using parallel programming techniques to improve performance and take advantage of multi-core processors.
+
+## CMake Flags (Optional)
+There are many different build flags that can be passed to cmake to adjust how libopenshot
+is compiled. Some of these flags might be required when compiling on certain OSes, just
+depending on how your build environment is setup. To add a build flag, follow this general
+syntax: `cmake -DMAGICKCORE_HDRI_ENABLE=1 -DENABLE_TESTS=1 ../`
+
+* MAGICKCORE_HDRI_ENABLE (default 0)
+* MAGICKCORE_QUANTUM_DEPTH (default 0)
+* OPENSHOT_IMAGEMAGICK_COMPATIBILITY (default 0)
+* DISABLE_TESTS (default 0)
+* CMAKE_PREFIX_PATH (`/location/to/missing/library/`)
+* PYTHON_INCLUDE_DIR (`/location/to/python/include/`)
+* PYTHON_LIBRARY (`/location/to/python/lib.a`)
+* PYTHON_FRAMEWORKS (`/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/`)
+* CMAKE_CXX_COMPILER (`/location/to/mingw/g++`)
+* CMAKE_C_COMPILER (`/location/to/mingw/gcc`)
+
+## Environment Variables
+
+Many environment variables will need to be set during this Windows installation guide.
+The command line will need to be closed and re-launched after any changes to your environment
+variables. Also, dependency libraries will not be found during linking or execution without
+being found in the PATH environment variable. So, if you get errors related to missing
+commands or libraries, double check the PATH variable.
+
+The following environment variables need to be added to your “System Variables”. Be sure to
+check each folder path for accuracy, as your paths will likely be different than this list.
+
+### Example Variables
+
+* DL_DIR (`C:\libdl`)
+* DXSDK_DIR (`C:\Program Files\Microsoft DirectX SDK (June 2010)\`)
+* FFMPEGDIR (`C:\ffmpeg-git-95f163b-win32-dev`)
+* FREETYPE_DIR (`C:\Program Files\GnuWin32`)
+* HOME (`C:\msys\1.0\home`)
+* LIBOPENSHOT_AUDIO_DIR (`C:\Program Files\libopenshot-audio`)
+* QTDIR (`C:\qt5`)
+* SNDFILE_DIR (`C:\Program Files\libsndfile`)
+* UNITTEST_DIR (`C:\UnitTest++`)
+* ZMQDIR (`C:\msys2\usr\local\`)
+* PATH (`The following paths are an example`)
+ * `C:\Qt5\bin; C:\Qt5\MinGW\bin\; C:\msys\1.0\local\lib; C:\Program Files\CMake 2.8\bin; C:\UnitTest++\build; C:\libopenshot\build\src; C:\Program Files\doxygen\bin; C:\ffmpeg-git-95f163b-win32-dev\lib; C:\swigwin-2.0.4; C:\Python33; C:\Program Files\Project\lib; C:\msys2\usr\local\`
+
+
+
+
+
+## Obtaining Source Code
+
+The first step in installing libopenshot is to obtain the most recent source code. The source code
+is available on [GitHub](https://github.com/OpenShot/libopenshot). Use the following command to
+obtain the latest libopenshot source code.
+
+```
+git clone https://github.com/OpenShot/libopenshot.git
+git clone https://github.com/OpenShot/libopenshot-audio.git
+```
+
+## Folder Structure (libopenshot)
+
+The source code is divided up into the following folders.
+
+### build/
+ * This folder needs to be manually created, and is used by cmake to store the temporary
+ build files, such as makefiles, as well as the final binaries (library and test executables).
+
+### cmake/
+ * This folder contains custom modules not included by default in cmake, used to find
+ dependency libraries and headers and determine if these libraries are installed.
+
+### doc/
+ * This folder contains documentation and related files, such as logos and images
+ required by the doxygen auto-generated documentation.
+
+### include/
+ * This folder contains all headers (*.h) used by libopenshot.
+
+### src/
+ * This folder contains all source code (*.cpp) used by libopenshot.
+
+### tests/
+ * This folder contains all unit test code. Each class has it’s own test file (*.cpp), and
+ uses UnitTest++ macros to keep the test code simple and manageable.
+
+### thirdparty/
+ * This folder contains code not written by the OpenShot team. For example, jsoncpp, an
+ open-source JSON parser.
+
+## Install MSYS2 Dependencies
+
+Most Windows dependencies needed for libopenshot-audio, libopenshot, and openshot-qt
+can be installed easily with MSYS2 and the pacman package manager. Follow these
+directions to setup a Windows build environment for OpenShot.
+
+1) Install MSYS2: http://www.msys2.org/
+
+2) Run MSYS2 command prompt (for example: `C:\msys64\msys2_shell.cmd`)
+
+3) Append PATH (so MSYS2 can find executables and libraries):
+
+```
+PATH=$PATH:/c/msys64/mingw64/bin:/c/msys64/mingw64/lib (64-bit PATH)
+ or
+PATH=$PATH:/c/msys32/mingw32/bin:/c/msys32/mingw32/lib (32-bit PATH)
+```
+
+4) Update and upgrade all packages
+
+```
+pacman -Syu
+```
+
+5a) Install the following packages (**64-Bit**)
+
+```
+pacman -S --needed base-devel mingw-w64-x86_64-toolchain
+pacman -S mingw64/mingw-w64-x86_64-ffmpeg
+pacman -S mingw64/mingw-w64-x86_64-python3-pyqt5
+pacman -S mingw64/mingw-w64-x86_64-swig
+pacman -S mingw64/mingw-w64-x86_64-cmake
+pacman -S mingw64/mingw-w64-x86_64-doxygen
+pacman -S mingw64/mingw-w64-x86_64-python3-pip
+pacman -S mingw32/mingw-w64-i686-zeromq
+pacman -S mingw64/mingw-w64-x86_64-python3-pyzmq
+pacman -S mingw64/mingw-w64-x86_64-python3-cx_Freeze
+pacman -S git
+
+# Install ImageMagick if needed (OPTIONAL and NOT NEEDED)
+pacman -S mingw64/mingw-w64-x86_64-imagemagick
+```
+
+5b) **Or** Install the following packages (**32-Bit**)
+
+```
+pacman -S --needed base-devel mingw32/mingw-w64-i686-toolchain
+pacman -S mingw32/mingw-w64-i686-ffmpeg
+pacman -S mingw32/mingw-w64-i686-python3-pyqt5
+pacman -S mingw32/mingw-w64-i686-swig
+pacman -S mingw32/mingw-w64-i686-cmake
+pacman -S mingw32/mingw-w64-i686-doxygen
+pacman -S mingw32/mingw-w64-i686-python3-pip
+pacman -S mingw32/mingw-w64-i686-zeromq
+pacman -S mingw32/mingw-w64-i686-python3-pyzmq
+pacman -S mingw32/mingw-w64-i686-python3-cx_Freeze
+pacman -S git
+
+# Install ImageMagick if needed (OPTIONAL and NOT NEEDED)
+pacman -S mingw32/mingw-w32-x86_32-imagemagick
+```
+
+6) Install Python PIP Dependencies
+
+```
+pip3 install httplib2
+pip3 install slacker
+pip3 install tinys3
+pip3 install github3.py
+pip3 install requests
+```
+
+7) Download Unittest++ (https://github.com/unittest-cpp/unittest-cpp) into /MSYS2/[USER]/unittest-cpp-master/
+
+```
+cmake -G "MSYS Makefiles" ../ -DCMAKE_MAKE_PROGRAM=mingw32-make -DCMAKE_INSTALL_PREFIX:PATH=/usr
+mingw32-make install
+```
+
+8) ZMQ++ Header (This might not be needed anymore)
+ NOTE: Download and copy zmq.hpp into the /c/msys64/mingw64/include/ folder
+
+## Manual Dependencies
+
+### DLfcn
+ * https://github.com/dlfcn-win32/dlfcn-win32
+ * Download and Extract the Win32 Static (.tar.bz2) archive to a local folder: `C:\libdl\`
+ * Create an environment variable called DL_DIR and set the value to `C:\libdl\`. This environment variable will be used by CMake to find the binary and header file.
+
+### DirectX SDK / Windows SDK
+ * Windows 7: (DirectX SDK) http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=6812
+ * Windows 8: (Windows SDK)
+ * https://msdn.microsoft.com/en-us/windows/desktop/aa904949
+ * Download and Install the SDK Setup program. This is needed for the JUCE library to play audio on Windows.
+Create an environment variable called DXSDK_DIR and set the value to `C:\Program Files\Microsoft DirectX SDK (June 2010)\` (your path might be different). This environment variable will be used by CMake to find the binaries and header files.
+
+### libSndFile
+ * http://www.mega-nerd.com/libsndfile/#Download
+ * Download and Install the Win32 Setup program.
+ * Create an environment variable called SNDFILE_DIR and set the value to `C:\Program Files\libsndfile`. This environment variable will be used by CMake to find the binary and header files.
+
+### libzmq
+ * http://zeromq.org/intro:get-the-software
+ * Download source code (zip)
+ * Follow their instructions, and build with mingw
+ * Create an environment variable called ZMQDIR and set the value to `C:\libzmq\build\` (the location of the compiled version). This environment variable will be used by CMake to find the binary and header files.
+
+## Windows Build Instructions (libopenshot-audio)
+In order to compile libopenshot-audio, launch a command prompt and enter the following commands. This does not require the MSYS2 prompt, but it should work in both the Windows command prompt and the MSYS2 prompt.
+
+```
+cd [libopenshot-audio repo folder]
+mkdir build
+cd build
+cmake -G “MinGW Makefiles” ../
+mingw32-make
+mingw32-make install
+openshot-audio-test-sound (This should play a test sound)
+```
+
+## Windows Build Instructions (libopenshot)
+Run the following commands to build libopenshot:
+
+```
+cd [libopenshot repo folder]
+mkdir build
+cd build
+cmake -G "MinGW Makefiles" -DPYTHON_INCLUDE_DIR="C:/Python34/include/" -DPYTHON_LIBRARY="C:/Python34/libs/libpython34.a" ../
+mingw32-make
+```
+
+If you are missing any dependencies for libopenshot, you will receive error messages at this point.
+Just install the missing dependencies, and run the above commands again. Repeat until no error
+messages are displayed and the build process completes.
+
+Also, if you are having trouble building, please see the CMake Flags section above, as
+it might provide a solution for finding a missing folder path, missing Python 3 library, etc...
+
+To run all unit tests (and verify everything is working correctly), launch a terminal, and enter:
+
+```
+mingw32-make test
+```
+
+To auto-generate the documentation for libopenshot, launch a terminal, and enter:
+
+```
+mingw32-make doc
+```
+
+This will use doxygen to generate a folder of HTML files, with all classes and methods
+documented. The folder is located at build/doc/html/. Once libopenshot has been successfully
+built, we need to install it (i.e. copy it to the correct folder, so other libraries can find it).
+
+```
+mingw32-make install
+```
+
+This should copy the binary files to `C:\Program Files\openshot\lib\`, and the header
+files to `C:\Program Files\openshot\include\...` This is where other projects will
+look for the libopenshot files when building.. Python 3 bindings are also installed
+at this point. let's verify the python bindings work:
+
+```
+python3
+>>> import openshot
+```
+
+If no errors are displayed, you have successfully compiled and installed libopenshot on
+your system. Congratulations and be sure to read our wiki on [Becoming an OpenShot Developer](https://github.com/OpenShot/openshot-qt/wiki/Become-a-Developer)!
+Welcome to the OpenShot developer community! We look forward to meeting you!
diff --git a/doc/InstallationGuide.pdf b/doc/InstallationGuide.pdf
deleted file mode 100644
index 4cd294e5..00000000
Binary files a/doc/InstallationGuide.pdf and /dev/null differ
diff --git a/include/AudioBufferSource.h b/include/AudioBufferSource.h
index 57826f66..4addb37d 100644
--- a/include/AudioBufferSource.h
+++ b/include/AudioBufferSource.h
@@ -3,9 +3,12 @@
* @brief Header file for AudioBufferSource class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -37,7 +40,7 @@
#endif
#include
-#include "JuceLibraryCode/JuceHeader.h"
+#include "JuceHeader.h"
using namespace std;
diff --git a/include/AudioDeviceInfo.h b/include/AudioDeviceInfo.h
new file mode 100644
index 00000000..4099430e
--- /dev/null
+++ b/include/AudioDeviceInfo.h
@@ -0,0 +1,46 @@
+/**
+ * @file
+ * @brief Header file for Audio Device Info struct
+ * @author Jonathan Thomas
+ *
+ * @ref License
+ */
+
+/* LICENSE
+ *
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
+ * . This file is part of
+ * OpenShot Library (libopenshot), an open-source project dedicated to
+ * delivering high quality video editing and animation solutions to the
+ * world. For more information visit .
+ *
+ * OpenShot Library (libopenshot) is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * OpenShot Library (libopenshot) is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with OpenShot Library. If not, see .
+ */
+
+#ifndef OPENSHOT_AUDIODEVICEINFO_H
+#define OPENSHOT_AUDIODEVICEINFO_H
+
+
+/**
+ * @brief This struct hold information about Audio Devices
+ *
+ * The type and name of the audio device.
+ */
+struct AudioDeviceInfo
+{
+ string name;
+ string type;
+};
+
+#endif
\ No newline at end of file
diff --git a/include/AudioReaderSource.h b/include/AudioReaderSource.h
index 31b17d80..679aed61 100644
--- a/include/AudioReaderSource.h
+++ b/include/AudioReaderSource.h
@@ -3,9 +3,12 @@
* @brief Header file for AudioReaderSource class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -37,8 +40,8 @@
#endif
#include
-#include "JuceLibraryCode/JuceHeader.h"
#include "ReaderBase.h"
+#include "JuceHeader.h"
using namespace std;
diff --git a/include/AudioResampler.h b/include/AudioResampler.h
index 412d49b1..85a44b1f 100644
--- a/include/AudioResampler.h
+++ b/include/AudioResampler.h
@@ -3,9 +3,12 @@
* @brief Header file for AudioResampler class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -38,9 +41,9 @@
#define _NDEBUG
#endif
-#include "JuceLibraryCode/JuceHeader.h"
#include "AudioBufferSource.h"
#include "Exceptions.h"
+#include "JuceHeader.h"
namespace openshot {
diff --git a/include/CacheBase.h b/include/CacheBase.h
index aaef5320..3760e84b 100644
--- a/include/CacheBase.h
+++ b/include/CacheBase.h
@@ -3,9 +3,12 @@
* @brief Header file for CacheBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -109,6 +112,7 @@ namespace openshot {
virtual void SetJson(string value) = 0; ///< Load JSON string into this object
virtual Json::Value JsonValue() = 0; ///< Generate Json::JsonValue for this object
virtual void SetJsonValue(Json::Value root) = 0; ///< Load Json::JsonValue into this object
+ virtual ~CacheBase() = default;
};
diff --git a/include/CacheDisk.h b/include/CacheDisk.h
index adecda9a..11a8808c 100644
--- a/include/CacheDisk.h
+++ b/include/CacheDisk.h
@@ -3,9 +3,12 @@
* @brief Header file for CacheDisk class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/CacheMemory.h b/include/CacheMemory.h
index 2f3f018b..eb11f273 100644
--- a/include/CacheMemory.h
+++ b/include/CacheMemory.h
@@ -3,9 +3,12 @@
* @brief Header file for CacheMemory class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -71,7 +74,7 @@ namespace openshot {
CacheMemory(int64_t max_bytes);
// Default destructor
- ~CacheMemory();
+ virtual ~CacheMemory();
/// @brief Add a Frame to the cache
/// @param frame The openshot::Frame object needing to be cached.
diff --git a/include/ChannelLayouts.h b/include/ChannelLayouts.h
index 657d2757..673eeccd 100644
--- a/include/ChannelLayouts.h
+++ b/include/ChannelLayouts.h
@@ -3,9 +3,12 @@
* @brief Header file for ChannelLayout class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/ChunkReader.h b/include/ChunkReader.h
index aa151093..5b330b70 100644
--- a/include/ChunkReader.h
+++ b/include/ChunkReader.h
@@ -3,9 +3,12 @@
* @brief Header file for ChunkReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -29,8 +32,6 @@
#define OPENSHOT_CHUNK_READER_H
#include "ReaderBase.h"
-#include "FFmpegReader.h"
-
#include
#include
#include
@@ -107,7 +108,7 @@ namespace openshot
string path;
bool is_open;
int64_t chunk_size;
- FFmpegReader *local_reader;
+ ReaderBase *local_reader;
ChunkLocation previous_location;
ChunkVersion version;
std::shared_ptr last_frame;
diff --git a/include/ChunkWriter.h b/include/ChunkWriter.h
index 2cdef4fe..5ac9be4a 100644
--- a/include/ChunkWriter.h
+++ b/include/ChunkWriter.h
@@ -3,9 +3,12 @@
* @brief Header file for ChunkWriter class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Clip.h b/include/Clip.h
index f30844b2..c092c2ad 100644
--- a/include/Clip.h
+++ b/include/Clip.h
@@ -3,9 +3,12 @@
* @brief Header file for Clip class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -36,7 +39,6 @@
#include
#include
#include
-#include "JuceLibraryCode/JuceHeader.h"
#include "AudioResampler.h"
#include "ClipBase.h"
#include "Color.h"
@@ -44,18 +46,10 @@
#include "EffectBase.h"
#include "Effects.h"
#include "EffectInfo.h"
-#include "FFmpegReader.h"
#include "Fraction.h"
-#include "FrameMapper.h"
-#ifdef USE_IMAGEMAGICK
- #include "ImageReader.h"
- #include "TextReader.h"
-#endif
-#include "QtImageReader.h"
-#include "ChunkReader.h"
#include "KeyFrame.h"
#include "ReaderBase.h"
-#include "DummyReader.h"
+#include "JuceHeader.h"
using namespace std;
using namespace openshot;
@@ -121,7 +115,10 @@ namespace openshot {
// File Reader object
ReaderBase* reader;
- bool manage_reader;
+
+ /// If we allocated a reader, we store it here to free it later
+ /// (reader member variable itself may have been replaced)
+ ReaderBase* allocated_reader;
/// Adjust frame number minimum value
int64_t adjust_frame_number_minimum(int64_t frame_number);
@@ -136,7 +133,7 @@ namespace openshot {
std::shared_ptr GetOrCreateFrame(int64_t number);
/// Adjust the audio and image of a time mapped frame
- std::shared_ptr get_time_mapped_frame(std::shared_ptr frame, int64_t frame_number);
+ void get_time_mapped_frame(std::shared_ptr frame, int64_t frame_number);
/// Init default settings for a clip
void init_settings();
@@ -151,8 +148,8 @@ namespace openshot {
void reverse_buffer(juce::AudioSampleBuffer* buffer);
public:
- GravityType gravity; ///< The gravity of a clip determines where it snaps to it's parent
- ScaleType scale; ///< The scale determines how a clip should be resized to fit it's parent
+ GravityType gravity; ///< The gravity of a clip determines where it snaps to its parent
+ ScaleType scale; ///< The scale determines how a clip should be resized to fit its parent
AnchorType anchor; ///< The anchor determines what parent a clip should snap to
FrameDisplayType display; ///< The format to display the frame number (if any)
VolumeMixType mixing; ///< What strategy should be followed when mixing audio with other clips
@@ -169,7 +166,7 @@ namespace openshot {
Clip(ReaderBase* new_reader);
/// Destructor
- ~Clip();
+ virtual ~Clip();
/// @brief Add an effect to the clip
/// @param effect Add an effect to the clip. An effect can modify the audio or video of an openshot::Frame.
diff --git a/include/ClipBase.h b/include/ClipBase.h
index 06341640..ab3f0637 100644
--- a/include/ClipBase.h
+++ b/include/ClipBase.h
@@ -3,9 +3,12 @@
* @brief Header file for ClipBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -58,8 +61,6 @@ namespace openshot {
float start; ///< The position in seconds to start playing (used to trim the beginning of a clip)
float end; ///< The position in seconds to end playing (used to trim the ending of a clip)
string previous_properties; ///< This string contains the previous JSON properties
- int max_width; ///< The maximum image width needed by this clip (used for optimizations)
- int max_height; ///< The maximium image height needed by this clip (used for optimizations)
/// Generate JSON for a property
Json::Value add_property_json(string name, float value, string type, string memo, Keyframe* keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame);
@@ -70,7 +71,7 @@ namespace openshot {
public:
/// Constructor for the base clip
- ClipBase() { max_width = 0; max_height = 0; };
+ ClipBase() { };
// Compare a clip using the Position() property
bool operator< ( ClipBase& a) { return (Position() < a.Position()); }
@@ -93,9 +94,6 @@ namespace openshot {
void Start(float value) { start = value; } ///< Set start position (in seconds) of clip (trim start of video)
void End(float value) { end = value; } ///< Set end position (in seconds) of clip (trim end of video)
- /// Set Max Image Size (used for performance optimization)
- void SetMaxSize(int width, int height) { max_width = width; max_height = height; };
-
/// Get and Set JSON methods
virtual string Json() = 0; ///< Generate JSON string of this object
virtual void SetJson(string value) = 0; ///< Load JSON string into this object
@@ -106,6 +104,7 @@ namespace openshot {
/// of all properties at any time)
virtual string PropertiesJSON(int64_t requested_frame) = 0;
+ virtual ~ClipBase() = default;
};
diff --git a/include/Color.h b/include/Color.h
index a0edd602..d06bee91 100644
--- a/include/Color.h
+++ b/include/Color.h
@@ -3,9 +3,12 @@
* @brief Header file for Color class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Coordinate.h b/include/Coordinate.h
index 0ca6b7b8..6ab296dc 100644
--- a/include/Coordinate.h
+++ b/include/Coordinate.h
@@ -3,9 +3,12 @@
* @brief Header file for Coordinate class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -52,11 +55,6 @@ namespace openshot {
* \endcode
*/
class Coordinate {
- private:
- bool increasing; ///< Is the Y value increasing or decreasing?
- Fraction repeated; ///< Fraction of repeated Y values (for example, 1/3 would be the first Y value of 3 repeated values)
- double delta; ///< This difference in Y value (from the previous unique Y value)
-
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)
@@ -69,27 +67,6 @@ namespace openshot {
/// @param y The Y coordinate (usually representing the value of the property being animated)
Coordinate(double x, double y);
- /// @brief Set the repeating Fraction (used internally on the timeline, to track changes to coordinates)
- /// @param is_repeated The fraction representing how many times this coordinate Y value repeats (only used on the timeline)
- void Repeat(Fraction is_repeated) { repeated=is_repeated; }
-
- /// Get the repeating Fraction (used internally on the timeline, to track changes to coordinates)
- Fraction Repeat() { return repeated; }
-
- /// @brief Set the increasing flag (used internally on the timeline, to track changes to coordinates)
- /// @param is_increasing Indicates if this coordinate Y value is increasing (when compared to the previous coordinate)
- void IsIncreasing(bool is_increasing) { increasing = is_increasing; }
-
- /// Get the increasing flag (used internally on the timeline, to track changes to coordinates)
- bool IsIncreasing() { return increasing; }
-
- /// @brief Set the delta / difference between previous coordinate value (used internally on the timeline, to track changes to coordinates)
- /// @param new_delta Indicates how much this Y value differs from the previous Y value
- void Delta(double new_delta) { delta=new_delta; }
-
- /// Get the delta / difference between previous coordinate value (used internally on the timeline, to track changes to coordinates)
- float Delta() { return delta; }
-
/// Get and Set JSON methods
string Json(); ///< Generate JSON string of this object
Json::Value JsonValue(); ///< Generate Json::JsonValue for this object
diff --git a/include/CrashHandler.h b/include/CrashHandler.h
index e3a4bbe5..76d788f2 100644
--- a/include/CrashHandler.h
+++ b/include/CrashHandler.h
@@ -3,9 +3,12 @@
* @brief Header file for CrashHandler class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -53,13 +56,15 @@ namespace openshot {
class CrashHandler {
private:
/// Default constructor
- CrashHandler(){}; // Don't allow user to create an instance of this singleton
+ CrashHandler(){return;}; // Don't allow user to create an instance of this singleton
/// Default copy method
- CrashHandler(CrashHandler const&){}; // Don't allow the user to copy this instance
+ //CrashHandler(CrashHandler const&){}; // Don't allow the user to copy this instance
+ CrashHandler(CrashHandler const&) = delete; // Don't allow the user to copy this instance
/// Default assignment operator
- CrashHandler & operator=(CrashHandler const&){}; // Don't allow the user to assign this instance
+ //CrashHandler & operator=(CrashHandler const&){}; // Don't allow the user to assign this instance
+ CrashHandler & operator=(CrashHandler const&) = delete; // Don't allow the user to assign this instance
/// Private variable to keep track of singleton instance
static CrashHandler *m_pInstance;
diff --git a/include/DecklinkInput.h b/include/DecklinkInput.h
index 9964461d..87207505 100644
--- a/include/DecklinkInput.h
+++ b/include/DecklinkInput.h
@@ -3,7 +3,10 @@
* @brief Header file for DecklinkInput class
* @author Jonathan Thomas , Blackmagic Design
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
* Copyright (c) 2009 Blackmagic Design
*
@@ -30,7 +33,7 @@
* DEALINGS IN THE SOFTWARE.
*
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -62,9 +65,9 @@
#include
#include "DeckLinkAPI.h"
-#include "../include/Frame.h"
+#include "Frame.h"
#include "CacheMemory.h"
-#include "../include/OpenMPUtilities.h"
+#include "OpenMPUtilities.h"
/// Implementation of the Blackmagic Decklink API (used by the DecklinkReader)
class DeckLinkInputDelegate : public IDeckLinkInputCallback
diff --git a/include/DecklinkOutput.h b/include/DecklinkOutput.h
index fb461438..ebaa9ab4 100644
--- a/include/DecklinkOutput.h
+++ b/include/DecklinkOutput.h
@@ -3,7 +3,10 @@
* @brief Header file for DecklinkOutput class
* @author Jonathan Thomas , Blackmagic Design
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
* Copyright (c) 2009 Blackmagic Design
*
@@ -30,7 +33,7 @@
* DEALINGS IN THE SOFTWARE.
*
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -63,8 +66,8 @@
#include "DeckLinkAPI.h"
#include "CacheMemory.h"
-#include "../include/Frame.h"
-#include "../include/OpenMPUtilities.h"
+#include "Frame.h"
+#include "OpenMPUtilities.h"
enum OutputSignal {
kOutputSignalPip = 0,
diff --git a/include/DecklinkReader.h b/include/DecklinkReader.h
index 3ce9273f..3dc7e23d 100644
--- a/include/DecklinkReader.h
+++ b/include/DecklinkReader.h
@@ -3,9 +3,12 @@
* @brief Header file for DecklinkReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/DecklinkWriter.h b/include/DecklinkWriter.h
index 00ac8b3e..809890f3 100644
--- a/include/DecklinkWriter.h
+++ b/include/DecklinkWriter.h
@@ -3,9 +3,12 @@
* @brief Header file for DecklinkWriter class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/DummyReader.h b/include/DummyReader.h
index 559215de..adae512f 100644
--- a/include/DummyReader.h
+++ b/include/DummyReader.h
@@ -3,9 +3,12 @@
* @brief Header file for DummyReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -64,6 +67,8 @@ namespace openshot
/// Constructor for DummyReader.
DummyReader(Fraction fps, int width, int height, int sample_rate, int channels, float duration);
+ virtual ~DummyReader();
+
/// Close File
void Close();
diff --git a/include/EffectBase.h b/include/EffectBase.h
index 209369a8..a16b6620 100644
--- a/include/EffectBase.h
+++ b/include/EffectBase.h
@@ -3,9 +3,12 @@
* @brief Header file for EffectBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -32,8 +35,8 @@
#include
#include
#include "ClipBase.h"
-#include "Frame.h"
#include "Json.h"
+#include "Frame.h"
using namespace std;
@@ -82,7 +85,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
@@ -105,6 +108,7 @@ namespace openshot
/// Set the order that this effect should be executed.
void Order(int new_order) { order = new_order; }
+ virtual ~EffectBase() = default;
};
}
diff --git a/include/EffectInfo.h b/include/EffectInfo.h
index 999c9b6a..7806f096 100644
--- a/include/EffectInfo.h
+++ b/include/EffectInfo.h
@@ -3,9 +3,12 @@
* @brief Header file for the EffectInfo class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Effects.h b/include/Effects.h
index 224c48be..746da4c0 100644
--- a/include/Effects.h
+++ b/include/Effects.h
@@ -6,9 +6,12 @@
* @brief This header includes all commonly used effects for libopenshot, for ease-of-use.
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Enums.h b/include/Enums.h
index fb91f1fa..387191ea 100644
--- a/include/Enums.h
+++ b/include/Enums.h
@@ -3,9 +3,12 @@
* @brief Header file for TextReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Exceptions.h b/include/Exceptions.h
index fe76d6dc..0fb2bb1e 100644
--- a/include/Exceptions.h
+++ b/include/Exceptions.h
@@ -3,9 +3,12 @@
* @brief Header file for all Exception classes
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/FFmpegReader.h b/include/FFmpegReader.h
index 6072756a..894d3e5d 100644
--- a/include/FFmpegReader.h
+++ b/include/FFmpegReader.h
@@ -3,9 +3,12 @@
* @brief Header file for FFmpegReader class
* @author Jonathan Thomas , Fabrice Bellard
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2013 OpenShot Studios, LLC, Fabrice Bellard
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC, Fabrice Bellard
* (http://www.openshotstudios.com). This file is part of
* OpenShot Library (http://www.openshot.org), an open-source project
* dedicated to delivering high quality video editing and animation solutions
@@ -42,24 +45,25 @@
#include
#include
#include "CacheMemory.h"
+#include "Clip.h"
#include "Exceptions.h"
#include "OpenMPUtilities.h"
+#include "Settings.h"
using namespace std;
-namespace openshot
-{
+namespace openshot {
/**
* @brief This struct holds the associated video frame and starting sample # for an audio packet.
*
* Because audio packets do not match up with video frames, this helps determine exactly
* where the audio packet's samples belong.
*/
- struct AudioLocation
- {
+ struct AudioLocation {
int64_t frame;
int sample_start;
+
bool is_near(AudioLocation location, int samples_per_frame, int64_t amount);
};
@@ -89,14 +93,16 @@ namespace openshot
* r.Close();
* @endcode
*/
- class FFmpegReader : public ReaderBase
- {
+ class FFmpegReader : public ReaderBase {
private:
string path;
AVFormatContext *pFormatCtx;
int i, videoStream, audioStream;
AVCodecContext *pCodecCtx, *aCodecCtx;
+#if (LIBAVFORMAT_VERSION_MAJOR >= 57)
+ AVBufferRef *hw_device_ctx = NULL; //PM
+#endif
AVStream *pStream, *aStream;
AVPacket *packet;
AVFrame *pFrame;
@@ -140,7 +146,15 @@ namespace openshot
int64_t video_pts_offset;
int64_t last_frame;
int64_t largest_frame_processed;
- int64_t current_video_frame; // can't reliably use PTS of video to determine this
+ int64_t current_video_frame; // can't reliably use PTS of video to determine this
+
+ int hw_de_supported = 0; // Is set by FFmpegReader
+#if IS_FFMPEG_3_2
+ AVPixelFormat hw_de_av_pix_fmt = AV_PIX_FMT_NONE;
+ AVHWDeviceType hw_de_av_device_type = AV_HWDEVICE_TYPE_NONE;
+#endif
+
+ int IsHardwareDecodeSupported(int codecid);
/// Check for the correct frames per second value by scanning the 1st few seconds of video packets.
void CheckFPS();
@@ -148,7 +162,7 @@ namespace openshot
/// Check the current seek position and determine if we need to seek again
bool CheckSeek(bool is_video);
- /// Check if a frame is missing and attempt to replace it's frame image (and
+ /// Check if a frame is missing and attempt to replace its frame image (and
bool CheckMissingFrame(int64_t requested_frame);
/// Check the working queue, and move finished frames to the finished queue
@@ -196,11 +210,11 @@ namespace openshot
/// Read the stream until we find the requested Frame
std::shared_ptr ReadStream(int64_t requested_frame);
- /// Remove AVFrame from cache (and deallocate it's memory)
- void RemoveAVFrame(AVFrame*);
+ /// Remove AVFrame from cache (and deallocate its memory)
+ void RemoveAVFrame(AVFrame *);
- /// Remove AVPacket from cache (and deallocate it's memory)
- void RemoveAVPacket(AVPacket*);
+ /// Remove AVPacket from cache (and deallocate its memory)
+ void RemoveAVPacket(AVPacket *);
/// Seek to a specific Frame. This is not always frame accurate, it's more of an estimation on many codecs.
void Seek(int64_t requested_frame);
@@ -226,19 +240,19 @@ namespace openshot
/// frame 1, or it throws one of the following exceptions.
FFmpegReader(string path);
- /// Constructor for FFmpegReader. This only opens the media file to inspect it's properties
+ /// Constructor for FFmpegReader. This only opens the media file to inspect its properties
/// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful
/// when you are inflating the object using JSON after instantiating it.
FFmpegReader(string path, bool inspect_reader);
/// Destructor
- ~FFmpegReader();
+ virtual ~FFmpegReader();
/// Close File
void Close();
/// Get the cache object used by this reader
- CacheMemory* GetCache() { return &final_cache; };
+ CacheMemory *GetCache() { return &final_cache; };
/// Get a shared pointer to a openshot::Frame object for a specific frame number of this reader.
///
diff --git a/include/FFmpegUtilities.h b/include/FFmpegUtilities.h
index 578c6586..e3df704b 100644
--- a/include/FFmpegUtilities.h
+++ b/include/FFmpegUtilities.h
@@ -3,9 +3,12 @@
* @brief Header file for FFmpegUtilities
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -42,8 +45,19 @@
extern "C" {
#include
#include
+ #if (LIBAVFORMAT_VERSION_MAJOR >= 57)
+ #include //PM
+ #endif
#include
+ // Change this to the first version swrescale works
+ #if (LIBAVFORMAT_VERSION_MAJOR >= 57)
+ #define USE_SW
+ #endif
+ #ifdef USE_SW
+ #include
+ #else
#include
+ #endif
#include
#include
#include
@@ -106,7 +120,37 @@
#define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P
#endif
- #if IS_FFMPEG_3_2
+ // FFmpeg's libavutil/common.h defines an RSHIFT incompatible with Ruby's
+ // definition in ruby/config.h, so we move it to FF_RSHIFT
+ #ifdef RSHIFT
+ #define FF_RSHIFT(a, b) RSHIFT(a, b)
+ #undef RSHIFT
+ #endif
+
+ #ifdef USE_SW
+ #define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count) \
+ swr_convert(ctx, out, out_count, (const uint8_t **)in, in_count)
+ #define SWR_ALLOC() swr_alloc()
+ #define SWR_CLOSE(ctx) {}
+ #define SWR_FREE(ctx) swr_free(ctx)
+ #define SWR_INIT(ctx) swr_init(ctx)
+ #define SWRCONTEXT SwrContext
+ #else
+ #define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count) \
+ avresample_convert(ctx, out, linesize, out_count, (uint8_t **)in, linesize2, in_count)
+ #define SWR_ALLOC() avresample_alloc_context()
+ #define SWR_CLOSE(ctx) avresample_close(ctx)
+ #define SWR_FREE(ctx) avresample_free(ctx)
+ #define SWR_INIT(ctx) avresample_open(ctx)
+ #define SWRCONTEXT AVAudioResampleContext
+ #endif
+
+
+ #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
+ #define AV_REGISTER_ALL
+ #define AVCODEC_REGISTER_ALL
+ #define AV_FILENAME url
+ #define MY_INPUT_BUFFER_PADDING_SIZE AV_INPUT_BUFFER_PADDING_SIZE
#define AV_ALLOCATE_FRAME() av_frame_alloc()
#define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1)
#define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
@@ -137,7 +181,49 @@
st_codec = c; \
av_st->codecpar->codec_id = av_codec->id;
#define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec) avcodec_parameters_from_context(av_stream->codecpar, av_codec);
+ #elif IS_FFMPEG_3_2
+ #define AV_REGISTER_ALL av_register_all();
+ #define AVCODEC_REGISTER_ALL avcodec_register_all();
+ #define AV_FILENAME filename
+ #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
+ #define AV_ALLOCATE_FRAME() av_frame_alloc()
+ #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1)
+ #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
+ #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
+ #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
+ #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context)
+ #define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
+ #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id
+ auto AV_GET_CODEC_CONTEXT = [](AVStream* av_stream, AVCodec* av_codec) { \
+ AVCodecContext *context = avcodec_alloc_context3(av_codec); \
+ avcodec_parameters_to_context(context, av_stream->codecpar); \
+ return context; \
+ };
+ #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_codec;
+ #define AV_GET_CODEC_FROM_STREAM(av_stream,codec_in)
+ #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
+ #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) (AVPixelFormat) av_stream->codecpar->format
+ #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
+ #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 1)
+ #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1)
+ #define AV_OUTPUT_CONTEXT(output_context, path) avformat_alloc_output_context2( output_context, NULL, NULL, path)
+ #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
+ #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) av_opt_set(priv_data, name, value, 0); avcodec_parameters_from_context(av_stream->codecpar, avcodec);
+ #define AV_FORMAT_NEW_STREAM(oc, st_codec, av_codec, av_st) av_st = avformat_new_stream(oc, NULL);\
+ if (!av_st) \
+ throw OutOfMemory("Could not allocate memory for the video stream.", path); \
+ _Pragma ("GCC diagnostic push"); \
+ _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\""); \
+ avcodec_get_context_defaults3(av_st->codec, av_codec); \
+ c = av_st->codec; \
+ _Pragma ("GCC diagnostic pop"); \
+ st_codec = c;
+ #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec) avcodec_parameters_from_context(av_stream->codecpar, av_codec);
#elif LIBAVFORMAT_VERSION_MAJOR >= 55
+ #define AV_REGISTER_ALL av_register_all();
+ #define AVCODEC_REGISTER_ALL avcodec_register_all();
+ #define AV_FILENAME filename
+ #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
#define AV_ALLOCATE_FRAME() av_frame_alloc()
#define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
#define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
@@ -164,6 +250,10 @@
c = av_st->codec;
#define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
#else
+ #define AV_REGISTER_ALL av_register_all();
+ #define AVCODEC_REGISTER_ALL avcodec_register_all();
+ #define AV_FILENAME filename
+ #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
#define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
#define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
#define AV_RESET_FRAME(av_frame) avcodec_get_frame_defaults(av_frame)
diff --git a/include/FFmpegWriter.h b/include/FFmpegWriter.h
index 8343002e..8b3a4673 100644
--- a/include/FFmpegWriter.h
+++ b/include/FFmpegWriter.h
@@ -3,9 +3,12 @@
* @brief Header file for FFmpegWriter class
* @author Jonathan Thomas , Fabrice Bellard
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2013 OpenShot Studios, LLC, Fabrice Bellard
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC, Fabrice Bellard
* (http://www.openshotstudios.com). This file is part of
* OpenShot Library (http://www.openshot.org), an open-source project
* dedicated to delivering high quality video editing and animation solutions
@@ -51,18 +54,17 @@
#include "Exceptions.h"
#include "OpenMPUtilities.h"
#include "ZmqLogger.h"
+#include "Settings.h"
using namespace std;
-namespace openshot
-{
+namespace openshot {
/// This enumeration designates the type of stream when encoding (video or audio)
- enum StreamType
- {
- VIDEO_STREAM, ///< A video stream (used to determine which type of stream)
- AUDIO_STREAM ///< An audio stream (used to determine which type of stream)
+ enum StreamType {
+ VIDEO_STREAM, ///< A video stream (used to determine which type of stream)
+ AUDIO_STREAM ///< An audio stream (used to determine which type of stream)
};
/**
@@ -82,7 +84,7 @@ namespace openshot
* FFmpegWriter w("/home/jonathan/NewVideo.webm");
*
* // Set options
- * w.SetAudioOptions(true, "libvorbis", 44100, 2, 128000); // Sample Rate: 44100, Channels: 2, Bitrate: 128000
+ * w.SetAudioOptions(true, "libvorbis", 44100, 2, ChannelLayout::LAYOUT_STEREO, 128000); // Sample Rate: 44100, Channels: 2, Bitrate: 128000
* w.SetVideoOptions(true, "libvpx", openshot::Fraction(24,1), 720, 480, openshot::Fraction(1,1), false, false, 300000); // FPS: 24, Size: 720x480, Pixel Ratio: 1/1, Bitrate: 300000
*
* // Open the writer
@@ -109,7 +111,7 @@ namespace openshot
* FFmpegWriter w("/home/jonathan/NewVideo.webm");
*
* // Set options
- * w.SetAudioOptions(true, "libvorbis", 44100, 2, 128000); // Sample Rate: 44100, Channels: 2, Bitrate: 128000
+ * w.SetAudioOptions(true, "libvorbis", 44100, 2, ChannelLayout::LAYOUT_STEREO, 128000); // Sample Rate: 44100, Channels: 2, Bitrate: 128000
* w.SetVideoOptions(true, "libvpx", openshot::Fraction(24,1), 720, 480, openshot::Fraction(1,1), false, false, 300000); // FPS: 24, Size: 720x480, Pixel Ratio: 1/1, Bitrate: 300000
*
* // Prepare Streams (Optional method that must be called before any SetOption calls)
@@ -140,8 +142,7 @@ namespace openshot
* r.Close();
* @endcode
*/
- class FFmpegWriter : public WriterBase
- {
+ class FFmpegWriter : public WriterBase {
private:
string path;
int cache_size;
@@ -154,56 +155,56 @@ namespace openshot
bool write_header;
bool write_trailer;
- AVOutputFormat *fmt;
- AVFormatContext *oc;
- AVStream *audio_st, *video_st;
- AVCodecContext *video_codec;
- AVCodecContext *audio_codec;
- SwsContext *img_convert_ctx;
- double audio_pts, video_pts;
- int16_t *samples;
- uint8_t *audio_outbuf;
- uint8_t *audio_encoder_buffer;
+ AVOutputFormat *fmt;
+ AVFormatContext *oc;
+ AVStream *audio_st, *video_st;
+ AVCodecContext *video_codec;
+ AVCodecContext *audio_codec;
+ SwsContext *img_convert_ctx;
+ double audio_pts, video_pts;
+ int16_t *samples;
+ uint8_t *audio_outbuf;
+ uint8_t *audio_encoder_buffer;
- int num_of_rescalers;
+ int num_of_rescalers;
int rescaler_position;
- vector image_rescalers;
+ vector image_rescalers;
- int audio_outbuf_size;
- int audio_input_frame_size;
- int initial_audio_input_frame_size;
- int audio_input_position;
- int audio_encoder_buffer_size;
- AVAudioResampleContext *avr;
- AVAudioResampleContext *avr_planar;
+ int audio_outbuf_size;
+ int audio_input_frame_size;
+ int initial_audio_input_frame_size;
+ int audio_input_position;
+ int audio_encoder_buffer_size;
+ SWRCONTEXT *avr;
+ SWRCONTEXT *avr_planar;
- /* Resample options */
- int original_sample_rate;
- int original_channels;
+ /* Resample options */
+ int original_sample_rate;
+ int original_channels;
- std::shared_ptr last_frame;
- deque > spooled_audio_frames;
- deque > spooled_video_frames;
+ std::shared_ptr last_frame;
+ deque > spooled_audio_frames;
+ deque > spooled_video_frames;
- deque > queued_audio_frames;
- deque > queued_video_frames;
+ deque > queued_audio_frames;
+ deque > queued_video_frames;
- deque > processed_frames;
- deque > deallocate_frames;
+ deque > processed_frames;
+ deque > deallocate_frames;
- map, AVFrame*> av_frames;
+ map, AVFrame *> av_frames;
- /// Add an AVFrame to the cache
- void add_avframe(std::shared_ptr frame, AVFrame* av_frame);
+ /// Add an AVFrame to the cache
+ void add_avframe(std::shared_ptr frame, AVFrame *av_frame);
/// Add an audio output stream
- AVStream* add_audio_stream();
+ AVStream *add_audio_stream();
/// Add a video output stream
- AVStream* add_video_stream();
+ AVStream *add_video_stream();
/// Allocate an AVFrame object
- AVFrame* allocate_avframe(PixelFormat pix_fmt, int width, int height, int *buffer_size, uint8_t *new_buffer);
+ AVFrame *allocate_avframe(PixelFormat pix_fmt, int width, int height, int *buffer_size, uint8_t *new_buffer);
/// Auto detect format (from path)
void auto_detect_format();
@@ -235,10 +236,10 @@ namespace openshot
void process_video_packet(std::shared_ptr frame);
/// write all queued frames' audio to the video file
- void write_audio_packets(bool final);
+ void write_audio_packets(bool is_final);
/// write video frame
- bool write_video_packet(std::shared_ptr frame, AVFrame* frame_final);
+ bool write_video_packet(std::shared_ptr frame, AVFrame *frame_final);
/// write all queued frames
void write_queued_frames();
@@ -302,7 +303,7 @@ namespace openshot
/// @param interlaced Does this video need to be interlaced?
/// @param top_field_first Which frame should be used as the top field?
/// @param bit_rate The video bit rate used during encoding
- void SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height,Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate);
+ void SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height, Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate);
/// @brief Set custom options (some codecs accept additional params). This must be called after the
/// PrepareStreams() method, otherwise the streams have not been initialized yet.
@@ -323,7 +324,7 @@ namespace openshot
/// @param reader A openshot::ReaderBase object which will provide frames to be written
/// @param start The starting frame number of the reader
/// @param length The number of frames to write
- void WriteFrame(ReaderBase* reader, int64_t start, int64_t length);
+ void WriteFrame(ReaderBase *reader, int64_t start, int64_t length);
/// @brief Write the file trailer (after all frames are written). This is called automatically
/// by the Close() method if this method has not yet been called.
diff --git a/include/Fraction.h b/include/Fraction.h
index 7f5e5881..9ffcda1f 100644
--- a/include/Fraction.h
+++ b/include/Fraction.h
@@ -3,9 +3,12 @@
* @brief Header file for Fraction class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Frame.h b/include/Frame.h
index a7ad509f..cb855fe4 100644
--- a/include/Frame.h
+++ b/include/Frame.h
@@ -3,9 +3,12 @@
* @brief Header file for Frame class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -53,16 +56,16 @@
#include
#include
#include "ZmqLogger.h"
-#ifdef USE_IMAGEMAGICK
- #include "Magick++.h"
-#endif
-#include "JuceLibraryCode/JuceHeader.h"
#include "ChannelLayouts.h"
#include "AudioBufferSource.h"
#include "AudioResampler.h"
#include "Fraction.h"
+#include "JuceHeader.h"
+#ifdef USE_IMAGEMAGICK
+ #include "MagickUtilities.h"
+#endif
-
+#pragma SWIG nowarn=362
using namespace std;
namespace openshot
@@ -159,7 +162,7 @@ namespace openshot
Frame& operator= (const Frame& other);
/// Destructor
- ~Frame();
+ virtual ~Frame();
/// Add (or replace) pixel data to the frame (based on a solid color)
void AddColor(int new_width, int new_height, string new_color);
@@ -197,7 +200,7 @@ namespace openshot
/// Clean up buffer after QImage is deleted
static void cleanUpBuffer(void *info);
- /// Clear the waveform image (and deallocate it's memory)
+ /// Clear the waveform image (and deallocate its memory)
void ClearWaveform();
/// Copy data and pointers from another Frame instance
@@ -249,6 +252,9 @@ namespace openshot
/// Get pixel data (for only a single scan-line)
const unsigned char* GetPixels(int row);
+ /// Check a specific pixel color value (returns True/False)
+ bool CheckPixel(int row, int col, int red, int green, int blue, int alpha, int threshold);
+
/// Get height of image
int GetHeight();
diff --git a/include/FrameMapper.h b/include/FrameMapper.h
index e70fdbc5..78e8944e 100644
--- a/include/FrameMapper.h
+++ b/include/FrameMapper.h
@@ -3,9 +3,12 @@
* @brief Header file for the FrameMapper class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -34,11 +37,11 @@
#include
#include
#include "CacheMemory.h"
-#include "../include/ReaderBase.h"
-#include "../include/Frame.h"
-#include "../include/Fraction.h"
-#include "../include/Exceptions.h"
-#include "../include/KeyFrame.h"
+#include "ReaderBase.h"
+#include "Frame.h"
+#include "Fraction.h"
+#include "Exceptions.h"
+#include "KeyFrame.h"
// Include FFmpeg headers and macros
@@ -146,7 +149,7 @@ namespace openshot
ReaderBase *reader; // The source video reader
CacheMemory final_cache; // Cache of actual Frame objects
bool is_dirty; // When this is true, the next call to GetFrame will re-init the mapping
- AVAudioResampleContext *avr; // Audio resampling context object
+ SWRCONTEXT *avr; // Audio resampling context object
// Internal methods used by init
void AddField(int64_t frame);
@@ -170,7 +173,7 @@ namespace openshot
FrameMapper(ReaderBase *reader, Fraction target_fps, PulldownType target_pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
/// Destructor
- ~FrameMapper();
+ virtual ~FrameMapper();
/// Change frame rate or audio mapping details
void ChangeMapping(Fraction target_fps, PulldownType pulldown, int target_sample_rate, int target_channels, ChannelLayout target_channel_layout);
@@ -213,6 +216,9 @@ namespace openshot
/// Get the current reader
ReaderBase* Reader();
+ /// Set the current reader
+ void Reader(ReaderBase *new_reader) { reader = new_reader; }
+
/// Resample audio and map channels (if needed)
void ResampleMappedAudio(std::shared_ptr frame, int64_t original_frame_number);
diff --git a/include/ImageReader.h b/include/ImageReader.h
index e698e0c1..b02d2f04 100644
--- a/include/ImageReader.h
+++ b/include/ImageReader.h
@@ -3,9 +3,12 @@
* @brief Header file for ImageReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -28,6 +31,9 @@
#ifndef OPENSHOT_IMAGE_READER_H
#define OPENSHOT_IMAGE_READER_H
+// Require ImageMagick support
+#ifdef USE_IMAGEMAGICK
+
#include "ReaderBase.h"
#include
@@ -36,9 +42,9 @@
#include
#include
#include
-#include "Magick++.h"
#include "CacheMemory.h"
#include "Exceptions.h"
+#include "MagickUtilities.h"
using namespace std;
@@ -77,7 +83,7 @@ namespace openshot
/// frame 1, or it throws one of the following exceptions.
ImageReader(string path);
- /// Constructor for ImageReader. This only opens the media file to inspect it's properties
+ /// Constructor for ImageReader. This only opens the media file to inspect its properties
/// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful
/// when you are inflating the object using JSON after instantiating it.
ImageReader(string path, bool inspect_reader);
@@ -113,4 +119,5 @@ namespace openshot
}
-#endif
+#endif //USE_IMAGEMAGICK
+#endif //OPENSHOT_IMAGE_READER_H
diff --git a/include/ImageWriter.h b/include/ImageWriter.h
index 25177134..c1d2726a 100644
--- a/include/ImageWriter.h
+++ b/include/ImageWriter.h
@@ -3,9 +3,12 @@
* @brief Header file for ImageWriter class
* @author Jonathan Thomas , Fabrice Bellard
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2013 OpenShot Studios, LLC, Fabrice Bellard
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC, Fabrice Bellard
* (http://www.openshotstudios.com). This file is part of
* OpenShot Library (http://www.openshot.org), an open-source project
* dedicated to delivering high quality video editing and animation solutions
@@ -32,10 +35,11 @@
* along with OpenShot Library. If not, see .
*/
-
#ifndef OPENSHOT_IMAGE_WRITER_H
#define OPENSHOT_IMAGE_WRITER_H
+#ifdef USE_IMAGEMAGICK
+
#include "ReaderBase.h"
#include "WriterBase.h"
@@ -44,11 +48,10 @@
#include
#include
#include
-#include "Magick++.h"
#include "CacheMemory.h"
#include "Exceptions.h"
#include "OpenMPUtilities.h"
-
+#include "MagickUtilities.h"
using namespace std;
@@ -127,7 +130,7 @@ namespace openshot
/// @param height Height in pixels of image
/// @param quality Quality of image (0 to 100, 70 is default)
/// @param loops Number of times to repeat the image (used on certain multi-frame image formats, such as GIF)
- /// @param combine Combine frames into a single image (if possible), or save each frame as it's own image
+ /// @param combine Combine frames into a single image (if possible), or save each frame as its own image
void SetVideoOptions(string format, Fraction fps, int width, int height,
int quality, int loops, bool combine);
@@ -145,4 +148,5 @@ namespace openshot
}
-#endif
+#endif //USE_IMAGEMAGICK
+#endif //OPENSHOT_IMAGE_WRITER_H
diff --git a/include/Json.h b/include/Json.h
index 970034a5..3a10ab74 100644
--- a/include/Json.h
+++ b/include/Json.h
@@ -3,9 +3,12 @@
* @brief Header file for JSON class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/KeyFrame.h b/include/KeyFrame.h
index bab87f7c..14f519a1 100644
--- a/include/KeyFrame.h
+++ b/include/KeyFrame.h
@@ -3,9 +3,12 @@
* @brief Header file for the Keyframe class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/MagickUtilities.h b/include/MagickUtilities.h
new file mode 100644
index 00000000..f3b7ea12
--- /dev/null
+++ b/include/MagickUtilities.h
@@ -0,0 +1,61 @@
+/**
+ * @file
+ * @brief Header file for MagickUtilities (IM6/IM7 compatibility overlay)
+ * @author Jonathan Thomas
+ * @author FeRD (Frank Dana)
+ */
+
+/* LICENSE
+ *
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
+ * . This file is part of
+ * OpenShot Library (libopenshot), an open-source project dedicated to
+ * delivering high quality video editing and animation solutions to the
+ * world. For more information visit .
+ *
+ * OpenShot Library (libopenshot) is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * OpenShot Library (libopenshot) is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with OpenShot Library. If not, see .
+ */
+
+#ifndef OPENSHOT_MAGICK_UTILITIES_H
+#define OPENSHOT_MAGICK_UTILITIES_H
+
+#ifdef USE_IMAGEMAGICK
+
+ #include "Magick++.h"
+
+ // Determine ImageMagick version, as IM7 isn't fully
+ // backwards compatible
+ #ifndef NEW_MAGICK
+ #define NEW_MAGICK (MagickLibVersion >= 0x700)
+ #endif
+
+ // IM7: ->alpha(bool)
+ // IM6: ->matte(bool)
+ #if NEW_MAGICK
+ #define MAGICK_IMAGE_ALPHA(im, a) im->alpha((a))
+ #else
+ #define MAGICK_IMAGE_ALPHA(im, a) im->matte((a))
+ #endif
+
+ // IM7: vector
+ // IM6: list
+ // (both have the push_back() method which is all we use)
+ #if NEW_MAGICK
+ #define MAGICK_DRAWABLE vector
+ #else
+ #define MAGICK_DRAWABLE list
+ #endif
+
+#endif
+#endif
diff --git a/include/OpenMPUtilities.h b/include/OpenMPUtilities.h
index 8a95a950..e0087064 100644
--- a/include/OpenMPUtilities.h
+++ b/include/OpenMPUtilities.h
@@ -3,9 +3,12 @@
* @brief Header file for OpenMPUtilities (set some common macros)
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -29,8 +32,17 @@
#define OPENSHOT_OPENMP_UTILITIES_H
#include
+#include
+#include
+
+#include "Settings.h"
+
+using namespace std;
+using namespace openshot;
+
+// Calculate the # of OpenMP Threads to allow
+#define OPEN_MP_NUM_PROCESSORS (min(omp_get_num_procs(), max(2, openshot::Settings::Instance()->OMP_THREADS) ))
+#define FF_NUM_PROCESSORS (min(omp_get_num_procs(), max(2, openshot::Settings::Instance()->FF_THREADS) ))
- // Calculate the # of OpenMP Threads to allow
- #define OPEN_MP_NUM_PROCESSORS omp_get_num_procs()
#endif
diff --git a/include/OpenShot.h b/include/OpenShot.h
index e4b60f3e..fb53164c 100644
--- a/include/OpenShot.h
+++ b/include/OpenShot.h
@@ -64,15 +64,18 @@
* canvas (i.e. pan & scan).
* \image html /doc/images/Timeline_Layers.png
*
- * ### Build Instructions (Linux, Mac, and Windows) ###
- * For a step-by-step guide to building / compiling libopenshot, check out the
- * Official Installation Guide.
+ * ### Build Instructions ###
+ * Build instructions are available for all three major Operating Systems:
+ * * [Building libopenshot for Windows](doc/INSTALL-WINDOWS.md)
+ * * [Building libopenshot for MacOS](doc/INSTALL-MAC.md)
+ * * [Building libopenshot for Linux](doc/INSTALL-LINUX.md)
*
* ### Want to Learn More? ###
* To continue learning about libopenshot, take a look at the full list of classes available.
*
+ * \anchor License
* ### License & Copyright ###
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -134,5 +137,6 @@
#include "Profiles.h"
#include "QtImageReader.h"
#include "Timeline.h"
+#include "Settings.h"
#endif
diff --git a/include/PlayerBase.h b/include/PlayerBase.h
index 80cdf708..f017c3f2 100644
--- a/include/PlayerBase.h
+++ b/include/PlayerBase.h
@@ -3,9 +3,12 @@
* @brief Header file for PlayerBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -29,7 +32,7 @@
#define OPENSHOT_PLAYER_BASE_H
#include
-#include "../include/ReaderBase.h"
+#include "ReaderBase.h"
using namespace std;
@@ -104,6 +107,7 @@ namespace openshot
/// Set the Volume (1.0 = normal volume, <1.0 = quieter, >1.0 louder)
virtual void Volume(float new_volume) = 0;
+ virtual ~PlayerBase() = default;
};
}
diff --git a/include/Point.h b/include/Point.h
index 139aa64d..d9a5e33d 100644
--- a/include/Point.h
+++ b/include/Point.h
@@ -3,9 +3,12 @@
* @brief Header file for Point class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Profiles.h b/include/Profiles.h
index fa279d57..a6e3d22d 100644
--- a/include/Profiles.h
+++ b/include/Profiles.h
@@ -3,9 +3,12 @@
* @brief Header file for Profile class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Qt/AudioPlaybackThread.h b/include/Qt/AudioPlaybackThread.h
index 9f534749..94abf806 100644
--- a/include/Qt/AudioPlaybackThread.h
+++ b/include/Qt/AudioPlaybackThread.h
@@ -4,9 +4,12 @@
* @author Duzy Chan
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -29,9 +32,11 @@
#ifndef OPENSHOT_AUDIO_PLAYBACK_THREAD_H
#define OPENSHOT_AUDIO_PLAYBACK_THREAD_H
-#include "../../include/ReaderBase.h"
-#include "../../include/RendererBase.h"
-#include "../../include/AudioReaderSource.h"
+#include "../ReaderBase.h"
+#include "../RendererBase.h"
+#include "../AudioReaderSource.h"
+#include "../AudioDeviceInfo.h"
+#include "../Settings.h"
namespace openshot
{
@@ -57,14 +62,20 @@ namespace openshot
class AudioDeviceManagerSingleton {
private:
/// Default constructor (Don't allow user to create an instance of this singleton)
- AudioDeviceManagerSingleton(){};
+ AudioDeviceManagerSingleton(){ initialise_error=""; };
/// Private variable to keep track of singleton instance
static AudioDeviceManagerSingleton * m_pInstance;
public:
- /// Create or get an instance of this singleton (invoke the class with this method)
- static AudioDeviceManagerSingleton * Instance(int numChannels);
+ /// Error found during JUCE initialise method
+ string initialise_error;
+
+ /// List of valid audio device names
+ vector audio_device_names;
+
+ /// Override with no channels and no preferred audio device
+ static AudioDeviceManagerSingleton * Instance();
/// Public device manager property
AudioDeviceManager audioDeviceManager;
@@ -78,52 +89,58 @@ namespace openshot
*/
class AudioPlaybackThread : Thread
{
- AudioSourcePlayer player;
- AudioTransportSource transport;
- MixerAudioSource mixer;
- AudioReaderSource *source;
- double sampleRate;
- int numChannels;
- WaitableEvent play;
- WaitableEvent played;
- int buffer_size;
- bool is_playing;
- SafeTimeSliceThread time_thread;
-
- /// Constructor
- AudioPlaybackThread();
- /// Destructor
- ~AudioPlaybackThread();
+ AudioSourcePlayer player;
+ AudioTransportSource transport;
+ MixerAudioSource mixer;
+ AudioReaderSource *source;
+ double sampleRate;
+ int numChannels;
+ WaitableEvent play;
+ WaitableEvent played;
+ int buffer_size;
+ bool is_playing;
+ SafeTimeSliceThread time_thread;
- /// Set the current thread's reader
- void Reader(ReaderBase *reader);
+ /// Constructor
+ AudioPlaybackThread();
+ /// Destructor
+ ~AudioPlaybackThread();
- /// Get the current frame object (which is filling the buffer)
- std::shared_ptr getFrame();
+ /// Set the current thread's reader
+ void Reader(ReaderBase *reader);
- /// Get the current frame number being played
- int64_t getCurrentFramePosition();
+ /// Get the current frame object (which is filling the buffer)
+ std::shared_ptr getFrame();
- /// Play the audio
- void Play();
+ /// Get the current frame number being played
+ int64_t getCurrentFramePosition();
- /// Seek the audio thread
- void Seek(int64_t new_position);
+ /// Play the audio
+ void Play();
- /// Stop the audio playback
- void Stop();
+ /// Seek the audio thread
+ void Seek(int64_t new_position);
- /// Start thread
- void run();
-
- /// Set Speed (The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...)
- void setSpeed(int new_speed) { if (source) source->setSpeed(new_speed); }
+ /// Stop the audio playback
+ void Stop();
- /// Get Speed (The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...)
- int getSpeed() const { if (source) return source->getSpeed(); else return 1; }
+ /// Start thread
+ void run();
- friend class PlayerPrivate;
- friend class QtPlayer;
+ /// Set Speed (The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...)
+ void setSpeed(int new_speed) { if (source) source->setSpeed(new_speed); }
+
+ /// Get Speed (The speed and direction to playback a reader (1=normal, 2=fast, 3=faster, -1=rewind, etc...)
+ int getSpeed() const { if (source) return source->getSpeed(); else return 1; }
+
+ /// Get Audio Error (if any)
+ string getError() { return AudioDeviceManagerSingleton::Instance()->initialise_error; }
+
+ /// Get Audio Device Names (if any)
+ vector getAudioDeviceNames() { return AudioDeviceManagerSingleton::Instance()->audio_device_names; };
+
+ friend class PlayerPrivate;
+ friend class QtPlayer;
};
}
diff --git a/include/Qt/PlayerDemo.h b/include/Qt/PlayerDemo.h
index c02f863c..e5d304a4 100644
--- a/include/Qt/PlayerDemo.h
+++ b/include/Qt/PlayerDemo.h
@@ -3,9 +3,12 @@
* @brief Header file for demo application for QtPlayer class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Qt/PlayerPrivate.h b/include/Qt/PlayerPrivate.h
index 3311dea9..f846fb2a 100644
--- a/include/Qt/PlayerPrivate.h
+++ b/include/Qt/PlayerPrivate.h
@@ -4,9 +4,12 @@
* @author Duzy Chan
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -29,12 +32,12 @@
#ifndef OPENSHOT_PLAYER_PRIVATE_H
#define OPENSHOT_PLAYER_PRIVATE_H
-#include "../../include/ReaderBase.h"
-#include "../../include/RendererBase.h"
-#include "../../include/AudioReaderSource.h"
-#include "../../include/Qt/AudioPlaybackThread.h"
-#include "../../include/Qt/VideoPlaybackThread.h"
-#include "../../include/Qt/VideoCacheThread.h"
+#include "../ReaderBase.h"
+#include "../RendererBase.h"
+#include "../AudioReaderSource.h"
+#include "../Qt/AudioPlaybackThread.h"
+#include "../Qt/VideoPlaybackThread.h"
+#include "../Qt/VideoCacheThread.h"
namespace openshot
{
diff --git a/include/Qt/VideoCacheThread.h b/include/Qt/VideoCacheThread.h
index 3f781f62..6fbf6d58 100644
--- a/include/Qt/VideoCacheThread.h
+++ b/include/Qt/VideoCacheThread.h
@@ -3,9 +3,12 @@
* @brief Source file for VideoCacheThread class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -28,9 +31,9 @@
#ifndef OPENSHOT_VIDEO_CACHE_THREAD_H
#define OPENSHOT_VIDEO_CACHE_THREAD_H
-#include "../../include/OpenMPUtilities.h"
-#include "../../include/ReaderBase.h"
-#include "../../include/RendererBase.h"
+#include "../OpenMPUtilities.h"
+#include "../ReaderBase.h"
+#include "../RendererBase.h"
namespace openshot
{
diff --git a/include/Qt/VideoPlaybackThread.h b/include/Qt/VideoPlaybackThread.h
index 03ffe6d2..753c7778 100644
--- a/include/Qt/VideoPlaybackThread.h
+++ b/include/Qt/VideoPlaybackThread.h
@@ -4,9 +4,12 @@
* @author Duzy Chan
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -29,8 +32,8 @@
#ifndef OPENSHOT_VIDEO_PLAYBACK_THREAD_H
#define OPENSHOT_VIDEO_PLAYBACK_THREAD_H
-#include "../../include/ReaderBase.h"
-#include "../../include/RendererBase.h"
+#include "../ReaderBase.h"
+#include "../RendererBase.h"
namespace openshot
{
diff --git a/include/Qt/VideoRenderWidget.h b/include/Qt/VideoRenderWidget.h
index 19675cc8..429940e7 100644
--- a/include/Qt/VideoRenderWidget.h
+++ b/include/Qt/VideoRenderWidget.h
@@ -3,9 +3,12 @@
* @brief Header file for Video RendererWidget class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/Qt/VideoRenderer.h b/include/Qt/VideoRenderer.h
index aaf973ca..1bdbfac3 100644
--- a/include/Qt/VideoRenderer.h
+++ b/include/Qt/VideoRenderer.h
@@ -3,9 +3,12 @@
* @brief Header file for Video Renderer class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/QtImageReader.h b/include/QtImageReader.h
index 772a879e..814e3cb3 100644
--- a/include/QtImageReader.h
+++ b/include/QtImageReader.h
@@ -3,9 +3,12 @@
* @brief Header file for QtImageReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -28,19 +31,14 @@
#ifndef OPENSHOT_QIMAGE_READER_H
#define OPENSHOT_QIMAGE_READER_H
-#include "ReaderBase.h"
-
#include
#include
#include
#include
#include
#include
-#include
-#include
-#include
-#include "CacheMemory.h"
#include "Exceptions.h"
+#include "ReaderBase.h"
using namespace std;
@@ -70,9 +68,10 @@ namespace openshot
{
private:
string path;
- std::shared_ptr image; ///> Original image (full quality)
- std::shared_ptr cached_image; ///> Scaled for performance
- bool is_open;
+ std::shared_ptr image; ///> Original image (full quality)
+ std::shared_ptr cached_image; ///> Scaled for performance
+ bool is_open; ///> Is Reader opened
+ QSize max_size; ///> Current max_size as calculated with Clip properties
public:
@@ -80,11 +79,13 @@ namespace openshot
/// frame 1, or it throws one of the following exceptions.
QtImageReader(string path);
- /// Constructor for QtImageReader. This only opens the media file to inspect it's properties
+ /// Constructor for QtImageReader. This only opens the media file to inspect its properties
/// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful
/// when you are inflating the object using JSON after instantiating it.
QtImageReader(string path, bool inspect_reader);
+ virtual ~QtImageReader();
+
/// Close File
void Close();
@@ -110,9 +111,6 @@ namespace openshot
Json::Value JsonValue(); ///< Generate Json::JsonValue for this object
void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object
- /// Set Max Image Size (used for performance optimization)
- void SetMaxSize(int width, int height);
-
/// Open File - which is called by the constructor automatically
void Open();
};
diff --git a/include/QtPlayer.h b/include/QtPlayer.h
index 8774b886..5d0beba6 100644
--- a/include/QtPlayer.h
+++ b/include/QtPlayer.h
@@ -4,9 +4,12 @@
* @author Duzy Chan
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -31,9 +34,9 @@
#include
#include
-#include "../include/PlayerBase.h"
-#include "../include/Qt/PlayerPrivate.h"
-#include "../include/RendererBase.h"
+#include "PlayerBase.h"
+#include "Qt/PlayerPrivate.h"
+#include "RendererBase.h"
using namespace std;
@@ -59,6 +62,12 @@ namespace openshot
/// Close audio device
void CloseAudioDevice();
+ /// Get Error (if any)
+ string GetError();
+
+ /// Get Audio Devices from JUCE
+ vector GetAudioDeviceNames();
+
/// Play the video
void Play();
diff --git a/include/ReaderBase.h b/include/ReaderBase.h
index 2b3ee917..0d14ea19 100644
--- a/include/ReaderBase.h
+++ b/include/ReaderBase.h
@@ -3,9 +3,12 @@
* @brief Header file for ReaderBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -35,6 +38,7 @@
#include
#include "CacheMemory.h"
#include "ChannelLayouts.h"
+#include "ClipBase.h"
#include "Fraction.h"
#include "Frame.h"
#include "Json.h"
@@ -99,9 +103,7 @@ namespace openshot
/// Section lock for multiple threads
CriticalSection getFrameCriticalSection;
CriticalSection processingCriticalSection;
-
- int max_width; ///< The maximum image width needed by this clip (used for optimizations)
- int max_height; ///< The maximium image height needed by this clip (used for optimizations)
+ ClipBase* parent;
public:
@@ -111,6 +113,12 @@ namespace openshot
/// Information about the current media file
ReaderInfo info;
+ /// Parent clip object of this reader (which can be unparented and NULL)
+ ClipBase* GetClip();
+
+ /// Set parent clip object of this reader
+ void SetClip(ClipBase* clip);
+
/// Close the reader (and any resources it was consuming)
virtual void Close() = 0;
@@ -140,11 +148,10 @@ namespace openshot
virtual Json::Value JsonValue() = 0; ///< Generate Json::JsonValue for this object
virtual void SetJsonValue(Json::Value root) = 0; ///< Load Json::JsonValue into this object
- /// Set Max Image Size (used for performance optimization)
- void SetMaxSize(int width, int height) { max_width = width; max_height = height; };
-
/// Open the reader (and start consuming resources, such as images or video files)
virtual void Open() = 0;
+
+ virtual ~ReaderBase() = default;
};
}
diff --git a/include/RendererBase.h b/include/RendererBase.h
index 3f1c0b1c..2638d336 100644
--- a/include/RendererBase.h
+++ b/include/RendererBase.h
@@ -3,9 +3,12 @@
* @brief Header file for RendererBase class
* @author Duzy Chan
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -28,7 +31,7 @@
#ifndef OPENSHOT_RENDERER_BASE_H
#define OPENSHOT_RENDERER_BASE_H
-#include "../include/Frame.h"
+#include "Frame.h"
#include // for realloc
#include
diff --git a/include/Settings.h b/include/Settings.h
new file mode 100644
index 00000000..11d7f76c
--- /dev/null
+++ b/include/Settings.h
@@ -0,0 +1,135 @@
+/**
+ * @file
+ * @brief Header file for global Settings class
+ * @author Jonathan Thomas
+ *
+ * @ref License
+ */
+
+/* LICENSE
+ *
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
+ * . This file is part of
+ * OpenShot Library (libopenshot), an open-source project dedicated to
+ * delivering high quality video editing and animation solutions to the
+ * world. For more information visit .
+ *
+ * OpenShot Library (libopenshot) is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * OpenShot Library (libopenshot) is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with OpenShot Library. If not, see .
+ */
+
+#ifndef OPENSHOT_SETTINGS_H
+#define OPENSHOT_SETTINGS_H
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "JuceHeader.h"
+
+
+using namespace std;
+
+namespace openshot {
+
+ /**
+ * @brief This class is contains settings used by libopenshot (and can be safely toggled at any point)
+ *
+ * Settings class is used primarily to toggle scale settings between preview and rendering, and adjust
+ * other runtime related settings.
+ */
+ class Settings {
+ private:
+
+ /// Default constructor
+ Settings(){}; // Don't allow user to create an instance of this singleton
+
+#if __GNUC__ >=7
+ /// Default copy method
+ Settings(Settings const&) = delete; // Don't allow the user to assign this instance
+
+ /// Default assignment operator
+ Settings & operator=(Settings const&) = delete; // Don't allow the user to assign this instance
+#else
+ /// Default copy method
+ Settings(Settings const&) {}; // Don't allow the user to assign this instance
+
+ /// Default assignment operator
+ Settings & operator=(Settings const&); // Don't allow the user to assign this instance
+#endif
+
+ /// Private variable to keep track of singleton instance
+ static Settings * m_pInstance;
+
+ public:
+ /**
+ * @brief Use video codec for faster video decoding (if supported)
+ *
+ * 0 - No acceleration,
+ * 1 - Linux VA-API,
+ * 2 - nVidia NVDEC,
+ * 3 - Windows D3D9,
+ * 4 - Windows D3D11,
+ * 5 - MacOS / VideoToolBox,
+ * 6 - Linux VDPAU,
+ * 7 - Intel QSV
+ */
+ int HARDWARE_DECODER = 0;
+
+ /// Scale mode used in FFmpeg decoding and encoding (used as an optimization for faster previews)
+ bool HIGH_QUALITY_SCALING = false;
+
+ /// Maximum width for image data (useful for optimzing for a smaller preview or render)
+ int MAX_WIDTH = 0;
+
+ /// Maximum height for image data (useful for optimzing for a smaller preview or render)
+ int MAX_HEIGHT = 0;
+
+ /// Wait for OpenMP task to finish before continuing (used to limit threads on slower systems)
+ bool WAIT_FOR_VIDEO_PROCESSING_TASK = false;
+
+ /// Number of threads of OpenMP
+ int OMP_THREADS = 12;
+
+ /// Number of threads that ffmpeg uses
+ int FF_THREADS = 8;
+
+ /// Maximum rows that hardware decode can handle
+ int DE_LIMIT_HEIGHT_MAX = 1100;
+
+ /// Maximum columns that hardware decode can handle
+ int DE_LIMIT_WIDTH_MAX = 1950;
+
+ /// Which GPU to use to decode (0 is the first)
+ int HW_DE_DEVICE_SET = 0;
+
+ /// Which GPU to use to encode (0 is the first)
+ int HW_EN_DEVICE_SET = 0;
+
+ /// The audio device name to use during playback
+ string PLAYBACK_AUDIO_DEVICE_NAME = "";
+
+ /// Create or get an instance of this logger singleton (invoke the class with this method)
+ static Settings * Instance();
+ };
+
+}
+
+#endif
diff --git a/include/Tests.h b/include/Tests.h
index b7d9dbf5..b647cb0e 100644
--- a/include/Tests.h
+++ b/include/Tests.h
@@ -3,9 +3,12 @@
* @brief Header file for UnitTests
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/include/TextReader.h b/include/TextReader.h
index d7d653d2..7b276f7f 100644
--- a/include/TextReader.h
+++ b/include/TextReader.h
@@ -3,9 +3,12 @@
* @brief Header file for TextReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -28,6 +31,9 @@
#ifndef OPENSHOT_TEXT_READER_H
#define OPENSHOT_TEXT_READER_H
+// Require ImageMagick support
+#ifdef USE_IMAGEMAGICK
+
#include "ReaderBase.h"
#include
@@ -36,10 +42,10 @@
#include
#include
#include
-#include "Magick++.h"
#include "CacheMemory.h"
#include "Enums.h"
#include "Exceptions.h"
+#include "MagickUtilities.h"
using namespace std;
@@ -90,8 +96,9 @@ namespace openshot
double size;
string text_color;
string background_color;
+ string text_background_color;
std::shared_ptr image;
- list lines;
+ MAGICK_DRAWABLE lines;
bool is_open;
GravityType gravity;
@@ -110,9 +117,13 @@ namespace openshot
/// @param font The font of the text
/// @param size The size of the text
/// @param text_color The color of the text
- /// @param background_color The background color of the text (also supports Transparent)
+ /// @param background_color The background color of the text frame image (also supports Transparent)
TextReader(int width, int height, int x_offset, int y_offset, GravityType gravity, string text, string font, double size, string text_color, string background_color);
+ /// Draw a box under rendered text using the specified color.
+ /// @param text_background_color The background color behind the text
+ void SetTextBackgroundColor(string color);
+
/// Close Reader
void Close();
@@ -144,4 +155,5 @@ namespace openshot
}
-#endif
+#endif //USE_IMAGEMAGICK
+#endif //OPENSHOT_TEXT_READER_H
diff --git a/include/Timeline.h b/include/Timeline.h
index ed5c2ab3..3793f301 100644
--- a/include/Timeline.h
+++ b/include/Timeline.h
@@ -3,9 +3,12 @@
* @brief Header file for Timeline class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -30,6 +33,7 @@
#include
#include
+#include
#include
#include
#include "CacheBase.h"
@@ -48,6 +52,7 @@
#include "KeyFrame.h"
#include "OpenMPUtilities.h"
#include "ReaderBase.h"
+#include "Settings.h"
using namespace std;
using namespace openshot;
@@ -99,6 +104,7 @@ namespace openshot {
* Fraction(25,1), // framerate
* 44100, // sample rate
* 2 // channels
+ * ChannelLayout::LAYOUT_STEREO,
* );
*
* // Create some clips
@@ -151,6 +157,8 @@ namespace openshot {
map open_clips; /// effects; /// allocated_frame_mappers; ///< all the frame mappers we allocated and must free
+ bool managed_cache; ///< Does this timeline instance manage the cache object
/// Process a new layer of video or audio
void add_layer(std::shared_ptr new_frame, Clip* source_clip, int64_t clip_frame_number, int64_t timeline_frame_number, bool is_top_clip, float max_volume);
@@ -204,6 +212,8 @@ namespace openshot {
/// @param channel_layout The channel layout (i.e. mono, stereo, 3 point surround, etc...)
Timeline(int width, int height, Fraction fps, int sample_rate, int channels, ChannelLayout channel_layout);
+ virtual ~Timeline();
+
/// @brief Add an openshot::Clip to the timeline
/// @param clip Add an openshot::Clip to the timeline. A clip can contain any type of Reader.
void AddClip(Clip* clip);
@@ -236,7 +246,8 @@ namespace openshot {
/// Get the cache object used by this reader
CacheBase* GetCache() { return final_cache; };
- /// Get the cache object used by this reader
+ /// Set the cache object used by this reader. You must now manage the lifecycle
+ /// of this cache object though (Timeline will not delete it for you).
void SetCache(CacheBase* new_cache);
/// Get an openshot::Frame object for a specific frame number of this timeline.
@@ -265,6 +276,10 @@ namespace openshot {
Json::Value JsonValue(); ///< Generate Json::JsonValue for this object
void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object
+ /// Set Max Image Size (used for performance optimization). Convenience function for setting
+ /// Settings::Instance()->MAX_WIDTH and Settings::Instance()->MAX_HEIGHT.
+ void SetMaxSize(int width, int height);
+
/// @brief Apply a special formatted JSON object, which represents a change to the timeline (add, update, delete)
/// This is primarily designed to keep the timeline (and its child objects... such as clips and effects) in sync
/// with another application... such as OpenShot Video Editor (http://www.openshot.org).
diff --git a/include/Version.h b/include/Version.h
index cd72ab20..ec9e94a6 100644
--- a/include/Version.h
+++ b/include/Version.h
@@ -3,9 +3,12 @@
* @brief Header file that includes the version number of libopenshot
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -35,9 +38,9 @@
#endif
#define OPENSHOT_VERSION_MAJOR 0; /// Major version number is incremented when huge features are added or improved.
-#define OPENSHOT_VERSION_MINOR 1; /// Minor version is incremented when smaller (but still very important) improvements are added.
-#define OPENSHOT_VERSION_BUILD 9; /// Build number is incremented when minor bug fixes and less important improvements are added.
-#define OPENSHOT_VERSION_SO 14; /// Shared object version number. This increments any time the API and ABI changes (so old apps will no longer link)
+#define OPENSHOT_VERSION_MINOR 2; /// Minor version is incremented when smaller (but still very important) improvements are added.
+#define OPENSHOT_VERSION_BUILD 3; /// Build number is incremented when minor bug fixes and less important improvements are added.
+#define OPENSHOT_VERSION_SO 17; /// Shared object version number. This increments any time the API and ABI changes (so old apps will no longer link)
#define OPENSHOT_VERSION_MAJOR_MINOR STRINGIZE(OPENSHOT_VERSION_MAJOR) "." STRINGIZE(OPENSHOT_VERSION_MINOR); /// A string of the "Major.Minor" version
#define OPENSHOT_VERSION_ALL STRINGIZE(OPENSHOT_VERSION_MAJOR) "." STRINGIZE(OPENSHOT_VERSION_MINOR) "." STRINGIZE(OPENSHOT_VERSION_BUILD); /// A string of the entire version "Major.Minor.Build"
diff --git a/include/WriterBase.h b/include/WriterBase.h
index 8f424054..7620da64 100644
--- a/include/WriterBase.h
+++ b/include/WriterBase.h
@@ -3,9 +3,12 @@
* @brief Header file for WriterBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -116,6 +119,8 @@ namespace openshot
/// Open the writer (and start initializing streams)
virtual void Open() = 0;
+
+ virtual ~WriterBase() = default;
};
}
diff --git a/include/ZmqLogger.h b/include/ZmqLogger.h
index c134f2cf..96e16213 100644
--- a/include/ZmqLogger.h
+++ b/include/ZmqLogger.h
@@ -3,9 +3,12 @@
* @brief Header file for ZeroMQ-based Logger class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -29,7 +32,6 @@
#define OPENSHOT_LOGGER_H
-#include "JuceLibraryCode/JuceHeader.h"
#include
#include
#include
@@ -40,6 +42,7 @@
#include
#include
#include
+#include "JuceHeader.h"
using namespace std;
@@ -47,11 +50,10 @@ using namespace std;
namespace openshot {
/**
- * @brief This abstract class is the base class, used by all readers in libopenshot.
+ * @brief This class is used for logging and sending those logs over a ZemoMQ socket to a listener
*
- * Readers are types of classes that read video, audio, and image files, and
- * return openshot::Frame objects. The only requirements for a 'reader', are to
- * derive from this base class, implement the GetFrame method, and call the InitFileInfo() method.
+ * OpenShot desktop editor listens to this port, to receive libopenshot debug output. It both logs to
+ * a file and sends the stdout over a socket.
*/
class ZmqLogger {
private:
@@ -72,11 +74,19 @@ namespace openshot {
/// Default constructor
ZmqLogger(){}; // Don't allow user to create an instance of this singleton
+#if __GNUC__ >=7
/// Default copy method
- ZmqLogger(ZmqLogger const&){}; // Don't allow the user to copy this instance
+ ZmqLogger(ZmqLogger const&) = delete; // Don't allow the user to assign this instance
/// Default assignment operator
- ZmqLogger & operator=(ZmqLogger const&){}; // Don't allow the user to assign this instance
+ ZmqLogger & operator=(ZmqLogger const&) = delete; // Don't allow the user to assign this instance
+#else
+ /// Default copy method
+ ZmqLogger(ZmqLogger const&) {}; // Don't allow the user to assign this instance
+
+ /// Default assignment operator
+ ZmqLogger & operator=(ZmqLogger const&); // Don't allow the user to assign this instance
+#endif
/// Private variable to keep track of singleton instance
static ZmqLogger * m_pInstance;
diff --git a/include/effects/Bars.h b/include/effects/Bars.h
index 27d21725..515d2f11 100644
--- a/include/effects/Bars.h
+++ b/include/effects/Bars.h
@@ -3,9 +3,12 @@
* @brief Header file for Bars effect class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -80,7 +83,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Blur.h b/include/effects/Blur.h
index 314dabbe..6d48c172 100644
--- a/include/effects/Blur.h
+++ b/include/effects/Blur.h
@@ -3,9 +3,12 @@
* @brief Header file for Blur effect class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -93,7 +96,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Brightness.h b/include/effects/Brightness.h
index 67ab4c9c..fd43f784 100644
--- a/include/effects/Brightness.h
+++ b/include/effects/Brightness.h
@@ -3,9 +3,12 @@
* @brief Header file for Brightness class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -80,7 +83,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/ChromaKey.h b/include/effects/ChromaKey.h
index 000dbba4..4440302b 100644
--- a/include/effects/ChromaKey.h
+++ b/include/effects/ChromaKey.h
@@ -3,9 +3,12 @@
* @brief Header file for ChromaKey class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -77,7 +80,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/ColorShift.h b/include/effects/ColorShift.h
index 4b3de2bb..44c7269b 100644
--- a/include/effects/ColorShift.h
+++ b/include/effects/ColorShift.h
@@ -3,9 +3,12 @@
* @brief Header file for Color Shift effect class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -84,7 +87,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Crop.h b/include/effects/Crop.h
index 7921a78d..93b54e31 100644
--- a/include/effects/Crop.h
+++ b/include/effects/Crop.h
@@ -3,9 +3,12 @@
* @brief Header file for Crop effect class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -69,7 +72,6 @@ namespace openshot
/// Default constructor, which takes 4 curves. These curves animate the crop over time.
///
- /// @param color The curve to adjust the color of bars
/// @param left The curve to adjust the left bar size (between 0 and 1)
/// @param top The curve to adjust the top bar size (between 0 and 1)
/// @param right The curve to adjust the right bar size (between 0 and 1)
@@ -80,7 +82,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Deinterlace.h b/include/effects/Deinterlace.h
index c1fb7227..1559a09e 100644
--- a/include/effects/Deinterlace.h
+++ b/include/effects/Deinterlace.h
@@ -3,9 +3,12 @@
* @brief Header file for De-interlace class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -73,7 +76,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Hue.h b/include/effects/Hue.h
index 4f680047..e6652391 100644
--- a/include/effects/Hue.h
+++ b/include/effects/Hue.h
@@ -3,9 +3,12 @@
* @brief Header file for Hue effect class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -70,7 +73,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Mask.h b/include/effects/Mask.h
index ad1a6aab..de48219c 100644
--- a/include/effects/Mask.h
+++ b/include/effects/Mask.h
@@ -3,9 +3,12 @@
* @brief Header file for Mask class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -25,8 +28,8 @@
* along with OpenShot Library. If not, see .
*/
-#ifndef OPENSHOT_WIPE_EFFECT_H
-#define OPENSHOT_WIPE_EFFECT_H
+#ifndef OPENSHOT_MASK_EFFECT_H
+#define OPENSHOT_MASK_EFFECT_H
#include "../EffectBase.h"
@@ -45,6 +48,7 @@
#include "../QtImageReader.h"
#include "../ChunkReader.h"
#ifdef USE_IMAGEMAGICK
+ #include "../MagickUtilities.h"
#include "../ImageReader.h"
#endif
@@ -54,7 +58,7 @@ namespace openshot
{
/**
- * @brief This class uses the ImageMagick++ libraries, to apply alpha (or transparency) masks
+ * @brief This class uses the image libraries to apply alpha (or transparency) masks
* to any frame. It can also be animated, and used as a powerful Wipe transition.
*
* These masks / wipes can also be combined, such as a transparency mask on top of a clip, which
@@ -65,6 +69,7 @@ namespace openshot
private:
ReaderBase *reader;
std::shared_ptr original_mask;
+ bool needs_refresh;
/// Init effect settings
void init_effect_details();
@@ -90,7 +95,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Negate.h b/include/effects/Negate.h
index 84621132..f2437fee 100644
--- a/include/effects/Negate.h
+++ b/include/effects/Negate.h
@@ -3,9 +3,12 @@
* @brief Header file for Negate class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -61,7 +64,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Pixelate.h b/include/effects/Pixelate.h
index b8ca2998..06509894 100644
--- a/include/effects/Pixelate.h
+++ b/include/effects/Pixelate.h
@@ -3,9 +3,12 @@
* @brief Header file for Pixelate effect class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -79,7 +82,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Saturation.h b/include/effects/Saturation.h
index d49069a6..a24d01ee 100644
--- a/include/effects/Saturation.h
+++ b/include/effects/Saturation.h
@@ -3,9 +3,12 @@
* @brief Header file for Saturation class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -77,7 +80,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Shift.h b/include/effects/Shift.h
index 86ccf7a4..db974ae2 100644
--- a/include/effects/Shift.h
+++ b/include/effects/Shift.h
@@ -3,9 +3,12 @@
* @brief Header file for Shift effect class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -73,7 +76,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/include/effects/Wave.h b/include/effects/Wave.h
index 04c1620f..022173ea 100644
--- a/include/effects/Wave.h
+++ b/include/effects/Wave.h
@@ -3,9 +3,12 @@
* @brief Header file for Wave effect class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -79,7 +82,7 @@ namespace openshot
/// modified openshot::Frame object
///
/// The frame object is passed into this method, and a frame_number is passed in which
- /// tells the effect which settings to use from it's keyframes (starting at 1).
+ /// tells the effect which settings to use from its keyframes (starting at 1).
///
/// @returns The modified openshot::Frame object
/// @param frame The frame object that needs the effect applied to it
diff --git a/src/AudioBufferSource.cpp b/src/AudioBufferSource.cpp
index 3b00f742..912d2552 100644
--- a/src/AudioBufferSource.cpp
+++ b/src/AudioBufferSource.cpp
@@ -3,9 +3,12 @@
* @brief Source file for AudioBufferSource class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/src/AudioReaderSource.cpp b/src/AudioReaderSource.cpp
index b1bb2cd3..4c42d2ed 100644
--- a/src/AudioReaderSource.cpp
+++ b/src/AudioReaderSource.cpp
@@ -3,9 +3,12 @@
* @brief Source file for AudioReaderSource class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/src/AudioResampler.cpp b/src/AudioResampler.cpp
index 442a91d9..d9c5a609 100644
--- a/src/AudioResampler.cpp
+++ b/src/AudioResampler.cpp
@@ -3,9 +3,12 @@
* @brief Source file for AudioResampler class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -74,9 +77,9 @@ AudioResampler::~AudioResampler()
void AudioResampler::SetBuffer(AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate)
{
if (sample_rate <= 0)
- sample_rate == 44100;
+ sample_rate = 44100;
if (new_sample_rate <= 0)
- new_sample_rate == 44100;
+ new_sample_rate = 44100;
// Set the sample ratio (the ratio of sample rate change)
source_ratio = sample_rate / new_sample_rate;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7df1b69b..76b83145 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -4,7 +4,7 @@
#
# @section LICENSE
#
-# Copyright (c) 2008-2014 OpenShot Studios, LLC
+# Copyright (c) 2008-2019 OpenShot Studios, LLC
# . This file is part of
# OpenShot Library (libopenshot), an open-source project dedicated to
# delivering high quality video editing and animation solutions to the
@@ -37,12 +37,12 @@ IF (WIN32)
ENDIF(WIN32)
IF (APPLE)
# If you still get errors compiling with GCC 4.8, mac headers need to be patched: http://hamelot.co.uk/programming/osx-gcc-dispatch_block_t-has-not-been-declared-invalid-typedef/
- SET_PROPERTY(GLOBAL PROPERTY JUCE_MAC "JUCE_MAC")
- ADD_DEFINITIONS(-DNDEBUG)
- SET(EXTENSION "mm")
-
- SET(JUCE_PLATFORM_SPECIFIC_DIR build/macosx/platform_specific_code)
- SET(JUCE_PLATFORM_SPECIFIC_LIBRARIES "-framework Carbon -framework Cocoa -framework CoreFoundation -framework CoreAudio -framework CoreMidi -framework IOKit -framework AGL -framework AudioToolbox -framework QuartzCore -lobjc -framework Accelerate")
+ SET_PROPERTY(GLOBAL PROPERTY JUCE_MAC "JUCE_MAC")
+ ADD_DEFINITIONS(-DNDEBUG)
+ SET(EXTENSION "mm")
+
+ SET(JUCE_PLATFORM_SPECIFIC_DIR build/macosx/platform_specific_code)
+ SET(JUCE_PLATFORM_SPECIFIC_LIBRARIES "-framework Carbon -framework Cocoa -framework CoreFoundation -framework CoreAudio -framework CoreMidi -framework IOKit -framework AGL -framework AudioToolbox -framework QuartzCore -lobjc -framework Accelerate")
ENDIF(APPLE)
################ IMAGE MAGICK ##################
@@ -74,20 +74,43 @@ IF (ImageMagick_FOUND)
SET(CMAKE_SWIG_FLAGS "-DUSE_IMAGEMAGICK=1")
ENDIF (ImageMagick_FOUND)
-
+
################### FFMPEG #####################
# Find FFmpeg libraries (used for video encoding / decoding)
FIND_PACKAGE(FFmpeg REQUIRED)
-# Include FFmpeg headers (needed for compile)
-include_directories(${FFMPEG_INCLUDE_DIR})
+IF (AVCODEC_FOUND)
+ include_directories(${AVCODEC_INCLUDE_DIRS})
+ENDIF (AVCODEC_FOUND)
+IF (AVDEVICE_FOUND)
+ include_directories(${AVDEVICE_INCLUDE_DIRS})
+ENDIF (AVDEVICE_FOUND)
+IF (AVFORMAT_FOUND)
+ include_directories(${AVFORMAT_INCLUDE_DIRS})
+ENDIF (AVFORMAT_FOUND)
+IF (AVFILTER_FOUND)
+ include_directories(${AVFILTER_INCLUDE_DIRS})
+ENDIF (AVFILTER_FOUND)
+IF (AVUTIL_FOUND)
+ include_directories(${AVUTIL_INCLUDE_DIRS})
+ENDIF (AVUTIL_FOUND)
+IF (POSTPROC_FOUND)
+ include_directories(${POSTPROC_INCLUDE_DIRS})
+ENDIF (POSTPROC_FOUND)
+IF (SWSCALE_FOUND)
+ include_directories(${SWSCALE_INCLUDE_DIRS})
+ENDIF (SWSCALE_FOUND)
+IF (SWRESAMPLE_FOUND)
+ include_directories(${SWRESAMPLE_INCLUDE_DIRS})
+ENDIF (SWRESAMPLE_FOUND)
+IF (AVRESAMPLE_FOUND)
+ include_directories(${AVRESAMPLE_INCLUDE_DIRS})
+ENDIF (AVRESAMPLE_FOUND)
################# LIBOPENSHOT-AUDIO ###################
# Find JUCE-based openshot Audio libraries
FIND_PACKAGE(OpenShotAudio REQUIRED)
-message('LIBOPENSHOT_AUDIO_INCLUDE_DIRS: ${LIBOPENSHOT_AUDIO_INCLUDE_DIRS}')
-
# Include Juce headers (needed for compile)
include_directories(${LIBOPENSHOT_AUDIO_INCLUDE_DIRS})
@@ -112,11 +135,11 @@ add_definitions(${Qt5Gui_DEFINITIONS})
add_definitions(${Qt5Multimedia_DEFINITIONS})
add_definitions(${Qt5MultimediaWidgets_DEFINITIONS})
-SET(QT_LIBRARIES ${Qt5Widgets_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Multimedia_LIBRARIES}
- ${Qt5MultimediaWidgets_LIBRARIES})
+SET(QT_LIBRARIES ${Qt5Widgets_LIBRARIES}
+ ${Qt5Core_LIBRARIES}
+ ${Qt5Gui_LIBRARIES}
+ ${Qt5Multimedia_LIBRARIES}
+ ${Qt5MultimediaWidgets_LIBRARIES})
# Set compiler flags for Qt
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} ")
@@ -133,15 +156,15 @@ qt5_wrap_cpp(MOC_FILES ${QT_HEADER_FILES})
# Find BlackMagic DeckLinkAPI libraries
IF (ENABLE_BLACKMAGIC)
FIND_PACKAGE(BlackMagic)
-
+
IF (BLACKMAGIC_FOUND)
# Include headers (needed for compile)
include_directories(${BLACKMAGIC_INCLUDE_DIR})
-
+
# define a global var (used in the C++)
add_definitions( -DUSE_BLACKMAGIC=1 )
SET(CMAKE_SWIG_FLAGS "-DUSE_BLACKMAGIC=1")
-
+
ENDIF (BLACKMAGIC_FOUND)
ENDIF (ENABLE_BLACKMAGIC)
@@ -150,24 +173,39 @@ ENDIF (ENABLE_BLACKMAGIC)
FIND_PACKAGE(OpenMP)
if (OPENMP_FOUND)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} ")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} ")
endif(OPENMP_FOUND)
################### ZEROMQ #####################
# Find ZeroMQ library (used for socket communication & logging)
FIND_PACKAGE(ZMQ REQUIRED)
-# Include FFmpeg headers (needed for compile)
+# Include ZeroMQ headers (needed for compile)
include_directories(${ZMQ_INCLUDE_DIRS})
+################### RESVG #####################
+# Find resvg library (used for rendering svg files)
+FIND_PACKAGE(RESVG)
+
+# Include resvg headers (optional SVG library)
+if (RESVG_FOUND)
+ include_directories(${RESVG_INCLUDE_DIRS})
+
+ # define a global var (used in the C++)
+ add_definitions( -DUSE_RESVG=1 )
+ SET(CMAKE_SWIG_FLAGS "-DUSE_RESVG=1")
+endif(RESVG_FOUND)
+
################### JSONCPP #####################
# Include jsoncpp headers (needed for JSON parsing)
if (USE_SYSTEM_JSONCPP)
+ message(STATUS "Discovering system JsonCPP (USE_SYSTEM_JSONCPP enabled)")
find_package(JsonCpp REQUIRED)
include_directories(${JSONCPP_INCLUDE_DIRS})
+ message(STATUS "Discovering system JsonCPP - done")
else()
- message("Using embedded JsonCpp")
- include_directories("../thirdparty/jsoncpp/include")
+ message(STATUS "Using embedded JsonCpp (USE_SYSTEM_JSONCPP not enabled)")
+ include_directories("../thirdparty/jsoncpp")
endif(USE_SYSTEM_JSONCPP)
############### PROFILING #################
@@ -182,8 +220,8 @@ FILE(GLOB QT_PLAYER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/Qt/*.cpp")
############### SET LIBRARY SOURCE FILES #################
SET ( OPENSHOT_SOURCE_FILES
- AudioBufferSource.cpp
- AudioReaderSource.cpp
+ AudioBufferSource.cpp
+ AudioReaderSource.cpp
AudioResampler.cpp
CacheBase.cpp
CacheDisk.cpp
@@ -214,39 +252,39 @@ SET ( OPENSHOT_SOURCE_FILES
Profiles.cpp
QtImageReader.cpp
QtPlayer.cpp
+ Settings.cpp
Timeline.cpp
QtTextReader.cpp
+
# Qt Video Player
${QT_PLAYER_FILES}
${MOC_FILES})
- IF (NOT USE_SYSTEM_JSONCPP)
- # Third Party JSON Parser
- SET ( OPENSHOT_SOURCE_FILES ${OPENSHOT_SOURCE_FILES}
- ../thirdparty/jsoncpp/src/lib_json/json_reader.cpp
- ../thirdparty/jsoncpp/src/lib_json/json_value.cpp
- ../thirdparty/jsoncpp/src/lib_json/json_writer.cpp)
- ENDIF (NOT USE_SYSTEM_JSONCPP)
+IF (NOT USE_SYSTEM_JSONCPP)
+ # Third Party JSON Parser
+ SET ( OPENSHOT_SOURCE_FILES ${OPENSHOT_SOURCE_FILES}
+ ../thirdparty/jsoncpp/jsoncpp.cpp )
+ENDIF (NOT USE_SYSTEM_JSONCPP)
+
+# ImageMagic related files
+IF (ImageMagick_FOUND)
+ SET ( OPENSHOT_SOURCE_FILES ${OPENSHOT_SOURCE_FILES}
+ ImageReader.cpp
+ ImageWriter.cpp
+ TextReader.cpp)
+ENDIF (ImageMagick_FOUND)
+
+# BlackMagic related files
+IF (BLACKMAGIC_FOUND)
+ SET ( OPENSHOT_SOURCE_FILES ${OPENSHOT_SOURCE_FILES}
+ DecklinkInput.cpp
+ DecklinkReader.cpp
+ DecklinkOutput.cpp
+ DecklinkWriter.cpp)
+ENDIF (BLACKMAGIC_FOUND)
- # ImageMagic related files
- IF (ImageMagick_FOUND)
- SET ( OPENSHOT_SOURCE_FILES ${OPENSHOT_SOURCE_FILES}
- ImageReader.cpp
- ImageWriter.cpp
- TextReader.cpp)
- ENDIF (ImageMagick_FOUND)
- # BlackMagic related files
- IF (BLACKMAGIC_FOUND)
- SET ( OPENSHOT_SOURCE_FILES ${OPENSHOT_SOURCE_FILES}
- DecklinkInput.cpp
- DecklinkReader.cpp
- DecklinkOutput.cpp
- DecklinkWriter.cpp)
- ENDIF (BLACKMAGIC_FOUND)
-
-
# Get list of headers
file(GLOB_RECURSE headers ${CMAKE_SOURCE_DIR}/include/*.h)
@@ -255,44 +293,75 @@ SET(CMAKE_MACOSX_RPATH 0)
############### CREATE LIBRARY #################
# Create shared openshot library
-add_library(openshot SHARED
- ${OPENSHOT_SOURCE_FILES}
- ${headers} )
+add_library(openshot SHARED
+ ${OPENSHOT_SOURCE_FILES}
+ ${headers} )
# Set SONAME and other library properties
set_target_properties(openshot
- PROPERTIES
- VERSION ${PROJECT_VERSION}
- SOVERSION ${SO_VERSION}
- INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
- )
+ PROPERTIES
+ VERSION ${PROJECT_VERSION}
+ SOVERSION ${SO_VERSION}
+ INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
+ )
############### LINK LIBRARY #################
SET ( REQUIRED_LIBRARIES
- ${FFMPEG_LIBRARIES}
${LIBOPENSHOT_AUDIO_LIBRARIES}
${QT_LIBRARIES}
${PROFILER}
${JSONCPP_LIBRARY}
${ZMQ_LIBRARIES}
)
-
- IF (OPENMP_FOUND)
- SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${OpenMP_CXX_FLAGS} )
- ENDIF (OPENMP_FOUND)
-
- IF (ImageMagick_FOUND)
- SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${ImageMagick_LIBRARIES} )
- ENDIF (ImageMagick_FOUND)
- IF (BLACKMAGIC_FOUND)
- SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${BLACKMAGIC_LIBRARY_DIR} )
- ENDIF (BLACKMAGIC_FOUND)
+IF (AVCODEC_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVCODEC_LIBRARIES} )
+ENDIF (AVCODEC_FOUND)
+IF (AVDEVICE_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVDEVICE_LIBRARIES} )
+ENDIF (AVDEVICE_FOUND)
+IF (AVFORMAT_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVFORMAT_LIBRARIES} )
+ENDIF (AVFORMAT_FOUND)
+IF (AVFILTER_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVFILTER_LIBRARIES} )
+ENDIF (AVFILTER_FOUND)
+IF (AVUTIL_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVUTIL_LIBRARIES} )
+ENDIF (AVUTIL_FOUND)
+IF (POSTPROC_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${POSTPROC_LIBRARIES} )
+ENDIF (POSTPROC_FOUND)
+IF (SWSCALE_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${SWSCALE_LIBRARIES} )
+ENDIF (SWSCALE_FOUND)
+IF (SWRESAMPLE_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${SWRESAMPLE_LIBRARIES} )
+ENDIF (SWRESAMPLE_FOUND)
+IF (AVRESAMPLE_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${AVRESAMPLE_LIBRARIES} )
+ENDIF (AVRESAMPLE_FOUND)
- IF (WIN32)
- # Required for exception handling on Windows
- SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} "imagehlp" "dbghelp" )
- ENDIF(WIN32)
+IF (RESVG_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${RESVG_LIBRARIES} )
+ENDIF(RESVG_FOUND)
+
+IF (OPENMP_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${OpenMP_CXX_FLAGS} )
+ENDIF (OPENMP_FOUND)
+
+IF (ImageMagick_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${ImageMagick_LIBRARIES} )
+ENDIF (ImageMagick_FOUND)
+
+IF (BLACKMAGIC_FOUND)
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${BLACKMAGIC_LIBRARY_DIR} )
+ENDIF (BLACKMAGIC_FOUND)
+
+IF (WIN32)
+ # Required for exception handling on Windows
+ SET ( REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} "imagehlp" "dbghelp" )
+ENDIF(WIN32)
# Link all referenced libraries
target_link_libraries(openshot ${REQUIRED_LIBRARIES})
@@ -315,9 +384,9 @@ target_link_libraries(openshot-player openshot)
############### TEST BLACKMAGIC CAPTURE APP ################
IF (BLACKMAGIC_FOUND)
# Create test executable
- add_executable(openshot-blackmagic
- examples/ExampleBlackmagic.cpp)
-
+ add_executable(openshot-blackmagic
+ examples/ExampleBlackmagic.cpp)
+
# Link test executable to the new library
target_link_libraries(openshot-blackmagic openshot)
ENDIF (BLACKMAGIC_FOUND)
@@ -331,13 +400,13 @@ set(LIB_INSTALL_DIR lib${LIB_SUFFIX}) # determine correct lib folder
# Install primary library
INSTALL( TARGETS openshot
- ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
- LIBRARY DESTINATION ${LIB_INSTALL_DIR}
- COMPONENT library )
-
-INSTALL(FILES ${headers}
- DESTINATION ${CMAKE_INSTALL_PREFIX}/include/libopenshot )
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ COMPONENT library )
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/include/libopenshot
+ FILES_MATCHING PATTERN "*.h")
############### CPACK PACKAGING ##############
IF(MINGW)
diff --git a/src/CacheBase.cpp b/src/CacheBase.cpp
index cffd995d..0016694a 100644
--- a/src/CacheBase.cpp
+++ b/src/CacheBase.cpp
@@ -3,9 +3,12 @@
* @brief Source file for CacheBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -69,4 +72,4 @@ void CacheBase::SetJsonValue(Json::Value root) {
// Set data from Json (if key is found)
if (!root["max_bytes"].isNull())
max_bytes = atoll(root["max_bytes"].asString().c_str());
-}
\ No newline at end of file
+}
diff --git a/src/CacheDisk.cpp b/src/CacheDisk.cpp
index 23854f3a..4d446746 100644
--- a/src/CacheDisk.cpp
+++ b/src/CacheDisk.cpp
@@ -3,9 +3,12 @@
* @brief Source file for CacheDisk class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -486,8 +489,12 @@ Json::Value CacheDisk::JsonValue() {
// Parse and append range data (if any)
Json::Value ranges;
- Json::Reader reader;
- bool success = reader.parse( json_ranges, ranges );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( json_ranges.c_str(),
+ json_ranges.c_str() + json_ranges.size(), &ranges, &errors );
if (success)
root["ranges"] = ranges;
@@ -500,8 +507,12 @@ void CacheDisk::SetJson(string value) {
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( value, root );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( value.c_str(),
+ value.c_str() + value.size(), &root, &errors );
if (!success)
// Raise exception
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
diff --git a/src/CacheMemory.cpp b/src/CacheMemory.cpp
index f830d74e..4de6bb1f 100644
--- a/src/CacheMemory.cpp
+++ b/src/CacheMemory.cpp
@@ -3,9 +3,12 @@
* @brief Source file for Cache class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -340,8 +343,13 @@ Json::Value CacheMemory::JsonValue() {
// Parse and append range data (if any)
Json::Value ranges;
- Json::Reader reader;
- bool success = reader.parse( json_ranges, ranges );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( json_ranges.c_str(),
+ json_ranges.c_str() + json_ranges.size(), &ranges, &errors );
+
if (success)
root["ranges"] = ranges;
@@ -354,8 +362,12 @@ void CacheMemory::SetJson(string value) {
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( value, root );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( value.c_str(),
+ value.c_str() + value.size(), &root, &errors );
if (!success)
// Raise exception
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
diff --git a/src/ChunkReader.cpp b/src/ChunkReader.cpp
index 8308a0c9..8d5b466e 100644
--- a/src/ChunkReader.cpp
+++ b/src/ChunkReader.cpp
@@ -3,9 +3,12 @@
* @brief Source file for ChunkReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -26,6 +29,7 @@
*/
#include "../include/ChunkReader.h"
+#include "../include/FFmpegReader.h"
using namespace openshot;
@@ -41,7 +45,7 @@ ChunkReader::ChunkReader(string path, ChunkVersion chunk_version)
previous_location.number = 0;
previous_location.frame = 0;
- // Open and Close the reader, to populate it's attributes (such as height, width, etc...)
+ // Open and Close the reader, to populate its attributes (such as height, width, etc...)
Open();
Close();
}
@@ -75,8 +79,10 @@ void ChunkReader::load_json()
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( json_string.str(), root );
+ Json::CharReaderBuilder rbuilder;
+
+ string errors;
+ bool success = Json::parseFromStream(rbuilder, json_string, &root, &errors);
if (!success)
// Raise exception
throw InvalidJSON("Chunk folder could not be opened.", path);
@@ -227,7 +233,6 @@ std::shared_ptr ChunkReader::GetFrame(int64_t requested_frame)
cout << "Load READER: " << chunk_video_path << endl;
// Load new FFmpegReader
local_reader = new FFmpegReader(chunk_video_path);
- local_reader->enable_seek = false; // disable seeking
local_reader->Open(); // open reader
} catch (InvalidFile)
@@ -278,8 +283,12 @@ void ChunkReader::SetJson(string value) {
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( value, root );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( value.c_str(),
+ value.c_str() + value.size(), &root, &errors );
if (!success)
// Raise exception
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
diff --git a/src/ChunkWriter.cpp b/src/ChunkWriter.cpp
index 958fecb7..5dad4df3 100644
--- a/src/ChunkWriter.cpp
+++ b/src/ChunkWriter.cpp
@@ -3,9 +3,12 @@
* @brief Source file for ChunkWriter class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/src/Clip.cpp b/src/Clip.cpp
index 913fd71f..8c669042 100644
--- a/src/Clip.cpp
+++ b/src/Clip.cpp
@@ -3,9 +3,12 @@
* @brief Source file for Clip class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -26,6 +29,15 @@
*/
#include "../include/Clip.h"
+#include "../include/FFmpegReader.h"
+#include "../include/FrameMapper.h"
+#ifdef USE_IMAGEMAGICK
+ #include "../include/ImageReader.h"
+ #include "../include/TextReader.h"
+#endif
+#include "../include/QtImageReader.h"
+#include "../include/ChunkReader.h"
+#include "../include/DummyReader.h"
using namespace openshot;
@@ -92,9 +104,6 @@ void Clip::init_settings()
// Init audio and video overrides
has_audio = Keyframe(-1.0);
has_video = Keyframe(-1.0);
-
- // Default pointers
- manage_reader = false;
}
// Init reader's rotation (if any)
@@ -122,14 +131,14 @@ void Clip::init_reader_rotation() {
}
// Default Constructor for a clip
-Clip::Clip() : reader(NULL), resampler(NULL), audio_cache(NULL)
+Clip::Clip() : resampler(NULL), audio_cache(NULL), reader(NULL), allocated_reader(NULL)
{
// Init all default settings
init_settings();
}
// Constructor with reader
-Clip::Clip(ReaderBase* new_reader) : reader(new_reader), resampler(NULL), audio_cache(NULL)
+Clip::Clip(ReaderBase* new_reader) : resampler(NULL), audio_cache(NULL), reader(new_reader), allocated_reader(NULL)
{
// Init all default settings
init_settings();
@@ -143,7 +152,7 @@ Clip::Clip(ReaderBase* new_reader) : reader(new_reader), resampler(NULL), audio_
}
// Constructor with filepath
-Clip::Clip(string path) : reader(NULL), resampler(NULL), audio_cache(NULL)
+Clip::Clip(string path) : resampler(NULL), audio_cache(NULL), reader(NULL), allocated_reader(NULL)
{
// Init all default settings
init_settings();
@@ -185,7 +194,7 @@ Clip::Clip(string path) : reader(NULL), resampler(NULL), audio_cache(NULL)
// Update duration
if (reader) {
End(reader->info.duration);
- manage_reader = true;
+ allocated_reader = reader;
init_reader_rotation();
}
}
@@ -194,9 +203,9 @@ Clip::Clip(string path) : reader(NULL), resampler(NULL), audio_cache(NULL)
Clip::~Clip()
{
// Delete the reader if clip created it
- if (manage_reader && reader) {
- delete reader;
- reader = NULL;
+ if (allocated_reader) {
+ delete allocated_reader;
+ allocated_reader = NULL;
}
// Close the resampler
@@ -212,6 +221,9 @@ void Clip::Reader(ReaderBase* new_reader)
// set reader pointer
reader = new_reader;
+ // set parent
+ reader->SetClip(this);
+
// Init rotation (if any)
init_reader_rotation();
}
@@ -260,7 +272,7 @@ void Clip::Close()
// Get end position of clip (trim end of video), which can be affected by the time curve.
float Clip::End()
{
- // if a time curve is present, use it's length
+ // if a time curve is present, use its length
if (time.Points.size() > 1)
{
// Determine the FPS fo this clip
@@ -328,13 +340,13 @@ std::shared_ptr Clip::GetFrame(int64_t requested_frame)
frame->AddAudio(true, channel, 0, original_frame->GetAudioSamples(channel), original_frame->GetAudioSamplesCount(), 1.0);
// Get time mapped frame number (used to increase speed, change direction, etc...)
- std::shared_ptr new_frame = get_time_mapped_frame(frame, requested_frame);
+ get_time_mapped_frame(frame, requested_frame);
// Apply effects to the frame (if any)
- apply_effects(new_frame);
+ apply_effects(frame);
// Return processed 'frame'
- return new_frame;
+ return frame;
}
else
// Throw error if reader not initialized
@@ -377,7 +389,7 @@ void Clip::reverse_buffer(juce::AudioSampleBuffer* buffer)
}
// Adjust the audio and image of a time mapped frame
-std::shared_ptr Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_number)
+void Clip::get_time_mapped_frame(std::shared_ptr frame, int64_t frame_number)
{
// Check for valid reader
if (!reader)
@@ -388,7 +400,6 @@ std::shared_ptr Clip::get_time_mapped_frame(std::shared_ptr frame,
if (time.Values.size() > 1)
{
const GenericScopedLock lock(getFrameCriticalSection);
- std::shared_ptr new_frame;
// create buffer and resampler
juce::AudioSampleBuffer *samples = NULL;
@@ -396,14 +407,7 @@ std::shared_ptr Clip::get_time_mapped_frame(std::shared_ptr frame,
resampler = new AudioResampler();
// Get new frame number
- int new_frame_number = adjust_frame_number_minimum(round(time.GetValue(frame_number)));
-
- // Create a new frame
- int samples_in_frame = Frame::GetSamplesPerFrame(new_frame_number, reader->info.fps, reader->info.sample_rate, frame->GetAudioChannelsCount());
- new_frame = std::make_shared(new_frame_number, 1, 1, "#000000", samples_in_frame, frame->GetAudioChannelsCount());
-
- // Copy the image from the new frame
- new_frame->AddImage(std::shared_ptr(new QImage(*GetOrCreateFrame(new_frame_number)->GetImage())));
+ int new_frame_number = frame->number;
// Get delta (difference in previous Y value)
int delta = int(round(time.GetDelta(frame_number)));
@@ -451,7 +455,7 @@ std::shared_ptr Clip::get_time_mapped_frame(std::shared_ptr frame,
start -= 1;
for (int channel = 0; channel < channels; channel++)
// Add new (slower) samples, to the frame object
- new_frame->AddAudio(true, channel, 0, resampled_buffer->getReadPointer(channel, start),
+ frame->AddAudio(true, channel, 0, resampled_buffer->getReadPointer(channel, start),
number_of_samples, 1.0f);
// Clean up
@@ -559,7 +563,7 @@ std::shared_ptr Clip::get_time_mapped_frame(std::shared_ptr frame,
// Add the newly resized audio samples to the current frame
for (int channel = 0; channel < channels; channel++)
// Add new (slower) samples, to the frame object
- new_frame->AddAudio(true, channel, 0, buffer->getReadPointer(channel), number_of_samples, 1.0f);
+ frame->AddAudio(true, channel, 0, buffer->getReadPointer(channel), number_of_samples, 1.0f);
// Clean up
buffer = NULL;
@@ -580,7 +584,7 @@ std::shared_ptr Clip::get_time_mapped_frame(std::shared_ptr frame,
// Add reversed samples to the frame object
for (int channel = 0; channel < channels; channel++)
- new_frame->AddAudio(true, channel, 0, samples->getReadPointer(channel), number_of_samples, 1.0f);
+ frame->AddAudio(true, channel, 0, samples->getReadPointer(channel), number_of_samples, 1.0f);
}
@@ -588,13 +592,7 @@ std::shared_ptr Clip::get_time_mapped_frame(std::shared_ptr frame,
delete samples;
samples = NULL;
}
-
- // Return new time mapped frame
- return new_frame;
-
- } else
- // Use original frame
- return frame;
+ }
}
// Adjust frame number minimum value
@@ -620,35 +618,6 @@ std::shared_ptr Clip::GetOrCreateFrame(int64_t number)
// Debug output
ZmqLogger::Instance()->AppendDebugMethod("Clip::GetOrCreateFrame (from reader)", "number", number, "samples_in_frame", samples_in_frame, "", -1, "", -1, "", -1, "", -1);
- // Determine the max size of this clips source image (based on the timeline's size, the scaling mode,
- // and the scaling keyframes). This is a performance improvement, to keep the images as small as possible,
- // without losing quality. NOTE: We cannot go smaller than the timeline itself, or the add_layer timeline
- // method will scale it back to timeline size before scaling it smaller again. This needs to be fixed in
- // the future.
- if (scale == SCALE_FIT || scale == SCALE_STRETCH) {
- // Best fit or Stretch scaling (based on max timeline size * scaling keyframes)
- float max_scale_x = scale_x.GetMaxPoint().co.Y;
- float max_scale_y = scale_y.GetMaxPoint().co.Y;
- reader->SetMaxSize(max(float(max_width), max_width * max_scale_x), max(float(max_height), max_height * max_scale_y));
-
- } else if (scale == SCALE_CROP) {
- // Cropping scale mode (based on max timeline size * cropped size * scaling keyframes)
- float max_scale_x = scale_x.GetMaxPoint().co.Y;
- float max_scale_y = scale_y.GetMaxPoint().co.Y;
- QSize width_size(max_width * max_scale_x, round(max_width / (float(reader->info.width) / float(reader->info.height))));
- QSize height_size(round(max_height / (float(reader->info.height) / float(reader->info.width))), max_height * max_scale_y);
-
- // respect aspect ratio
- if (width_size.width() >= max_width && width_size.height() >= max_height)
- reader->SetMaxSize(max(max_width, width_size.width()), max(max_height, width_size.height()));
- else
- reader->SetMaxSize(max(max_width, height_size.width()), max(max_height, height_size.height()));
-
- } else {
- // No scaling, use original image size (slower)
- reader->SetMaxSize(0, 0);
- }
-
// Attempt to get a frame (but this could fail if a reader has just been closed)
new_frame = reader->GetFrame(number);
@@ -671,6 +640,7 @@ std::shared_ptr Clip::GetOrCreateFrame(int64_t number)
new_frame = std::make_shared(number, reader->info.width, reader->info.height, "#000000", samples_in_frame, reader->info.channels);
new_frame->SampleRate(reader->info.sample_rate);
new_frame->ChannelsLayout(reader->info.channel_layout);
+ new_frame->AddAudioSilence(samples_in_frame);
return new_frame;
}
@@ -819,8 +789,12 @@ void Clip::SetJson(string value) {
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( value, root );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( value.c_str(),
+ value.c_str() + value.size(), &root, &errors );
if (!success)
// Raise exception
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
@@ -925,13 +899,14 @@ void Clip::SetJsonValue(Json::Value root) {
if (!existing_effect["type"].isNull()) {
// Create instance of effect
- e = EffectInfo().CreateEffect(existing_effect["type"].asString());
+ if (e = EffectInfo().CreateEffect(existing_effect["type"].asString())) {
- // Load Json into Effect
- e->SetJsonValue(existing_effect);
+ // Load Json into Effect
+ e->SetJsonValue(existing_effect);
- // Add Effect to Timeline
- AddEffect(e);
+ // Add Effect to Timeline
+ AddEffect(e);
+ }
}
}
}
@@ -994,9 +969,11 @@ void Clip::SetJsonValue(Json::Value root) {
reader->SetJsonValue(root["reader"]);
}
- // mark as managed reader
- if (reader)
- manage_reader = true;
+ // mark as managed reader and set parent
+ if (reader) {
+ reader->SetClip(this);
+ allocated_reader = reader;
+ }
// Re-Open reader (if needed)
if (already_open)
diff --git a/src/ClipBase.cpp b/src/ClipBase.cpp
index 80cad87d..60bdb633 100644
--- a/src/ClipBase.cpp
+++ b/src/ClipBase.cpp
@@ -3,9 +3,12 @@
* @brief Source file for EffectBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -108,4 +111,4 @@ Json::Value ClipBase::add_property_choice_json(string name, int value, int selec
// return JsonValue
return new_choice;
-}
\ No newline at end of file
+}
diff --git a/src/Color.cpp b/src/Color.cpp
index df2cf097..21c3f146 100644
--- a/src/Color.cpp
+++ b/src/Color.cpp
@@ -3,9 +3,12 @@
* @brief Source file for EffectBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -107,8 +110,12 @@ void Color::SetJson(string value) {
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( value, root );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( value.c_str(),
+ value.c_str() + value.size(), &root, &errors );
if (!success)
// Raise exception
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
diff --git a/src/Coordinate.cpp b/src/Coordinate.cpp
index 41ee420a..5baeb5bf 100644
--- a/src/Coordinate.cpp
+++ b/src/Coordinate.cpp
@@ -3,9 +3,12 @@
* @brief Source file for Coordinate class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -32,12 +35,12 @@ using namespace openshot;
// Default constructor for a coordinate, which defaults the X and Y to zero (0,0)
Coordinate::Coordinate() :
- X(0), Y(0), increasing(true), repeated(1,1), delta(0.0) {
+ X(0), Y(0) {
}
// Constructor which also allows the user to set the X and Y
Coordinate::Coordinate(double x, double y) :
- X(x), Y(y), increasing(true), repeated(1,1), delta(0.0) {
+ X(x), Y(y) {
}
@@ -70,8 +73,12 @@ void Coordinate::SetJson(string value) {
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( value, root );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( value.c_str(),
+ value.c_str() + value.size(), &root, &errors );
if (!success)
// Raise exception
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
@@ -96,15 +103,4 @@ void Coordinate::SetJsonValue(Json::Value root) {
X = root["X"].asDouble();
if (!root["Y"].isNull())
Y = root["Y"].asDouble();
- if (!root["increasing"].isNull())
- increasing = root["increasing"].asBool();
- if (!root["repeated"].isNull() && root["repeated"].isObject())
- {
- if (!root["repeated"]["num"].isNull())
- repeated.num = root["repeated"]["num"].asInt();
- if (!root["repeated"]["den"].isNull())
- repeated.den = root["repeated"]["den"].asInt();
- }
- if (!root["delta"].isNull())
- delta = root["delta"].asDouble();
}
diff --git a/src/CrashHandler.cpp b/src/CrashHandler.cpp
index e7827d09..1782f5ba 100644
--- a/src/CrashHandler.cpp
+++ b/src/CrashHandler.cpp
@@ -3,9 +3,12 @@
* @brief Source file for CrashHandler class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/src/DecklinkInput.cpp b/src/DecklinkInput.cpp
index 99d13341..da5a8d00 100644
--- a/src/DecklinkInput.cpp
+++ b/src/DecklinkInput.cpp
@@ -3,7 +3,10 @@
* @brief Source file for DecklinkInput class
* @author Jonathan Thomas , Blackmagic Design
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
* Copyright (c) 2009 Blackmagic Design
*
@@ -30,7 +33,7 @@
* DEALINGS IN THE SOFTWARE.
*
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/src/DecklinkOutput.cpp b/src/DecklinkOutput.cpp
index 8606420a..2dee7e9e 100644
--- a/src/DecklinkOutput.cpp
+++ b/src/DecklinkOutput.cpp
@@ -3,7 +3,10 @@
* @brief Source file for DecklinkOutput class
* @author Jonathan Thomas , Blackmagic Design
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
* Copyright (c) 2009 Blackmagic Design
*
@@ -30,7 +33,7 @@
* DEALINGS IN THE SOFTWARE.
*
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/src/DecklinkReader.cpp b/src/DecklinkReader.cpp
index 1d9b70b9..230a6689 100644
--- a/src/DecklinkReader.cpp
+++ b/src/DecklinkReader.cpp
@@ -3,9 +3,12 @@
* @brief Source file for DecklinkReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -265,8 +268,12 @@ void DecklinkReader::SetJson(string value) {
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( value, root );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( value.c_str(),
+ value.c_str() + value.size(), &root, &errors );
if (!success)
// Raise exception
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
diff --git a/src/DecklinkWriter.cpp b/src/DecklinkWriter.cpp
index dd0de9c5..7dcede04 100644
--- a/src/DecklinkWriter.cpp
+++ b/src/DecklinkWriter.cpp
@@ -3,9 +3,12 @@
* @brief Source file for DecklinkWriter class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp
index 8fe039ab..aa1e6a56 100644
--- a/src/DummyReader.cpp
+++ b/src/DummyReader.cpp
@@ -3,9 +3,12 @@
* @brief Source file for DummyReader class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -66,11 +69,14 @@ DummyReader::DummyReader(Fraction fps, int width, int height, int sample_rate, i
info.display_ratio.num = size.num;
info.display_ratio.den = size.den;
- // Open and Close the reader, to populate it's attributes (such as height, width, etc...)
+ // Open and Close the reader, to populate its attributes (such as height, width, etc...)
Open();
Close();
}
+DummyReader::~DummyReader() {
+}
+
// Open image file
void DummyReader::Open()
{
@@ -140,8 +146,12 @@ void DummyReader::SetJson(string value) {
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( value, root );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( value.c_str(),
+ value.c_str() + value.size(), &root, &errors );
if (!success)
// Raise exception
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
diff --git a/src/EffectBase.cpp b/src/EffectBase.cpp
index c0afded8..9bf30986 100644
--- a/src/EffectBase.cpp
+++ b/src/EffectBase.cpp
@@ -3,9 +3,12 @@
* @brief Source file for EffectBase class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -99,8 +102,12 @@ void EffectBase::SetJson(string value) {
// Parse JSON string into JSON objects
Json::Value root;
- Json::Reader reader;
- bool success = reader.parse( value, root );
+ Json::CharReaderBuilder rbuilder;
+ Json::CharReader* reader(rbuilder.newCharReader());
+
+ string errors;
+ bool success = reader->parse( value.c_str(),
+ value.c_str() + value.size(), &root, &errors );
if (!success)
// Raise exception
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
diff --git a/src/EffectInfo.cpp b/src/EffectInfo.cpp
index 23bc9d02..0b9c360d 100644
--- a/src/EffectInfo.cpp
+++ b/src/EffectInfo.cpp
@@ -3,9 +3,12 @@
* @brief Source file for EffectInfo class
* @author Jonathan Thomas
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2014 OpenShot Studios, LLC
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC
* . This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
@@ -82,6 +85,7 @@ EffectBase* EffectInfo::CreateEffect(string effect_type) {
else if (effect_type == "Wave")
return new Wave();
+ return NULL;
}
// Generate Json::JsonValue for this object
diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp
index 5a4c936d..10d89051 100644
--- a/src/FFmpegReader.cpp
+++ b/src/FFmpegReader.cpp
@@ -3,9 +3,12 @@
* @brief Source file for FFmpegReader class
* @author Jonathan Thomas , Fabrice Bellard
*
- * @section LICENSE
+ * @ref License
+ */
+
+/* LICENSE
*
- * Copyright (c) 2008-2013 OpenShot Studios, LLC, Fabrice Bellard
+ * Copyright (c) 2008-2019 OpenShot Studios, LLC, Fabrice Bellard
* (http://www.openshotstudios.com). This file is part of
* OpenShot Library (http://www.openshot.org), an open-source project
* dedicated to delivering high quality video editing and animation solutions
@@ -30,25 +33,74 @@
#include "../include/FFmpegReader.h"
+#define ENABLE_VAAPI 0
+
+#if IS_FFMPEG_3_2
+#pragma message "You are compiling with experimental hardware decode"
+#else
+#pragma message "You are compiling only with software decode"
+#endif
+
+#if IS_FFMPEG_3_2
+#define MAX_SUPPORTED_WIDTH 1950
+#define MAX_SUPPORTED_HEIGHT 1100
+
+#if ENABLE_VAAPI
+#include "libavutil/hwcontext_vaapi.h"
+
+typedef struct VAAPIDecodeContext {
+ VAProfile va_profile;
+ VAEntrypoint va_entrypoint;
+ VAConfigID va_config;
+ VAContextID va_context;
+
+#if FF_API_STRUCT_VAAPI_CONTEXT
+ // FF_DISABLE_DEPRECATION_WARNINGS
+ int have_old_context;
+ struct vaapi_context *old_context;
+ AVBufferRef *device_ref;
+ // FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ AVHWDeviceContext *device;
+ AVVAAPIDeviceContext *hwctx;
+
+ AVHWFramesContext *frames;
+ AVVAAPIFramesContext *hwfc;
+
+ enum AVPixelFormat surface_format;
+ int surface_count;
+ } VAAPIDecodeContext;
+#endif
+#endif
+
+
using namespace openshot;
+int hw_de_on = 0;
+#if IS_FFMPEG_3_2
+ AVPixelFormat hw_de_av_pix_fmt_global = AV_PIX_FMT_NONE;
+ AVHWDeviceType hw_de_av_device_type_global = AV_HWDEVICE_TYPE_NONE;
+#endif
+
FFmpegReader::FFmpegReader(string path)
- : last_frame(0), is_seeking(0), seeking_pts(0), seeking_frame(0), seek_count(0),
- audio_pts_offset(99999), video_pts_offset(99999), path(path), is_video_seek(true), check_interlace(false),
- check_fps(false), enable_seek(true), is_open(false), seek_audio_frame_found(0), seek_video_frame_found(0),
- prev_samples(0), prev_pts(0), pts_total(0), pts_counter(0), is_duration_known(false), largest_frame_processed(0),
- current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0), packet(NULL) {
+ : last_frame(0), is_seeking(0), seeking_pts(0), seeking_frame(0), seek_count(0),
+ audio_pts_offset(99999), video_pts_offset(99999), path(path), is_video_seek(true), check_interlace(false),
+ check_fps(false), enable_seek(true), is_open(false), seek_audio_frame_found(0), seek_video_frame_found(0),
+ prev_samples(0), prev_pts(0), pts_total(0), pts_counter(0), is_duration_known(false), largest_frame_processed(0),
+ current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0),
+ packet(NULL) {
// Initialize FFMpeg, and register all formats and codecs
- av_register_all();
- avcodec_register_all();
+ AV_REGISTER_ALL
+ AVCODEC_REGISTER_ALL
// Init cache
working_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * info.fps.ToDouble() * 2, info.width, info.height, info.sample_rate, info.channels);
missing_frames.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels);
final_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels);
- // Open and Close the reader, to populate it's attributes (such as height, width, etc...)
+ // Open and Close the reader, to populate its attributes (such as height, width, etc...)
Open();
Close();
}
@@ -58,18 +110,19 @@ FFmpegReader::FFmpegReader(string path, bool inspect_reader)
audio_pts_offset(99999), video_pts_offset(99999), path(path), is_video_seek(true), check_interlace(false),
check_fps(false), enable_seek(true), is_open(false), seek_audio_frame_found(0), seek_video_frame_found(0),
prev_samples(0), prev_pts(0), pts_total(0), pts_counter(0), is_duration_known(false), largest_frame_processed(0),
- current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0), packet(NULL) {
+ current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0),
+ packet(NULL) {
// Initialize FFMpeg, and register all formats and codecs
- av_register_all();
- avcodec_register_all();
+ AV_REGISTER_ALL
+ AVCODEC_REGISTER_ALL
// Init cache
working_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * info.fps.ToDouble() * 2, info.width, info.height, info.sample_rate, info.channels);
missing_frames.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels);
final_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels);
- // Open and Close the reader, to populate it's attributes (such as height, width, etc...)
+ // Open and Close the reader, to populate its attributes (such as height, width, etc...)
if (inspect_reader) {
Open();
Close();
@@ -83,8 +136,7 @@ FFmpegReader::~FFmpegReader() {
}
// This struct holds the associated video frame and starting sample # for an audio packet.
-bool AudioLocation::is_near(AudioLocation location, int samples_per_frame, int64_t amount)
-{
+bool AudioLocation::is_near(AudioLocation location, int samples_per_frame, int64_t amount) {
// Is frame even close to this one?
if (abs(location.frame - frame) >= 2)
// This is too far away to be considered
@@ -101,13 +153,94 @@ bool AudioLocation::is_near(AudioLocation location, int samples_per_frame, int64
return false;
}
-void FFmpegReader::Open()
+#if IS_FFMPEG_3_2
+
+// Get hardware pix format
+static enum AVPixelFormat get_hw_dec_format(AVCodecContext *ctx, const enum AVPixelFormat *pix_fmts)
{
+ const enum AVPixelFormat *p;
+
+ for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
+ switch (*p) {
+#if defined(__linux__)
+ // Linux pix formats
+ case AV_PIX_FMT_VAAPI:
+ hw_de_av_pix_fmt_global = AV_PIX_FMT_VAAPI;
+ hw_de_av_device_type_global = AV_HWDEVICE_TYPE_VAAPI;
+ return *p;
+ break;
+ case AV_PIX_FMT_VDPAU:
+ hw_de_av_pix_fmt_global = AV_PIX_FMT_VDPAU;
+ hw_de_av_device_type_global = AV_HWDEVICE_TYPE_VDPAU;
+ return *p;
+ break;
+#endif
+#if defined(_WIN32)
+ // Windows pix formats
+ case AV_PIX_FMT_DXVA2_VLD:
+ hw_de_av_pix_fmt_global = AV_PIX_FMT_DXVA2_VLD;
+ hw_de_av_device_type_global = AV_HWDEVICE_TYPE_DXVA2;
+ return *p;
+ break;
+ case AV_PIX_FMT_D3D11:
+ hw_de_av_pix_fmt_global = AV_PIX_FMT_D3D11;
+ hw_de_av_device_type_global = AV_HWDEVICE_TYPE_D3D11VA;
+ return *p;
+ break;
+#endif
+#if defined(__APPLE__)
+ // Apple pix formats
+ case AV_PIX_FMT_VIDEOTOOLBOX:
+ hw_de_av_pix_fmt_global = AV_PIX_FMT_VIDEOTOOLBOX;
+ hw_de_av_device_type_global = AV_HWDEVICE_TYPE_VIDEOTOOLBOX;
+ return *p;
+ break;
+#endif
+ // Cross-platform pix formats
+ case AV_PIX_FMT_CUDA:
+ hw_de_av_pix_fmt_global = AV_PIX_FMT_CUDA;
+ hw_de_av_device_type_global = AV_HWDEVICE_TYPE_CUDA;
+ return *p;
+ break;
+ case AV_PIX_FMT_QSV:
+ hw_de_av_pix_fmt_global = AV_PIX_FMT_QSV;
+ hw_de_av_device_type_global = AV_HWDEVICE_TYPE_QSV;
+ return *p;
+ break;
+ }
+ }
+ ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::get_hw_dec_format (Unable to decode this file using hardware decode)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ return AV_PIX_FMT_NONE;
+}
+
+int FFmpegReader::IsHardwareDecodeSupported(int codecid)
+{
+ int ret;
+ switch (codecid) {
+ case AV_CODEC_ID_H264:
+ case AV_CODEC_ID_MPEG2VIDEO:
+ case AV_CODEC_ID_VC1:
+ case AV_CODEC_ID_WMV1:
+ case AV_CODEC_ID_WMV2:
+ case AV_CODEC_ID_WMV3:
+ ret = 1;
+ break;
+ default :
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+#endif
+
+void FFmpegReader::Open() {
// Open reader if not already open
- if (!is_open)
- {
+ if (!is_open) {
// Initialize format context
pFormatCtx = NULL;
+ {
+ hw_de_on = (openshot::Settings::Instance()->HARDWARE_DECODER == 0 ? 0 : 1);
+ }
// Open video file
if (avformat_open_input(&pFormatCtx, path.c_str(), NULL, NULL) != 0)
@@ -120,8 +253,7 @@ void FFmpegReader::Open()
videoStream = -1;
audioStream = -1;
// Loop through each stream, and identify the video and audio stream index
- for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
- {
+ for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++) {
// Is this a video stream?
if (AV_GET_CODEC_TYPE(pFormatCtx->streams[i]) == AVMEDIA_TYPE_VIDEO && videoStream < 0) {
videoStream = i;
@@ -135,8 +267,7 @@ void FFmpegReader::Open()
throw NoStreamsFound("No video or audio streams found in this file.", path);
// Is there a video stream?
- if (videoStream != -1)
- {
+ if (videoStream != -1) {
// Set the stream index
info.video_stream_index = videoStream;
@@ -148,23 +279,232 @@ void FFmpegReader::Open()
// Get codec and codec context from stream
AVCodec *pCodec = avcodec_find_decoder(codecId);
- pCodecCtx = AV_GET_CODEC_CONTEXT(pStream, pCodec);
-
- // Set number of threads equal to number of processors (not to exceed 16)
- pCodecCtx->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
-
- if (pCodec == NULL) {
- throw InvalidCodec("A valid video codec could not be found for this file.", path);
- }
-
- // Init options
AVDictionary *opts = NULL;
- av_dict_set(&opts, "strict", "experimental", 0);
+ int retry_decode_open = 2;
+ // If hw accel is selected but hardware cannot handle repeat with software decoding
+ do {
+ pCodecCtx = AV_GET_CODEC_CONTEXT(pStream, pCodec);
+#if IS_FFMPEG_3_2
+ if (hw_de_on && (retry_decode_open==2)) {
+ // Up to here no decision is made if hardware or software decode
+ hw_de_supported = IsHardwareDecodeSupported(pCodecCtx->codec_id);
+ }
+#endif
+ retry_decode_open = 0;
- // Open video codec
- if (avcodec_open2(pCodecCtx, pCodec, &opts) < 0)
- throw InvalidCodec("A video codec was found, but could not be opened.", path);
+ // Set number of threads equal to number of processors (not to exceed 16)
+ pCodecCtx->thread_count = min(FF_NUM_PROCESSORS, 16);
+ if (pCodec == NULL) {
+ throw InvalidCodec("A valid video codec could not be found for this file.", path);
+ }
+
+ // Init options
+ av_dict_set(&opts, "strict", "experimental", 0);
+#if IS_FFMPEG_3_2
+ if (hw_de_on && hw_de_supported) {
+ // Open Hardware Acceleration
+ int i_decoder_hw = 0;
+ char adapter[256];
+ char *adapter_ptr = NULL;
+ int adapter_num;
+ adapter_num = openshot::Settings::Instance()->HW_DE_DEVICE_SET;
+ fprintf(stderr, "\n\nDecodiing Device Nr: %d\n", adapter_num);
+
+ // Set hardware pix format (callback)
+ pCodecCtx->get_format = get_hw_dec_format;
+
+ if (adapter_num < 3 && adapter_num >=0) {
+#if defined(__linux__)
+ snprintf(adapter,sizeof(adapter),"/dev/dri/renderD%d", adapter_num+128);
+ adapter_ptr = adapter;
+ i_decoder_hw = openshot::Settings::Instance()->HARDWARE_DECODER;
+ switch (i_decoder_hw) {
+ case 1:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_VAAPI;
+ break;
+ case 2:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_CUDA;
+ break;
+ case 6:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_VDPAU;
+ break;
+ case 7:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_QSV;
+ break;
+ default:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_VAAPI;
+ break;
+ }
+
+#elif defined(_WIN32)
+ adapter_ptr = NULL;
+ i_decoder_hw = openshot::Settings::Instance()->HARDWARE_DECODER;
+ switch (i_decoder_hw) {
+ case 2:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_CUDA;
+ break;
+ case 3:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_DXVA2;
+ break;
+ case 4:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_D3D11VA;
+ break;
+ case 7:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_QSV;
+ break;
+ default:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_DXVA2;
+ break;
+ }
+#elif defined(__APPLE__)
+ adapter_ptr = NULL;
+ i_decoder_hw = openshot::Settings::Instance()->HARDWARE_DECODER;
+ switch (i_decoder_hw) {
+ case 5:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_VIDEOTOOLBOX;
+ break;
+ case 7:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_QSV;
+ break;
+ default:
+ hw_de_av_device_type = AV_HWDEVICE_TYPE_VIDEOTOOLBOX;
+ break;
+ }
+#endif
+
+ } else {
+ adapter_ptr = NULL; // Just to be sure
+ }
+
+ // Check if it is there and writable
+#if defined(__linux__)
+ if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
+#elif defined(_WIN32)
+ if( adapter_ptr != NULL ) {
+#elif defined(__APPLE__)
+ if( adapter_ptr != NULL ) {
+#endif
+ ZmqLogger::Instance()->AppendDebugMethod("Decode Device present using device", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ }
+ else {
+ adapter_ptr = NULL; // use default
+ ZmqLogger::Instance()->AppendDebugMethod("Decode Device not present using default", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ }
+
+ hw_device_ctx = NULL;
+ // Here the first hardware initialisations are made
+ if (av_hwdevice_ctx_create(&hw_device_ctx, hw_de_av_device_type, adapter_ptr, NULL, 0) >= 0) {
+ if (!(pCodecCtx->hw_device_ctx = av_buffer_ref(hw_device_ctx))) {
+ throw InvalidCodec("Hardware device reference create failed.", path);
+ }
+
+ /*
+ av_buffer_unref(&ist->hw_frames_ctx);
+ ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
+ if (!ist->hw_frames_ctx) {
+ av_log(avctx, AV_LOG_ERROR, "Error creating a CUDA frames context\n");
+ return AVERROR(ENOMEM);
+ }
+
+ frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data;
+
+ frames_ctx->format = AV_PIX_FMT_CUDA;
+ frames_ctx->sw_format = avctx->sw_pix_fmt;
+ frames_ctx->width = avctx->width;
+ frames_ctx->height = avctx->height;
+
+ av_log(avctx, AV_LOG_DEBUG, "Initializing CUDA frames context: sw_format = %s, width = %d, height = %d\n",
+ av_get_pix_fmt_name(frames_ctx->sw_format), frames_ctx->width, frames_ctx->height);
+
+
+ ret = av_hwframe_ctx_init(pCodecCtx->hw_device_ctx);
+ ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error initializing a CUDA frame pool\n");
+ return ret;
+ }
+ */
+ }
+ else {
+ throw InvalidCodec("Hardware device create failed.", path);
+ }
+ }
+#endif
+
+ // Open video codec
+ if (avcodec_open2(pCodecCtx, pCodec, &opts) < 0)
+ throw InvalidCodec("A video codec was found, but could not be opened.", path);
+
+#if IS_FFMPEG_3_2
+ if (hw_de_on && hw_de_supported) {
+ AVHWFramesConstraints *constraints = NULL;
+ void *hwconfig = NULL;
+ hwconfig = av_hwdevice_hwconfig_alloc(hw_device_ctx);
+
+// TODO: needs va_config!
+#if ENABLE_VAAPI
+ ((AVVAAPIHWConfig *)hwconfig)->config_id = ((VAAPIDecodeContext *)(pCodecCtx->priv_data))->va_config;
+#endif
+ constraints = av_hwdevice_get_hwframe_constraints(hw_device_ctx,hwconfig);
+ if (constraints) {
+ if (pCodecCtx->coded_width < constraints->min_width ||
+ pCodecCtx->coded_height < constraints->min_height ||
+ pCodecCtx->coded_width > constraints->max_width ||
+ pCodecCtx->coded_height > constraints->max_height) {
+ ZmqLogger::Instance()->AppendDebugMethod("DIMENSIONS ARE TOO LARGE for hardware acceleration\n", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ hw_de_supported = 0;
+ retry_decode_open = 1;
+ AV_FREE_CONTEXT(pCodecCtx);
+ if (hw_device_ctx) {
+ av_buffer_unref(&hw_device_ctx);
+ hw_device_ctx = NULL;
+ }
+ }
+ else {
+ // All is just peachy
+ ZmqLogger::Instance()->AppendDebugMethod("\nDecode hardware acceleration is used\n", "Min width :", constraints->min_width, "Min Height :", constraints->min_height, "MaxWidth :", constraints->max_width, "MaxHeight :", constraints->max_height, "Frame width :", pCodecCtx->coded_width, "Frame height :", pCodecCtx->coded_height);
+ retry_decode_open = 0;
+ }
+ av_hwframe_constraints_free(&constraints);
+ if (hwconfig) {
+ av_freep(&hwconfig);
+ }
+ }
+ else {
+ int max_h, max_w;
+ //max_h = ((getenv( "LIMIT_HEIGHT_MAX" )==NULL) ? MAX_SUPPORTED_HEIGHT : atoi(getenv( "LIMIT_HEIGHT_MAX" )));
+ max_h = openshot::Settings::Instance()->DE_LIMIT_HEIGHT_MAX;
+ //max_w = ((getenv( "LIMIT_WIDTH_MAX" )==NULL) ? MAX_SUPPORTED_WIDTH : atoi(getenv( "LIMIT_WIDTH_MAX" )));
+ max_w = openshot::Settings::Instance()->DE_LIMIT_WIDTH_MAX;
+ ZmqLogger::Instance()->AppendDebugMethod("Constraints could not be found using default limit\n", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ //cerr << "Constraints could not be found using default limit\n";
+ if (pCodecCtx->coded_width < 0 ||
+ pCodecCtx->coded_height < 0 ||
+ pCodecCtx->coded_width > max_w ||
+ pCodecCtx->coded_height > max_h ) {
+ ZmqLogger::Instance()->AppendDebugMethod("DIMENSIONS ARE TOO LARGE for hardware acceleration\n", "Max Width :", max_w, "Max Height :", max_h, "Frame width :", pCodecCtx->coded_width, "Frame height :", pCodecCtx->coded_height, "", -1, "", -1);
+ hw_de_supported = 0;
+ retry_decode_open = 1;
+ AV_FREE_CONTEXT(pCodecCtx);
+ if (hw_device_ctx) {
+ av_buffer_unref(&hw_device_ctx);
+ hw_device_ctx = NULL;
+ }
+ }
+ else {
+ ZmqLogger::Instance()->AppendDebugMethod("\nDecode hardware acceleration is used\n", "Max Width :", max_w, "Max Height :", max_h, "Frame width :", pCodecCtx->coded_width, "Frame height :", pCodecCtx->coded_height, "", -1, "", -1);
+ retry_decode_open = 0;
+ }
+ }
+ } // if hw_de_on && hw_de_supported
+ else {
+ ZmqLogger::Instance()->AppendDebugMethod("\nDecode in software is used\n", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ }
+#else
+ retry_decode_open = 0;
+#endif
+ } while (retry_decode_open); // retry_decode_open
// Free options
av_dict_free(&opts);
@@ -173,8 +513,7 @@ void FFmpegReader::Open()
}
// Is there an audio stream?
- if (audioStream != -1)
- {
+ if (audioStream != -1) {
// Set the stream index
info.audio_stream_index = audioStream;
@@ -189,7 +528,7 @@ void FFmpegReader::Open()
aCodecCtx = AV_GET_CODEC_CONTEXT(aStream, aCodec);
// Set number of threads equal to number of processors (not to exceed 16)
- aCodecCtx->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
+ aCodecCtx->thread_count = min(FF_NUM_PROCESSORS, 16);
if (aCodec == NULL) {
throw InvalidCodec("A valid audio codec could not be found for this file.", path);
@@ -232,24 +571,34 @@ void FFmpegReader::Open()
}
}
-void FFmpegReader::Close()
-{
+void FFmpegReader::Close() {
// Close all objects, if reader is 'open'
- if (is_open)
- {
+ if (is_open) {
// Mark as "closed"
is_open = false;
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::Close", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ if (packet) {
+ // Remove previous packet before getting next one
+ RemoveAVPacket(packet);
+ packet = NULL;
+ }
+
// Close the codec
- if (info.has_video)
- {
+ if (info.has_video) {
avcodec_flush_buffers(pCodecCtx);
AV_FREE_CONTEXT(pCodecCtx);
+#if IS_FFMPEG_3_2
+ if (hw_de_on) {
+ if (hw_device_ctx) {
+ av_buffer_unref(&hw_device_ctx);
+ hw_device_ctx = NULL;
+ }
+ }
+#endif
}
- if (info.has_audio)
- {
+ if (info.has_audio) {
avcodec_flush_buffers(aCodecCtx);
AV_FREE_CONTEXT(aCodecCtx);
}
@@ -261,7 +610,7 @@ void FFmpegReader::Close()
// Clear processed lists
{
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processed_video_frames.clear();
processed_audio_frames.clear();
processing_video_frames.clear();
@@ -284,18 +633,19 @@ void FFmpegReader::Close()
seek_video_frame_found = 0;
current_video_frame = 0;
has_missing_frames = false;
+
+ last_video_frame.reset();
}
}
-void FFmpegReader::UpdateAudioInfo()
-{
+void FFmpegReader::UpdateAudioInfo() {
// Set values of FileInfo struct
info.has_audio = true;
info.file_size = pFormatCtx->pb ? avio_size(pFormatCtx->pb) : -1;
info.acodec = aCodecCtx->codec->name;
info.channels = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels;
if (AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout == 0)
- AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout = av_get_default_channel_layout( AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels );
+ AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout = av_get_default_channel_layout(AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels);
info.channel_layout = (ChannelLayout) AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout;
info.sample_rate = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->sample_rate;
info.audio_bit_rate = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->bit_rate;
@@ -309,15 +659,13 @@ void FFmpegReader::UpdateAudioInfo()
info.duration = aStream->duration * info.audio_timebase.ToDouble();
// Check for an invalid video length
- if (info.has_video && info.video_length <= 0)
- {
+ if (info.has_video && info.video_length <= 0) {
// Calculate the video length from the audio duration
info.video_length = info.duration * info.fps.ToDouble();
}
// Set video timebase (if no video stream was found)
- if (!info.has_video)
- {
+ if (!info.has_video) {
// Set a few important default video settings (so audio can be divided into frames)
info.fps.num = 24;
info.fps.den = 1;
@@ -328,6 +676,11 @@ void FFmpegReader::UpdateAudioInfo()
info.height = 480;
}
+ // Fix invalid video lengths for certain types of files (MP3 for example)
+ if (info.has_video && ((info.duration * info.fps.ToDouble()) - info.video_length > 60)) {
+ info.video_length = info.duration * info.fps.ToDouble();
+ }
+
// Add audio metadata (if any found)
AVDictionaryEntry *tag = NULL;
while ((tag = av_dict_get(aStream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
@@ -337,34 +690,30 @@ void FFmpegReader::UpdateAudioInfo()
}
}
-void FFmpegReader::UpdateVideoInfo()
-{
+void FFmpegReader::UpdateVideoInfo() {
+ if (check_fps)
+ // Already initialized all the video metadata, no reason to do it again
+ return;
+
// Set values of FileInfo struct
info.has_video = true;
info.file_size = pFormatCtx->pb ? avio_size(pFormatCtx->pb) : -1;
info.height = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->height;
info.width = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->width;
info.vcodec = pCodecCtx->codec->name;
- info.video_bit_rate = pFormatCtx->bit_rate;
- if (!check_fps)
- {
- // set frames per second (fps)
- info.fps.num = pStream->avg_frame_rate.num;
- info.fps.den = pStream->avg_frame_rate.den;
- }
+ info.video_bit_rate = (pFormatCtx->bit_rate / 8);
- if (pStream->sample_aspect_ratio.num != 0)
- {
+ // set frames per second (fps)
+ info.fps.num = pStream->avg_frame_rate.num;
+ info.fps.den = pStream->avg_frame_rate.den;
+
+ if (pStream->sample_aspect_ratio.num != 0) {
info.pixel_ratio.num = pStream->sample_aspect_ratio.num;
info.pixel_ratio.den = pStream->sample_aspect_ratio.den;
- }
- else if (AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.num != 0)
- {
+ } else if (AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.num != 0) {
info.pixel_ratio.num = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.num;
info.pixel_ratio.den = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.den;
- }
- else
- {
+ } else {
info.pixel_ratio.num = 1;
info.pixel_ratio.den = 1;
}
@@ -398,15 +747,12 @@ void FFmpegReader::UpdateVideoInfo()
info.duration = (info.file_size / info.video_bit_rate);
// No duration found in stream of file
- if (info.duration <= 0.0f)
- {
+ if (info.duration <= 0.0f) {
// No duration is found in the video stream
info.duration = -1;
info.video_length = -1;
is_duration_known = false;
- }
- else
- {
+ } else {
// Yes, a duration was found
is_duration_known = true;
@@ -415,16 +761,10 @@ void FFmpegReader::UpdateVideoInfo()
}
// Override an invalid framerate
- if (info.fps.ToFloat() > 240.0f || (info.fps.num == 0 || info.fps.den == 0))
- {
- // Set a few important default video settings (so audio can be divided into frames)
- info.fps.num = 24;
- info.fps.den = 1;
- info.video_timebase.num = 1;
- info.video_timebase.den = 24;
-
- // Calculate number of frames
- info.video_length = round(info.duration * info.fps.ToDouble());
+ if (info.fps.ToFloat() > 240.0f || (info.fps.num <= 0 || info.fps.den <= 0) || info.video_length <= 0) {
+ // Calculate FPS, duration, video bit rate, and video length manually
+ // by scanning through all the video stream packets
+ CheckFPS();
}
// Add video metadata (if any)
@@ -437,8 +777,7 @@ void FFmpegReader::UpdateVideoInfo()
}
-std::shared_ptr FFmpegReader::GetFrame(int64_t requested_frame)
-{
+std::shared_ptr FFmpegReader::GetFrame(int64_t requested_frame) {
// Check for open reader (or throw exception)
if (!is_open)
throw ReaderClosed("The FFmpegReader is closed. Call Open() before calling this method.", path);
@@ -463,64 +802,54 @@ std::shared_ptr FFmpegReader::GetFrame(int64_t requested_frame)
// Return the cached frame
return frame;
- }
- else
- {
- // Create a scoped lock, allowing only a single thread to run the following code at one time
- const GenericScopedLock lock(getFrameCriticalSection);
-
- // Check the cache a 2nd time (due to a potential previous lock)
- if (has_missing_frames)
- CheckMissingFrame(requested_frame);
- frame = final_cache.GetFrame(requested_frame);
- if (frame) {
- // Debug output
- ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetFrame", "returned cached frame on 2nd look", requested_frame, "", -1, "", -1, "", -1, "", -1, "", -1);
-
- // Return the cached frame
- return frame;
- }
-
- // Frame is not in cache
- // Reset seek count
- seek_count = 0;
-
- // Check for first frame (always need to get frame 1 before other frames, to correctly calculate offsets)
- if (last_frame == 0 && requested_frame != 1)
- // Get first frame
- ReadStream(1);
-
- // Are we within X frames of the requested frame?
- int64_t diff = requested_frame - last_frame;
- if (diff >= 1 && diff <= 20)
+ } else {
+#pragma omp critical (ReadStream)
{
- // Continue walking the stream
- return ReadStream(requested_frame);
- }
- else
- {
- // Greater than 30 frames away, or backwards, we need to seek to the nearest key frame
- if (enable_seek)
- // Only seek if enabled
- Seek(requested_frame);
+ // Check the cache a 2nd time (due to a potential previous lock)
+ frame = final_cache.GetFrame(requested_frame);
+ if (frame) {
+ // Debug output
+ ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetFrame", "returned cached frame on 2nd look", requested_frame, "", -1, "", -1, "", -1, "", -1, "", -1);
- else if (!enable_seek && diff < 0)
- {
- // Start over, since we can't seek, and the requested frame is smaller than our position
- Close();
- Open();
+ // Return the cached frame
+ } else {
+ // Frame is not in cache
+ // Reset seek count
+ seek_count = 0;
+
+ // Check for first frame (always need to get frame 1 before other frames, to correctly calculate offsets)
+ if (last_frame == 0 && requested_frame != 1)
+ // Get first frame
+ ReadStream(1);
+
+ // Are we within X frames of the requested frame?
+ int64_t diff = requested_frame - last_frame;
+ if (diff >= 1 && diff <= 20) {
+ // Continue walking the stream
+ frame = ReadStream(requested_frame);
+ } else {
+ // Greater than 30 frames away, or backwards, we need to seek to the nearest key frame
+ if (enable_seek)
+ // Only seek if enabled
+ Seek(requested_frame);
+
+ else if (!enable_seek && diff < 0) {
+ // Start over, since we can't seek, and the requested frame is smaller than our position
+ Close();
+ Open();
+ }
+
+ // Then continue walking the stream
+ frame = ReadStream(requested_frame);
+ }
}
-
- // Then continue walking the stream
- return ReadStream(requested_frame);
- }
-
+ } //omp critical
+ return frame;
}
}
// Read the stream until we find the requested Frame
-std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame)
-{
+std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame) {
// Allocate video frame
bool end_of_stream = false;
bool check_seek = false;
@@ -530,7 +859,7 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame)
// Minimum number of packets to process (for performance reasons)
int packets_processed = 0;
int minimum_packets = OPEN_MP_NUM_PROCESSORS;
- int max_packets = 4096;
+ int max_packets = 4096;
// Set the number of threads in OpenMP
omp_set_num_threads(OPEN_MP_NUM_PROCESSORS);
@@ -540,20 +869,19 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame)
// Debug output
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ReadStream", "requested_frame", requested_frame, "OPEN_MP_NUM_PROCESSORS", OPEN_MP_NUM_PROCESSORS, "", -1, "", -1, "", -1, "", -1);
- #pragma omp parallel
+#pragma omp parallel
{
- #pragma omp single
+#pragma omp single
{
// Loop through the stream until the correct frame is found
- while (true)
- {
+ while (true) {
// Get the next packet into a local variable called packet
packet_error = GetNextPacket();
int processing_video_frames_size = 0;
int processing_audio_frames_size = 0;
{
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processing_video_frames_size = processing_video_frames.size();
processing_audio_frames_size = processing_audio_frames.size();
}
@@ -561,14 +889,13 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame)
// Wait if too many frames are being processed
while (processing_video_frames_size + processing_audio_frames_size >= minimum_packets) {
usleep(2500);
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processing_video_frames_size = processing_video_frames.size();
processing_audio_frames_size = processing_audio_frames.size();
}
// Get the next packet (if any)
- if (packet_error < 0)
- {
+ if (packet_error < 0) {
// Break loop when no more packets found
end_of_stream = true;
break;
@@ -578,54 +905,57 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame)
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ReadStream (GetNextPacket)", "requested_frame", requested_frame, "processing_video_frames_size", processing_video_frames_size, "processing_audio_frames_size", processing_audio_frames_size, "minimum_packets", minimum_packets, "packets_processed", packets_processed, "is_seeking", is_seeking);
// Video packet
- if (info.has_video && packet->stream_index == videoStream)
- {
+ if (info.has_video && packet->stream_index == videoStream) {
// Reset this counter, since we have a video packet
num_packets_since_video_frame = 0;
// Check the status of a seek (if any)
- if (is_seeking)
- #pragma omp critical (openshot_seek)
- check_seek = CheckSeek(true);
- else
- check_seek = false;
+ if (is_seeking)
+#pragma omp critical (openshot_seek)
+ check_seek = CheckSeek(true);
+ else
+ check_seek = false;
- if (check_seek) {
- // Jump to the next iteration of this loop
- continue;
- }
+ if (check_seek) {
+ // Jump to the next iteration of this loop
+ continue;
+ }
// Get the AVFrame from the current packet
frame_finished = GetAVFrame();
// Check if the AVFrame is finished and set it
- if (frame_finished)
- {
+ if (frame_finished) {
// Update PTS / Frame Offset (if any)
UpdatePTSOffset(true);
// Process Video Packet
ProcessVideoPacket(requested_frame);
+
+ if (openshot::Settings::Instance()->WAIT_FOR_VIDEO_PROCESSING_TASK) {
+ // Wait on each OMP task to complete before moving on to the next one. This slows
+ // down processing considerably, but might be more stable on some systems.
+#pragma omp taskwait
+ }
}
}
// Audio packet
- else if (info.has_audio && packet->stream_index == audioStream)
- {
+ else if (info.has_audio && packet->stream_index == audioStream) {
// Increment this (to track # of packets since the last video packet)
num_packets_since_video_frame++;
// Check the status of a seek (if any)
- if (is_seeking)
- #pragma omp critical (openshot_seek)
- check_seek = CheckSeek(false);
- else
- check_seek = false;
+ if (is_seeking)
+#pragma omp critical (openshot_seek)
+ check_seek = CheckSeek(false);
+ else
+ check_seek = false;
- if (check_seek) {
- // Jump to the next iteration of this loop
- continue;
- }
+ if (check_seek) {
+ // Jump to the next iteration of this loop
+ continue;
+ }
// Update PTS / Frame Offset (if any)
UpdatePTSOffset(false);
@@ -638,17 +968,13 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame)
}
// Check if working frames are 'finished'
- bool is_cache_found = false;
if (!is_seeking) {
- // Check for any missing frames
- CheckMissingFrame(requested_frame);
-
// Check for final frames
CheckWorkingFrames(false, requested_frame);
}
// Check if requested 'final' frame is available
- is_cache_found = (final_cache.GetFrame(requested_frame) != NULL);
+ bool is_cache_found = (final_cache.GetFrame(requested_frame) != NULL);
// Increment frames processed
packets_processed++;
@@ -660,6 +986,7 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame)
} // end while
} // end omp single
+
} // end omp parallel
// Debug output
@@ -682,8 +1009,7 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame)
if (frame) {
// return the largest processed frame (assuming it was the last in the video file)
return frame;
- }
- else {
+ } else {
// The largest processed frame is no longer in cache, return a blank frame
std::shared_ptr f = CreateFrame(largest_frame_processed);
f->AddColor(info.width, info.height, "#000");
@@ -694,51 +1020,88 @@ std::shared_ptr FFmpegReader::ReadStream(int64_t requested_frame)
}
// Get the next packet (if any)
-int FFmpegReader::GetNextPacket()
-{
+int FFmpegReader::GetNextPacket() {
int found_packet = 0;
- AVPacket *next_packet = new AVPacket();
- found_packet = av_read_frame(pFormatCtx, next_packet);
-
- if (packet) {
- // Remove previous packet before getting next one
- RemoveAVPacket(packet);
- packet = NULL;
- }
-
- if (found_packet >= 0)
+ AVPacket *next_packet;
+#pragma omp critical(getnextpacket)
{
- // Update current packet pointer
- packet = next_packet;
- }
+ next_packet = new AVPacket();
+ found_packet = av_read_frame(pFormatCtx, next_packet);
+
+ if (packet) {
+ // Remove previous packet before getting next one
+ RemoveAVPacket(packet);
+ packet = NULL;
+ }
+
+ if (found_packet >= 0) {
+ // Update current packet pointer
+ packet = next_packet;
+ }
+ else
+ delete next_packet;
+ }
// Return if packet was found (or error number)
return found_packet;
}
// Get an AVFrame (if any)
-bool FFmpegReader::GetAVFrame()
-{
+bool FFmpegReader::GetAVFrame() {
int frameFinished = -1;
int ret = 0;
// Decode video frame
AVFrame *next_frame = AV_ALLOCATE_FRAME();
- #pragma omp critical (packet_cache)
+#pragma omp critical (packet_cache)
{
- #if IS_FFMPEG_3_2
+#if IS_FFMPEG_3_2
frameFinished = 0;
+
ret = avcodec_send_packet(pCodecCtx, packet);
+
+ // Get the format from the variables set in get_hw_dec_format
+ hw_de_av_pix_fmt = hw_de_av_pix_fmt_global;
+ hw_de_av_device_type = hw_de_av_device_type_global;
+
if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAVFrame (Packet not sent)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
}
else {
- pFrame = new AVFrame();
- while (ret >= 0) {
- ret = avcodec_receive_frame(pCodecCtx, next_frame);
- if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
- break;
+ AVFrame *next_frame2;
+ if (hw_de_on && hw_de_supported) {
+ next_frame2 = AV_ALLOCATE_FRAME();
}
+ else
+ {
+ next_frame2 = next_frame;
+ }
+ pFrame = AV_ALLOCATE_FRAME();
+ while (ret >= 0) {
+ ret = avcodec_receive_frame(pCodecCtx, next_frame2);
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+ break;
+ }
+ if (ret != 0) {
+ ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAVFrame (invalid return frame received)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ }
+ if (hw_de_on && hw_de_supported) {
+ int err;
+ if (next_frame2->format == hw_de_av_pix_fmt) {
+ next_frame->format = AV_PIX_FMT_YUV420P;
+ if ((err = av_hwframe_transfer_data(next_frame,next_frame2,0)) < 0) {
+ ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAVFrame (Failed to transfer data to output frame)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ }
+ if ((err = av_frame_copy_props(next_frame,next_frame2)) < 0) {
+ ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAVFrame (Failed to copy props to output frame)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+ }
+ }
+ }
+ else
+ { // No hardware acceleration used -> no copy from GPU memory needed
+ next_frame = next_frame2;
+ }
+
// TODO also handle possible further frames
// Use only the first frame like avcodec_decode_video2
if (frameFinished == 0 ) {
@@ -753,15 +1116,20 @@ bool FFmpegReader::GetAVFrame()
}
}
}
+ if (hw_de_on && hw_de_supported) {
+ AV_FREE_FRAME(&next_frame2);
+ }
}
- #else
+#else
avcodec_decode_video2(pCodecCtx, next_frame, &frameFinished, packet);
+ // always allocate pFrame (because we do that in the ffmpeg >= 3.2 as well); it will always be freed later
+ pFrame = AV_ALLOCATE_FRAME();
+
// is frame finished
if (frameFinished) {
// AVFrames are clobbered on the each call to avcodec_decode_video, so we
// must make a copy of the image data before this method is called again.
- pFrame = AV_ALLOCATE_FRAME();
avpicture_alloc((AVPicture *) pFrame, pCodecCtx->pix_fmt, info.width, info.height);
av_picture_copy((AVPicture *) pFrame, (AVPicture *) next_frame, pCodecCtx->pix_fmt, info.width,
info.height);
@@ -773,7 +1141,7 @@ bool FFmpegReader::GetAVFrame()
info.top_field_first = next_frame->top_field_first;
}
}
- #endif
+#endif
}
// deallocate the frame
@@ -784,11 +1152,9 @@ bool FFmpegReader::GetAVFrame()
}
// Check the current seek position and determine if we need to seek again
-bool FFmpegReader::CheckSeek(bool is_video)
-{
+bool FFmpegReader::CheckSeek(bool is_video) {
// Are we seeking for a specific frame?
- if (is_seeking)
- {
+ if (is_seeking) {
// Determine if both an audio and video packet have been decoded since the seek happened.
// If not, allow the ReadStream method to keep looping
if ((is_video_seek && !seek_video_frame_found) || (!is_video_seek && !seek_audio_frame_found))
@@ -804,16 +1170,13 @@ bool FFmpegReader::CheckSeek(bool is_video)
max_seeked_frame = seek_video_frame_found;
// determine if we are "before" the requested frame
- if (max_seeked_frame >= seeking_frame)
- {
+ if (max_seeked_frame >= seeking_frame) {
// SEEKED TOO FAR
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::CheckSeek (Too far, seek again)", "is_video_seek", is_video_seek, "max_seeked_frame", max_seeked_frame, "seeking_frame", seeking_frame, "seeking_pts", seeking_pts, "seek_video_frame_found", seek_video_frame_found, "seek_audio_frame_found", seek_audio_frame_found);
// Seek again... to the nearest Keyframe
Seek(seeking_frame - (10 * seek_count * seek_count));
- }
- else
- {
+ } else {
// SEEK WORKED
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::CheckSeek (Successful)", "is_video_seek", is_video_seek, "current_pts", packet->pts, "seeking_pts", seeking_pts, "seeking_frame", seeking_frame, "seek_video_frame_found", seek_video_frame_found, "seek_audio_frame_found", seek_audio_frame_found);
@@ -829,8 +1192,7 @@ bool FFmpegReader::CheckSeek(bool is_video)
}
// Process a video packet
-void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
-{
+void FFmpegReader::ProcessVideoPacket(int64_t requested_frame) {
// Calculate current frame #
int64_t current_frame = ConvertVideoPTStoFrame(GetVideoPTS());
@@ -839,8 +1201,7 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
seek_video_frame_found = current_frame;
// Are we close enough to decode the frame? and is this frame # valid?
- if ((current_frame < (requested_frame - 20)) or (current_frame == -1))
- {
+ if ((current_frame < (requested_frame - 20)) or (current_frame == -1)) {
// Remove frame and packet
RemoveAVFrame(pFrame);
@@ -860,12 +1221,13 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
int width = info.width;
int64_t video_length = info.video_length;
AVFrame *my_frame = pFrame;
+ pFrame = NULL;
// Add video frame to list of processing video frames
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processing_video_frames[current_frame] = current_frame;
- #pragma omp task firstprivate(current_frame, my_frame, height, width, video_length, pix_fmt)
+#pragma omp task firstprivate(current_frame, my_frame, height, width, video_length, pix_fmt)
{
// Create variables for a RGB Frame (since most videos are not in RGB, we must convert it)
AVFrame *pFrameRGB = NULL;
@@ -877,9 +1239,52 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
if (pFrameRGB == NULL)
throw OutOfBoundsFrame("Convert Image Broke!", current_frame, video_length);
- // Determine if video needs to be scaled down (for performance reasons)
- // Timelines pass their size to the clips, which pass their size to the readers (as max size)
- // If a clip is being scaled larger, it will set max_width and max_height = 0 (which means don't down scale)
+ // Determine the max size of this source image (based on the timeline's size, the scaling mode,
+ // and the scaling keyframes). This is a performance improvement, to keep the images as small as possible,
+ // without losing quality. NOTE: We cannot go smaller than the timeline itself, or the add_layer timeline
+ // method will scale it back to timeline size before scaling it smaller again. This needs to be fixed in
+ // the future.
+ int max_width = openshot::Settings::Instance()->MAX_WIDTH;
+ if (max_width <= 0)
+ max_width = info.width;
+ int max_height = openshot::Settings::Instance()->MAX_HEIGHT;
+ if (max_height <= 0)
+ max_height = info.height;
+
+ Clip *parent = (Clip *) GetClip();
+ if (parent) {
+ if (parent->scale == SCALE_FIT || parent->scale == SCALE_STRETCH) {
+ // Best fit or Stretch scaling (based on max timeline size * scaling keyframes)
+ float max_scale_x = parent->scale_x.GetMaxPoint().co.Y;
+ float max_scale_y = parent->scale_y.GetMaxPoint().co.Y;
+ max_width = max(float(max_width), max_width * max_scale_x);
+ max_height = max(float(max_height), max_height * max_scale_y);
+
+ } else if (parent->scale == SCALE_CROP) {
+ // Cropping scale mode (based on max timeline size * cropped size * scaling keyframes)
+ float max_scale_x = parent->scale_x.GetMaxPoint().co.Y;
+ float max_scale_y = parent->scale_y.GetMaxPoint().co.Y;
+ QSize width_size(max_width * max_scale_x,
+ round(max_width / (float(info.width) / float(info.height))));
+ QSize height_size(round(max_height / (float(info.height) / float(info.width))),
+ max_height * max_scale_y);
+ // respect aspect ratio
+ if (width_size.width() >= max_width && width_size.height() >= max_height) {
+ max_width = max(max_width, width_size.width());
+ max_height = max(max_height, width_size.height());
+ } else {
+ max_width = max(max_width, height_size.width());
+ max_height = max(max_height, height_size.height());
+ }
+
+ } else {
+ // No scaling, use original image size (slower)
+ max_width = info.width;
+ max_height = info.height;
+ }
+ }
+
+ // Determine if image needs to be scaled (for performance reasons)
int original_height = height;
if (max_width != 0 && max_height != 0 && max_width < width && max_height < height) {
// Override width and height (but maintain aspect ratio)
@@ -901,14 +1306,18 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
// Determine required buffer size and allocate buffer
numBytes = AV_GET_IMAGE_SIZE(PIX_FMT_RGBA, width, height);
- #pragma omp critical (video_buffer)
+#pragma omp critical (video_buffer)
buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
// Copy picture data from one AVFrame (or AVPicture) to another one.
AV_COPY_PICTURE_DATA(pFrameRGB, buffer, PIX_FMT_RGBA, width, height);
+ int scale_mode = SWS_FAST_BILINEAR;
+ if (openshot::Settings::Instance()->HIGH_QUALITY_SCALING) {
+ scale_mode = SWS_LANCZOS;
+ }
SwsContext *img_convert_ctx = sws_getContext(info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx), width,
- height, PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL);
+ height, PIX_FMT_RGBA, scale_mode, NULL, NULL, NULL);
// Resize / Convert to RGB
sws_scale(img_convert_ctx, my_frame->data, my_frame->linesize, 0,
@@ -924,7 +1333,7 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
working_cache.Add(f);
// Keep track of last last_video_frame
- #pragma omp critical (video_buffer)
+#pragma omp critical (video_buffer)
last_video_frame = f;
// Free the RGB image
@@ -937,7 +1346,7 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
// Remove video frame from list of processing video frames
{
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processing_video_frames.erase(current_frame);
processed_video_frames[current_frame] = current_frame;
}
@@ -950,15 +1359,13 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
}
// Process an audio packet
-void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_frame, int starting_sample)
-{
+void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_frame, int starting_sample) {
// Track 1st audio packet after a successful seek
if (!seek_audio_frame_found && is_seeking)
seek_audio_frame_found = target_frame;
// Are we close enough to decode the frame's audio?
- if (target_frame < (requested_frame - 20))
- {
+ if (target_frame < (requested_frame - 20)) {
// Debug output
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessAudioPacket (Skipped)", "requested_frame", requested_frame, "target_frame", target_frame, "starting_sample", starting_sample, "", -1, "", -1, "", -1);
@@ -978,10 +1385,10 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
int data_size = 0;
// re-initialize buffer size (it gets changed in the avcodec_decode_audio2 method call)
- int buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE;
- #pragma omp critical (ProcessAudioPacket)
+ int buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE + MY_INPUT_BUFFER_PADDING_SIZE;
+#pragma omp critical (ProcessAudioPacket)
{
- #if IS_FFMPEG_3_2
+#if IS_FFMPEG_3_2
int ret = 0;
frame_finished = 1;
while((packet->size > 0 || (!packet->data && frame_finished)) && ret >= 0) {
@@ -1008,7 +1415,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
{
ret = -1;
}
- #else
+#else
int used = avcodec_decode_audio4(aCodecCtx, audio_frame, &frame_finished, packet);
#endif
}
@@ -1016,12 +1423,12 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
if (frame_finished) {
// determine how many samples were decoded
- int planar = av_sample_fmt_is_planar((AVSampleFormat)AV_GET_CODEC_PIXEL_FORMAT(aStream, aCodecCtx));
+ int planar = av_sample_fmt_is_planar((AVSampleFormat) AV_GET_CODEC_PIXEL_FORMAT(aStream, aCodecCtx));
int plane_size = -1;
data_size = av_samples_get_buffer_size(&plane_size,
- AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels,
- audio_frame->nb_samples,
- (AVSampleFormat)(AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx)), 1);
+ AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels,
+ audio_frame->nb_samples,
+ (AVSampleFormat) (AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx)), 1);
// Calculate total number of samples
packet_samples = audio_frame->nb_samples * AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels;
@@ -1047,12 +1454,11 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
// Add audio frame to list of processing audio frames
{
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processing_audio_frames.insert(pair(previous_packet_location.frame, previous_packet_location.frame));
}
- while (pts_remaining_samples)
- {
+ while (pts_remaining_samples) {
// Get Samples per frame (for this frame number)
int samples_per_frame = Frame::GetSamplesPerFrame(previous_packet_location.frame, info.fps, info.sample_rate, info.channels);
@@ -1071,7 +1477,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
// Add audio frame to list of processing audio frames
{
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processing_audio_frames.insert(pair(previous_packet_location.frame, previous_packet_location.frame));
}
@@ -1083,7 +1489,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
// Allocate audio buffer
- int16_t *audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
+ int16_t *audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + MY_INPUT_BUFFER_PADDING_SIZE];
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessAudioPacket (ReSample)", "packet_samples", packet_samples, "info.channels", info.channels, "info.sample_rate", info.sample_rate, "aCodecCtx->sample_fmt", AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx), "AV_SAMPLE_FMT_S16", AV_SAMPLE_FMT_S16, "", -1);
@@ -1093,36 +1499,36 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
audio_converted->nb_samples = audio_frame->nb_samples;
av_samples_alloc(audio_converted->data, audio_converted->linesize, info.channels, audio_frame->nb_samples, AV_SAMPLE_FMT_S16, 0);
- AVAudioResampleContext *avr = NULL;
+ SWRCONTEXT *avr = NULL;
int nb_samples = 0;
// setup resample context
- avr = avresample_alloc_context();
- av_opt_set_int(avr, "in_channel_layout", AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout, 0);
+ avr = SWR_ALLOC();
+ av_opt_set_int(avr, "in_channel_layout", AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout, 0);
av_opt_set_int(avr, "out_channel_layout", AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout, 0);
- av_opt_set_int(avr, "in_sample_fmt", AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx), 0);
- av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
- av_opt_set_int(avr, "in_sample_rate", info.sample_rate, 0);
- av_opt_set_int(avr, "out_sample_rate", info.sample_rate, 0);
- av_opt_set_int(avr, "in_channels", info.channels, 0);
- av_opt_set_int(avr, "out_channels", info.channels, 0);
- int r = avresample_open(avr);
+ av_opt_set_int(avr, "in_sample_fmt", AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx), 0);
+ av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+ av_opt_set_int(avr, "in_sample_rate", info.sample_rate, 0);
+ av_opt_set_int(avr, "out_sample_rate", info.sample_rate, 0);
+ av_opt_set_int(avr, "in_channels", info.channels, 0);
+ av_opt_set_int(avr, "out_channels", info.channels, 0);
+ int r = SWR_INIT(avr);
// Convert audio samples
- nb_samples = avresample_convert(avr, // audio resample context
- audio_converted->data, // output data pointers
- audio_converted->linesize[0], // output plane size, in bytes. (0 if unknown)
- audio_converted->nb_samples, // maximum number of samples that the output buffer can hold
- audio_frame->data, // input data pointers
- audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
- audio_frame->nb_samples); // number of input samples to convert
+ nb_samples = SWR_CONVERT(avr, // audio resample context
+ audio_converted->data, // output data pointers
+ audio_converted->linesize[0], // output plane size, in bytes. (0 if unknown)
+ audio_converted->nb_samples, // maximum number of samples that the output buffer can hold
+ audio_frame->data, // input data pointers
+ audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
+ audio_frame->nb_samples); // number of input samples to convert
// Copy audio samples over original samples
memcpy(audio_buf, audio_converted->data[0], audio_converted->nb_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * info.channels);
// Deallocate resample buffer
- avresample_close(avr);
- avresample_free(&avr);
+ SWR_CLOSE(avr);
+ SWR_FREE(&avr);
avr = NULL;
// Free AVFrames
@@ -1131,8 +1537,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
int64_t starting_frame_number = -1;
bool partial_frame = true;
- for (int channel_filter = 0; channel_filter < info.channels; channel_filter++)
- {
+ for (int channel_filter = 0; channel_filter < info.channels; channel_filter++) {
// Array of floats (to hold samples for each channel)
starting_frame_number = target_frame;
int channel_buffer_size = packet_samples / info.channels;
@@ -1146,11 +1551,9 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
// Toggle through each channel number, since channel data is stored like (left right left right)
int channel = 0;
int position = 0;
- for (int sample = 0; sample < packet_samples; sample++)
- {
+ for (int sample = 0; sample < packet_samples; sample++) {
// Only add samples for current channel
- if (channel_filter == channel)
- {
+ if (channel_filter == channel) {
// Add sample (convert from (-32768 to 32768) to (-1.0 to 1.0))
channel_buffer[position] = audio_buf[sample] * (1.0f / (1 << 15));
@@ -1161,7 +1564,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
// increment channel (if needed)
if ((channel + 1) < info.channels)
// move to next channel
- channel ++;
+ channel++;
else
// reset channel
channel = 0;
@@ -1170,9 +1573,8 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
// Loop through samples, and add them to the correct frames
int start = starting_sample;
int remaining_samples = channel_buffer_size;
- float *iterate_channel_buffer = channel_buffer; // pointer to channel buffer
- while (remaining_samples > 0)
- {
+ float *iterate_channel_buffer = channel_buffer; // pointer to channel buffer
+ while (remaining_samples > 0) {
// Get Samples per frame (for this frame number)
int samples_per_frame = Frame::GetSamplesPerFrame(starting_frame_number, info.fps, info.sample_rate, info.channels);
@@ -1226,7 +1628,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
// Remove audio frame from list of processing audio frames
{
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
// Update all frames as completed
for (int64_t f = target_frame; f < starting_frame_number; f++) {
// Remove the frame # from the processing list. NOTE: If more than one thread is
@@ -1255,10 +1657,8 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
}
-
// Seek to a specific frame. This is not always frame accurate, it's more of an estimation on many codecs.
-void FFmpegReader::Seek(int64_t requested_frame)
-{
+void FFmpegReader::Seek(int64_t requested_frame) {
// Adjust for a requested frame that is too small or too large
if (requested_frame < 1)
requested_frame = 1;
@@ -1268,7 +1668,7 @@ void FFmpegReader::Seek(int64_t requested_frame)
int processing_video_frames_size = 0;
int processing_audio_frames_size = 0;
{
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processing_video_frames_size = processing_video_frames.size();
processing_audio_frames_size = processing_audio_frames.size();
}
@@ -1279,7 +1679,7 @@ void FFmpegReader::Seek(int64_t requested_frame)
// Wait for any processing frames to complete
while (processing_video_frames_size + processing_audio_frames_size > 0) {
usleep(2500);
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processing_video_frames_size = processing_video_frames.size();
processing_audio_frames_size = processing_audio_frames.size();
}
@@ -1290,7 +1690,7 @@ void FFmpegReader::Seek(int64_t requested_frame)
// Clear processed lists
{
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
processing_audio_frames.clear();
processing_video_frames.clear();
processed_video_frames.clear();
@@ -1317,8 +1717,7 @@ void FFmpegReader::Seek(int64_t requested_frame)
// If seeking near frame 1, we need to close and re-open the file (this is more reliable than seeking)
int buffer_amount = max(OPEN_MP_NUM_PROCESSORS, 8);
- if (requested_frame - buffer_amount < 20)
- {
+ if (requested_frame - buffer_amount < 20) {
// Close and re-open file (basically seeking to frame 1)
Close();
Open();
@@ -1336,21 +1735,18 @@ void FFmpegReader::Seek(int64_t requested_frame)
}
seek_audio_frame_found = 0; // used to detect which frames to throw away after a seek
seek_video_frame_found = 0; // used to detect which frames to throw away after a seek
- }
- else
- {
+
+ } else {
// Seek to nearest key-frame (aka, i-frame)
bool seek_worked = false;
int64_t seek_target = 0;
// Seek video stream (if any)
- if (!seek_worked && info.has_video)
- {
+ if (!seek_worked && info.has_video) {
seek_target = ConvertFrameToVideoPTS(requested_frame - buffer_amount);
if (av_seek_frame(pFormatCtx, info.video_stream_index, seek_target, AVSEEK_FLAG_BACKWARD) < 0) {
- fprintf(stderr, "%s: error while seeking video stream\n", pFormatCtx->filename);
- } else
- {
+ fprintf(stderr, "%s: error while seeking video stream\n", pFormatCtx->AV_FILENAME);
+ } else {
// VIDEO SEEK
is_video_seek = true;
seek_worked = true;
@@ -1358,13 +1754,11 @@ void FFmpegReader::Seek(int64_t requested_frame)
}
// Seek audio stream (if not already seeked... and if an audio stream is found)
- if (!seek_worked && info.has_audio)
- {
+ if (!seek_worked && info.has_audio) {
seek_target = ConvertFrameToAudioPTS(requested_frame - buffer_amount);
if (av_seek_frame(pFormatCtx, info.audio_stream_index, seek_target, AVSEEK_FLAG_BACKWARD) < 0) {
- fprintf(stderr, "%s: error while seeking audio stream\n", pFormatCtx->filename);
- } else
- {
+ fprintf(stderr, "%s: error while seeking audio stream\n", pFormatCtx->AV_FILENAME);
+ } else {
// AUDIO SEEK
is_video_seek = false;
seek_worked = true;
@@ -1372,8 +1766,7 @@ void FFmpegReader::Seek(int64_t requested_frame)
}
// Was the seek successful?
- if (seek_worked)
- {
+ if (seek_worked) {
// Flush audio buffer
if (info.has_audio)
avcodec_flush_buffers(aCodecCtx);
@@ -1396,9 +1789,7 @@ void FFmpegReader::Seek(int64_t requested_frame)
seek_audio_frame_found = 0; // used to detect which frames to throw away after a seek
seek_video_frame_found = 0; // used to detect which frames to throw away after a seek
- }
- else
- {
+ } else {
// seek failed
is_seeking = false;
seeking_pts = 0;
@@ -1420,10 +1811,9 @@ void FFmpegReader::Seek(int64_t requested_frame)
}
// Get the PTS for the current video packet
-int64_t FFmpegReader::GetVideoPTS()
-{
+int64_t FFmpegReader::GetVideoPTS() {
int64_t current_pts = 0;
- if(packet->dts != AV_NOPTS_VALUE)
+ if (packet->dts != AV_NOPTS_VALUE)
current_pts = packet->dts;
// Return adjusted PTS
@@ -1431,11 +1821,9 @@ int64_t FFmpegReader::GetVideoPTS()
}
// Update PTS Offset (if any)
-void FFmpegReader::UpdatePTSOffset(bool is_video)
-{
+void FFmpegReader::UpdatePTSOffset(bool is_video) {
// Determine the offset between the PTS and Frame number (only for 1st frame)
- if (is_video)
- {
+ if (is_video) {
// VIDEO PACKET
if (video_pts_offset == 99999) // Has the offset been set yet?
{
@@ -1445,9 +1833,7 @@ void FFmpegReader::UpdatePTSOffset(bool is_video)
// debug output
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::UpdatePTSOffset (Video)", "video_pts_offset", video_pts_offset, "is_video", is_video, "", -1, "", -1, "", -1, "", -1);
}
- }
- else
- {
+ } else {
// AUDIO PACKET
if (audio_pts_offset == 99999) // Has the offset been set yet?
{
@@ -1461,8 +1847,7 @@ void FFmpegReader::UpdatePTSOffset(bool is_video)
}
// Convert PTS into Frame Number
-int64_t FFmpegReader::ConvertVideoPTStoFrame(int64_t pts)
-{
+int64_t FFmpegReader::ConvertVideoPTStoFrame(int64_t pts) {
// Apply PTS offset
pts = pts + video_pts_offset;
int64_t previous_video_frame = current_video_frame;
@@ -1482,10 +1867,10 @@ int64_t FFmpegReader::ConvertVideoPTStoFrame(int64_t pts)
if (frame == previous_video_frame) {
// return -1 frame number
frame = -1;
- }
- else
+ } else {
// Increment expected frame
current_video_frame++;
+ }
if (current_video_frame < frame)
// has missing frames
@@ -1493,7 +1878,7 @@ int64_t FFmpegReader::ConvertVideoPTStoFrame(int64_t pts)
// Sometimes frames are missing due to varying timestamps, or they were dropped. Determine
// if we are missing a video frame.
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
while (current_video_frame < frame) {
if (!missing_video_frames.count(current_video_frame)) {
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ConvertVideoPTStoFrame (tracking missing frame)", "current_video_frame", current_video_frame, "previous_video_frame", previous_video_frame, "", -1, "", -1, "", -1, "", -1);
@@ -1514,8 +1899,7 @@ int64_t FFmpegReader::ConvertVideoPTStoFrame(int64_t pts)
}
// Convert Frame Number into Video PTS
-int64_t FFmpegReader::ConvertFrameToVideoPTS(int64_t frame_number)
-{
+int64_t FFmpegReader::ConvertFrameToVideoPTS(int64_t frame_number) {
// Get timestamp of this frame (in seconds)
double seconds = double(frame_number) / info.fps.ToDouble();
@@ -1527,8 +1911,7 @@ int64_t FFmpegReader::ConvertFrameToVideoPTS(int64_t frame_number)
}
// Convert Frame Number into Video PTS
-int64_t FFmpegReader::ConvertFrameToAudioPTS(int64_t frame_number)
-{
+int64_t FFmpegReader::ConvertFrameToAudioPTS(int64_t frame_number) {
// Get timestamp of this frame (in seconds)
double seconds = double(frame_number) / info.fps.ToDouble();
@@ -1540,8 +1923,7 @@ int64_t FFmpegReader::ConvertFrameToAudioPTS(int64_t frame_number)
}
// Calculate Starting video frame and sample # for an audio PTS
-AudioLocation FFmpegReader::GetAudioPTSLocation(int64_t pts)
-{
+AudioLocation FFmpegReader::GetAudioPTSLocation(int64_t pts) {
// Apply PTS offset
pts = pts + audio_pts_offset;
@@ -1574,8 +1956,7 @@ AudioLocation FFmpegReader::GetAudioPTSLocation(int64_t pts)
// Compare to previous audio packet (and fix small gaps due to varying PTS timestamps)
if (previous_packet_location.frame != -1) {
- if (location.is_near(previous_packet_location, samples_per_frame, samples_per_frame))
- {
+ if (location.is_near(previous_packet_location, samples_per_frame, samples_per_frame)) {
int64_t orig_frame = location.frame;
int orig_start = location.sample_start;
@@ -1590,11 +1971,11 @@ AudioLocation FFmpegReader::GetAudioPTSLocation(int64_t pts)
// Debug output
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAudioPTSLocation (Audio Gap Ignored - too big)", "Previous location frame", previous_packet_location.frame, "Target Frame", location.frame, "Target Audio Sample", location.sample_start, "pts", pts, "", -1, "", -1);
- const GenericScopedLock lock(processingCriticalSection);
+ const GenericScopedLock lock(processingCriticalSection);
for (int64_t audio_frame = previous_packet_location.frame; audio_frame < location.frame; audio_frame++) {
if (!missing_audio_frames.count(audio_frame)) {
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAudioPTSLocation (tracking missing frame)", "missing_audio_frame", audio_frame, "previous_audio_frame", previous_packet_location.frame, "new location frame", location.frame, "", -1, "", -1, "", -1);
- missing_audio_frames.insert(pair(previous_packet_location.frame - 1, audio_frame));
+ missing_audio_frames.insert(pair(audio_frame, previous_packet_location.frame - 1));
}
}
}
@@ -1608,12 +1989,10 @@ AudioLocation FFmpegReader::GetAudioPTSLocation(int64_t pts)
}
// Create a new Frame (or return an existing one) and add it to the working queue.
-std::shared_ptr