Merge branch 'master' into otio_improvments
This commit is contained in:
@@ -1,117 +0,0 @@
|
||||
REM Get git hash in variable [this seems to be the most efficient way]
|
||||
git rev-parse --short=8 HEAD > hash.txt
|
||||
git rev-parse HEAD > longhash.txt
|
||||
set /p GITHASH= < hash.txt
|
||||
set /p GITLONGHASH= < longhash.txt
|
||||
set /p TRAVIS_COMMIT= < longhash.txt
|
||||
|
||||
REM Set up Visual Studio x64 environment
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
|
||||
|
||||
REM Install 64-bit packages
|
||||
set VCPKG_DEFAULT_TRIPLET=x64-windows
|
||||
|
||||
REM Hack to only install release builds for time
|
||||
echo set(VCPKG_BUILD_TYPE release) >> C:\Tools\vcpkg\triplets\x64-windows.cmake
|
||||
|
||||
REM Install Open*IO libraries
|
||||
vcpkg install opencolorio
|
||||
vcpkg install openimageio
|
||||
|
||||
REM Integrate libraries
|
||||
cd c:\tools\vcpkg
|
||||
vcpkg integrate install
|
||||
cd %APPVEYOR_BUILD_FOLDER%
|
||||
|
||||
REM Acquire FFmpeg
|
||||
set FFMPEG_VER=ffmpeg-4.2.3-win64
|
||||
curl https://ffmpeg.zeranoe.com/builds/win64/dev/%FFMPEG_VER%-dev.zip > %FFMPEG_VER%-dev.zip
|
||||
curl https://ffmpeg.zeranoe.com/builds/win64/shared/%FFMPEG_VER%-shared.zip > %FFMPEG_VER%-shared.zip
|
||||
7z x %FFMPEG_VER%-dev.zip
|
||||
7z x %FFMPEG_VER%-shared.zip
|
||||
|
||||
REM Acquire Google Crashpad
|
||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
set PATH=%PATH%;%APPVEYOR_BUILD_FOLDER%\depot_tools
|
||||
|
||||
REM Run `fetch` through cmd /c since fetch is a batch file that seems to call exit
|
||||
cmd /c fetch crashpad
|
||||
cd crashpad
|
||||
cmd /c gn gen out/Default
|
||||
|
||||
REM Patch to build a dynamic release instead of a static release
|
||||
ren out\Default\toolchain.ninja toolchain.ninja.old
|
||||
sed "s/${cflags_c}/${cflags_c} \/MD/g" out\Default\toolchain.ninja.old > out\Default\toolchain.ninja
|
||||
|
||||
REM Build Crashpad
|
||||
ninja.exe -C out/Default
|
||||
cd ..
|
||||
|
||||
REM Add Qt, FFmpeg, and Crashpad to path
|
||||
set PATH=%PATH%;C:\Qt\5.13.2\msvc2017_64\bin;%APPVEYOR_BUILD_FOLDER%\%FFMPEG_VER%-dev;%APPVEYOR_BUILD_FOLDER%\crashpad;%APPVEYOR_BUILD_FOLDER%\crashpad\out\Default
|
||||
|
||||
REM Run cmake
|
||||
cmake -G "Ninja" . -DCMAKE_TOOLCHAIN_FILE=c:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
|
||||
REM Build with Ninja
|
||||
ninja.exe || exit /B 1
|
||||
|
||||
REM If this is a pull request, no further packaging/deploying needs to be done
|
||||
if NOT "%APPVEYOR_PULL_REQUEST_NUMBER%" == "" goto end
|
||||
|
||||
REM Create Crashpad symbol file and upload it
|
||||
C:\msys64\usr\bin\wget.exe https://github.com/google/breakpad/blob/master/src/tools/windows/binaries/dump_syms.exe?raw=true -O dump_syms.exe
|
||||
dump_syms app\olive-editor.pdb > olive-editor.sym
|
||||
curl -F symfile=@olive-editor.sym https://olivevideoeditor.org/crashpad/symbols.php
|
||||
|
||||
REM Start building package
|
||||
mkdir olive-editor
|
||||
cd olive-editor
|
||||
copy ..\app\olive-editor.exe .
|
||||
copy ..\app\olive-editor.pdb .
|
||||
copy ..\app\crashhandler.exe .
|
||||
copy ..\crashpad\out\Default\crashpad_handler.exe .
|
||||
windeployqt olive-editor.exe
|
||||
copy ..\%FFMPEG_VER%-shared\bin\*.dll .
|
||||
copy ..\app\*.dll .
|
||||
|
||||
REM Package done, begin deployment
|
||||
cd ..
|
||||
set PKGNAME=Olive-%GITHASH%-Windows-x86_64
|
||||
|
||||
REM Create installer
|
||||
copy app\packaging\windows\nsis\* .
|
||||
"C:/Program Files (x86)/NSIS/makensis.exe" -V4 -DX64 "-XOutFile %PKGNAME%.exe" olive.nsi
|
||||
|
||||
REM Create portable
|
||||
copy nul olive-editor\portable
|
||||
7z a %PKGNAME%.zip olive-editor
|
||||
|
||||
REM If this was a tagged build, upload
|
||||
if "%APPVEYOR_REPO_TAG%"=="true" GOTO upload
|
||||
|
||||
REM Else, if this is a continuous build, check if this commit is the most recent
|
||||
|
||||
REM Force locale to UTF-8 or grep -P fails
|
||||
set LC_ALL=en_US.UTF-8
|
||||
|
||||
curl -H "Authorization: token %GITHUB_TOKEN%" https://api.github.com/repos/olive-editor/olive/commits/master > repoinfo.txt
|
||||
grep -Po '(?^<=: \")(([a-z0-9])\w+)(?=\")' -m 1 repoinfo.txt > latestcommit.txt
|
||||
set /p REMOTEHASH= < latestcommit.txt
|
||||
if "%REMOTEHASH%"=="%GITLONGHASH%" GOTO upload
|
||||
|
||||
REM The previous if statements failed, skip to the end
|
||||
GOTO end
|
||||
|
||||
:upload
|
||||
set /p UPLOADTOOL_BODY= < latestcommit.txt
|
||||
|
||||
curl -L https://github.com/probonopd/uploadtool/raw/master/upload.sh > upload.sh
|
||||
bash upload.sh Olive*.zip
|
||||
bash upload.sh Olive*.exe
|
||||
|
||||
:end
|
||||
REM Check if this build should set up a debugging session
|
||||
IF "%ENABLE_RDP%"=="1" (
|
||||
powershell -command "$blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))"
|
||||
)
|
||||
@@ -10,6 +10,15 @@ on:
|
||||
- 'docker/**'
|
||||
- 'CONTRIBUTING.md'
|
||||
- 'README.md'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/FUNDING.yml'
|
||||
- 'docker/**'
|
||||
- 'CONTRIBUTING.md'
|
||||
- 'README.md'
|
||||
|
||||
env:
|
||||
DOWNLOAD_TOOL: curl -fLOSs --retry 2 --retry-delay 60
|
||||
@@ -257,6 +266,7 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
GH_AUTH_KEY: ${{ secrets.GH_AUTH_KEY }}
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
curl -fLSs --retry 2 --retry-delay 60 \
|
||||
https://github.com/google/breakpad/blob/master/src/tools/windows/binaries/dump_syms.exe?raw=true > dump_syms.exe
|
||||
@@ -320,6 +330,12 @@ jobs:
|
||||
$DOWNLOAD_TOOL https://olivevideoeditor.org/deps/ocio-mac.zip
|
||||
$EXTRACT_TOOL ocio-mac.zip
|
||||
|
||||
- name: Acquire OpenTimelineIO
|
||||
shell: bash
|
||||
run: |
|
||||
$DOWNLOAD_TOOL https://olivevideoeditor.org/deps/otio-mac.zip
|
||||
$EXTRACT_TOOL otio-mac.zip
|
||||
|
||||
- name: Acquire OpenEXR
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
+37
-12
@@ -1,19 +1,39 @@
|
||||
*.pro.user*
|
||||
Makefile
|
||||
.qmake.stash
|
||||
effects/frei0r
|
||||
ts/*.qm
|
||||
docs
|
||||
history
|
||||
build/
|
||||
.DS_Store
|
||||
# CMake artifacts
|
||||
/build*/
|
||||
|
||||
.vscode
|
||||
.vs
|
||||
# Doxygen
|
||||
/docs/
|
||||
|
||||
# Visual Studio (Code)
|
||||
.localhistory/
|
||||
.history/
|
||||
.vscode/
|
||||
.vs/
|
||||
/out/
|
||||
CmakeSettings.json
|
||||
|
||||
# macOS General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Windows folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares (Windows)
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
#
|
||||
# Qt ignores taken from https://github.com/github/gitignore
|
||||
# Qt ignores taken from https://github.com/github/gitignore/blob/master/Qt.gitignore
|
||||
#
|
||||
|
||||
# C++ objects and libs
|
||||
@@ -24,6 +44,7 @@ CmakeSettings.json
|
||||
*.la
|
||||
*.lai
|
||||
*.so
|
||||
*.so.*
|
||||
*.dll
|
||||
*.dylib
|
||||
|
||||
@@ -46,6 +67,8 @@ ui_*.h
|
||||
*.jsc
|
||||
Makefile*
|
||||
*build-*
|
||||
*.qm
|
||||
*.prl
|
||||
|
||||
# Qt unit tests
|
||||
target_wrapper.*
|
||||
@@ -65,3 +88,5 @@ compile_commands.json
|
||||
|
||||
# QtCreator local machine specific files for imported projects
|
||||
*creator.user*
|
||||
|
||||
*_qmlcache.qrc
|
||||
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
language: cpp
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
env: ARCH=x86_64
|
||||
compiler: gcc
|
||||
sudo: require
|
||||
dist: xenial
|
||||
- os: osx
|
||||
osx_image: xcode10.3
|
||||
before_cache:
|
||||
- brew cleanup
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
- ffmpeg
|
||||
- qt5
|
||||
- grep
|
||||
- opencolorio
|
||||
- openimageio
|
||||
update: true
|
||||
# Can't build on Windows - affected by https://travis-ci.community/t/current-known-issues-please-read-this-before-posting-a-new-topic/264/10
|
||||
# - os: windows
|
||||
|
||||
before_install:
|
||||
- source ./.travis/before_install.sh
|
||||
|
||||
install:
|
||||
- source ./.travis/install.sh
|
||||
|
||||
script:
|
||||
- source ./.travis/script.sh
|
||||
|
||||
after_success:
|
||||
- source ./.travis/after_success.sh
|
||||
|
||||
branches:
|
||||
except:
|
||||
- # Do not build tags that we create when we upload to GitHub Releases
|
||||
- /^(?i:continuous)/
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if there's been a new commit since this build, and if so don't upload it
|
||||
|
||||
GREP_PATH=grep
|
||||
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
GREP_PATH=ggrep
|
||||
fi
|
||||
|
||||
# Get current repo commit from GitHub (problems arose from trying to pipe cURL directly into grep, so we buffer it through a file)
|
||||
REMOTE=$(curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/olive-editor/olive/commits/master | $GREP_PATH -Po '(?<=: \")(([a-z0-9])\w+)(?=\")' -m 1 --)
|
||||
LOCAL=$(git rev-parse HEAD)
|
||||
|
||||
if [ "$TRAVIS_TAG" != "" ] || [ "$REMOTE" == "$LOCAL" ]
|
||||
then
|
||||
echo "[INFO] Still current. Uploading..."
|
||||
|
||||
export UPLOADTOOL_BODY=$(cat release.txt)
|
||||
|
||||
# Retrieve upload tool
|
||||
wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
|
||||
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
|
||||
bash upload.sh Olive*.zip
|
||||
|
||||
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
|
||||
find appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
|
||||
|
||||
bash upload.sh Olive*.AppImage*
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
echo "[INFO] No longer current. $REMOTE vs $LOCAL - aborting upload."
|
||||
|
||||
fi
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
|
||||
# Qt 5.11
|
||||
sudo add-apt-repository ppa:beineri/opt-qt-5.11.0-xenial -y
|
||||
|
||||
# FFmpeg 4.x
|
||||
sudo add-apt-repository ppa:jonathonf/ffmpeg-4 -y
|
||||
|
||||
# OpenColorIO
|
||||
sudo add-apt-repository ppa:olive-editor/opencolorio -y
|
||||
|
||||
# Update apt
|
||||
sudo apt-get update -qq
|
||||
|
||||
fi
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
|
||||
export PATH="/usr/local/opt/qt/bin:/usr/local/opt/python@2/libexec/bin:$PATH"
|
||||
|
||||
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
|
||||
sudo apt-get -y -o Dpkg::Options::="--force-overwrite" install qt511base qt511multimedia qt511svg qt511tools libavformat-dev libavcodec-dev libavfilter-dev libavutil-dev libswscale-dev libswresample-dev libopencolorio-dev libopenimageio-dev libgl1-mesa-dev
|
||||
source /opt/qt*/bin/qt*-env.sh
|
||||
|
||||
# Acquire latest cmake (apt somehow gets the wrong version?)
|
||||
wget -c https://github.com/Kitware/CMake/releases/download/v3.17.2/cmake-3.17.2-Linux-x86_64.sh -O cmake.sh
|
||||
chmod +x cmake.sh
|
||||
./cmake.sh --skip-license --prefix=cmake --exclude-dir
|
||||
export PATH=$PWD/cmake/bin:$PATH
|
||||
|
||||
fi
|
||||
@@ -1,76 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# linuxdeployqt uses this for naming the file
|
||||
export VERSION=$(git rev-parse --short=8 HEAD)
|
||||
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
|
||||
# Generate Makefile
|
||||
cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
|
||||
# Make
|
||||
make -j$(sysctl -n hw.ncpu)
|
||||
|
||||
# Handle compile failure
|
||||
if [ "$?" != "0" ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BUNDLE_NAME=Olive.app
|
||||
|
||||
# Move bundle to working directory
|
||||
mv app/$BUNDLE_NAME .
|
||||
|
||||
# Move Qt deps into bundle
|
||||
macdeployqt $BUNDLE_NAME
|
||||
|
||||
# Fix other deps that macdeployqt missed
|
||||
curl -fLOSs --retry 3 https://github.com/arl/macdeployqtfix/raw/master/macdeployqtfix.py
|
||||
python2 macdeployqtfix.py $BUNDLE_NAME/Contents/MacOS/Olive /usr/local/Cellar/qt5/5.*/
|
||||
|
||||
# Fix deps on crash handler
|
||||
python2 macdeployqtfix.py $BUNDLE_NAME/Contents/MacOS/olive-crashhandler /usr/local/Cellar/qt5/5.*/
|
||||
|
||||
# Fix OpenEXR libs that seem to be missed by both macdeployqt _and_ macdeployqtfix
|
||||
cd $BUNDLE_NAME/Contents/Frameworks
|
||||
exrlib=(libImath-*.dylib libHalf-*.dylib libIexMath-*.dylib libIex-*.dylib libIlmThread-*.dylib)
|
||||
|
||||
for a in ${exrlib[@]}; do
|
||||
for b in ${exrlib[@]}; do
|
||||
install_name_tool -change @rpath/$b @executable_path/../Frameworks/$b $a
|
||||
done
|
||||
done
|
||||
|
||||
cd ../../..
|
||||
|
||||
# Distribute in zip
|
||||
zip -r Olive-$VERSION-macOS.zip $BUNDLE_NAME
|
||||
|
||||
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
|
||||
# Generate Makefile
|
||||
cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
|
||||
# Make
|
||||
make -j$(nproc)
|
||||
|
||||
# Handle compile failure
|
||||
if [ "$?" != "0" ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use `make install` on `appdir` to place files in the correct place
|
||||
make DESTDIR=appdir install
|
||||
|
||||
# Download linuxdeployqt
|
||||
wget -c -nv "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage"
|
||||
chmod a+x linuxdeployqt-continuous-x86_64.AppImage
|
||||
|
||||
unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH
|
||||
|
||||
# Use linuxdeployqt to set up dependencies
|
||||
./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/local/share/applications/*.desktop -extra-plugins=imageformats/libqsvg.so -appimage
|
||||
|
||||
fi
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -41,9 +41,9 @@ endif()
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
find_package(OpenColorIO REQUIRED)
|
||||
find_package(OpenColorIO 2.0.0 REQUIRED)
|
||||
|
||||
find_package(OpenImageIO 1.6 REQUIRED)
|
||||
find_package(OpenImageIO 2.1.12 REQUIRED)
|
||||
|
||||
find_package(OpenEXR REQUIRED)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Olive is a free non-linear video editor for Windows, macOS, and Linux.
|
||||
|
||||

|
||||
|
||||
**Discover more:** [Website](https://www.olivevideoeditor.org/) | [Binaries](https://olivevideoeditor.org/download.php) | [Twitter](https://twitter.com/oliveteam) | [Discord](https://discord.gg/4Ae9KZn) | [Patreon](https://www.patreon.com/olivevideoeditor) | [Tutorials](https://github.com/olive-editor/olive/wiki/Overview-Guide)
|
||||
**Discover more:** [Website](https://www.olivevideoeditor.org/) | [Binaries](https://olivevideoeditor.org/download.php) | [Patreon](https://www.patreon.com/olivevideoeditor) | [Twitter](https://twitter.com/oliveteam) | [Wiki](https://github.com/olive-editor/olive/wiki/Overview-Guide) | [Community Discord (Unofficial)](https://discord.gg/4Ae9KZn)
|
||||
|
||||
**NOTE: Olive is alpha software and is considered highly unstable. While we highly appreciate users testing and providing usage information, please use at your own risk.**
|
||||
|
||||
|
||||
+18
-12
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -41,7 +41,9 @@ add_subdirectory(project)
|
||||
add_subdirectory(render)
|
||||
add_subdirectory(shaders)
|
||||
add_subdirectory(task)
|
||||
add_subdirectory(threading)
|
||||
add_subdirectory(timeline)
|
||||
add_subdirectory(ts)
|
||||
add_subdirectory(tool)
|
||||
add_subdirectory(ui)
|
||||
add_subdirectory(undo)
|
||||
@@ -61,11 +63,25 @@ if(APPLE)
|
||||
)
|
||||
endif()
|
||||
|
||||
# Add translations
|
||||
qt5_add_translation(OLIVE_QM_FILES ${OLIVE_TS_FILES})
|
||||
|
||||
set(QRC_BODY "")
|
||||
foreach(QM_FILE ${OLIVE_QM_FILES})
|
||||
get_filename_component(QM_FILENAME_COMPONENT ${QM_FILE} NAME_WE)
|
||||
string(APPEND QRC_BODY "<file alias=\"${QM_FILENAME_COMPONENT}\">${QM_FILE}</file>\n")
|
||||
endforeach()
|
||||
configure_file(ts/translations.qrc.in ts/translations.qrc @ONLY)
|
||||
|
||||
set(OLIVE_RESOURCES
|
||||
${OLIVE_RESOURCES}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ts/translations.qrc
|
||||
)
|
||||
|
||||
# Add executable
|
||||
add_executable(${OLIVE_TARGET}
|
||||
${OLIVE_SOURCES}
|
||||
${OLIVE_RESOURCES}
|
||||
${OLIVE_QM_FILES}
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
@@ -264,16 +280,6 @@ endif()
|
||||
# Set compiler definitions
|
||||
target_compile_definitions(${OLIVE_TARGET} PRIVATE ${OLIVE_DEFINITIONS})
|
||||
|
||||
set(OLIVE_TS_FILES
|
||||
# FIXME: Empty variable
|
||||
)
|
||||
|
||||
if(UPDATE_TS)
|
||||
qt5_create_translation(OLIVE_QM_FILES ${CMAKE_SOURCE_DIR} ${OLIVE_TS_FILES})
|
||||
else()
|
||||
qt5_add_translation(OLIVE_QM_FILES ${OLIVE_TS_FILES})
|
||||
endif()
|
||||
|
||||
add_subdirectory(packaging)
|
||||
|
||||
if(DOXYGEN_FOUND)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -24,8 +24,6 @@ set(OLIVE_SOURCES
|
||||
audio/outputdeviceproxy.cpp
|
||||
audio/outputmanager.h
|
||||
audio/outputmanager.cpp
|
||||
audio/sampleformat.h
|
||||
audio/sampleformat.cpp
|
||||
audio/tempoprocessor.h
|
||||
audio/tempoprocessor.cpp
|
||||
PARENT_SCOPE
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "config/config.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
AudioManager* AudioManager::instance_ = nullptr;
|
||||
|
||||
@@ -124,36 +124,8 @@ void AudioManager::SetOutputDevice(const QAudioDeviceInfo &info)
|
||||
format.setChannelCount(output_params_.channel_count());
|
||||
format.setCodec("audio/pcm");
|
||||
format.setByteOrder(QAudioFormat::LittleEndian);
|
||||
|
||||
switch (output_params_.format()) {
|
||||
case SampleFormat::SAMPLE_FMT_U8:
|
||||
format.setSampleSize(8);
|
||||
format.setSampleType(QAudioFormat::UnSignedInt);
|
||||
break;
|
||||
case SampleFormat::SAMPLE_FMT_S16:
|
||||
format.setSampleSize(16);
|
||||
format.setSampleType(QAudioFormat::SignedInt);
|
||||
break;
|
||||
case SampleFormat::SAMPLE_FMT_S32:
|
||||
format.setSampleSize(32);
|
||||
format.setSampleType(QAudioFormat::SignedInt);
|
||||
break;
|
||||
case SampleFormat::SAMPLE_FMT_S64:
|
||||
format.setSampleSize(64);
|
||||
format.setSampleType(QAudioFormat::SignedInt);
|
||||
break;
|
||||
case SampleFormat::SAMPLE_FMT_FLT:
|
||||
format.setSampleSize(32);
|
||||
format.setSampleType(QAudioFormat::Float);
|
||||
break;
|
||||
case SampleFormat::SAMPLE_FMT_DBL:
|
||||
format.setSampleSize(64);
|
||||
format.setSampleType(QAudioFormat::Float);
|
||||
break;
|
||||
case SampleFormat::SAMPLE_FMT_COUNT:
|
||||
case SampleFormat::SAMPLE_FMT_INVALID:
|
||||
abort();
|
||||
}
|
||||
format.setSampleSize(output_params_.bits_per_sample());
|
||||
format.setSampleType(AudioParams::GetQtSampleType(output_params_.format()));
|
||||
|
||||
if (info.isFormatSupported(format)) {
|
||||
QMetaObject::invokeMethod(output_manager_,
|
||||
@@ -296,4 +268,4 @@ void AudioManager::InputDevicesRefreshed()
|
||||
emit InputListReady();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "render/audioparams.h"
|
||||
#include "render/audioplaybackcache.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
/**
|
||||
* @brief Audio input and output management class
|
||||
@@ -124,6 +124,6 @@ private slots:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // AUDIOMANAGER_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "config/config.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
const int AudioVisualWaveform::kSumSampleRate = 200;
|
||||
|
||||
@@ -151,6 +151,10 @@ void AudioVisualWaveform::Shift(const rational &from, const rational &to)
|
||||
return;
|
||||
}
|
||||
|
||||
if (from_index > data_.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (from_index > to_index) {
|
||||
// Shifting backwards <-
|
||||
int copy_sz = data_.size() - from_index;
|
||||
@@ -330,4 +334,4 @@ void AudioVisualWaveform::ExpandMinMax(AudioVisualWaveform::SamplePerChannel &su
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "codec/samplebuffer.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
/**
|
||||
* @brief A buffer of data used to store a visual representation of audio
|
||||
@@ -108,8 +108,8 @@ private:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(OLIVE_NAMESPACE::AudioVisualWaveform)
|
||||
Q_DECLARE_METATYPE(olive::AudioVisualWaveform)
|
||||
|
||||
#endif // SUMSAMPLES_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "audiomanager.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
AudioOutputDeviceProxy::AudioOutputDeviceProxy(QObject *parent) :
|
||||
QIODevice(parent),
|
||||
@@ -137,4 +137,4 @@ qint64 AudioOutputDeviceProxy::ReverseAwareRead(char *data, qint64 maxlen)
|
||||
return read_count;
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "common/define.h"
|
||||
#include "tempoprocessor.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
/**
|
||||
* @brief QIODevice wrapper that can adjust speed/reverse an audio file
|
||||
@@ -61,6 +61,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // AUDIOOUTPUTDEVICEPROXY_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include <QFile>
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
AudioOutputManager::AudioOutputManager(QObject *parent) :
|
||||
QObject(parent),
|
||||
@@ -151,4 +151,4 @@ void AudioOutputManager::OutputStateChanged(QAudio::State state)
|
||||
qDebug() << state << output_->error();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "outputdeviceproxy.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class AudioOutputManager : public QObject
|
||||
{
|
||||
@@ -59,7 +59,7 @@ public slots:
|
||||
void ResetToPushMode();
|
||||
|
||||
// Queued
|
||||
void SetParameters(OLIVE_NAMESPACE::AudioParams params);
|
||||
void SetParameters(olive::AudioParams params);
|
||||
|
||||
// Queued
|
||||
void Close();
|
||||
@@ -84,6 +84,6 @@ private slots:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // AUDIOHYBRIDDEVICE_H
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "sampleformat.h"
|
||||
|
||||
#include "core.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
const SampleFormat::Format SampleFormat::kInternalFormat = SAMPLE_FMT_FLT;
|
||||
|
||||
QString SampleFormat::GetSampleFormatName(const SampleFormat::Format &f)
|
||||
{
|
||||
switch (f) {
|
||||
case SAMPLE_FMT_U8:
|
||||
return tr("Unsigned 8-bit");
|
||||
case SAMPLE_FMT_S16:
|
||||
return tr("Signed 16-bit");
|
||||
case SAMPLE_FMT_S32:
|
||||
return tr("Signed 32-bit");
|
||||
case SAMPLE_FMT_S64:
|
||||
return tr("Signed 64-bit");
|
||||
case SAMPLE_FMT_FLT:
|
||||
return tr("32-bit Float");
|
||||
case SAMPLE_FMT_DBL:
|
||||
return tr("64-bit Float");
|
||||
case SAMPLE_FMT_COUNT:
|
||||
case SAMPLE_FMT_INVALID:
|
||||
break;
|
||||
}
|
||||
|
||||
return tr("Invalid");
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
@@ -1,58 +0,0 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef SAMPLEFORMAT_H
|
||||
#define SAMPLEFORMAT_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "common/define.h"
|
||||
#include "render/rendermodes.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class SampleFormat : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SampleFormat() = default;
|
||||
|
||||
enum Format {
|
||||
SAMPLE_FMT_INVALID = -1,
|
||||
|
||||
SAMPLE_FMT_U8,
|
||||
SAMPLE_FMT_S16,
|
||||
SAMPLE_FMT_S32,
|
||||
SAMPLE_FMT_S64,
|
||||
SAMPLE_FMT_FLT,
|
||||
SAMPLE_FMT_DBL,
|
||||
|
||||
SAMPLE_FMT_COUNT
|
||||
};
|
||||
|
||||
static const Format kInternalFormat;
|
||||
|
||||
static QString GetSampleFormatName(const Format& f);
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
#endif // SAMPLEFORMAT_H
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -28,9 +28,9 @@ extern "C" {
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "codec/ffmpeg/ffmpegcommon.h"
|
||||
#include "common/ffmpegutils.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
TempoProcessor::TempoProcessor() :
|
||||
filter_graph_(nullptr),
|
||||
@@ -75,7 +75,7 @@ bool TempoProcessor::Open(const AudioParams ¶ms, const double& speed)
|
||||
1,
|
||||
params_.sample_rate(),
|
||||
params_.sample_rate(),
|
||||
FFmpegCommon::GetFFmpegSampleFormat(params_.format()),
|
||||
FFmpegUtils::GetFFmpegSampleFormat(params_.format()),
|
||||
params.channel_layout());
|
||||
|
||||
// Create buffer and buffersink
|
||||
@@ -171,7 +171,7 @@ void TempoProcessor::Push(const char *data, int length)
|
||||
|
||||
// Allocate a buffer for the number of samples we got
|
||||
src_frame->sample_rate = params_.sample_rate();
|
||||
src_frame->format = FFmpegCommon::GetFFmpegSampleFormat(params_.format());
|
||||
src_frame->format = FFmpegUtils::GetFFmpegSampleFormat(params_.format());
|
||||
src_frame->channel_layout = params_.channel_layout();
|
||||
src_frame->nb_samples = params_.bytes_to_samples(length);
|
||||
src_frame->pts = timestamp_;
|
||||
@@ -274,4 +274,4 @@ AVFilterContext *TempoProcessor::CreateTempoFilter(AVFilterGraph* graph, AVFilte
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -35,7 +35,7 @@ extern "C" {
|
||||
|
||||
#include "render/audioparams.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class TempoProcessor
|
||||
{
|
||||
@@ -78,6 +78,6 @@ private:
|
||||
bool flushed_;
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // TEMPOPROCESSOR_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,11 +20,11 @@
|
||||
|
||||
#include "cliexportmanager.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
CLIExportManager::CLIExportManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "task/export/export.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class CLIExportManager : public QObject
|
||||
{
|
||||
@@ -31,6 +31,6 @@ public:
|
||||
CLIExportManager();
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // CLIEXPORTMANAGER_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
CLIProgressDialog::CLIProgressDialog(const QString& title, QObject *parent) :
|
||||
QObject(parent),
|
||||
@@ -103,4 +103,4 @@ void CLIProgressDialog::SetProgress(double p)
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class CLIProgressDialog : public QObject
|
||||
{
|
||||
@@ -47,6 +47,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // CLIPROGRESSDIALOG_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "clitaskdialog.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
CLITaskDialog::CLITaskDialog(Task *task, QObject* parent) :
|
||||
CLIProgressDialog(task->GetTitle(), parent),
|
||||
@@ -34,4 +34,4 @@ bool CLITaskDialog::Run()
|
||||
return task_->Start();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "cli/cliprogress/cliprogressdialog.h"
|
||||
#include "task/task.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class CLITaskDialog : public CLIProgressDialog
|
||||
{
|
||||
@@ -39,6 +39,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // CLITASKDIALOG_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
+174
-64
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,11 +24,11 @@
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "codec/ffmpeg/ffmpegcommon.h"
|
||||
#include "codec/ffmpeg/ffmpegdecoder.h"
|
||||
#include "codec/oiio/oiiodecoder.h"
|
||||
#include "codec/waveinput.h"
|
||||
#include "codec/waveoutput.h"
|
||||
#include "common/ffmpegutils.h"
|
||||
#include "common/filefunctions.h"
|
||||
#include "common/timecodefunctions.h"
|
||||
#ifdef USE_OTIO
|
||||
@@ -37,57 +37,162 @@
|
||||
#include "task/taskmanager.h"
|
||||
#include "project/project.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
QMutex Decoder::currently_conforming_mutex_;
|
||||
QWaitCondition Decoder::currently_conforming_wait_cond_;
|
||||
QVector<Decoder::CurrentlyConforming> Decoder::currently_conforming_;
|
||||
|
||||
Decoder::Decoder() :
|
||||
open_(false),
|
||||
stream_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Decoder::Decoder(Stream *fs) :
|
||||
open_(false),
|
||||
stream_(fs)
|
||||
bool Decoder::Open(StreamPtr fs)
|
||||
{
|
||||
}
|
||||
QMutexLocker locker(&mutex_);
|
||||
|
||||
StreamPtr Decoder::stream() const
|
||||
{
|
||||
return stream_;
|
||||
}
|
||||
if (stream_) {
|
||||
// Decoder is already open. Return TRUE if the stream is the stream we have, or FALSE if not.
|
||||
if (stream_ == fs) {
|
||||
return true;
|
||||
} else {
|
||||
qWarning() << "Tried to open a decoder that was already open with another stream";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Stream was not open, try opening it now
|
||||
if (fs == nullptr) {
|
||||
// Cannot open null stream
|
||||
qCritical() << "Decoder attempted to open null stream";
|
||||
return false;
|
||||
}
|
||||
|
||||
void Decoder::set_stream(StreamPtr fs)
|
||||
{
|
||||
Close();
|
||||
if (fs->footage()->decoder() != id()) {
|
||||
qCritical() << "Tried to open footage in incorrect decoder";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set stream
|
||||
stream_ = fs;
|
||||
}
|
||||
|
||||
FramePtr Decoder::RetrieveVideo(const rational &/*timecode*/, const int &/*divider*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SampleBufferPtr Decoder::RetrieveAudio(const rational &/*timecode*/, const rational &/*length*/, const AudioParams &/*params*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Decoder::SupportsVideo()
|
||||
{
|
||||
// Try open internal
|
||||
if (OpenInternal()) {
|
||||
return true;
|
||||
} else {
|
||||
// Unset stream
|
||||
CloseInternal();
|
||||
stream_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Decoder::SupportsAudio()
|
||||
FramePtr Decoder::RetrieveVideo(const rational &timecode, const int ÷r)
|
||||
{
|
||||
return false;
|
||||
QMutexLocker locker(&mutex_);
|
||||
|
||||
if (!stream_) {
|
||||
qCritical() << "Can't retrieve video on a closed decoder";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!SupportsVideo()) {
|
||||
qCritical() << "Decoder doesn't support video";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (stream_->type() != Stream::kVideo) {
|
||||
qCritical() << "Tried to retrieve video from a non-video stream";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return RetrieveVideoInternal(timecode, divider);
|
||||
}
|
||||
|
||||
SampleBufferPtr Decoder::RetrieveAudio(const TimeRange &range, const AudioParams ¶ms, const QAtomicInt *cancelled)
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
|
||||
if (!stream_) {
|
||||
qCritical() << "Can't retrieve audio on a closed decoder";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!SupportsAudio()) {
|
||||
qCritical() << "Decoder doesn't support audio";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (stream_->type() != Stream::kAudio) {
|
||||
qCritical() << "Tried to retrieve audio from a non-audio stream";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Determine if we already have a conformed version
|
||||
QString conform_filename = GetConformedFilename(params);
|
||||
CurrentlyConforming want_conform = {stream_, params};
|
||||
|
||||
currently_conforming_mutex_.lock();
|
||||
|
||||
// Wait for conform to complete
|
||||
while (currently_conforming_.contains(want_conform)) {
|
||||
currently_conforming_wait_cond_.wait(¤tly_conforming_mutex_);
|
||||
}
|
||||
|
||||
// See if we got the conform
|
||||
SampleBufferPtr buffer = RetrieveAudioFromConform(conform_filename, range);
|
||||
|
||||
if (!buffer) {
|
||||
// We'll need to conform this ourselves
|
||||
currently_conforming_.append(want_conform);
|
||||
currently_conforming_mutex_.unlock();
|
||||
|
||||
// We conform to a different filename until it's done to make it clear even across sessions
|
||||
// whether this conform is ready or not
|
||||
QString working_fn = conform_filename;
|
||||
working_fn.append(QStringLiteral(".working"));
|
||||
|
||||
if (ConformAudioInternal(working_fn, params, cancelled)) {
|
||||
// Move file to standard conform name, making it clear this conform is ready for use
|
||||
QFile::remove(conform_filename);
|
||||
QFile::rename(working_fn, conform_filename);
|
||||
|
||||
// Return audio as planned
|
||||
buffer = RetrieveAudioFromConform(conform_filename, range);
|
||||
} else {
|
||||
// Failed
|
||||
qCritical() << "Failed to conform audio";
|
||||
}
|
||||
|
||||
currently_conforming_mutex_.lock();
|
||||
currently_conforming_.removeOne(want_conform);
|
||||
currently_conforming_wait_cond_.wakeAll();
|
||||
}
|
||||
|
||||
currently_conforming_mutex_.unlock();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void Decoder::Close()
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
|
||||
if (stream_) {
|
||||
CloseInternal();
|
||||
stream_ = nullptr;
|
||||
} else {
|
||||
qWarning() << "Tried to close a decoder that wasn't open";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DECODER STATIC PUBLIC MEMBERS
|
||||
*/
|
||||
|
||||
QVector<DecoderPtr> ReceiveListOfAllDecoders() {
|
||||
QVector<DecoderPtr> ReceiveListOfAllDecoders()
|
||||
{
|
||||
QVector<DecoderPtr> decoders;
|
||||
|
||||
// The order in which these decoders are added is their priority when probing. Hence FFmpeg should usually be last,
|
||||
@@ -98,7 +203,7 @@ QVector<DecoderPtr> ReceiveListOfAllDecoders() {
|
||||
return decoders;
|
||||
}
|
||||
|
||||
FootagePtr Decoder::ProbeMedia(Project* project, const QString &filename, const QAtomicInt* cancelled)
|
||||
FootagePtr Decoder::Probe(Project* project, const QString &filename, const QAtomicInt* cancelled)
|
||||
{
|
||||
// Check for a valid filename
|
||||
if (filename.isEmpty()) {
|
||||
@@ -184,37 +289,6 @@ QString Decoder::GetIndexFilename()
|
||||
return QDir(stream_->footage()->project()->cache_path()).filePath(FileFunctions::GetUniqueFileIdentifier(stream()->footage()->filename()).append(QString::number(stream()->index())));
|
||||
}
|
||||
|
||||
bool Decoder::ConformAudio(const QAtomicInt *, const AudioParams& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Decoder::HasConformedVersion(const AudioParams ¶ms)
|
||||
{
|
||||
if (stream()->type() != Stream::kAudio) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AudioStreamPtr audio_stream = std::static_pointer_cast<AudioStream>(stream());
|
||||
|
||||
if (audio_stream->has_conformed_version(params)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get indexed WAV file
|
||||
WaveInput input(GetIndexFilename());
|
||||
|
||||
bool index_already_matches = false;
|
||||
|
||||
if (input.open()) {
|
||||
index_already_matches = (input.params() == params);
|
||||
|
||||
input.close();
|
||||
}
|
||||
|
||||
return index_already_matches;
|
||||
}
|
||||
|
||||
void Decoder::SignalProcessingProgress(const int64_t &ts)
|
||||
{
|
||||
if (stream()->duration() != AV_NOPTS_VALUE && stream()->duration() != 0) {
|
||||
@@ -267,4 +341,40 @@ int64_t Decoder::GetImageSequenceIndex(const QString &filename)
|
||||
return number_only.toLongLong();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
FramePtr Decoder::RetrieveVideoInternal(const rational &timecode, const int ÷r)
|
||||
{
|
||||
Q_UNUSED(timecode)
|
||||
Q_UNUSED(divider)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Decoder::ConformAudioInternal(const QString& filename, const AudioParams ¶ms, const QAtomicInt* cancelled)
|
||||
{
|
||||
Q_UNUSED(filename)
|
||||
Q_UNUSED(cancelled)
|
||||
Q_UNUSED(params)
|
||||
return false;
|
||||
}
|
||||
|
||||
SampleBufferPtr Decoder::RetrieveAudioFromConform(const QString &conform_filename, const TimeRange& range)
|
||||
{
|
||||
WaveInput input(conform_filename);
|
||||
|
||||
if (input.open()) {
|
||||
const AudioParams& input_params = input.params();
|
||||
|
||||
// Read bytes from wav
|
||||
QByteArray packed_data = input.read(input_params.time_to_bytes(range.in()),
|
||||
input_params.time_to_bytes(range.length()));
|
||||
input.close();
|
||||
|
||||
// Create sample buffer
|
||||
SampleBufferPtr sample_buffer = SampleBuffer::CreateFromPackedData(input_params, packed_data);
|
||||
|
||||
return sample_buffer;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+115
-129
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,7 @@ extern "C" {
|
||||
|
||||
#include <QMutex>
|
||||
#include <QObject>
|
||||
#include <QWaitCondition>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "codec/frame.h"
|
||||
@@ -35,7 +36,7 @@ extern "C" {
|
||||
#include "common/rational.h"
|
||||
#include "project/item/footage/footage.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class Decoder;
|
||||
using DecoderPtr = std::shared_ptr<Decoder>;
|
||||
@@ -68,117 +69,46 @@ public:
|
||||
|
||||
Decoder();
|
||||
|
||||
Decoder(Stream* fs);
|
||||
|
||||
DISABLE_COPY_MOVE(Decoder)
|
||||
|
||||
/**
|
||||
* @brief Unique decoder ID
|
||||
*/
|
||||
virtual QString id() = 0;
|
||||
|
||||
StreamPtr stream() const;
|
||||
void set_stream(StreamPtr fs);
|
||||
virtual bool SupportsVideo(){return false;}
|
||||
virtual bool SupportsAudio(){return false;}
|
||||
|
||||
/**
|
||||
* @brief Probe a footage file and dump metadata about it
|
||||
* @brief Open stream for decoding
|
||||
*
|
||||
* When a Footage file is imported, we'll need to know whether Olive is equipped with a decoder for utilizing it
|
||||
* and metadata should be retrieved about it if so. For this purpose, the Footage object is passed through all
|
||||
* Probe() functions of available deocders until one returns TRUE. A FALSE return means the Decoder was unable to
|
||||
* parse this file and the next should be tried.
|
||||
* This function is thread safe.
|
||||
*
|
||||
* Probe() differs from Open() since it focuses on a file as a whole rather than one particular stream. Probe()
|
||||
* should be able to be run directly without calling Open() or Close() and should free its memory before returning.
|
||||
*
|
||||
* Probe() will never be called on an object that is also used for decoding. In other words, it will never be called
|
||||
* alongside Open() or Close() externally, so Probe() can use variables that would otherwise be used for decoding
|
||||
* without conflict.
|
||||
*
|
||||
* @param f
|
||||
*
|
||||
* A Footage object to probe. The Footage object will have a valid filename and will be empty prior to being sent
|
||||
* to this function (i.e. Footage::Clear() will not have to be called).
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if the Decoder was able to decode this file. FALSE if not. This function should have filled the Footage
|
||||
* object with metadata if it returns TRUE. Otherwise, the Footage object should be untouched.
|
||||
* Returns TRUE if stream could be opened successfully. Also returns TRUE if the decoder is
|
||||
* already open and the stream == the stream provided. Returns FALSE if the stream couldn't
|
||||
* be opened OR if already open and the stream is NOT the same.
|
||||
*/
|
||||
virtual FootagePtr Probe(const QString& filename, const QAtomicInt* cancelled) const = 0;
|
||||
bool Open(StreamPtr fs);
|
||||
|
||||
/**
|
||||
* @brief Open media/allocate memory
|
||||
* @brief Retrieves a video frame from footage
|
||||
*
|
||||
* Any file handles or memory allocation that needs to be done before this instance of a Decoder can return data
|
||||
* should be done here.
|
||||
* This function will always return a valid frame unless a fatal error occurs (in such case,
|
||||
* nullptr will return). If the timecode is before the start of the footage, this function should
|
||||
* return the first frame. Likewise, if it is after the timecode, this function should return the
|
||||
* last frame.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if successful and ready to return data, FALSE if failed to open and unable to retrieve data. If the function
|
||||
* fails, any memory allocated should be free'd before returning FALSE, possibly by calling Close().
|
||||
* This function is thread safe and can only run while the decoder is open. \see Open()
|
||||
*/
|
||||
virtual bool Open() = 0;
|
||||
FramePtr RetrieveVideo(const rational& timecode, const int& divider);
|
||||
|
||||
/**
|
||||
* @brief Retrieve video frame
|
||||
* @brief Retrieve audio data from footage
|
||||
*
|
||||
* The main function for retrieving video data from the Decoder. This function should always provide complete frame
|
||||
* data (i.e. no partial frames) at the timecode provided. The Decoder should perform any steps required to retrieve
|
||||
* a complete frame separate from the rest of the program, using any form of caching/indexing to keep this as
|
||||
* performant as possible.
|
||||
* This function will always return a sample buffer unless a fatal error occurs (in such case,
|
||||
* nullptr will return). The SampleBuffer should always have enough audio for the range provided.
|
||||
*
|
||||
* It's acceptable for this function to check whether the Decoder is open, and call Open() if not. If Open() returns
|
||||
* false, this function should return nullptr.
|
||||
*
|
||||
* @param timecode
|
||||
*
|
||||
* The timecode (a rational in seconds) to retrieve the frame at. If there is not a frame at this precise location
|
||||
* this should be corrected internally to the closest fit for the timecode.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A FramePtr of valid data at this timecode or nullptr if there was nothing to retrieve at the provided timecode or
|
||||
* the media could not be opened.
|
||||
* This function is thread safe and can only run while the decoder is open. \see Open()
|
||||
*/
|
||||
virtual FramePtr RetrieveVideo(const rational& timecode, const int& divider);
|
||||
|
||||
/**
|
||||
* @brief Retrieve video frame
|
||||
*
|
||||
* The main function for retrieving audio data from the Decoder. This function should always provide complete frame
|
||||
* data (i.e. no missing samples) at the timecode and length requested. The Decoder should perform any steps
|
||||
* required to retrieve a complete frame separate from the rest of the program, using any form of caching/indexing
|
||||
* to keep this as performant as possible.
|
||||
*
|
||||
* It's acceptable for this function to check whether the Decoder is open, and call Open() if not. If Open() returns
|
||||
* false, this function should return nullptr.
|
||||
*
|
||||
* @param timecode
|
||||
*
|
||||
* The starting timecode (a rational in seconds) to retrieve the data at.
|
||||
*
|
||||
* @param length
|
||||
*
|
||||
* The total length of audio data to retrieve (a rational in seconds).
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A FramePtr of valid data at this timecode of the requested length or nullptr if there was nothing to retrieve at
|
||||
* the provided timecode or the media could not be opened.
|
||||
*/
|
||||
virtual SampleBufferPtr RetrieveAudio(const rational& timecode, const rational& length, const AudioParams& params);
|
||||
|
||||
virtual bool SupportsVideo();
|
||||
virtual bool SupportsAudio();
|
||||
|
||||
/**
|
||||
* @brief Close media/deallocate memory
|
||||
*
|
||||
* Any file handles or memory allocations opened in Open() should be cleaned up here.
|
||||
*
|
||||
* As the main memory freeing function, it's good practice to call this in Open() if there's an error that prevents
|
||||
* correct function before Open() returns. As such, Close() should be prepared for not all memory/file handles to
|
||||
* have been opened successfully.
|
||||
*/
|
||||
virtual void Close() = 0;
|
||||
SampleBufferPtr RetrieveAudio(const TimeRange& range, const AudioParams& params, const QAtomicInt *cancelled);
|
||||
|
||||
/**
|
||||
* @brief Try to probe a Footage file by passing it through all available Decoders
|
||||
@@ -199,7 +129,27 @@ public:
|
||||
*
|
||||
* TRUE if a Decoder was successfully able to parse and probe this file. FALSE if not.
|
||||
*/
|
||||
static FootagePtr ProbeMedia(Project *project, const QString& filename, const QAtomicInt *cancelled);
|
||||
static FootagePtr Probe(Project *project, const QString& filename, const QAtomicInt *cancelled);
|
||||
|
||||
/**
|
||||
* @brief Generate a Footage object from a file
|
||||
*
|
||||
* If this decoder is able to parse this file, it will return a valid FootagePtr. Otherwise, it
|
||||
* will return nullptr.
|
||||
*
|
||||
* For sub-classes, this function should be effectively static. We can't do virtual static
|
||||
* functions in C++, but it should hold and access no state during its run.
|
||||
*
|
||||
* This function is re-entrant.
|
||||
*/
|
||||
virtual FootagePtr Probe(const QString& filename, const QAtomicInt* cancelled) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Closes media/deallocates memory
|
||||
*
|
||||
* This function is thread safe and can only run while the decoder is open. \see Open()
|
||||
*/
|
||||
void Close();
|
||||
|
||||
/**
|
||||
* @brief Create a Decoder instance using a Decoder ID
|
||||
@@ -210,42 +160,45 @@ public:
|
||||
*/
|
||||
static DecoderPtr CreateFromID(const QString& id);
|
||||
|
||||
/**
|
||||
* @brief AUDIO ONLY: Produces a complete PCM extraction of the audio stream
|
||||
*
|
||||
* Internally, our render engine only deals with PCM since it provides the least headaches and
|
||||
* modern computers have the processing power to do it.
|
||||
*
|
||||
* Resamples and converts the currently open audio to match the params. If the audio doesn't need
|
||||
* conforming (e.g. audio params already match or a conformed match already exists), this function
|
||||
* will return immediately. Otherwise it will block the calling thread until the conform is
|
||||
* complete. This function should therefore only be called from a background render thread.
|
||||
*
|
||||
* All audio decoders must override this. It's not pure since video decoders don't need to use
|
||||
* this, but default behavior will abort since it should never be called.
|
||||
*/
|
||||
virtual bool ConformAudio(const QAtomicInt* cancelled, const AudioParams ¶ms);
|
||||
|
||||
/**
|
||||
* @brief AUDIO ONLY: Returns whether a transcode of this audio matching the specified params
|
||||
* already exists
|
||||
*/
|
||||
bool HasConformedVersion(const AudioParams& params);
|
||||
|
||||
static QString TransformImageSequenceFileName(const QString& filename, const int64_t& number);
|
||||
|
||||
static int GetImageSequenceDigitCount(const QString& filename);
|
||||
|
||||
static int64_t GetImageSequenceIndex(const QString& filename);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief While indexing, this signal will provide progress as a percentage (0-100 inclusive) if
|
||||
* available
|
||||
*/
|
||||
void IndexProgress(double);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Internal open function
|
||||
*
|
||||
* Sub-classes must override this function. Function will already be mutexed, so there is no need
|
||||
* to worry about thread safety. Also many other sanity checks will be done before this, so
|
||||
* sub-classes only need to worry about their own opening functions. It is guaranteed that the
|
||||
* decoder is not open yet and that the footage stream was from that sub-classes probe function.
|
||||
*
|
||||
* Return TRUE if everything opened successfully and the decoder is ready to work. Otherwise,
|
||||
* return FALSE. If this function returns false, Decoder will call CloseInternal to clean any
|
||||
* memory allocated during OpenInternal.
|
||||
*/
|
||||
virtual bool OpenInternal() = 0;
|
||||
|
||||
/**
|
||||
* @brief Internal close function
|
||||
*
|
||||
* Sub-classes must override this function. Function should be able to safely clear all allocated
|
||||
* memory. It may be called even if Open() didn't complete or RetrieveVideo() was never called.
|
||||
*/
|
||||
virtual void CloseInternal() = 0;
|
||||
|
||||
/**
|
||||
* @brief Internal frame retrieval function
|
||||
*
|
||||
* Sub-classes must override this function IF they support video. Function is already mutexed
|
||||
* so sub-classes don't need to worry about thread safety.
|
||||
*/
|
||||
virtual FramePtr RetrieveVideoInternal(const rational& timecode, const int& divider);
|
||||
|
||||
virtual bool ConformAudioInternal(const QString& filename, const AudioParams ¶ms, const QAtomicInt* cancelled);
|
||||
|
||||
void SignalProcessingProgress(const int64_t& ts);
|
||||
|
||||
/**
|
||||
@@ -255,15 +208,48 @@ protected:
|
||||
|
||||
QString GetIndexFilename();
|
||||
|
||||
bool open_;
|
||||
struct CurrentlyConforming {
|
||||
StreamPtr stream;
|
||||
AudioParams params;
|
||||
|
||||
bool operator==(const CurrentlyConforming& rhs) const
|
||||
{
|
||||
return this->stream == rhs.stream && this->params == rhs.params;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Return currently open stream
|
||||
*
|
||||
* This function is NOT thread safe and should therefore only be called by thread safe functions.
|
||||
*/
|
||||
StreamPtr stream() const
|
||||
{
|
||||
return stream_;
|
||||
}
|
||||
|
||||
static QMutex currently_conforming_mutex_;
|
||||
static QWaitCondition currently_conforming_wait_cond_;
|
||||
static QVector<CurrentlyConforming> currently_conforming_;
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief While indexing, this signal will provide progress as a percentage (0-100 inclusive) if
|
||||
* available
|
||||
*/
|
||||
void IndexProgress(double);
|
||||
|
||||
private:
|
||||
SampleBufferPtr RetrieveAudioFromConform(const QString& conform_filename, const TimeRange &range);
|
||||
|
||||
StreamPtr stream_;
|
||||
|
||||
QMutex mutex_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(OLIVE_NAMESPACE::Decoder::RetrieveState)
|
||||
Q_DECLARE_METATYPE(olive::Decoder::RetrieveState)
|
||||
|
||||
#endif // DECODER_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "ffmpeg/ffmpegencoder.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
Encoder::Encoder(const EncodingParams ¶ms) :
|
||||
params_(params)
|
||||
@@ -236,4 +236,4 @@ Encoder* Encoder::CreateFromID(const QString &id, const EncodingParams& params)
|
||||
return new FFmpegEncoder(params);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
+11
-6
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "render/audioparams.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class Encoder;
|
||||
using EncoderPtr = std::shared_ptr<Encoder>;
|
||||
@@ -114,19 +114,24 @@ public:
|
||||
|
||||
virtual bool Open() = 0;
|
||||
|
||||
virtual bool WriteFrame(OLIVE_NAMESPACE::FramePtr frame, OLIVE_NAMESPACE::rational time) = 0;
|
||||
virtual void WriteAudio(OLIVE_NAMESPACE::AudioParams pcm_info,
|
||||
virtual bool WriteFrame(olive::FramePtr frame, olive::rational time) = 0;
|
||||
virtual void WriteAudio(olive::AudioParams pcm_info,
|
||||
QIODevice *file) = 0;
|
||||
void WriteAudio(OLIVE_NAMESPACE::AudioParams pcm_info,
|
||||
void WriteAudio(olive::AudioParams pcm_info,
|
||||
const QString& pcm_filename);
|
||||
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual VideoParams::Format GetDesiredPixelFormat() const
|
||||
{
|
||||
return VideoParams::kFormatInvalid;
|
||||
}
|
||||
|
||||
private:
|
||||
EncodingParams params_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // ENCODER_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@ extern "C" {
|
||||
#include <libavutil/pixdesc.h>
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
QString ExportCodec::GetCodecName(ExportCodec::Codec c)
|
||||
{
|
||||
@@ -125,4 +125,4 @@ QStringList ExportCodec::GetPixelFormatsForCodec(ExportCodec::Codec c)
|
||||
return pix_fmts;
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -26,9 +26,11 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class ExportCodec : public QObject {
|
||||
class ExportCodec : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Codec {
|
||||
kCodecDNxHD,
|
||||
@@ -55,6 +57,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // EXPORTCODEC_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "exportformat.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
QString ExportFormat::GetName(olive::ExportFormat::Format f)
|
||||
{
|
||||
@@ -135,4 +135,4 @@ QList<ExportCodec::Codec> ExportFormat::GetAudioCodecs(ExportFormat::Format f)
|
||||
return {};
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,9 +27,11 @@
|
||||
#include "common/define.h"
|
||||
#include "exportcodec.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class ExportFormat : public QObject {
|
||||
class ExportFormat : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Format {
|
||||
kFormatDNxHD,
|
||||
@@ -51,6 +53,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // EXPORTFORMAT_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
codec/ffmpeg/avframeptr.h
|
||||
codec/ffmpeg/ffmpegcommon.h
|
||||
codec/ffmpeg/ffmpegcommon.cpp
|
||||
codec/ffmpeg/ffmpegdecoder.h
|
||||
codec/ffmpeg/ffmpegdecoder.cpp
|
||||
codec/ffmpeg/ffmpegencoder.h
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "ffmpegcommon.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
AVPixelFormat FFmpegCommon::GetCompatiblePixelFormat(const AVPixelFormat &pix_fmt)
|
||||
{
|
||||
AVPixelFormat possible_pix_fmts[] = {
|
||||
AV_PIX_FMT_RGB24,
|
||||
AV_PIX_FMT_RGBA,
|
||||
AV_PIX_FMT_RGB48,
|
||||
AV_PIX_FMT_RGBA64,
|
||||
AV_PIX_FMT_NONE
|
||||
};
|
||||
|
||||
return avcodec_find_best_pix_fmt_of_list(possible_pix_fmts,
|
||||
pix_fmt,
|
||||
1,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
SampleFormat::Format FFmpegCommon::GetNativeSampleFormat(const AVSampleFormat &smp_fmt)
|
||||
{
|
||||
switch (smp_fmt) {
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
return SampleFormat::SAMPLE_FMT_U8;
|
||||
case AV_SAMPLE_FMT_S16:
|
||||
return SampleFormat::SAMPLE_FMT_S16;
|
||||
case AV_SAMPLE_FMT_S32:
|
||||
return SampleFormat::SAMPLE_FMT_S32;
|
||||
case AV_SAMPLE_FMT_S64:
|
||||
return SampleFormat::SAMPLE_FMT_S64;
|
||||
case AV_SAMPLE_FMT_FLT:
|
||||
return SampleFormat::SAMPLE_FMT_FLT;
|
||||
case AV_SAMPLE_FMT_DBL:
|
||||
return SampleFormat::SAMPLE_FMT_DBL;
|
||||
case AV_SAMPLE_FMT_U8P :
|
||||
case AV_SAMPLE_FMT_S16P:
|
||||
case AV_SAMPLE_FMT_S32P:
|
||||
case AV_SAMPLE_FMT_S64P:
|
||||
case AV_SAMPLE_FMT_FLTP:
|
||||
case AV_SAMPLE_FMT_DBLP:
|
||||
case AV_SAMPLE_FMT_NONE:
|
||||
case AV_SAMPLE_FMT_NB:
|
||||
break;
|
||||
}
|
||||
|
||||
return SampleFormat::SAMPLE_FMT_INVALID;
|
||||
}
|
||||
|
||||
AVSampleFormat FFmpegCommon::GetFFmpegSampleFormat(const SampleFormat::Format &smp_fmt)
|
||||
{
|
||||
switch (smp_fmt) {
|
||||
case SampleFormat::SAMPLE_FMT_U8:
|
||||
return AV_SAMPLE_FMT_U8;
|
||||
case SampleFormat::SAMPLE_FMT_S16:
|
||||
return AV_SAMPLE_FMT_S16;
|
||||
case SampleFormat::SAMPLE_FMT_S32:
|
||||
return AV_SAMPLE_FMT_S32;
|
||||
case SampleFormat::SAMPLE_FMT_S64:
|
||||
return AV_SAMPLE_FMT_S64;
|
||||
case SampleFormat::SAMPLE_FMT_FLT:
|
||||
return AV_SAMPLE_FMT_FLT;
|
||||
case SampleFormat::SAMPLE_FMT_DBL:
|
||||
return AV_SAMPLE_FMT_DBL;
|
||||
case SampleFormat::SAMPLE_FMT_INVALID:
|
||||
case SampleFormat::SAMPLE_FMT_COUNT:
|
||||
break;
|
||||
}
|
||||
|
||||
return AV_SAMPLE_FMT_NONE;
|
||||
}
|
||||
|
||||
AVPixelFormat FFmpegCommon::GetFFmpegPixelFormat(const PixelFormat::Format &pix_fmt)
|
||||
{
|
||||
switch (pix_fmt) {
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
return AV_PIX_FMT_RGBA;
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
return AV_PIX_FMT_RGBA64;
|
||||
case PixelFormat::PIX_FMT_RGB8:
|
||||
return AV_PIX_FMT_RGB24;
|
||||
case PixelFormat::PIX_FMT_RGB16U:
|
||||
return AV_PIX_FMT_RGB48;
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
case PixelFormat::PIX_FMT_RGB16F:
|
||||
case PixelFormat::PIX_FMT_RGB32F:
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
break;
|
||||
}
|
||||
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
PixelFormat::Format FFmpegCommon::GetCompatiblePixelFormat(const PixelFormat::Format &pix_fmt)
|
||||
{
|
||||
switch (pix_fmt) {
|
||||
case PixelFormat::PIX_FMT_RGB8:
|
||||
return PixelFormat::PIX_FMT_RGB8;
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
return PixelFormat::PIX_FMT_RGBA8;
|
||||
case PixelFormat::PIX_FMT_RGB16U:
|
||||
case PixelFormat::PIX_FMT_RGB16F:
|
||||
case PixelFormat::PIX_FMT_RGB32F:
|
||||
return PixelFormat::PIX_FMT_RGB16U;
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
return PixelFormat::PIX_FMT_RGBA16U;
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
break;
|
||||
}
|
||||
|
||||
return PixelFormat::PIX_FMT_INVALID;
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
+262
-680
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -32,107 +32,12 @@ extern "C" {
|
||||
#include <QVector>
|
||||
#include <QWaitCondition>
|
||||
|
||||
#include "audio/sampleformat.h"
|
||||
#include "avframeptr.h"
|
||||
#include "codec/decoder.h"
|
||||
#include "codec/waveoutput.h"
|
||||
#include "ffmpegframepool.h"
|
||||
#include "project/item/footage/videostream.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class FFmpegDecoderInstance : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FFmpegDecoderInstance(const char* filename, int stream_index);
|
||||
virtual ~FFmpegDecoderInstance();
|
||||
|
||||
DISABLE_COPY_MOVE(FFmpegDecoderInstance)
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
void SetFramePool(FFmpegFramePool* frame_pool);
|
||||
|
||||
int64_t RangeStart() const;
|
||||
int64_t RangeEnd() const;
|
||||
bool CacheContainsTime(const int64_t& t) const;
|
||||
bool CacheWillContainTime(const int64_t& t) const;
|
||||
bool CacheCouldContainTime(const int64_t& t) const;
|
||||
bool CacheIsEmpty() const;
|
||||
FFmpegFramePool::ElementPtr GetFrameFromCache(const int64_t& t) const;
|
||||
|
||||
void RemoveFramesBefore(const qint64& t);
|
||||
int TruncateCacheRangeToTime(const qint64& t);
|
||||
int TruncateCacheRangeToFrames(int nb_frames);
|
||||
void RemoveFirstFrame();
|
||||
|
||||
AVFormatContext* fmt_ctx() const
|
||||
{
|
||||
return fmt_ctx_;
|
||||
}
|
||||
|
||||
AVStream* stream() const
|
||||
{
|
||||
return avstream_;
|
||||
}
|
||||
|
||||
void ClearFrameCache();
|
||||
|
||||
FFmpegFramePool::ElementPtr RetrieveFrame(const int64_t &target_ts, int divider, bool cache_is_locked);
|
||||
|
||||
/**
|
||||
* @brief Uses the FFmpeg API to retrieve a packet (stored in pkt_) and decode it (stored in frame_)
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* An FFmpeg error code, or >= 0 on success
|
||||
*/
|
||||
int GetFrame(AVPacket* pkt, AVFrame* frame);
|
||||
|
||||
QMutex* cache_lock();
|
||||
QWaitCondition* cache_wait_cond();
|
||||
|
||||
bool IsWorking();
|
||||
void SetWorking(bool working);
|
||||
|
||||
private:
|
||||
void ClearResources();
|
||||
|
||||
void Seek(int64_t timestamp);
|
||||
|
||||
void InitScaler(int divider);
|
||||
void FreeScaler();
|
||||
|
||||
AVFormatContext* fmt_ctx_;
|
||||
AVCodecContext* codec_ctx_;
|
||||
AVStream* avstream_;
|
||||
AVDictionary* opts_;
|
||||
|
||||
SwsContext* scale_ctx_;
|
||||
int scale_divider_;
|
||||
|
||||
int64_t second_ts_;
|
||||
|
||||
QWaitCondition cache_wait_cond_;
|
||||
QMutex cache_lock_;
|
||||
QList<FFmpegFramePool::ElementPtr> cached_frames_;
|
||||
FFmpegFramePool* frame_pool_;
|
||||
|
||||
int64_t cache_target_time_;
|
||||
|
||||
bool is_working_;
|
||||
QMutex is_working_mutex_;
|
||||
|
||||
bool cache_at_zero_;
|
||||
bool cache_at_eof_;
|
||||
|
||||
QTimer* clear_timer_;
|
||||
static const int kMaxFrameLife;
|
||||
|
||||
private slots:
|
||||
void ClearTimerEvent();
|
||||
|
||||
};
|
||||
namespace olive {
|
||||
|
||||
/**
|
||||
* @brief A Decoder derivative that wraps FFmpeg functions as on Olive decoder
|
||||
@@ -147,40 +52,62 @@ public:
|
||||
// Destructor
|
||||
virtual ~FFmpegDecoder() override;
|
||||
|
||||
virtual FootagePtr Probe(const QString& filename, const QAtomicInt* cancelled) const override;
|
||||
|
||||
virtual bool Open() override;
|
||||
virtual FramePtr RetrieveVideo(const rational &timecode, const int& divider) override;
|
||||
virtual SampleBufferPtr RetrieveAudio(const rational &timecode, const rational &length, const AudioParams& params) override;
|
||||
virtual void Close() override;
|
||||
|
||||
virtual QString id() override;
|
||||
|
||||
virtual bool SupportsVideo() override;
|
||||
virtual bool SupportsAudio() override;
|
||||
virtual bool SupportsVideo() override{return true;}
|
||||
virtual bool SupportsAudio() override{return true;}
|
||||
|
||||
virtual bool ConformAudio(const QAtomicInt* cancelled, const AudioParams& p) override;
|
||||
virtual FootagePtr Probe(const QString& filename, const QAtomicInt* cancelled) const override;
|
||||
|
||||
struct FFmpegFramePoolKey {
|
||||
int width;
|
||||
int height;
|
||||
AVPixelFormat format;
|
||||
|
||||
bool operator==(const FFmpegFramePoolKey& k) const
|
||||
{
|
||||
return width == k.width && height == k.height && format == k.format;
|
||||
}
|
||||
};
|
||||
protected:
|
||||
virtual bool OpenInternal() override;
|
||||
virtual FramePtr RetrieveVideoInternal(const rational &timecode, const int& divider) override;
|
||||
virtual bool ConformAudioInternal(const QString& filename, const AudioParams ¶ms, const QAtomicInt* cancelled) override;
|
||||
virtual void CloseInternal() override;
|
||||
|
||||
private:
|
||||
class Instance
|
||||
{
|
||||
public:
|
||||
Instance();
|
||||
|
||||
~Instance()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool Open(const char* filename, int stream_index);
|
||||
|
||||
void Close();
|
||||
|
||||
/**
|
||||
* @brief Handle an error
|
||||
* @brief Uses the FFmpeg API to retrieve a packet (stored in pkt_) and decode it (stored in frame_)
|
||||
*
|
||||
* Immediately closes the Decoder (freeing memory resources) and sends the string provided to the warning stream.
|
||||
* As this function closes the Decoder, no further Decoder functions should be performed after this is called
|
||||
* (unless the Decoder is opened again first).
|
||||
* @return
|
||||
*
|
||||
* An FFmpeg error code, or >= 0 on success
|
||||
*/
|
||||
void Error(const QString& s);
|
||||
int GetFrame(AVPacket* pkt, AVFrame* frame);
|
||||
|
||||
void Seek(int64_t timestamp);
|
||||
|
||||
AVFormatContext* fmt_ctx() const
|
||||
{
|
||||
return fmt_ctx_;
|
||||
}
|
||||
|
||||
AVStream* avstream() const
|
||||
{
|
||||
return avstream_;
|
||||
}
|
||||
|
||||
private:
|
||||
AVFormatContext* fmt_ctx_;
|
||||
AVCodecContext* codec_ctx_;
|
||||
AVStream* avstream_;
|
||||
AVDictionary* opts_;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Handle an FFmpeg error code
|
||||
@@ -190,42 +117,50 @@ private:
|
||||
*
|
||||
* @param error_code
|
||||
*/
|
||||
void FFmpegError(int error_code);
|
||||
|
||||
void ClearResources();
|
||||
static QString FFmpegError(int error_code);
|
||||
|
||||
void InitScaler(int divider);
|
||||
void FreeScaler();
|
||||
|
||||
FramePtr RetrieveStillImage(const rational& timecode, const int& divider);
|
||||
|
||||
static PixelFormat::Format GetNativePixelFormat(AVPixelFormat pix_fmt);
|
||||
static VideoParams::Format GetNativePixelFormat(AVPixelFormat pix_fmt);
|
||||
static int GetNativeChannelCount(AVPixelFormat pix_fmt);
|
||||
|
||||
static uint64_t ValidateChannelLayout(AVStream *stream);
|
||||
|
||||
static bool StreamUsesMultipleInstances(StreamPtr stream);
|
||||
void FFmpegBufferToNativeBuffer(uint8_t** input_data, int* input_linesize, uint8_t **output_buffer, int *output_linesize);
|
||||
|
||||
FramePtr BuffersToNativeFrame(int divider, int width, int height, const rational &ts, uint8_t **input_data, int* input_linesize);
|
||||
FFmpegFramePool::ElementPtr GetFrameFromCache(const int64_t& t) const;
|
||||
|
||||
void ClearFrameCache();
|
||||
|
||||
FFmpegFramePool::ElementPtr RetrieveFrame(const int64_t &target_ts, int divider);
|
||||
|
||||
void RemoveFirstFrame();
|
||||
|
||||
SwsContext* scale_ctx_;
|
||||
int scale_divider_;
|
||||
AVPixelFormat src_pix_fmt_;
|
||||
AVPixelFormat ideal_pix_fmt_;
|
||||
PixelFormat::Format native_pix_fmt_;
|
||||
VideoParams::Format native_pix_fmt_;
|
||||
int native_channel_count_;
|
||||
|
||||
struct FFmpegFramePoolValue {
|
||||
FFmpegFramePool* pool = nullptr;
|
||||
int handles = 0;
|
||||
};
|
||||
FFmpegFramePool pool_;
|
||||
|
||||
static QHash< Stream*, QList<FFmpegDecoderInstance*> > instance_map_;
|
||||
static QHash< FFmpegFramePoolKey, FFmpegFramePoolValue > frame_pool_map_;
|
||||
static QMutex instance_map_lock_;
|
||||
int64_t second_ts_;
|
||||
|
||||
QList<FFmpegFramePool::ElementPtr> cached_frames_;
|
||||
|
||||
bool is_working_;
|
||||
QMutex is_working_mutex_;
|
||||
|
||||
bool cache_at_zero_;
|
||||
bool cache_at_eof_;
|
||||
|
||||
Instance instance_;
|
||||
|
||||
};
|
||||
|
||||
uint qHash(const FFmpegDecoder::FFmpegFramePoolKey& r);
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // FFMPEGDECODER_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -26,17 +26,17 @@ extern "C" {
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#include "ffmpegcommon.h"
|
||||
#include "render/pixelformat.h"
|
||||
#include "common/ffmpegutils.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
FFmpegEncoder::FFmpegEncoder(const EncodingParams ¶ms) :
|
||||
Encoder(params),
|
||||
fmt_ctx_(nullptr),
|
||||
video_stream_(nullptr),
|
||||
video_codec_ctx_(nullptr),
|
||||
video_scale_ctx_(nullptr),
|
||||
video_alpha_scale_ctx_(nullptr),
|
||||
video_noalpha_scale_ctx_(nullptr),
|
||||
audio_stream_(nullptr),
|
||||
audio_codec_ctx_(nullptr),
|
||||
audio_resample_ctx_(nullptr),
|
||||
@@ -72,22 +72,42 @@ bool FFmpegEncoder::Open()
|
||||
}
|
||||
|
||||
// This is the format we will expect frames received in Write() to be in
|
||||
PixelFormat::Format native_pixel_fmt = params().video_params().format();
|
||||
VideoParams::Format native_pixel_fmt = params().video_params().format();
|
||||
|
||||
// This is the format we will need to convert the frame to for swscale to understand it
|
||||
video_conversion_fmt_ = FFmpegCommon::GetCompatiblePixelFormat(native_pixel_fmt);
|
||||
video_conversion_fmt_ = FFmpegUtils::GetCompatiblePixelFormat(native_pixel_fmt);
|
||||
|
||||
// This is the equivalent pixel format above as an AVPixelFormat that swscale can understand
|
||||
AVPixelFormat src_pix_fmt = FFmpegCommon::GetFFmpegPixelFormat(video_conversion_fmt_);
|
||||
AVPixelFormat src_alpha_pix_fmt = FFmpegUtils::GetFFmpegPixelFormat(video_conversion_fmt_,
|
||||
VideoParams::kRGBAChannelCount);
|
||||
|
||||
AVPixelFormat src_noalpha_pix_fmt = FFmpegUtils::GetFFmpegPixelFormat(video_conversion_fmt_,
|
||||
VideoParams::kRGBChannelCount);
|
||||
|
||||
if (src_alpha_pix_fmt == AV_PIX_FMT_NONE || src_noalpha_pix_fmt == AV_PIX_FMT_NONE) {
|
||||
Error(QStringLiteral("Failed to find suitable pixel format for this buffer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is the pixel format the encoder wants to encode to
|
||||
AVPixelFormat encoder_pix_fmt = video_codec_ctx_->pix_fmt;
|
||||
|
||||
// Set up a scaling context - if the native pixel format is not equal to the encoder's, we'll need to convert it
|
||||
// before encoding. Even if we don't, this may be useful for converting between linesizes, etc.
|
||||
video_scale_ctx_ = sws_getContext(params().video_params().width(),
|
||||
video_alpha_scale_ctx_ = sws_getContext(params().video_params().width(),
|
||||
params().video_params().height(),
|
||||
src_pix_fmt,
|
||||
src_alpha_pix_fmt,
|
||||
params().video_params().width(),
|
||||
params().video_params().height(),
|
||||
encoder_pix_fmt,
|
||||
0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
video_noalpha_scale_ctx_ = sws_getContext(params().video_params().width(),
|
||||
params().video_params().height(),
|
||||
src_noalpha_pix_fmt,
|
||||
params().video_params().width(),
|
||||
params().video_params().height(),
|
||||
encoder_pix_fmt,
|
||||
@@ -157,19 +177,22 @@ bool FFmpegEncoder::WriteFrame(FramePtr frame, rational time)
|
||||
|
||||
// We may need to convert this frame to a frame that swscale will understand
|
||||
if (frame->format() != video_conversion_fmt_) {
|
||||
frame = PixelFormat::ConvertPixelFormat(frame, video_conversion_fmt_);
|
||||
frame = frame->convert(video_conversion_fmt_);
|
||||
}
|
||||
|
||||
// Use swscale context to convert formats/linesizes
|
||||
input_data = frame->const_data();
|
||||
input_linesize = frame->linesize_bytes();
|
||||
error_code = sws_scale(video_scale_ctx_,
|
||||
|
||||
error_code = sws_scale((frame->channel_count() == VideoParams::kRGBAChannelCount) ? video_alpha_scale_ctx_ : video_noalpha_scale_ctx_,
|
||||
reinterpret_cast<const uint8_t**>(&input_data),
|
||||
&input_linesize,
|
||||
0,
|
||||
frame->height(),
|
||||
encoded_frame->data,
|
||||
encoded_frame->linesize);
|
||||
|
||||
|
||||
if (error_code < 0) {
|
||||
FFmpegError("Failed to scale frame", error_code);
|
||||
goto fail;
|
||||
@@ -208,7 +231,7 @@ void FFmpegEncoder::WriteAudio(AudioParams pcm_info, QIODevice* file)
|
||||
audio_codec_ctx_->sample_fmt,
|
||||
audio_codec_ctx_->sample_rate,
|
||||
static_cast<int64_t>(pcm_info.channel_layout()),
|
||||
FFmpegCommon::GetFFmpegSampleFormat(pcm_info.format()),
|
||||
FFmpegUtils::GetFFmpegSampleFormat(pcm_info.format()),
|
||||
pcm_info.sample_rate(),
|
||||
0,
|
||||
nullptr);
|
||||
@@ -300,9 +323,14 @@ void FFmpegEncoder::Close()
|
||||
open_ = false;
|
||||
}
|
||||
|
||||
if (video_scale_ctx_) {
|
||||
sws_freeContext(video_scale_ctx_);
|
||||
video_scale_ctx_ = nullptr;
|
||||
if (video_alpha_scale_ctx_) {
|
||||
sws_freeContext(video_alpha_scale_ctx_);
|
||||
video_alpha_scale_ctx_ = nullptr;
|
||||
}
|
||||
|
||||
if (video_noalpha_scale_ctx_) {
|
||||
sws_freeContext(video_noalpha_scale_ctx_);
|
||||
video_noalpha_scale_ctx_ = nullptr;
|
||||
}
|
||||
|
||||
if (video_codec_ctx_) {
|
||||
@@ -606,4 +634,4 @@ void FFmpegEncoder::Error(const QString &s)
|
||||
Close();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -30,7 +30,7 @@ extern "C" {
|
||||
|
||||
#include "codec/encoder.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class FFmpegEncoder : public Encoder
|
||||
{
|
||||
@@ -40,13 +40,18 @@ public:
|
||||
|
||||
virtual bool Open() override;
|
||||
|
||||
virtual bool WriteFrame(OLIVE_NAMESPACE::FramePtr frame, OLIVE_NAMESPACE::rational time) override;
|
||||
virtual bool WriteFrame(olive::FramePtr frame, olive::rational time) override;
|
||||
|
||||
virtual void WriteAudio(OLIVE_NAMESPACE::AudioParams pcm_info,
|
||||
virtual void WriteAudio(olive::AudioParams pcm_info,
|
||||
QIODevice *file) override;
|
||||
|
||||
virtual void Close() override;
|
||||
|
||||
virtual VideoParams::Format GetDesiredPixelFormat() const override
|
||||
{
|
||||
return video_conversion_fmt_;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Handle an error
|
||||
@@ -80,8 +85,9 @@ private:
|
||||
|
||||
AVStream* video_stream_;
|
||||
AVCodecContext* video_codec_ctx_;
|
||||
SwsContext* video_scale_ctx_;
|
||||
PixelFormat::Format video_conversion_fmt_;
|
||||
SwsContext* video_alpha_scale_ctx_;
|
||||
SwsContext* video_noalpha_scale_ctx_;
|
||||
VideoParams::Format video_conversion_fmt_;
|
||||
|
||||
AVStream* audio_stream_;
|
||||
AVCodecContext* audio_codec_ctx_;
|
||||
@@ -91,6 +97,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // FFMPEGENCODER_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,42 +20,32 @@
|
||||
|
||||
#include "ffmpegframepool.h"
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/imgutils.h>
|
||||
}
|
||||
#include "codec/frame.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
FFmpegFramePool::FFmpegFramePool(int element_count) :
|
||||
MemoryPool(element_count),
|
||||
width_(0),
|
||||
height_(0),
|
||||
format_(AV_PIX_FMT_NONE)
|
||||
format_(VideoParams::kFormatInvalid),
|
||||
channel_count_(0)
|
||||
{
|
||||
}
|
||||
|
||||
void FFmpegFramePool::SetParameters(int width, int height, AVPixelFormat format)
|
||||
void FFmpegFramePool::SetParameters(int width, int height, VideoParams::Format format, int channel_count)
|
||||
{
|
||||
Clear();
|
||||
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
format_ = format;
|
||||
channel_count_ = channel_count;
|
||||
}
|
||||
|
||||
size_t FFmpegFramePool::GetElementSize()
|
||||
{
|
||||
int buf_sz = av_image_get_buffer_size(static_cast<AVPixelFormat>(format_),
|
||||
width_,
|
||||
height_,
|
||||
1);
|
||||
|
||||
if (buf_sz < 0) {
|
||||
qDebug() << "Failed to find buffer size:" << buf_sz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buf_sz;
|
||||
return Frame::generate_linesize_bytes(width_, format_, channel_count_) * height_;
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -22,17 +22,16 @@
|
||||
#define FFMPEGFRAMEPOOL_H
|
||||
|
||||
#include "common/memorypool.h"
|
||||
#include "render/pixelformat.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class FFmpegFramePool : public MemoryPool<uint8_t>
|
||||
{
|
||||
public:
|
||||
FFmpegFramePool(int element_count);
|
||||
|
||||
void SetParameters(int width, int height, AVPixelFormat format);
|
||||
void SetParameters(int width, int height, VideoParams::Format format, int channel_count);
|
||||
|
||||
const int& width() const
|
||||
{
|
||||
@@ -52,10 +51,12 @@ private:
|
||||
|
||||
int height_;
|
||||
|
||||
AVPixelFormat format_;
|
||||
VideoParams::Format format_;
|
||||
|
||||
int channel_count_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // FFMPEGFRAMEPOOL_H
|
||||
|
||||
+47
-69
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,11 +20,14 @@
|
||||
|
||||
#include "frame.h"
|
||||
|
||||
#include <OpenImageIO/imagebuf.h>
|
||||
#include <QDebug>
|
||||
#include <QtGlobal>
|
||||
#include <QtMath>
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
#include "common/oiioutils.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
Frame::Frame() :
|
||||
timestamp_(0)
|
||||
@@ -45,33 +48,14 @@ void Frame::set_video_params(const VideoParams ¶ms)
|
||||
{
|
||||
params_ = params;
|
||||
|
||||
// Align linesize to 32
|
||||
linesize_ = qCeil(static_cast<double>(width()) / 32.0) * 32;
|
||||
linesize_ = generate_linesize_bytes(width(), params_.format(), params_.channel_count());
|
||||
linesize_pixels_ = linesize_ / params_.GetBytesPerPixel();
|
||||
}
|
||||
|
||||
int Frame::linesize_pixels() const
|
||||
int Frame::generate_linesize_bytes(int width, VideoParams::Format format, int channel_count)
|
||||
{
|
||||
return linesize_;
|
||||
}
|
||||
|
||||
int Frame::linesize_bytes() const
|
||||
{
|
||||
return linesize_pixels() * PixelFormat::BytesPerPixel(params_.format());
|
||||
}
|
||||
|
||||
const int &Frame::width() const
|
||||
{
|
||||
return params_.effective_width();
|
||||
}
|
||||
|
||||
const int &Frame::height() const
|
||||
{
|
||||
return params_.effective_height();
|
||||
}
|
||||
|
||||
const PixelFormat::Format &Frame::format() const
|
||||
{
|
||||
return params_.format();
|
||||
// Align to 32 bytes (not sure if this is necessary?)
|
||||
return VideoParams::GetBytesPerPixel(format, channel_count) * ((width + 31) & ~31);
|
||||
}
|
||||
|
||||
Color Frame::get_pixel(int x, int y) const
|
||||
@@ -80,11 +64,9 @@ Color Frame::get_pixel(int x, int y) const
|
||||
return Color();
|
||||
}
|
||||
|
||||
int pixel_index = y * linesize_pixels() + x;
|
||||
int byte_offset = y * linesize_bytes() + x * video_params().GetBytesPerPixel();
|
||||
|
||||
int byte_offset = PixelFormat::GetBufferSize(video_params().format(), pixel_index, 1);
|
||||
|
||||
return Color(data_.data() + byte_offset, video_params().format());
|
||||
return Color(data_.data() + byte_offset, video_params().format(), video_params().channel_count());
|
||||
}
|
||||
|
||||
bool Frame::contains_pixel(int x, int y) const
|
||||
@@ -98,57 +80,53 @@ void Frame::set_pixel(int x, int y, const Color &c)
|
||||
return;
|
||||
}
|
||||
|
||||
int pixel_index = y * linesize_pixels() + x;
|
||||
int byte_offset = y * linesize_bytes() + x * video_params().GetBytesPerPixel();
|
||||
|
||||
int byte_offset = PixelFormat::GetBufferSize(video_params().format(), pixel_index, 1);
|
||||
|
||||
c.toData(data_.data() + byte_offset, video_params().format());
|
||||
c.toData(data_.data() + byte_offset, video_params().format(), video_params().channel_count());
|
||||
}
|
||||
|
||||
const rational &Frame::timestamp() const
|
||||
{
|
||||
return timestamp_;
|
||||
}
|
||||
|
||||
void Frame::set_timestamp(const rational ×tamp)
|
||||
{
|
||||
timestamp_ = timestamp;
|
||||
}
|
||||
|
||||
char *Frame::data()
|
||||
{
|
||||
return data_.data();
|
||||
}
|
||||
|
||||
const char *Frame::const_data() const
|
||||
{
|
||||
return data_.constData();
|
||||
}
|
||||
|
||||
void Frame::allocate()
|
||||
bool Frame::allocate()
|
||||
{
|
||||
// Assume this frame is intended to be a video frame
|
||||
if (!params_.is_valid()) {
|
||||
qWarning() << "Tried to allocate a frame with invalid parameters";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
data_.resize(PixelFormat::GetBufferSize(params_.format(), linesize_, params_.height()));
|
||||
data_.resize(VideoParams::GetBufferSize(linesize_, height(), params_.format(), params_.channel_count()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Frame::is_allocated() const
|
||||
FramePtr Frame::convert(VideoParams::Format format) const
|
||||
{
|
||||
return !data_.isEmpty();
|
||||
// Create new params with destination format
|
||||
VideoParams params = params_;
|
||||
params.set_format(format);
|
||||
|
||||
// Create new frame
|
||||
FramePtr converted = Frame::Create();
|
||||
converted->set_video_params(params);
|
||||
converted->set_timestamp(timestamp_);
|
||||
converted->allocate();
|
||||
|
||||
// Do the conversion through OIIO for convenience
|
||||
OIIO::ImageBuf src(OIIO::ImageSpec(width(), height(),
|
||||
channel_count(),
|
||||
OIIOUtils::GetOIIOBaseTypeFromFormat(this->format())));
|
||||
|
||||
OIIOUtils::FrameToBuffer(this, &src);
|
||||
|
||||
OIIO::ImageBuf dst(OIIO::ImageSpec(converted->width(), converted->height(),
|
||||
channel_count(),
|
||||
OIIOUtils::GetOIIOBaseTypeFromFormat(format)));
|
||||
|
||||
if (dst.copy_pixels(src)) {
|
||||
OIIOUtils::BufferToFrame(&dst, converted.get());
|
||||
return converted;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Frame::destroy()
|
||||
{
|
||||
data_.clear();
|
||||
}
|
||||
|
||||
int Frame::allocated_size() const
|
||||
{
|
||||
return data_.size();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
+69
-18
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -26,10 +26,9 @@
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "render/color.h"
|
||||
#include "render/pixelformat.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class Frame;
|
||||
using FramePtr = std::shared_ptr<Frame>;
|
||||
@@ -47,11 +46,37 @@ public:
|
||||
const VideoParams& video_params() const;
|
||||
void set_video_params(const VideoParams& params);
|
||||
|
||||
int linesize_pixels() const;
|
||||
int linesize_bytes() const;
|
||||
const int& width() const;
|
||||
const int& height() const;
|
||||
const PixelFormat::Format& format() const;
|
||||
static int generate_linesize_bytes(int width, VideoParams::Format format, int channel_count);
|
||||
|
||||
int linesize_pixels() const
|
||||
{
|
||||
return linesize_pixels_;
|
||||
}
|
||||
|
||||
int linesize_bytes() const
|
||||
{
|
||||
return linesize_;
|
||||
}
|
||||
|
||||
int width() const
|
||||
{
|
||||
return params_.effective_width();
|
||||
}
|
||||
|
||||
int height() const
|
||||
{
|
||||
return params_.effective_height();
|
||||
}
|
||||
|
||||
VideoParams::Format format() const
|
||||
{
|
||||
return params_.format();
|
||||
}
|
||||
|
||||
int channel_count() const
|
||||
{
|
||||
return params_.channel_count();
|
||||
}
|
||||
|
||||
Color get_pixel(int x, int y) const;
|
||||
bool contains_pixel(int x, int y) const;
|
||||
@@ -62,18 +87,31 @@ public:
|
||||
*
|
||||
* This timestamp is always a rational that will equate to the time in seconds.
|
||||
*/
|
||||
const rational& timestamp() const;
|
||||
void set_timestamp(const rational& timestamp);
|
||||
const rational& timestamp() const
|
||||
{
|
||||
return timestamp_;
|
||||
}
|
||||
|
||||
void set_timestamp(const rational& timestamp)
|
||||
{
|
||||
timestamp_ = timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the data buffer of this frame
|
||||
*/
|
||||
char* data();
|
||||
char* data()
|
||||
{
|
||||
return data_.data();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the const data buffer of this frame
|
||||
*/
|
||||
const char* const_data() const;
|
||||
const char* const_data() const
|
||||
{
|
||||
return data_.constData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate memory buffer to store data based on parameters
|
||||
@@ -82,24 +120,35 @@ public:
|
||||
*
|
||||
* If a memory buffer has been previously allocated without destroying, this function will destroy it.
|
||||
*/
|
||||
void allocate();
|
||||
bool allocate();
|
||||
|
||||
/**
|
||||
* @brief Return whether the frame is allocated or not
|
||||
*/
|
||||
bool is_allocated() const;
|
||||
bool is_allocated() const
|
||||
{
|
||||
return !data_.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy a memory buffer allocated with allocate()
|
||||
*/
|
||||
void destroy();
|
||||
void destroy()
|
||||
{
|
||||
data_.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the size of the array returned in data() in bytes
|
||||
*
|
||||
* Returns 0 if nothing is allocated.
|
||||
*/
|
||||
int allocated_size() const;
|
||||
int allocated_size() const
|
||||
{
|
||||
return data_.size();
|
||||
}
|
||||
|
||||
FramePtr convert(VideoParams::Format format) const;
|
||||
|
||||
private:
|
||||
VideoParams params_;
|
||||
@@ -110,10 +159,12 @@ private:
|
||||
|
||||
int linesize_;
|
||||
|
||||
int linesize_pixels_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(OLIVE_NAMESPACE::FramePtr)
|
||||
Q_DECLARE_METATYPE(olive::FramePtr)
|
||||
|
||||
#endif // FRAME_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
codec/oiio/oiiodecoder.h
|
||||
codec/oiio/oiiodecoder.cpp
|
||||
codec/oiio/oiiodecoder.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
+61
-142
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,10 +27,11 @@
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "common/define.h"
|
||||
#include "common/oiioutils.h"
|
||||
#include "config/config.h"
|
||||
#include "core.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
QStringList OIIODecoder::supported_formats_;
|
||||
|
||||
@@ -40,6 +41,11 @@ OIIODecoder::OIIODecoder() :
|
||||
{
|
||||
}
|
||||
|
||||
OIIODecoder::~OIIODecoder()
|
||||
{
|
||||
CloseInternal();
|
||||
}
|
||||
|
||||
QString OIIODecoder::id()
|
||||
{
|
||||
return QStringLiteral("oiio");
|
||||
@@ -47,6 +53,10 @@ QString OIIODecoder::id()
|
||||
|
||||
FootagePtr OIIODecoder::Probe(const QString& filename, const QAtomicInt* cancelled) const
|
||||
{
|
||||
Q_UNUSED(cancelled)
|
||||
|
||||
// Filter out any file extensions that aren't expected to work - sometimes OIIO will crash trying
|
||||
// to open a file that it can't if it's given one
|
||||
if (!FileTypeIsSupported(filename)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -59,8 +69,9 @@ FootagePtr OIIODecoder::Probe(const QString& filename, const QAtomicInt* cancell
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Filter out OIIO detecting an "FFmpeg movie", we have a native FFmpeg decoder that can handle
|
||||
// it better
|
||||
if (!strcmp(in->format_name(), "FFmpeg movie")) {
|
||||
// If this is FFmpeg via OIIO, fall-through to our native FFmpeg decoder
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -70,8 +81,9 @@ FootagePtr OIIODecoder::Probe(const QString& filename, const QAtomicInt* cancell
|
||||
|
||||
image_stream->set_width(in->spec().width);
|
||||
image_stream->set_height(in->spec().height);
|
||||
image_stream->set_format(GetFormatFromOIIOBasetype(in->spec()));
|
||||
image_stream->set_pixel_aspect_ratio(GetPixelAspectRatioFromOIIO(in->spec()));
|
||||
image_stream->set_format(OIIOUtils::GetFormatFromOIIOBasetype(static_cast<OIIO::TypeDesc::BASETYPE>(in->spec().format.basetype)));
|
||||
image_stream->set_channel_count(in->spec().nchannels);
|
||||
image_stream->set_pixel_aspect_ratio(OIIOUtils::GetPixelAspectRatioFromOIIO(in->spec()));
|
||||
image_stream->set_video_type(VideoStream::kVideoTypeStill);
|
||||
|
||||
// Images will always have just one stream
|
||||
@@ -88,54 +100,47 @@ FootagePtr OIIODecoder::Probe(const QString& filename, const QAtomicInt* cancell
|
||||
// If we're here, we have a successful image open
|
||||
in->close();
|
||||
|
||||
#if OIIO_VERSION < 10903
|
||||
OIIO::ImageInput::destroy(in);
|
||||
#endif
|
||||
|
||||
return footage;
|
||||
}
|
||||
|
||||
bool OIIODecoder::Open()
|
||||
bool OIIODecoder::OpenInternal()
|
||||
{
|
||||
Q_ASSERT(stream());
|
||||
|
||||
if (stream()->type() != Stream::kVideo) {
|
||||
// Guard against non-video types
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we can open the filename provided, assume everything is working (even if this is an image
|
||||
// sequence with potentially missing frame)
|
||||
if (OpenImageHandler(stream()->footage()->filename())) {
|
||||
VideoStreamPtr video_stream = std::static_pointer_cast<VideoStream>(stream());
|
||||
|
||||
if (video_stream->video_type() == VideoStream::kVideoTypeVideo) {
|
||||
// This decoder only handles kVideoTypeImageSequence and kVideoTypeStill
|
||||
return false;
|
||||
if (video_stream->video_type() == VideoStream::kVideoTypeStill) {
|
||||
last_sequence_index_ = 0;
|
||||
} else {
|
||||
last_sequence_index_ = GetImageSequenceIndex(stream()->footage()->filename());
|
||||
}
|
||||
|
||||
if (video_stream->video_type() == VideoStream::kVideoTypeStill
|
||||
&& !OpenImageHandler(stream()->footage()->filename())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
open_ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FramePtr OIIODecoder::RetrieveVideo(const rational &timecode, const int& divider)
|
||||
FramePtr OIIODecoder::RetrieveVideoInternal(const rational &timecode, const int& divider)
|
||||
{
|
||||
if (!open_) {
|
||||
qWarning() << "Tried to retrieve video on a decoder that's still closed";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VideoStreamPtr video_stream = std::static_pointer_cast<VideoStream>(stream());
|
||||
|
||||
if (video_stream->video_type() == VideoStream::kVideoTypeImageSequence) {
|
||||
int64_t ts = video_stream->get_time_in_timebase_units(timecode);
|
||||
int64_t sequence_index;
|
||||
|
||||
if (!OpenImageHandler(TransformImageSequenceFileName(stream()->footage()->filename(), ts))) {
|
||||
if (video_stream->video_type() == VideoStream::kVideoTypeStill) {
|
||||
sequence_index = 0;
|
||||
} else {
|
||||
sequence_index = video_stream->get_time_in_timebase_units(timecode);
|
||||
}
|
||||
|
||||
if (last_sequence_index_ != sequence_index) {
|
||||
CloseImageHandle();
|
||||
|
||||
if (!OpenImageHandler(TransformImageSequenceFileName(stream()->footage()->filename(), sequence_index))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
last_sequence_index_ = sequence_index;
|
||||
}
|
||||
|
||||
FramePtr frame = Frame::Create();
|
||||
@@ -143,14 +148,15 @@ FramePtr OIIODecoder::RetrieveVideo(const rational &timecode, const int& divider
|
||||
frame->set_video_params(VideoParams(buffer_->spec().width,
|
||||
buffer_->spec().height,
|
||||
pix_fmt_,
|
||||
GetPixelAspectRatioFromOIIO(buffer_->spec()),
|
||||
channel_count_,
|
||||
OIIOUtils::GetPixelAspectRatioFromOIIO(buffer_->spec()),
|
||||
VideoParams::kInterlaceNone, // FIXME: Does OIIO deinterlace for us?
|
||||
divider));
|
||||
frame->allocate();
|
||||
|
||||
if (divider == 1) {
|
||||
|
||||
BufferToFrame(buffer_, frame);
|
||||
OIIOUtils::BufferToFrame(buffer_, frame.get());
|
||||
|
||||
} else {
|
||||
|
||||
@@ -161,106 +167,18 @@ FramePtr OIIODecoder::RetrieveVideo(const rational &timecode, const int& divider
|
||||
qWarning() << "OIIO resize failed";
|
||||
}
|
||||
|
||||
BufferToFrame(&dst, frame);
|
||||
OIIOUtils::BufferToFrame(&dst, frame.get());
|
||||
|
||||
}
|
||||
|
||||
if (video_stream->video_type() == VideoStream::kVideoTypeImageSequence) {
|
||||
CloseImageHandle();
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
void OIIODecoder::Close()
|
||||
void OIIODecoder::CloseInternal()
|
||||
{
|
||||
CloseImageHandle();
|
||||
}
|
||||
|
||||
bool OIIODecoder::SupportsVideo()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void OIIODecoder::FrameToBuffer(FramePtr frame, OIIO::ImageBuf *buf)
|
||||
{
|
||||
#if OIIO_VERSION < 20112
|
||||
//
|
||||
// Workaround for OIIO bug that ignores destination stride in versions OLDER than 2.1.12
|
||||
//
|
||||
// See more: https://github.com/OpenImageIO/oiio/pull/2487
|
||||
//
|
||||
int width_in_bytes = frame->width() * PixelFormat::BytesPerPixel(frame->format());
|
||||
|
||||
for (int i=0;i<buf->spec().height;i++) {
|
||||
memcpy(
|
||||
#if OIIO_VERSION < 10903
|
||||
reinterpret_cast<char*>(buf->localpixels()) + i * width_in_bytes,
|
||||
#else
|
||||
reinterpret_cast<char*>(buf->localpixels()) + i * buf->scanline_stride(),
|
||||
#endif
|
||||
frame->data() + i * frame->linesize_bytes(),
|
||||
width_in_bytes);
|
||||
}
|
||||
#else
|
||||
buf->set_pixels(OIIO::ROI(),
|
||||
buf->spec().format,
|
||||
frame->data(),
|
||||
OIIO::AutoStride,
|
||||
frame->linesize_bytes());
|
||||
#endif
|
||||
}
|
||||
|
||||
void OIIODecoder::BufferToFrame(OIIO::ImageBuf *buf, FramePtr frame)
|
||||
{
|
||||
#if OIIO_VERSION < 20112
|
||||
//
|
||||
// Workaround for OIIO bug that ignores destination stride in versions OLDER than 2.1.12
|
||||
//
|
||||
// See more: https://github.com/OpenImageIO/oiio/pull/2487
|
||||
//
|
||||
int width_in_bytes = frame->width() * PixelFormat::BytesPerPixel(frame->format());
|
||||
|
||||
for (int i=0;i<buf->spec().height;i++) {
|
||||
memcpy(frame->data() + i * frame->linesize_bytes(),
|
||||
#if OIIO_VERSION < 10903
|
||||
reinterpret_cast<const char*>(buf->localpixels()) + i * width_in_bytes,
|
||||
#else
|
||||
reinterpret_cast<const char*>(buf->localpixels()) + i * buf->scanline_stride(),
|
||||
#endif
|
||||
width_in_bytes);
|
||||
}
|
||||
#else
|
||||
buf->get_pixels(OIIO::ROI(),
|
||||
buf->spec().format,
|
||||
frame->data(),
|
||||
OIIO::AutoStride,
|
||||
frame->linesize_bytes());
|
||||
#endif
|
||||
}
|
||||
|
||||
PixelFormat::Format OIIODecoder::GetFormatFromOIIOBasetype(const OIIO::ImageSpec& spec)
|
||||
{
|
||||
bool has_alpha = (spec.nchannels == kRGBAChannels);
|
||||
|
||||
if (spec.format == OIIO::TypeDesc::UINT8) {
|
||||
return has_alpha ? PixelFormat::PIX_FMT_RGBA8 : PixelFormat::PIX_FMT_RGB8;
|
||||
} else if (spec.format == OIIO::TypeDesc::UINT16) {
|
||||
return has_alpha ? PixelFormat::PIX_FMT_RGBA16U : PixelFormat::PIX_FMT_RGB16U;
|
||||
} else if (spec.format == OIIO::TypeDesc::HALF) {
|
||||
return has_alpha ? PixelFormat::PIX_FMT_RGBA16F : PixelFormat::PIX_FMT_RGB16F;
|
||||
} else if (spec.format == OIIO::TypeDesc::FLOAT) {
|
||||
return has_alpha ? PixelFormat::PIX_FMT_RGBA32F : PixelFormat::PIX_FMT_RGB32F;
|
||||
} else {
|
||||
return PixelFormat::PIX_FMT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
rational OIIODecoder::GetPixelAspectRatioFromOIIO(const OIIO::ImageSpec &spec)
|
||||
{
|
||||
return rational::fromDouble(spec.get_float_attribute("PixelAspectRatio", 1));
|
||||
}
|
||||
|
||||
bool OIIODecoder::FileTypeIsSupported(const QString& fn)
|
||||
{
|
||||
// We prioritize OIIO over FFmpeg to pick up still images more effectively, but some OIIO decoders (notably OpenJPEG)
|
||||
@@ -297,23 +215,27 @@ bool OIIODecoder::OpenImageHandler(const QString &fn)
|
||||
// Check if we can work with this pixel format
|
||||
const OIIO::ImageSpec& spec = image_->spec();
|
||||
|
||||
is_rgba_ = (spec.nchannels == kRGBAChannels);
|
||||
// Store channel count
|
||||
channel_count_ = spec.nchannels;
|
||||
|
||||
pix_fmt_ = GetFormatFromOIIOBasetype(spec);
|
||||
// We use RGBA frames because that tends to be the native format of GPUs
|
||||
pix_fmt_ = OIIOUtils::GetFormatFromOIIOBasetype(static_cast<OIIO::TypeDesc::BASETYPE>(spec.format.basetype));
|
||||
|
||||
if (pix_fmt_ == PixelFormat::PIX_FMT_INVALID) {
|
||||
if (pix_fmt_ == VideoParams::kFormatInvalid) {
|
||||
qWarning() << "Failed to convert OIIO::ImageDesc to native pixel format";
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Many OIIO pixel formats are not handled here
|
||||
OIIO::TypeDesc type = PixelFormat::GetOIIOTypeDesc(pix_fmt_);
|
||||
OIIO::TypeDesc::BASETYPE type = OIIOUtils::GetOIIOBaseTypeFromFormat(pix_fmt_);
|
||||
|
||||
if (type == OIIO::TypeDesc::UNKNOWN) {
|
||||
qCritical() << "Failed to determine appropriate OIIO basetype from native format";
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer_ = new OIIO::ImageBuf(OIIO::ImageSpec(spec.width, spec.height, spec.nchannels, type),
|
||||
OIIO::InitializePixels::No);
|
||||
|
||||
#if OIIO_VERSION < 20100
|
||||
buffer_ = new OIIO::ImageBuf(OIIO::ImageSpec(spec.width, spec.height, spec.nchannels, type));
|
||||
#else
|
||||
buffer_ = new OIIO::ImageBuf(OIIO::ImageSpec(spec.width, spec.height, spec.nchannels, type), OIIO::InitializePixels::No);
|
||||
#endif
|
||||
image_->read_image(type, buffer_->localpixels());
|
||||
|
||||
return true;
|
||||
@@ -323,9 +245,6 @@ void OIIODecoder::CloseImageHandle()
|
||||
{
|
||||
if (image_) {
|
||||
image_->close();
|
||||
#if OIIO_VERSION < 10903
|
||||
OIIO::ImageInput::destroy(image_);
|
||||
#endif
|
||||
image_ = nullptr;
|
||||
}
|
||||
|
||||
@@ -335,4 +254,4 @@ void OIIODecoder::CloseImageHandle()
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,9 +25,8 @@
|
||||
#include <OpenImageIO/imagebuf.h>
|
||||
|
||||
#include "codec/decoder.h"
|
||||
#include "render/pixelformat.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class OIIODecoder : public Decoder
|
||||
{
|
||||
@@ -35,30 +34,21 @@ class OIIODecoder : public Decoder
|
||||
public:
|
||||
OIIODecoder();
|
||||
|
||||
virtual ~OIIODecoder() override;
|
||||
|
||||
virtual QString id() override;
|
||||
|
||||
virtual bool SupportsVideo() override{return true;}
|
||||
|
||||
virtual FootagePtr Probe(const QString& filename, const QAtomicInt* cancelled) const override;
|
||||
|
||||
virtual bool Open() override;
|
||||
virtual FramePtr RetrieveVideo(const rational &timecode, const int& divider) override;
|
||||
virtual void Close() override;
|
||||
|
||||
virtual bool SupportsVideo() override;
|
||||
|
||||
static void FrameToBuffer(FramePtr frame, OIIO::ImageBuf* buf);
|
||||
|
||||
static void BufferToFrame(OIIO::ImageBuf* buf, FramePtr frame);
|
||||
|
||||
static PixelFormat::Format GetFormatFromOIIOBasetype(const OIIO::ImageSpec& spec);
|
||||
|
||||
static rational GetPixelAspectRatioFromOIIO(const OIIO::ImageSpec& spec);
|
||||
protected:
|
||||
virtual bool OpenInternal() override;
|
||||
virtual FramePtr RetrieveVideoInternal(const rational &timecode, const int& divider) override;
|
||||
virtual void CloseInternal() override;
|
||||
|
||||
private:
|
||||
#if OIIO_VERSION < 10903
|
||||
OIIO::ImageInput* image_;
|
||||
#else
|
||||
std::unique_ptr<OIIO::ImageInput> image_;
|
||||
#endif
|
||||
|
||||
static bool FileTypeIsSupported(const QString& fn);
|
||||
|
||||
@@ -66,9 +56,11 @@ private:
|
||||
|
||||
void CloseImageHandle();
|
||||
|
||||
PixelFormat::Format pix_fmt_;
|
||||
int64_t last_sequence_index_;
|
||||
|
||||
bool is_rgba_;
|
||||
VideoParams::Format pix_fmt_;
|
||||
|
||||
int channel_count_;
|
||||
|
||||
OIIO::ImageBuf* buffer_;
|
||||
|
||||
@@ -76,6 +68,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // OIIODECODER_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "samplebuffer.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
SampleBuffer::SampleBuffer() :
|
||||
sample_count_per_channel_(0),
|
||||
@@ -38,6 +38,11 @@ SampleBufferPtr SampleBuffer::Create()
|
||||
return std::make_shared<SampleBuffer>();
|
||||
}
|
||||
|
||||
SampleBufferPtr SampleBuffer::CreateAllocated(const AudioParams &audio_params, const rational &length)
|
||||
{
|
||||
return CreateAllocated(audio_params, audio_params.time_to_samples(length));
|
||||
}
|
||||
|
||||
SampleBufferPtr SampleBuffer::CreateAllocated(const AudioParams &audio_params, int samples_per_channel)
|
||||
{
|
||||
SampleBufferPtr buffer = Create();
|
||||
@@ -305,4 +310,4 @@ void SampleBuffer::destroy_sample_buffer(float ***data, int nb_channels)
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "render/audioparams.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class SampleBuffer;
|
||||
using SampleBufferPtr = std::shared_ptr<SampleBuffer>;
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
virtual ~SampleBuffer();
|
||||
|
||||
static SampleBufferPtr Create();
|
||||
static SampleBufferPtr CreateAllocated(const AudioParams& audio_params, const rational& length);
|
||||
static SampleBufferPtr CreateAllocated(const AudioParams& audio_params, int samples_per_channel);
|
||||
static SampleBufferPtr CreateFromPackedData(const AudioParams& audio_params, const QByteArray& bytes);
|
||||
|
||||
@@ -93,8 +94,8 @@ private:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(OLIVE_NAMESPACE::SampleBufferPtr)
|
||||
Q_DECLARE_METATYPE(olive::SampleBufferPtr)
|
||||
|
||||
#endif // SAMPLEBUFFER_H
|
||||
|
||||
+10
-10
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,7 +27,7 @@ extern "C" {
|
||||
#include <QDataStream>
|
||||
#include <QtMath>
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
WaveInput::WaveInput(const QString &f) :
|
||||
file_(f)
|
||||
@@ -108,27 +108,27 @@ bool WaveInput::open()
|
||||
uint16_t bits_per_sample;
|
||||
data_stream >> bits_per_sample;
|
||||
|
||||
SampleFormat::Format format;
|
||||
AudioParams::Format format;
|
||||
|
||||
switch (bits_per_sample) {
|
||||
case 8:
|
||||
format = SampleFormat::SAMPLE_FMT_U8;
|
||||
format = AudioParams::kFormatUnsigned8;
|
||||
break;
|
||||
case 16:
|
||||
format = SampleFormat::SAMPLE_FMT_S16;
|
||||
format = AudioParams::kFormatSigned16;
|
||||
break;
|
||||
case 32:
|
||||
if (data_is_float) {
|
||||
format = SampleFormat::SAMPLE_FMT_FLT;
|
||||
format = AudioParams::kFormatFloat32;
|
||||
} else {
|
||||
format = SampleFormat::SAMPLE_FMT_S32;
|
||||
format = AudioParams::kFormatSigned32;
|
||||
}
|
||||
break;
|
||||
case 64:
|
||||
if (data_is_float) {
|
||||
format = SampleFormat::SAMPLE_FMT_DBL;
|
||||
format = AudioParams::kFormatFloat64;
|
||||
} else {
|
||||
format = SampleFormat::SAMPLE_FMT_S64;
|
||||
format = AudioParams::kFormatSigned64;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -239,4 +239,4 @@ qint64 WaveInput::calculate_max_read() const
|
||||
return data_size_ - (file_.pos() - data_position_ );
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "render/audioparams.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class WaveInput
|
||||
{
|
||||
@@ -70,6 +70,6 @@ private:
|
||||
quint32 data_size_;
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // WAVEINPUT_H
|
||||
|
||||
+13
-11
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,7 +20,9 @@
|
||||
|
||||
#include "waveoutput.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
#include "render/audioparams.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
const int16_t kWAVIntegerFormat = 1;
|
||||
const int16_t kWAVFloatFormat = 3;
|
||||
@@ -60,18 +62,18 @@ bool WaveOutput::open()
|
||||
|
||||
// Type of format
|
||||
switch (params_.format()) {
|
||||
case SampleFormat::SAMPLE_FMT_U8:
|
||||
case SampleFormat::SAMPLE_FMT_S16:
|
||||
case SampleFormat::SAMPLE_FMT_S32:
|
||||
case SampleFormat::SAMPLE_FMT_S64:
|
||||
case AudioParams::kFormatUnsigned8:
|
||||
case AudioParams::kFormatSigned16:
|
||||
case AudioParams::kFormatSigned32:
|
||||
case AudioParams::kFormatSigned64:
|
||||
write_int<int16_t>(&file_, kWAVIntegerFormat);
|
||||
break;
|
||||
case SampleFormat::SAMPLE_FMT_FLT:
|
||||
case SampleFormat::SAMPLE_FMT_DBL:
|
||||
case AudioParams::kFormatFloat32:
|
||||
case AudioParams::kFormatFloat64:
|
||||
write_int<int16_t>(&file_, kWAVFloatFormat);
|
||||
break;
|
||||
case SampleFormat::SAMPLE_FMT_INVALID:
|
||||
case SampleFormat::SAMPLE_FMT_COUNT:
|
||||
case AudioParams::kFormatInvalid:
|
||||
case AudioParams::kFormatCount:
|
||||
qWarning() << "Invalid sample format for WAVE audio";
|
||||
file_.close();
|
||||
return false;
|
||||
@@ -175,4 +177,4 @@ void WaveOutput::write_int(QFile *file, T integer)
|
||||
file->write(bytes);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,10 +24,9 @@
|
||||
#include <QByteArray>
|
||||
#include <QFile>
|
||||
|
||||
#include "audio/sampleformat.h"
|
||||
#include "render/audioparams.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class WaveOutput
|
||||
{
|
||||
@@ -64,6 +63,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // WAVEAUDIO_H
|
||||
|
||||
+21
-14
@@ -1,5 +1,5 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
# Copyright (C) 2020 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -16,43 +16,50 @@
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
common/bezier.h
|
||||
common/bezier.cpp
|
||||
common/bezier.h
|
||||
common/cancelableobject.h
|
||||
common/channellayout.h
|
||||
common/clamp.h
|
||||
common/commandlineparser.h
|
||||
common/commandlineparser.cpp
|
||||
common/crashpadinterface.h
|
||||
common/commandlineparser.h
|
||||
common/crashpadinterface.cpp
|
||||
common/crashpadinterface.h
|
||||
common/crashpadutils.h
|
||||
common/debug.h
|
||||
common/debug.cpp
|
||||
common/debug.h
|
||||
common/define.h
|
||||
common/filefunctions.h
|
||||
common/ffmpegutils.cpp
|
||||
common/ffmpegutils.h
|
||||
common/filefunctions.cpp
|
||||
common/flipmodifiers.h
|
||||
common/filefunctions.h
|
||||
common/flipmodifiers.cpp
|
||||
common/flipmodifiers.h
|
||||
common/functiontimer.h
|
||||
common/lerp.h
|
||||
common/memorypool.h
|
||||
common/memorypool.cpp
|
||||
common/otioutils.h
|
||||
common/qtutils.h
|
||||
common/memorypool.h
|
||||
common/ocioutils.cpp
|
||||
common/ocioutils.h
|
||||
common/oiioutils.cpp
|
||||
common/oiioutils.h
|
||||
common/qtutils.cpp
|
||||
common/qtutils.h
|
||||
common/range.h
|
||||
common/ratiodialog.h
|
||||
common/ratiodialog.cpp
|
||||
common/ratiodialog.h
|
||||
common/rational.h
|
||||
common/rational.cpp
|
||||
common/threadedobject.h
|
||||
common/threadsafemap.h
|
||||
common/threadedobject.cpp
|
||||
common/timecodefunctions.h
|
||||
common/threadedobject.h
|
||||
common/timecodefunctions.cpp
|
||||
common/timerange.h
|
||||
common/timecodefunctions.h
|
||||
common/timerange.cpp
|
||||
common/timerange.h
|
||||
common/tohex.h
|
||||
common/xmlutils.h
|
||||
common/xmlutils.cpp
|
||||
common/xmlutils.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class AutoScroll {
|
||||
public:
|
||||
@@ -34,6 +34,6 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // AUTOSCROLL_H
|
||||
|
||||
+10
-5
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -22,7 +22,9 @@
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
#include "common/clamp.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
double Bezier::QuadraticXtoT(double x, double a, double b, double c)
|
||||
{
|
||||
@@ -36,7 +38,10 @@ double Bezier::QuadraticTtoY(double a, double b, double c, double t)
|
||||
|
||||
double Bezier::CubicXtoT(double x_target, double a, double b, double c, double d)
|
||||
{
|
||||
double tolerance = 0.0001;
|
||||
const double tolerance = 0.0001;
|
||||
|
||||
// Clamp to prevent deadlocks
|
||||
x_target = clamp(x_target, a, d);
|
||||
|
||||
double lower = 0.0;
|
||||
double upper = 1.0;
|
||||
@@ -51,7 +56,7 @@ double Bezier::CubicXtoT(double x_target, double a, double b, double c, double d
|
||||
upper = percent;
|
||||
}
|
||||
|
||||
percent = (upper + lower) / 2.0;
|
||||
percent = (upper + lower) * 0.5;
|
||||
x = CubicTtoY(a, b, c, d, percent);
|
||||
}
|
||||
|
||||
@@ -63,4 +68,4 @@ double Bezier::CubicTtoY(double a, double b, double c, double d, double t)
|
||||
return qPow(1.0 - t, 3)*a + 3*qPow(1.0 - t, 2)*t*b + 3*(1.0 - t)*qPow(t, 2)*c + qPow(t, 3)*d;
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class Bezier
|
||||
{
|
||||
@@ -37,6 +37,6 @@ public:
|
||||
static double CubicTtoY(double a, double b, double c, double d, double t);
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // BEZIER_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class CancelableObject {
|
||||
public:
|
||||
@@ -34,19 +34,25 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void Cancel() {
|
||||
void Cancel()
|
||||
{
|
||||
cancelled_ = true;
|
||||
CancelEvent();
|
||||
}
|
||||
|
||||
const QAtomicInt& IsCancelled() const {
|
||||
const QAtomicInt& IsCancelled() const
|
||||
{
|
||||
return cancelled_;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void CancelEvent(){}
|
||||
|
||||
private:
|
||||
QAtomicInt cancelled_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // CANCELABLEOBJECT_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -34,11 +34,11 @@ CommandLineParser::~CommandLineParser()
|
||||
}
|
||||
}
|
||||
|
||||
const CommandLineParser::Option *CommandLineParser::AddOption(const QStringList &strings, const QString &description)
|
||||
const CommandLineParser::Option *CommandLineParser::AddOption(const QStringList &strings, const QString &description, bool takes_arg, const QString &arg_placeholder)
|
||||
{
|
||||
Option* o = new Option();
|
||||
|
||||
options_.append({strings, description, o});
|
||||
options_.append({strings, description, o, takes_arg, arg_placeholder});
|
||||
|
||||
return o;
|
||||
}
|
||||
@@ -72,6 +72,12 @@ void CommandLineParser::Process(int argc, char **argv)
|
||||
if (!s.compare(arg_basename, Qt::CaseInsensitive)) {
|
||||
// Flag discovered!
|
||||
o.option->Set();
|
||||
|
||||
if (o.takes_arg && i+1 < argc) {
|
||||
o.option->SetSetting(argv[i+1]);
|
||||
i++;
|
||||
}
|
||||
|
||||
matched_known = true;
|
||||
goto found_flag;
|
||||
}
|
||||
@@ -147,7 +153,11 @@ void CommandLineParser::PrintHelp(const char* filename)
|
||||
all_args.append(this_arg);
|
||||
}
|
||||
|
||||
if (o.arg_placeholder.isEmpty()) {
|
||||
printf(" %s\n", all_args.toUtf8().constData());
|
||||
} else {
|
||||
printf(" %s <%s>\n", all_args.toUtf8().constData(), o.arg_placeholder.toUtf8().constData());
|
||||
}
|
||||
|
||||
printf(" %s\n\n", o.description.toUtf8().constData());
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -33,7 +33,27 @@ public:
|
||||
|
||||
DISABLE_COPY_MOVE(CommandLineParser)
|
||||
|
||||
class Option {
|
||||
class PositionalArgument
|
||||
{
|
||||
public:
|
||||
PositionalArgument() = default;
|
||||
|
||||
const QString& GetSetting() const
|
||||
{
|
||||
return setting_;
|
||||
}
|
||||
|
||||
void SetSetting(const QString& s)
|
||||
{
|
||||
setting_ = s;
|
||||
}
|
||||
|
||||
private:
|
||||
QString setting_;
|
||||
|
||||
};
|
||||
|
||||
class Option : public PositionalArgument {
|
||||
public:
|
||||
Option()
|
||||
{
|
||||
@@ -55,29 +75,9 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class PositionalArgument
|
||||
{
|
||||
public:
|
||||
PositionalArgument() = default;
|
||||
|
||||
const QString& GetSetting() const
|
||||
{
|
||||
return setting_;
|
||||
}
|
||||
|
||||
void SetSetting(const QString& s)
|
||||
{
|
||||
setting_ = s;
|
||||
}
|
||||
|
||||
private:
|
||||
QString setting_;
|
||||
|
||||
};
|
||||
|
||||
CommandLineParser() = default;
|
||||
|
||||
const Option* AddOption(const QStringList& strings, const QString& description);
|
||||
const Option* AddOption(const QStringList& strings, const QString& description, bool takes_arg = false, const QString& arg_placeholder = QString());
|
||||
|
||||
const PositionalArgument* AddPositionalArgument(const QString& name, const QString& description, bool required = false);
|
||||
|
||||
@@ -90,6 +90,8 @@ private:
|
||||
QStringList args;
|
||||
QString description;
|
||||
Option* option;
|
||||
bool takes_arg;
|
||||
QString arg_placeholder;
|
||||
};
|
||||
|
||||
struct KnownPositionalArgument {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -40,7 +40,7 @@ crashpad::CrashpadClient *client;
|
||||
|
||||
QString GenerateReportPath()
|
||||
{
|
||||
return QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("reports"));
|
||||
return QDir(olive::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("reports"));
|
||||
}
|
||||
|
||||
base::FilePath GenerateReportPathForCrashpad()
|
||||
@@ -90,7 +90,7 @@ bool InitializeCrashpad()
|
||||
|
||||
base::FilePath reports_dir = GenerateReportPathForCrashpad();
|
||||
|
||||
base::FilePath metrics_dir(QSTRING_TO_BASE_STRING(QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("metrics"))));
|
||||
base::FilePath metrics_dir(QSTRING_TO_BASE_STRING(QDir(olive::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("metrics"))));
|
||||
|
||||
// Metadata that will be posted to the server with the crash report map
|
||||
std::map<std::string, std::string> annotations;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
void DebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
@@ -54,4 +54,4 @@ void DebugHandler(QtMsgType type, const QMessageLogContext &context, const QStri
|
||||
#endif
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,10 +25,10 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
void DebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // DEBUG_H
|
||||
|
||||
+6
-16
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -21,17 +21,7 @@
|
||||
#ifndef OLIVECOMMONDEFINE_H
|
||||
#define OLIVECOMMONDEFINE_H
|
||||
|
||||
#define OLIVE_NAMESPACE olive
|
||||
|
||||
#define OLIVE_NAMESPACE_ENTER namespace OLIVE_NAMESPACE {
|
||||
|
||||
#define OLIVE_NAMESPACE_EXIT }
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
const int kHSVChannels = 3;
|
||||
const int kRGBChannels = 3;
|
||||
const int kRGBAChannels = 4;
|
||||
namespace olive {
|
||||
|
||||
/// The minimum size an icon in ProjectExplorer can be
|
||||
const int kProjectIconSizeMinimum = 16;
|
||||
@@ -44,14 +34,14 @@ const int kProjectIconSizeDefault = 64;
|
||||
|
||||
const int kBytesInGigabyte = 1073741824;
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#define MACRO_NAME_AS_STR(s) #s
|
||||
#define MACRO_VAL_AS_STR(s) MACRO_NAME_AS_STR(s)
|
||||
|
||||
#define OLIVE_NS_CONST_ARG(x, y) QArgument<const OLIVE_NAMESPACE::x>("const " MACRO_VAL_AS_STR(OLIVE_NAMESPACE) "::" #x, y)
|
||||
#define OLIVE_NS_ARG(x, y) QArgument<OLIVE_NAMESPACE::x>(MACRO_VAL_AS_STR(OLIVE_NAMESPACE) "::" #x, y)
|
||||
#define OLIVE_NS_RETURN_ARG(x, y) QReturnArgument<OLIVE_NAMESPACE::x>(MACRO_VAL_AS_STR(OLIVE_NAMESPACE) "::" #x, y)
|
||||
#define OLIVE_NS_CONST_ARG(x, y) QArgument<const olive::x>("const " MACRO_VAL_AS_STR(olive) "::" #x, y)
|
||||
#define OLIVE_NS_ARG(x, y) QArgument<olive::x>(MACRO_VAL_AS_STR(olive) "::" #x, y)
|
||||
#define OLIVE_NS_RETURN_ARG(x, y) QReturnArgument<olive::x>(MACRO_VAL_AS_STR(olive) "::" #x, y)
|
||||
|
||||
/**
|
||||
* Copy/move deleters. Similar to Q_DISABLE_COPY_MOVE, et al. but those functions are not present in Qt < 5.13 so we
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/ffmpegutils.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
AVPixelFormat FFmpegUtils::GetCompatiblePixelFormat(const AVPixelFormat &pix_fmt)
|
||||
{
|
||||
AVPixelFormat possible_pix_fmts[] = {
|
||||
AV_PIX_FMT_RGB24,
|
||||
AV_PIX_FMT_RGBA,
|
||||
AV_PIX_FMT_RGB48,
|
||||
AV_PIX_FMT_RGBA64,
|
||||
AV_PIX_FMT_NONE
|
||||
};
|
||||
|
||||
return avcodec_find_best_pix_fmt_of_list(possible_pix_fmts,
|
||||
pix_fmt,
|
||||
1,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
AudioParams::Format FFmpegUtils::GetNativeSampleFormat(const AVSampleFormat &smp_fmt)
|
||||
{
|
||||
switch (smp_fmt) {
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
return AudioParams::kFormatUnsigned8;
|
||||
case AV_SAMPLE_FMT_S16:
|
||||
return AudioParams::kFormatSigned16;
|
||||
case AV_SAMPLE_FMT_S32:
|
||||
return AudioParams::kFormatSigned32;
|
||||
case AV_SAMPLE_FMT_S64:
|
||||
return AudioParams::kFormatSigned64;
|
||||
case AV_SAMPLE_FMT_FLT:
|
||||
return AudioParams::kFormatFloat32;
|
||||
case AV_SAMPLE_FMT_DBL:
|
||||
return AudioParams::kFormatFloat64;
|
||||
case AV_SAMPLE_FMT_U8P :
|
||||
case AV_SAMPLE_FMT_S16P:
|
||||
case AV_SAMPLE_FMT_S32P:
|
||||
case AV_SAMPLE_FMT_S64P:
|
||||
case AV_SAMPLE_FMT_FLTP:
|
||||
case AV_SAMPLE_FMT_DBLP:
|
||||
case AV_SAMPLE_FMT_NONE:
|
||||
case AV_SAMPLE_FMT_NB:
|
||||
break;
|
||||
}
|
||||
|
||||
return AudioParams::kFormatInvalid;
|
||||
}
|
||||
|
||||
AVSampleFormat FFmpegUtils::GetFFmpegSampleFormat(const AudioParams::Format &smp_fmt)
|
||||
{
|
||||
switch (smp_fmt) {
|
||||
case AudioParams::kFormatUnsigned8:
|
||||
return AV_SAMPLE_FMT_U8;
|
||||
case AudioParams::kFormatSigned16:
|
||||
return AV_SAMPLE_FMT_S16;
|
||||
case AudioParams::kFormatSigned32:
|
||||
return AV_SAMPLE_FMT_S32;
|
||||
case AudioParams::kFormatSigned64:
|
||||
return AV_SAMPLE_FMT_S64;
|
||||
case AudioParams::kFormatFloat32:
|
||||
return AV_SAMPLE_FMT_FLT;
|
||||
case AudioParams::kFormatFloat64:
|
||||
return AV_SAMPLE_FMT_DBL;
|
||||
case AudioParams::kFormatInvalid:
|
||||
case AudioParams::kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return AV_SAMPLE_FMT_NONE;
|
||||
}
|
||||
|
||||
AVPixelFormat FFmpegUtils::GetFFmpegPixelFormat(const VideoParams::Format &pix_fmt, int channel_layout)
|
||||
{
|
||||
if (channel_layout == VideoParams::kRGBChannelCount) {
|
||||
switch (pix_fmt) {
|
||||
case VideoParams::kFormatUnsigned8:
|
||||
return AV_PIX_FMT_RGB24;
|
||||
case VideoParams::kFormatUnsigned16:
|
||||
return AV_PIX_FMT_RGB48;
|
||||
case VideoParams::kFormatFloat16:
|
||||
case VideoParams::kFormatFloat32:
|
||||
case VideoParams::kFormatInvalid:
|
||||
case VideoParams::kFormatCount:
|
||||
break;
|
||||
}
|
||||
} else if (channel_layout == VideoParams::kRGBAChannelCount) {
|
||||
switch (pix_fmt) {
|
||||
case VideoParams::kFormatUnsigned8:
|
||||
return AV_PIX_FMT_RGBA;
|
||||
case VideoParams::kFormatUnsigned16:
|
||||
return AV_PIX_FMT_RGBA64;
|
||||
case VideoParams::kFormatFloat16:
|
||||
case VideoParams::kFormatFloat32:
|
||||
case VideoParams::kFormatInvalid:
|
||||
case VideoParams::kFormatCount:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
VideoParams::Format FFmpegUtils::GetCompatiblePixelFormat(const VideoParams::Format &pix_fmt)
|
||||
{
|
||||
switch (pix_fmt) {
|
||||
case VideoParams::kFormatUnsigned8:
|
||||
return VideoParams::kFormatUnsigned8;
|
||||
case VideoParams::kFormatUnsigned16:
|
||||
case VideoParams::kFormatFloat16:
|
||||
case VideoParams::kFormatFloat32:
|
||||
return VideoParams::kFormatUnsigned16;
|
||||
case VideoParams::kFormatInvalid:
|
||||
case VideoParams::kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return VideoParams::kFormatInvalid;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,12 +25,12 @@ extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
}
|
||||
|
||||
#include "audio/sampleformat.h"
|
||||
#include "render/pixelformat.h"
|
||||
#include "render/audioparams.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class FFmpegCommon {
|
||||
class FFmpegUtils {
|
||||
public:
|
||||
/**
|
||||
* @brief Returns an AVPixelFormat that can be used to convert a frame to a data type Olive supports with minimal data loss
|
||||
@@ -40,24 +40,24 @@ public:
|
||||
/**
|
||||
* @brief Returns a native pixel format that can be used to convert from a native frame to an AVFrame with minimal data loss
|
||||
*/
|
||||
static PixelFormat::Format GetCompatiblePixelFormat(const PixelFormat::Format& pix_fmt);
|
||||
static VideoParams::Format GetCompatiblePixelFormat(const VideoParams::Format& pix_fmt);
|
||||
|
||||
/**
|
||||
* @brief Returns an FFmpeg pixel format for a given native pixel format
|
||||
*/
|
||||
static AVPixelFormat GetFFmpegPixelFormat(const PixelFormat::Format& pix_fmt);
|
||||
static AVPixelFormat GetFFmpegPixelFormat(const VideoParams::Format& pix_fmt, int channel_layout);
|
||||
|
||||
/**
|
||||
* @brief Returns a native sample format type for a given AVSampleFormat
|
||||
*/
|
||||
static SampleFormat::Format GetNativeSampleFormat(const AVSampleFormat& smp_fmt);
|
||||
static AudioParams::Format GetNativeSampleFormat(const AVSampleFormat& smp_fmt);
|
||||
|
||||
/**
|
||||
* @brief Returns an FFmpeg sample format type for a given native type
|
||||
*/
|
||||
static AVSampleFormat GetFFmpegSampleFormat(const SampleFormat::Format &smp_fmt);
|
||||
static AVSampleFormat GetFFmpegSampleFormat(const AudioParams::Format &smp_fmt);
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // FFMPEGABSTRACTION_H
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "config/config.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
QString FileFunctions::GetUniqueFileIdentifier(const QString &filename)
|
||||
{
|
||||
@@ -187,4 +187,57 @@ QString FileFunctions::EnsureFilenameExtension(QString fn, const QString &extens
|
||||
return fn;
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
QString FileFunctions::ReadFileAsString(const QString &filename)
|
||||
{
|
||||
QFile f(filename);
|
||||
QString file_data;
|
||||
if (f.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QTextStream text_stream(&f);
|
||||
file_data = text_stream.readAll();
|
||||
f.close();
|
||||
}
|
||||
return file_data;
|
||||
}
|
||||
|
||||
QString FileFunctions::GetSafeTemporaryFilename(const QString &original)
|
||||
{
|
||||
int counter = 0;
|
||||
|
||||
QFileInfo original_info(original);
|
||||
QString basename = original_info.baseName();
|
||||
QString complete_suffix = original_info.completeSuffix();
|
||||
|
||||
// If we have a complete suffix, make sure there's a period in it
|
||||
if (!complete_suffix.isEmpty()) {
|
||||
complete_suffix.prepend('.');
|
||||
}
|
||||
|
||||
QString temp_abs_path;
|
||||
do {
|
||||
temp_abs_path = original_info.dir().filePath(
|
||||
QStringLiteral("%1.tmp%2%3").arg(basename,
|
||||
QString::number(counter),
|
||||
complete_suffix));
|
||||
counter++;
|
||||
} while (QFileInfo::exists(temp_abs_path));
|
||||
|
||||
return temp_abs_path;
|
||||
}
|
||||
|
||||
bool FileFunctions::RenameFileAllowOverwrite(const QString &from, const QString &to)
|
||||
{
|
||||
if (QFileInfo::exists(to) && !QFile::remove(to)) {
|
||||
qCritical() << "Couldn't remove existing file" << to << "for overwrite";
|
||||
return false;
|
||||
}
|
||||
|
||||
// By this point, we can assume `to` either never existed or has now been deleted
|
||||
if (!QFile::rename(from, to)) {
|
||||
qCritical() << "Failed to rename file" << from << "to" << to;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
/**
|
||||
* @brief A collection of static file and directory functions
|
||||
@@ -65,10 +65,29 @@ public:
|
||||
*/
|
||||
static QString EnsureFilenameExtension(QString fn, const QString& extension);
|
||||
|
||||
static QString ReadFileAsString(const QString& filename);
|
||||
|
||||
/**
|
||||
* @brief Returns a temporary filename that can be used while writing rather than the original
|
||||
*
|
||||
* If overwriting a file, it's safest to write to a new file first and then only replace it at
|
||||
* the end so that if the program crashes or the user cancels the save half way through, the
|
||||
* original file is still intact.
|
||||
*
|
||||
* This function returns a slight variant of the filename provided that's guaranteed to not exist
|
||||
* and therefore won't overwrite anything important.
|
||||
*/
|
||||
static QString GetSafeTemporaryFilename(const QString& original);
|
||||
|
||||
/**
|
||||
* @brief Renames a file from `from` to `to`, deleting `to` if such a file already exists first
|
||||
*/
|
||||
static bool RenameFileAllowOverwrite(const QString& from, const QString& to);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // FILEFUNCTIONS_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "flipmodifiers.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
Qt::KeyboardModifiers FlipControlAndShiftModifiers(Qt::KeyboardModifiers e) {
|
||||
if (e & Qt::ControlModifier & Qt::ShiftModifier) {
|
||||
@@ -38,4 +38,4 @@ Qt::KeyboardModifiers FlipControlAndShiftModifiers(Qt::KeyboardModifiers e) {
|
||||
return e;
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,10 +25,10 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
Qt::KeyboardModifiers FlipControlAndShiftModifiers(Qt::KeyboardModifiers e);
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // FLIPMODIFIERS_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "memorypool.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
size_t memory_pool_consumption = 0;
|
||||
QMutex memory_pool_consumption_lock;
|
||||
@@ -11,4 +11,4 @@ bool MemoryPoolLimitReached()
|
||||
return (memory_pool_consumption >= 2147483648);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
extern size_t memory_pool_consumption;
|
||||
extern QMutex memory_pool_consumption_lock;
|
||||
@@ -397,6 +397,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // MEMORYPOOL_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -18,43 +18,30 @@
|
||||
|
||||
***/
|
||||
|
||||
#ifndef AVFRAMEPTR_H
|
||||
#define AVFRAMEPTR_H
|
||||
#include "ocioutils.h"
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
namespace olive {
|
||||
|
||||
OCIO::BitDepth OCIOUtils::GetOCIOBitDepthFromPixelFormat(VideoParams::Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case VideoParams::kFormatUnsigned8:
|
||||
return OCIO::BIT_DEPTH_UINT8;
|
||||
case VideoParams::kFormatUnsigned16:
|
||||
return OCIO::BIT_DEPTH_UINT16;
|
||||
break;
|
||||
case VideoParams::kFormatFloat16:
|
||||
return OCIO::BIT_DEPTH_F16;
|
||||
break;
|
||||
case VideoParams::kFormatFloat32:
|
||||
return OCIO::BIT_DEPTH_F32;
|
||||
break;
|
||||
case VideoParams::kFormatInvalid:
|
||||
case VideoParams::kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return OCIO::BIT_DEPTH_UNKNOWN;
|
||||
}
|
||||
|
||||
#include <memory>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class AVFrameWrapper {
|
||||
public:
|
||||
AVFrameWrapper() {
|
||||
frame_ = av_frame_alloc();
|
||||
}
|
||||
|
||||
virtual ~AVFrameWrapper() {
|
||||
av_frame_free(&frame_);
|
||||
}
|
||||
|
||||
DISABLE_COPY_MOVE(AVFrameWrapper)
|
||||
|
||||
inline AVFrame* frame() const {
|
||||
return frame_;
|
||||
}
|
||||
|
||||
private:
|
||||
AVFrame* frame_;
|
||||
|
||||
};
|
||||
|
||||
using AVFramePtr = std::shared_ptr<AVFrameWrapper>;
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
#endif // AVFRAMEPTR_H
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -18,26 +18,22 @@
|
||||
|
||||
***/
|
||||
|
||||
#include "openglbackend.h"
|
||||
#ifndef OCIOUTILS_H
|
||||
#define OCIOUTILS_H
|
||||
|
||||
#include "openglworker.h"
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
namespace OCIO = OCIO_NAMESPACE;
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
#include "render/videoparams.h"
|
||||
|
||||
OpenGLBackend::OpenGLBackend(QObject* parent) :
|
||||
RenderBackend(parent)
|
||||
namespace olive {
|
||||
|
||||
class OCIOUtils
|
||||
{
|
||||
public:
|
||||
static OCIO::BitDepth GetOCIOBitDepthFromPixelFormat(VideoParams::Format format);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OpenGLBackend::~OpenGLBackend()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
RenderWorker *OpenGLBackend::CreateNewWorker()
|
||||
{
|
||||
return new OpenGLWorker(this);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
#endif // OCIOUTILS_H
|
||||
@@ -0,0 +1,81 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "oiioutils.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
void OIIOUtils::FrameToBuffer(const Frame* frame, OIIO::ImageBuf *buf)
|
||||
{
|
||||
buf->set_pixels(OIIO::ROI(),
|
||||
buf->spec().format,
|
||||
frame->const_data(),
|
||||
OIIO::AutoStride,
|
||||
frame->linesize_bytes());
|
||||
}
|
||||
|
||||
void OIIOUtils::BufferToFrame(OIIO::ImageBuf *buf, Frame* frame)
|
||||
{
|
||||
buf->get_pixels(OIIO::ROI(),
|
||||
buf->spec().format,
|
||||
frame->data(),
|
||||
OIIO::AutoStride,
|
||||
frame->linesize_bytes());
|
||||
}
|
||||
|
||||
rational OIIOUtils::GetPixelAspectRatioFromOIIO(const OIIO::ImageSpec &spec)
|
||||
{
|
||||
return rational::fromDouble(spec.get_float_attribute("PixelAspectRatio", 1));
|
||||
}
|
||||
|
||||
VideoParams::Format OIIOUtils::GetFormatFromOIIOBasetype(OIIO::TypeDesc::BASETYPE type)
|
||||
{
|
||||
switch (type) {
|
||||
case OIIO::TypeDesc::UNKNOWN:
|
||||
case OIIO::TypeDesc::NONE:
|
||||
break;
|
||||
|
||||
case OIIO::TypeDesc::INT8:
|
||||
case OIIO::TypeDesc::INT16:
|
||||
case OIIO::TypeDesc::INT32:
|
||||
case OIIO::TypeDesc::UINT32:
|
||||
case OIIO::TypeDesc::INT64:
|
||||
case OIIO::TypeDesc::UINT64:
|
||||
case OIIO::TypeDesc::STRING:
|
||||
case OIIO::TypeDesc::PTR:
|
||||
case OIIO::TypeDesc::LASTBASE:
|
||||
case OIIO::TypeDesc::DOUBLE:
|
||||
qDebug() << "Tried to use unknown OIIO base type";
|
||||
break;
|
||||
|
||||
case OIIO::TypeDesc::UINT8:
|
||||
return VideoParams::kFormatUnsigned8;
|
||||
case OIIO::TypeDesc::UINT16:
|
||||
return VideoParams::kFormatUnsigned16;
|
||||
case OIIO::TypeDesc::HALF:
|
||||
return VideoParams::kFormatFloat16;
|
||||
case OIIO::TypeDesc::FLOAT:
|
||||
return VideoParams::kFormatFloat32;
|
||||
}
|
||||
|
||||
return VideoParams::kFormatInvalid;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef OIIOUTILS_H
|
||||
#define OIIOUTILS_H
|
||||
|
||||
#include <OpenImageIO/imagebuf.h>
|
||||
#include <OpenImageIO/typedesc.h>
|
||||
|
||||
#include "codec/frame.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class OIIOUtils {
|
||||
public:
|
||||
static OIIO::TypeDesc::BASETYPE GetOIIOBaseTypeFromFormat(VideoParams::Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case VideoParams::kFormatUnsigned8:
|
||||
return OIIO::TypeDesc::UINT8;
|
||||
case VideoParams::kFormatUnsigned16:
|
||||
return OIIO::TypeDesc::UINT16;
|
||||
case VideoParams::kFormatFloat16:
|
||||
return OIIO::TypeDesc::HALF;
|
||||
case VideoParams::kFormatFloat32:
|
||||
return OIIO::TypeDesc::FLOAT;
|
||||
case VideoParams::kFormatInvalid:
|
||||
case VideoParams::kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return OIIO::TypeDesc::UNKNOWN;
|
||||
}
|
||||
|
||||
static void FrameToBuffer(const Frame *frame, OIIO::ImageBuf* buf);
|
||||
|
||||
static void BufferToFrame(OIIO::ImageBuf* buf, Frame* frame);
|
||||
|
||||
static VideoParams::Format GetFormatFromOIIOBasetype(OIIO::TypeDesc::BASETYPE type);
|
||||
|
||||
static rational GetPixelAspectRatioFromOIIO(const OIIO::ImageSpec& spec);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // OIIOUTILS_H
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
uint32_t ceil_to_power_of_2(uint32_t v)
|
||||
{
|
||||
@@ -51,6 +51,6 @@ uint32_t floor_to_power_of_2(uint32_t x)
|
||||
return x - (x >> 1);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // POWER_H
|
||||
|
||||
+12
-4
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,9 +20,9 @@
|
||||
|
||||
#include "qtutils.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
int QFontMetricsWidth(QFontMetrics fm, const QString& s) {
|
||||
int QtUtils::QFontMetricsWidth(QFontMetrics fm, const QString& s) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
|
||||
return fm.width(s);
|
||||
#else
|
||||
@@ -30,4 +30,12 @@ int QFontMetricsWidth(QFontMetrics fm, const QString& s) {
|
||||
#endif
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
QFrame *QtUtils::CreateHorizontalLine()
|
||||
{
|
||||
QFrame* horizontal_line = new QFrame();
|
||||
horizontal_line->setFrameShape(QFrame::HLine);
|
||||
horizontal_line->setFrameShadow(QFrame::Sunken);
|
||||
return horizontal_line;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-5
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -28,20 +28,27 @@
|
||||
*/
|
||||
|
||||
#include <QFontMetrics>
|
||||
#include <QFrame>
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
/**
|
||||
class QtUtils {
|
||||
public:
|
||||
/**
|
||||
* @brief Retrieves the width of a string according to certain QFontMetrics
|
||||
*
|
||||
* QFontMetrics::width() has been deprecatd in favor of QFontMetrics::horizontalAdvance(), but the
|
||||
* latter was only introduced in 5.11+. This function wraps the latter for 5.11+ and the former for
|
||||
* earlier.
|
||||
*/
|
||||
int QFontMetricsWidth(QFontMetrics fm, const QString& s);
|
||||
static int QFontMetricsWidth(QFontMetrics fm, const QString& s);
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
static QFrame* CreateHorizontalLine();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // QTVERSIONABSTRACTION_H
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QMessageBox>
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
double GetFloatRatioFromUser(QWidget* parent,
|
||||
const QString& title,
|
||||
@@ -88,4 +88,4 @@ double GetFloatRatioFromUser(QWidget* parent,
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
#include "common/rational.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
double GetFloatRatioFromUser(QWidget* parent,
|
||||
const QString& title,
|
||||
bool* ok_in);
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // RATIODIALOG_H
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "rational.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
rational rational::fromDouble(const double &flt)
|
||||
{
|
||||
@@ -393,9 +393,9 @@ uint qHash(const rational &r, uint seed)
|
||||
return ::qHash(r.toDouble(), seed);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const OLIVE_NAMESPACE::rational &r)
|
||||
QDebug operator<<(QDebug debug, const olive::rational &r)
|
||||
{
|
||||
return debug.space() << r.toDouble();
|
||||
/*
|
||||
|
||||
@@ -20,7 +20,7 @@ extern "C" {
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
typedef int64_t intType;
|
||||
/*
|
||||
@@ -141,10 +141,10 @@ private:
|
||||
|
||||
uint qHash(const rational& r, uint seed);
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const OLIVE_NAMESPACE::rational& r);
|
||||
QDebug operator<<(QDebug debug, const olive::rational& r);
|
||||
|
||||
Q_DECLARE_METATYPE(OLIVE_NAMESPACE::rational)
|
||||
Q_DECLARE_METATYPE(olive::rational)
|
||||
|
||||
#endif // RATIONAL_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "threadedobject.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
void ThreadedObject::LockDeletes()
|
||||
{
|
||||
@@ -54,4 +54,4 @@ bool ThreadedObject::TryLockMutex(int timeout)
|
||||
return threadobj_main_lock_.tryLock(timeout);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
namespace olive {
|
||||
|
||||
class ThreadedObject
|
||||
{
|
||||
@@ -45,6 +45,6 @@ private:
|
||||
QAtomicInt threadobj_delete_lock_;
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
}
|
||||
|
||||
#endif // THREADEDOBJECT_H
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user