Merge remote-tracking branch 'origin/main'

This commit is contained in:
2026-07-13 17:05:22 +08:00
606 changed files with 135087 additions and 138186 deletions
+215 -29
View File
@@ -14,7 +14,7 @@ jobs:
# Windows Installer (MSYS2)
# ------------------------------------------------------------------
windows:
runs-on: warp-windows-latest-x64-16x
runs-on: warp-windows-latest-x64-32x
steps:
- uses: actions/checkout@v4
with:
@@ -57,13 +57,21 @@ jobs:
- name: Deploy dependencies
shell: msys2 {0}
run: |
mkdir -p app/packaging/windows/nsis/olive-editor
cp build/app/olive-editor.exe app/packaging/windows/nsis/olive-editor/
windeployqt6 app/packaging/windows/nsis/olive-editor/olive-editor.exe
# Copy all non-Qt MSYS2 DLLs recursively
cd app/packaging/windows/nsis/olive-editor
for l in $(ntldd -R olive-editor.exe | grep -E 'mingw64|ucrt64|clang64' | sed 's/^[ \t]*//' | cut -d' ' -f3); do
cp -v "$l" .
mkdir -p app/packaging/windows/nsis/oak-editor
cp build/app/oak-editor.exe app/packaging/windows/nsis/oak-editor/
cp build/app/oak-render-worker.exe app/packaging/windows/nsis/oak-editor/
cp build/app/oakgl.dll app/packaging/windows/nsis/oak-editor/
if [ -f build/app/oakvulkan.dll ]; then
cp build/app/oakvulkan.dll app/packaging/windows/nsis/oak-editor/
fi
windeployqt6 app/packaging/windows/nsis/oak-editor/oak-editor.exe
# Copy all non-Qt MSYS2 DLLs recursively for every binary we ship
cd app/packaging/windows/nsis/oak-editor
for binary in oak-editor.exe oak-render-worker.exe oakgl.dll oakvulkan.dll; do
[ -f "$binary" ] || continue
for l in $(ntldd -R "$binary" | grep -E 'mingw64|ucrt64|clang64' | sed 's/^[ \t]*//' | cut -d' ' -f3); do
cp -v "$l" .
done
done
- name: Build installer
@@ -71,7 +79,7 @@ jobs:
run: |
cd app/packaging/windows/nsis
cp "${GITHUB_WORKSPACE}"/LICENSE .
makensis olive.nsi
makensis oak.nsi
mv setup.exe "${GITHUB_WORKSPACE}"/Oak-Video-Editor-Windows-x64.exe
- name: Upload artifact
@@ -122,21 +130,37 @@ jobs:
- name: Deploy Qt dependencies
run: |
export PATH="$(brew --prefix qt@6)/bin:$PATH"
macdeployqt build/app/Olive.app
macdeployqt build/app/Oak.app \
-verbose=2 \
-executable=build/app/Oak.app/Contents/MacOS/oak-render-worker
# Re-sign after macdeployqt (it breaks signatures when modifying libs)
codesign --force --deep --sign - build/app/Olive.app
codesign --force --deep --sign - build/app/Oak.app
- name: Verify macOS bundle plugins
run: |
ls -la build/app/Oak.app/Contents/PlugIns/platforms/ || (echo "Missing platform plugins!" && exit 1)
ls -la build/app/Oak.app/Contents/PlugIns/imageformats/ || true
echo "=== otool -L main binary ==="
otool -L build/app/Oak.app/Contents/MacOS/Oak | head -30
echo "=== otool -L worker ==="
otool -L build/app/Oak.app/Contents/MacOS/oak-render-worker | head -30
- name: Bundle non-Qt libraries
run: |
mkdir -p build/app/Olive.app/Contents/Frameworks
mkdir -p build/app/Oak.app/Contents/Frameworks
python3 << 'PYEOF'
import os, shutil, subprocess
APP = "build/app/Olive.app"
BINARY = f"{APP}/Contents/MacOS/Olive"
APP = "build/app/Oak.app"
MACOS_DIR = f"{APP}/Contents/MacOS"
DEST = f"{APP}/Contents/Frameworks"
os.makedirs(DEST, exist_ok=True)
QT_PREFIXES = ("Qt", "libQt")
def is_qt_lib(name):
return name.startswith(QT_PREFIXES)
def get_rpaths(binary):
out = subprocess.run(["otool", "-l", binary], capture_output=True, text=True).stdout
rpaths = []
@@ -178,42 +202,55 @@ jobs:
return p
return None
EXEC_RPATHS = get_rpaths(BINARY)
PROCESSED = set()
def process(target):
def process(target, exec_rpaths):
tdir = os.path.dirname(target)
print(f"Processing: {target}")
for dep in get_deps(target):
resolved = resolve(dep, EXEC_RPATHS if target == BINARY else [], tdir)
# Skip Qt frameworks and Qt dylibs; macdeployqt already deploys them.
dep_base = os.path.basename(dep)
if is_qt_lib(dep_base):
continue
resolved = resolve(dep, exec_rpaths, tdir)
if not resolved or not os.path.isfile(resolved):
continue
resolved = os.path.realpath(resolved)
if not (resolved.startswith("/opt/homebrew/") or resolved.startswith("/usr/local/") or resolved.startswith(os.path.realpath(os.getcwd()))):
continue
base = os.path.basename(resolved)
if is_qt_lib(base):
continue
if base in PROCESSED:
subprocess.run(["install_name_tool", "-change", dep, f"@rpath/{base}", target], capture_output=True)
continue
PROCESSED.add(base)
dst = os.path.join(DEST, base)
if os.path.abspath(resolved) == os.path.abspath(dst):
# Already in Frameworks (likely copied by macdeployqt), just fix paths
subprocess.run(["install_name_tool", "-id", f"@rpath/{base}", dst], capture_output=True)
subprocess.run(["install_name_tool", "-change", dep, f"@rpath/{base}", target], capture_output=True)
process(dst)
process(dst, exec_rpaths)
continue
print(f" Copying: {resolved} -> {dst}")
shutil.copy2(resolved, dst)
subprocess.run(["install_name_tool", "-id", f"@rpath/{base}", dst], capture_output=True)
subprocess.run(["install_name_tool", "-change", dep, f"@rpath/{base}", target], capture_output=True)
process(dst)
process(dst, exec_rpaths)
process(BINARY)
binaries = [os.path.join(MACOS_DIR, f) for f in os.listdir(MACOS_DIR)
if os.path.isfile(os.path.join(MACOS_DIR, f))]
if not binaries:
raise RuntimeError(f"No binaries found in {MACOS_DIR}")
for rp in EXEC_RPATHS:
subprocess.run(["install_name_tool", "-delete_rpath", rp, BINARY], capture_output=True)
subprocess.run(["install_name_tool", "-add_rpath", "@executable_path/../Frameworks", BINARY], capture_output=True)
main_binary = os.path.join(MACOS_DIR, "Oak")
main_rpaths = get_rpaths(main_binary)
for binary in binaries:
process(binary, main_rpaths)
# Ensure every binary can find libraries in Frameworks
for rp in get_rpaths(binary):
subprocess.run(["install_name_tool", "-delete_rpath", rp, binary], capture_output=True)
subprocess.run(["install_name_tool", "-add_rpath", "@executable_path/../Frameworks", binary], capture_output=True)
subprocess.run(["codesign", "--force", "--deep", "--sign", "-", APP], check=True)
print("Done. Frameworks:")
@@ -224,16 +261,19 @@ jobs:
- name: Debug bundle contents
run: |
echo "=== otool -L ==="
otool -L build/app/Olive.app/Contents/MacOS/Olive
otool -L build/app/Oak.app/Contents/MacOS/Oak
echo "=== Frameworks dir ==="
ls -la build/app/Olive.app/Contents/Frameworks/ || echo "(empty)"
ls -la build/app/Oak.app/Contents/Frameworks/ || echo "(empty)"
echo "=== App bundle size ==="
du -sh build/app/Olive.app
du -sh build/app/Oak.app
- name: Create DMG
run: |
mkdir -p build/app/dmg-staging
cp -R build/app/Oak.app build/app/dmg-staging/
ln -s /Applications build/app/dmg-staging/Applications
hdiutil create \
-srcfolder build/app/Olive.app \
-srcfolder build/app/dmg-staging \
-volname "Oak Video Editor" \
-fs HFS+ \
-format UDZO \
@@ -317,11 +357,157 @@ jobs:
name: oak-linux-appimage
path: Oak_Video_Editor-*.AppImage
# ------------------------------------------------------------------
# Debian package (.deb)
# ------------------------------------------------------------------
deb:
runs-on: warp-ubuntu-latest-x64-16x
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
cmake ninja-build pkg-config \
qt6-base-dev qt6-base-dev-tools qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libavfilter-dev \
libopencolorio-dev libopenimageio-dev libopenexr-dev libexpat1-dev \
portaudio19-dev libgl1-mesa-dev libxkbcommon-dev
- name: Build
run: |
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr \
-DBUILD_QT6=ON \
-DCMAKE_DISABLE_FIND_PACKAGE_Vulkan=ON
cmake --build build
- name: Create DEB package
run: |
cd build
cpack -G DEB
mv *.deb "${GITHUB_WORKSPACE}/"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: oak-deb-package
path: oak-video-editor_*.deb
# ------------------------------------------------------------------
# RPM package (.rpm)
# ------------------------------------------------------------------
rpm:
runs-on: warp-ubuntu-latest-x64-16x
container:
image: fedora:latest
steps:
- name: Install Git
run: dnf install -y git
- uses: actions/checkout@v4
with:
submodules: true
- name: Install dependencies
run: |
dnf install -y \
cmake ninja-build pkgconf-pkg-config \
qt6-qtbase-devel qt6-qtbase-private-devel qt6-qttools-devel \
ffmpeg-free-devel \
OpenImageIO-devel \
OpenColorIO-devel \
openexr-devel \
expat-devel \
portaudio-devel \
mesa-libGL-devel \
vulkan-headers \
vulkan-loader-devel \
libxkbcommon-devel \
gcc-c++ \
bzip2-devel \
rpm-build
- name: Build
run: |
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr \
-DBUILD_QT6=ON \
-DCMAKE_DISABLE_FIND_PACKAGE_Vulkan=ON
cmake --build build
- name: Create RPM package
run: |
cd build
cpack -G RPM
mv *.rpm "${GITHUB_WORKSPACE}/"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: oak-rpm-package
path: oak-video-editor-*.rpm
# ------------------------------------------------------------------
# Arch Linux package (.pkg.tar.zst)
# ------------------------------------------------------------------
archlinux:
runs-on: warp-ubuntu-latest-x64-16x
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Prepare source tarball and PKGBUILD
run: |
VERSION="${GITHUB_REF_NAME#v}"
# Arch pkgver cannot contain hyphens
PKGVER="${VERSION//-/_}"
TARBALL="oak-video-editor-${PKGVER}.tar.gz"
tar czf "/tmp/${TARBALL}" \
--transform "s,^,oak-video-editor-${PKGVER}/," \
--exclude='.git' \
--exclude='build' \
--exclude='*.tar.gz' \
.
mv "/tmp/${TARBALL}" "${TARBALL}"
sed "s/@VERSION@/${PKGVER}/g" app/packaging/arch/PKGBUILD.in > PKGBUILD
- name: Build package in Arch Linux container
run: |
docker run --rm \
-v "${PWD}:/build" \
-w /build \
archlinux:base-devel \
bash -c '
set -e
pacman-key --init
pacman -Syu --noconfirm
pacman -S --noconfirm --needed \
cmake ninja git pkgconf \
qt6-base qt6-tools ffmpeg openimageio opencolorio openexr expat portaudio \
mesa vulkan-icd-loader libxkbcommon fmt
useradd -m builder
chown -R builder /build
su builder -c "makepkg -s --noconfirm"
'
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: oak-arch-package
path: oak-video-editor-*.pkg.tar.zst
# ------------------------------------------------------------------
# Create Draft Release
# ------------------------------------------------------------------
release:
needs: [windows, macos, appimage]
needs: [windows, macos, appimage, deb, rpm, archlinux]
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [warp-ubuntu-latest-x64-16x, warp-macos-15-arm64-12x, warp-windows-latest-x64-16x]
os: [warp-ubuntu-latest-x64-16x, warp-macos-15-arm64-12x, warp-windows-latest-x64-32x]
env:
CMAKE_BUILD_TYPE: Release
# Enable OFX integration tests that require external plugin bundles
+1 -1
View File
@@ -1,5 +1,5 @@
# CMake artifacts
/build*/
/cmake-build-*
build
# Doxygen
@@ -1,25 +0,0 @@
From 6b0ef44eb189411d36c739ccde8a081a3e62034a Mon Sep 17 00:00:00 2001
From: Mike Solar <iam@mikesolar.com>
Date: Mon, 24 Nov 2025 20:57:12 +0800
Subject: [PATCH] Fix include path for Window_p.h in qtcommon directory
---
src/qtcommon/Window_p.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qtcommon/Window_p.h b/src/qtcommon/Window_p.h
index f29b209a5..d1d6b47ad 100644
--- a/src/qtcommon/Window_p.h
+++ b/src/qtcommon/Window_p.h
@@ -11,7 +11,7 @@
#pragma once
-#include "core/Window_p.h"
+#include "../core/Window_p.h"
#include "Screen_p.h"
#include <QPointer>
--
2.52.0
+30 -2
View File
@@ -17,8 +17,8 @@
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
project(olive-editor VERSION 0.3.0 LANGUAGES CXX)
set(PROJECT_VERSION "0.3.0-alpha")
project(olive-editor VERSION 0.4.0 LANGUAGES CXX)
set(PROJECT_VERSION "0.4.0-alpha")
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -DOFX_SUPPORTS_OPENGLRENDER)
@@ -337,3 +337,31 @@ if (BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
# ------------------------------------------------------------------------------
# CPack / system package configuration
# ------------------------------------------------------------------------------
set(CPACK_PACKAGE_NAME "oak-video-editor")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_VENDOR "Oak Video Editor Team")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Oak - Non-linear video editor")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://oakvideoeditor.org")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
# Debian
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Oak Video Editor Team")
set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
set(CPACK_DEBIAN_PACKAGE_DEPENDS
"libqt6core6, libqt6gui6, libqt6widgets6, libqt6opengl6, libqt6openglwidgets6, libqt6network6, libqt6concurrent6, libavcodec60, libavformat60, libavutil58, libswscale7, libswresample4, libavfilter9, libopenimageio2.4, libopencolorio2, libopenexr-3-1-30, libexpat1, libportaudio2, libgl1, libxkbcommon0")
# RPM
set(CPACK_RPM_PACKAGE_LICENSE "GPLv3")
set(CPACK_RPM_PACKAGE_GROUP "Applications/Multimedia")
set(CPACK_RPM_PACKAGE_URL "https://oakvideoeditor.org")
set(CPACK_RPM_PACKAGE_REQUIRES
"qt6-qtbase >= 6.0, qt6-qtbase-gui >= 6.0, qt6-qttools, ffmpeg-libs >= 6.0, OpenImageIO >= 2.4, OpenColorIO >= 2.0, openexr >= 3.1, expat, portaudio, mesa-libGL, libxkbcommon")
include(CPack)
+7 -12
View File
@@ -1,12 +1,6 @@
# Contributing to Olive
# Contributing to Oak
Thank you for your interest in contributing to Olive!
## Reporting issues
Bug reports help to make the software more stable and usable.
Please read the pinned [issue #1175](https://github.com/olive-editor/olive/issues/1175)
for guidelines before you create a new issue.
Thank you for your interest in contributing to Oak Video Editor!
## Writing code
@@ -22,9 +16,11 @@ In order to keep the code as readable and maintainable as possible, code
submitted should abide by the following standards:
* The code style generally follows the
[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
including, but not limited to:
* Indentation is 4 spaces wide, spaces only (no tabs)
[Linux Kernel Coding Style](https://www.kernel.org/doc/html/latest/process/coding-style.html)
with the following project-specific exceptions and notes:
* Indentation uses **tabs**, not spaces.
* Documentation comments should use **Javadoc-style** (`/** ... */`) where appropriate.
* The naming rules below are retained from the original Olive codebase:
* `lowercase_underscored_variable_names`
* `lowercase_underscored_functions()` or `SentenceCaseFunctions()`
* `class SentenceCaseClassesAndStructs {}`
@@ -33,4 +29,3 @@ submitted should abide by the following standards:
* `class_member_variables_` end with a `_`
* 100 column limit (where it doesn't impair readability)
* Unix line endings (only LF no CRLF)
* Javadoc documentation where appropriate
+5 -6
View File
@@ -1,10 +1,8 @@
# Oak Video Editor[![Build status](https://github.com/olive-editor/olive/workflows/CI/badge.svg?branch=master)](https://github.com/olive-editor/olive/actions?query=branch%3Amaster)
# Oak Video Editor[![CI](https://github.com/OakVideoEditorCommunity/oak/actions/workflows/ci.yml/badge.svg)](https://github.com/OakVideoEditorCommunity/oak/actions/workflows/ci.yml)
[中文](docs/zh/README.md)
Oak Video Editor is a free non-linear video editor for Windows, macOS, and Linux.
Unfortunately, the original author has not submitted code updates for over 7 months, and no public contact information (email or otherwise) is available to reach them directly.
This project is a community-maintained fork of Olive Video Editor.
![screen](https://olivevideoeditor.org/img/020-2.png)
@@ -12,9 +10,10 @@ This project is a community-maintained fork of Olive Video Editor.
**NOTE: Oak Video Editor is alpha software and is considered highly unstable. While we highly appreciate users testing and providing usage information, please use at your own risk.**
## Binaries
The original author compiled following binaries:
- [0.1.0 alpha](https://github.com/olive-editor/olive/releases/tag/0.1.0)
- [0.2.0 unstable development build](https://github.com/olive-editor/olive/releases/tag/0.2.0-nightly)
The binary can be downloaded here:
[v0.3.0](https://github.com/OakVideoEditorCommunity/oak/releases/tag/v0.3.0-alpha)
## Building from Source
-90
View File
@@ -1,90 +0,0 @@
# TODO
## 目标
- 实现 2–3 秒预渲染的 LRU 缓存和代理剪辑功能,并以“小步快跑”的方式在现有架构中逐步落地,确保每一步都可编译。
## 现有架构中的落点
- 播放/渲染调度:`app/render/renderprocessor.cpp`, `app/render/plugin/pluginrenderer.cpp`, `app/node/traverser.cpp`
- 插件节点输入/默认值:`app/node/plugins/Plugin.cpp`
- Clip 图像/纹理获取:`app/pluginSupport/OliveClip.cpp`, `app/pluginSupport/OliveClip.h`
- 节点与值系统:`app/node/node.h`, `app/node/node.cpp`, `app/node/value.h`
- 工程序列化:`app/node/project/serializer/*`
## LRU 缓存计划(代码改动 + 集成点)
### 步骤 1(可编译):新增缓存类型但不接入逻辑
- 新增缓存模块,例如 `app/render/cache/framecache.h/.cpp`
- 定义:
- `FrameCacheKey`(图哈希/版本、时间、参数、代理模式、渲染缩放)。
- `FrameCacheEntry`AVFrame 或 Texture + 元信息 + 字节数 + 最近访问时间)。
- `FrameCache` API`get(key)``put(key, entry)``invalidateByVersion(version)`
- 先只编译通过,不改变行为。
### 步骤 2(可编译):图版本号/失效机制
-`Node` 或渲染入口维护图版本号。
- 当参数变化、连线变化时递增。
- 渲染侧可读取版本号用于缓存失效。
### 步骤 3(小行为):仅缓存当前帧
-`renderprocessor.cpp` 播放路径上:
- 先查缓存,命中则直接显示。
- 未命中则正常渲染,并写入缓存。
- 缓存预算先设很小,风险低。
### 步骤 4(小行为):预渲染窗口
- 增加队列,渲染 [now, now+N]N=23 秒。
- 并发限制(例如 2–3 个任务),避免抢 UI。
- 优先级:当前帧 > 近未来。
- Seek 时取消/丢弃过期任务。
### 步骤 5(行为):LRU 淘汰
- 按内存预算/帧数上限淘汰最久未使用。
### 步骤 6(行为):CPU/GPU 策略
- 默认缓存 CPU 帧,播放时再上传 GPU。
- GPU 缓存可作为后续优化开关。
### 步骤 7(可观测性)
- 统计命中率、平均渲染耗时、掉帧。
- Debug 构建下输出日志。
## 代理剪辑计划(代码改动 + 集成点)
### 步骤 1(可编译):数据模型与序列化
- 在 clip 元数据里增加:
- `proxy_path``proxy_width``proxy_height``proxy_codec``proxy_fps`
-`app/node/project/serializer/*` 写入/读取。
### 步骤 2(小行为):代理选择策略
- 增加全局/每 clip 的代理模式:
- `Auto``ForceProxy``ForceOriginal`
- 在媒体解析层根据模式决定用原片还是代理。
### 步骤 3(行为):代理生成
- 新增后台转码任务(复用现有渲染/导出流程)。
- 生成完成后更新元数据。
### 步骤 4(行为):UI 接入
- 增加“生成代理”“重链接代理”入口。
- 在剪辑或预览上显示代理标识。
### 步骤 5(验证)
- 对比代理与原片的时间精度、音画同步。
- 导出默认使用原片。
## 小步快跑执行顺序(每步可编译)
1) 新增缓存模块/类型(不接入)。
2) 增加图版本号与失效接口。
3) 播放路径只缓存当前帧。
4) 预渲染 2–3 秒窗口 + 并发限制。
5) LRU 淘汰策略。
6) 图版本变更触发失效。
7) 统计与日志。
8) 代理元数据字段 + 序列化。
9) 代理选择策略(Auto/Force)。
10) 代理生成任务 + UI 入口。
## 待确认问题
- 缓存预算默认值(按硬件分级)。
- 代理文件默认存储路径。
- 是否做 GPU 纹理缓存。
-92
View File
@@ -1,92 +0,0 @@
# TODO
## Goal
- Add an LRU prerender cache (23 seconds ahead) and proxy clip support, implemented as incremental, compile-safe steps within the current architecture.
## Where the Changes Live (Current Architecture)
- Playback/render scheduling: `app/render/renderprocessor.cpp`, `app/render/plugin/pluginrenderer.cpp`, `app/node/traverser.cpp`
- Plugin node inputs/defaults: `app/node/plugins/Plugin.cpp`
- Clip image/texture fetch: `app/pluginSupport/OliveClip.cpp`, `app/pluginSupport/OliveClip.h`
- Node graph and values: `app/node/node.h`, `app/node/node.cpp`, `app/node/value.h`
- Project/serialization: `app/node/project/serializer/*`
## LRU Cache Plan (Code Changes + Integration Points)
### Step 1 (compile-safe): Introduce cache data types (no behavior yet)
- Add a small cache module, e.g. `app/render/cache/framecache.h/.cpp`.
- Define:
- `FrameCacheKey` (graph version/hash, time, params, proxy mode, render scale).
- `FrameCacheEntry` (AVFrame or Texture + metadata + byte size + last-used).
- `FrameCache` API: `get(key)`, `put(key, entry)`, `invalidateByVersion(version)`.
- Wire in a compile-only stub with no runtime usage.
### Step 2 (compile-safe): Define graph/version invalidation hook
- Add a lightweight “graph version” counter to `Node` or a render pipeline owner.
- Increment on param changes and graph edits.
- Expose a read-only version getter for the render pipeline.
### Step 3 (small behavior): Cache current frame only
- In `renderprocessor.cpp` playback path, check cache before rendering:
- If hit, present cached frame.
- If miss, render normally and `put` into cache.
- Keep budget small (few frames) to minimize risk.
### Step 4 (small behavior): Pre-render window scheduling
- Add a render queue for time range [now, now+N] (N = 23s).
- Limit worker count (e.g., 23 tasks) to avoid UI starvation.
- Prioritize current frame > near future.
- On seek, cancel or drop stale tasks.
### Step 5 (behavior): LRU eviction policy
- Enforce memory budget and frame count cap.
- Evict least-recently-used entries.
### Step 6 (behavior): GPU/CPU policy
- Cache CPU frames by default for safety.
- For GL outputs, upload from cached CPU frame when displayed.
- Optionally add GPU caching later behind a feature flag.
### Step 7 (observability)
- Add counters for hit rate, average render time, and drops.
- Log only in debug builds.
## Proxy Clip Plan (Code Changes + Integration Points)
### Step 1 (compile-safe): Data model + serialization
- Extend clip metadata with:
- `proxy_path`, `proxy_width`, `proxy_height`, `proxy_codec`, `proxy_fps`.
- Add read/write in `app/node/project/serializer/*`.
### Step 2 (small behavior): Proxy selection policy
- Add project-level and clip-level proxy mode:
- `Auto`, `ForceProxy`, `ForceOriginal`.
- Add a simple resolver in clip/media source code that picks proxy if enabled.
### Step 3 (behavior): Proxy generation pipeline
- Add a background task to build proxies (using existing render/export tasks).
- Store output path and metadata on success.
### Step 4 (behavior): UI wiring
- Add “Generate Proxy” action + proxy indicator.
- Add “Relink Proxy” dialog.
### Step 5 (validation)
- Compare proxy vs original for timing and sync.
- Ensure proxies are ignored for export unless explicitly enabled.
## Small-Step Implementation Plan (Each Step Builds)
1) Add cache module + types (no references).
2) Add graph version counter (increment on changes).
3) Wire cache lookup for current frame only.
4) Add prerender queue (23 seconds) with limited concurrency.
5) Add LRU eviction + memory budget.
6) Add cache invalidation on graph version change.
7) Add basic metrics/logging.
8) Add proxy metadata fields + serialization.
9) Add proxy selection policy (Auto/Force modes).
10) Add proxy generation task + UI entry points.
## Open Questions
- Default cache size per hardware tier.
- Where to store proxy files on disk.
- Whether to cache GPU textures or CPU frames only.
+222 -192
View File
@@ -17,8 +17,8 @@
# Set Olive sources and resources
set(OLIVE_SOURCES
core.h
core.cpp
core.h
core.cpp
)
#set(OLIVE_RESOURCES)
@@ -47,15 +47,15 @@ add_subdirectory(window)
qt_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()
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
${OLIVE_RESOURCES}
${CMAKE_CURRENT_BINARY_DIR}/ts/translations.qrc
render/job/pluginjob.cpp
render/job/pluginjob.h
widget/nodeparamview/nodeparambutton.cpp
@@ -64,18 +64,18 @@ set(OLIVE_RESOURCES
# Add version object
add_library(olive-version-obj
OBJECT
version.cpp
version.h
OBJECT
version.cpp
version.h
)
target_link_libraries(olive-version-obj PRIVATE Qt${QT_VERSION_MAJOR}::Core)
target_compile_options(olive-version-obj PRIVATE -DAPPVERSION="${PROJECT_VERSION}" -DAPPVERSIONLONG="${PROJECT_LONG_VERSION}" )
target_compile_options(olive-version-obj PRIVATE -DAPPVERSION="${PROJECT_VERSION}" -DAPPVERSIONLONG="${PROJECT_LONG_VERSION}")
# Add main library
add_library(libolive-editor
OBJECT
${OLIVE_SOURCES}
${OLIVE_RESOURCES}
OBJECT
${OLIVE_SOURCES}
${OLIVE_RESOURCES}
)
add_subdirectory(common)
add_subdirectory(pluginSupport)
@@ -89,218 +89,248 @@ set_target_properties(libolive-editor PROPERTIES PREFIX "")
option(OAK_ENABLE_DYNAMIC_RENDER_BACKEND "Build and use the dynamic render backend adapter" ON)
if (OAK_ENABLE_DYNAMIC_RENDER_BACKEND)
set_target_properties(libolive-editor PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_compile_definitions(libolive-editor PRIVATE OAK_ENABLE_DYNAMIC_RENDER_BACKEND)
set_target_properties(libolive-editor PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_compile_definitions(libolive-editor PRIVATE OAK_ENABLE_DYNAMIC_RENDER_BACKEND)
foreach(target olivecore kddockwidgets)
if (TARGET ${target})
set_target_properties(${target} PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
endforeach()
foreach (target olivecore kddockwidgets)
if (TARGET ${target})
set_target_properties(${target} PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif ()
endforeach ()
# Render core library: the minimal set of code required by the OpenGL/Vulkan backend
# libraries. Keeping this separate from libolive-editor prevents the backends from
# dragging in editor-wide state (project, task, cache, UI, etc.).
add_library(libolive-rendercore STATIC
common/avframeptr.h
common/define.h
common/filefunctions.cpp
common/filefunctions.h
common/qtutils.cpp
common/qtutils.h
common/xmlutils.cpp
common/xmlutils.h
node/param.cpp
node/param.h
node/splitvalue.h
node/value.cpp
node/value.h
node/valuedatabase.cpp
node/valuedatabase.h
render/backend/dynamicrenderer.cpp
render/backend/dynamicrenderer.h
render/backend/renderbackend_c.h
render/job/acceleratedjob.cpp
render/job/acceleratedjob.h
render/job/shaderjob.h
render/renderer.cpp
render/renderer.h
render/shadercode.h
render/texture.cpp
render/texture.h
render/videoparams.cpp
render/videoparams.h
)
set_target_properties(libolive-rendercore PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(libolive-rendercore PUBLIC
${CMAKE_SOURCE_DIR}/app
${CMAKE_SOURCE_DIR}/third_party/openfx/include
${CMAKE_SOURCE_DIR}/third_party/openfx/HostSupport/include
${OLIVE_INCLUDE_DIRS}
)
target_link_libraries(libolive-rendercore PUBLIC ${OLIVE_LIBRARIES} OfxHost)
target_compile_definitions(libolive-rendercore PUBLIC ${OLIVE_DEFINITIONS})
target_compile_options(libolive-rendercore PUBLIC ${OLIVE_COMPILE_OPTIONS})
add_library(oakgl SHARED
render/opengl/openglbackend_c.cpp
render/opengl/openglrenderer.cpp
render/opengl/openglrenderer.h
)
target_link_libraries(oakgl PRIVATE libolive-rendercore)
target_compile_definitions(oakgl PRIVATE OAK_RENDER_BACKEND_PLUGIN)
set_target_properties(oakgl PROPERTIES
OUTPUT_NAME oakgl
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
install(TARGETS oakgl
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
if(Vulkan_FOUND)
add_library(oakvulkan SHARED
render/vulkan/vulkanbackend_c.cpp
render/vulkan/vulkanrenderer.cpp
render/vulkan/vulkanrenderer.h
# Render core library: the minimal set of code required by the OpenGL/Vulkan backend
# libraries. Keeping this separate from libolive-editor prevents the backends from
# dragging in editor-wide state (project, task, cache, UI, etc.).
add_library(libolive-rendercore STATIC
common/avframeptr.h
common/define.h
common/filefunctions.cpp
common/filefunctions.h
common/qtutils.cpp
common/qtutils.h
common/xmlutils.cpp
common/xmlutils.h
node/param.cpp
node/param.h
node/splitvalue.h
node/value.cpp
node/value.h
node/valuedatabase.cpp
node/valuedatabase.h
render/backend/dynamicrenderer.cpp
render/backend/dynamicrenderer.h
render/backend/renderbackend_c.h
render/job/acceleratedjob.cpp
render/job/acceleratedjob.h
render/job/shaderjob.h
render/renderer.cpp
render/renderer.h
render/shadercode.h
render/texture.cpp
render/texture.h
render/videoparams.cpp
render/videoparams.h
)
target_link_libraries(oakvulkan PRIVATE libolive-rendercore)
target_link_libraries(oakvulkan PRIVATE Vulkan::Vulkan)
target_compile_definitions(oakvulkan PRIVATE OAK_HAS_VULKAN)
if(SHADERC_FOUND)
target_link_libraries(oakvulkan PRIVATE ${SHADERC_LIBRARIES})
target_include_directories(oakvulkan PRIVATE ${SHADERC_INCLUDE_DIRS})
target_compile_definitions(oakvulkan PRIVATE OAK_HAS_SHADERC)
endif()
set_target_properties(oakvulkan PROPERTIES
OUTPUT_NAME oakvulkan
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
set_target_properties(libolive-rendercore PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(libolive-rendercore PUBLIC
${CMAKE_SOURCE_DIR}/app
${CMAKE_SOURCE_DIR}/third_party/openfx/include
${CMAKE_SOURCE_DIR}/third_party/openfx/HostSupport/include
${OLIVE_INCLUDE_DIRS}
)
install(TARGETS oakvulkan
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
target_link_libraries(libolive-rendercore PUBLIC ${OLIVE_LIBRARIES} OfxHost)
target_compile_definitions(libolive-rendercore PUBLIC ${OLIVE_DEFINITIONS})
target_compile_options(libolive-rendercore PUBLIC ${OLIVE_COMPILE_OPTIONS})
add_library(oakgl SHARED
render/opengl/openglbackend_c.cpp
render/opengl/openglrenderer.cpp
render/opengl/openglrenderer.h
)
endif()
endif()
target_link_libraries(oakgl PRIVATE libolive-rendercore)
target_compile_definitions(oakgl PRIVATE OAK_RENDER_BACKEND_PLUGIN)
set_target_properties(oakgl PROPERTIES
OUTPUT_NAME oakgl
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
if (WIN32)
set_target_properties(oakgl PROPERTIES PREFIX "")
endif ()
install(TARGETS oakgl
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
if (Vulkan_FOUND)
add_library(oakvulkan SHARED
render/vulkan/vulkanbackend_c.cpp
render/vulkan/vulkanrenderer.cpp
render/vulkan/vulkanrenderer.h
)
target_link_libraries(oakvulkan PRIVATE libolive-rendercore)
target_link_libraries(oakvulkan PRIVATE Vulkan::Vulkan)
target_compile_definitions(oakvulkan PRIVATE OAK_HAS_VULKAN)
if (SHADERC_FOUND)
target_link_libraries(oakvulkan PRIVATE ${SHADERC_LIBRARIES})
target_include_directories(oakvulkan PRIVATE ${SHADERC_INCLUDE_DIRS})
target_compile_definitions(oakvulkan PRIVATE OAK_HAS_SHADERC)
endif ()
set_target_properties(oakvulkan PROPERTIES
OUTPUT_NAME oakvulkan
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
if (WIN32)
set_target_properties(oakvulkan PROPERTIES PREFIX "")
endif ()
install(TARGETS oakvulkan
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
endif ()
endif ()
add_library(oakgl-cabi-check OBJECT
render/opengl/openglbackend_c.cpp
render/opengl/openglbackend_c.cpp
)
target_include_directories(oakgl-cabi-check PRIVATE
${CMAKE_SOURCE_DIR}/app
${CMAKE_SOURCE_DIR}/third_party/openfx/include
${CMAKE_SOURCE_DIR}/third_party/openfx/HostSupport/include
${OLIVE_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/app
${CMAKE_SOURCE_DIR}/third_party/openfx/include
${CMAKE_SOURCE_DIR}/third_party/openfx/HostSupport/include
${OLIVE_INCLUDE_DIRS}
)
target_link_libraries(oakgl-cabi-check PRIVATE ${OLIVE_LIBRARIES} OfxHost)
target_compile_definitions(oakgl-cabi-check PRIVATE ${OLIVE_DEFINITIONS})
target_compile_options(oakgl-cabi-check PRIVATE ${OLIVE_COMPILE_OPTIONS})
if(Vulkan_FOUND)
add_library(oakvulkan-cabi-check OBJECT
render/vulkan/vulkanbackend_c.cpp
render/vulkan/vulkanrenderer.cpp
render/vulkan/vulkanrenderer.h
)
target_include_directories(oakvulkan-cabi-check PRIVATE
${CMAKE_SOURCE_DIR}/app
${CMAKE_SOURCE_DIR}/third_party/openfx/include
${CMAKE_SOURCE_DIR}/third_party/openfx/HostSupport/include
${OLIVE_INCLUDE_DIRS}
)
target_link_libraries(oakvulkan-cabi-check PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets)
target_link_libraries(oakvulkan-cabi-check PRIVATE Vulkan::Vulkan)
target_compile_definitions(oakvulkan-cabi-check PRIVATE OAK_HAS_VULKAN)
if(SHADERC_FOUND)
target_link_libraries(oakvulkan-cabi-check PRIVATE ${SHADERC_LIBRARIES})
target_include_directories(oakvulkan-cabi-check PRIVATE ${SHADERC_INCLUDE_DIRS})
target_compile_definitions(oakvulkan-cabi-check PRIVATE OAK_HAS_SHADERC)
endif()
target_compile_definitions(oakvulkan-cabi-check PRIVATE ${OLIVE_DEFINITIONS})
target_compile_options(oakvulkan-cabi-check PRIVATE ${OLIVE_COMPILE_OPTIONS})
endif()
if (Vulkan_FOUND)
add_library(oakvulkan-cabi-check OBJECT
render/vulkan/vulkanbackend_c.cpp
render/vulkan/vulkanrenderer.cpp
render/vulkan/vulkanrenderer.h
)
target_include_directories(oakvulkan-cabi-check PRIVATE
${CMAKE_SOURCE_DIR}/app
${CMAKE_SOURCE_DIR}/third_party/openfx/include
${CMAKE_SOURCE_DIR}/third_party/openfx/HostSupport/include
${OLIVE_INCLUDE_DIRS}
)
target_link_libraries(oakvulkan-cabi-check PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets)
target_link_libraries(oakvulkan-cabi-check PRIVATE Vulkan::Vulkan)
target_compile_definitions(oakvulkan-cabi-check PRIVATE OAK_HAS_VULKAN)
if (SHADERC_FOUND)
target_link_libraries(oakvulkan-cabi-check PRIVATE ${SHADERC_LIBRARIES})
target_include_directories(oakvulkan-cabi-check PRIVATE ${SHADERC_INCLUDE_DIRS})
target_compile_definitions(oakvulkan-cabi-check PRIVATE OAK_HAS_SHADERC)
endif ()
target_compile_definitions(oakvulkan-cabi-check PRIVATE ${OLIVE_DEFINITIONS})
target_compile_options(oakvulkan-cabi-check PRIVATE ${OLIVE_COMPILE_OPTIONS})
endif ()
# Add application
add_executable(olive-editor
main.cpp
$<TARGET_OBJECTS:libolive-editor>
$<TARGET_OBJECTS:olive-version-obj>
main.cpp
$<TARGET_OBJECTS:libolive-editor>
$<TARGET_OBJECTS:olive-version-obj>
)
target_include_directories(olive-editor PUBLIC pluginSupport)
target_link_libraries(olive-editor PUBLIC OfxHost)
add_dependencies(olive-editor oakgl-cabi-check)
if (OAK_ENABLE_DYNAMIC_RENDER_BACKEND)
add_dependencies(olive-editor oakgl)
if (TARGET oakvulkan)
add_dependencies(olive-editor oakvulkan)
endif()
endif()
add_dependencies(olive-editor oakgl)
if (TARGET oakvulkan)
add_dependencies(olive-editor oakvulkan)
endif ()
endif ()
# Ensure the render worker is always built together with the editor on every platform.
add_dependencies(olive-editor olive-render-worker)
# Add render worker process (olive-render-worker).
set_target_properties(olive-editor PROPERTIES OUTPUT_NAME "oak-editor")
# Add render worker process (oak-render-worker).
# Reuses the libolive-editor object library so the worker shares the exact same render/node/codec
# code as the editor. It is a headless app that owns its own offscreen GL context. The link set is
# currently the full OLIVE_LIBRARIES for simplicity; trimming UI-only dependencies is a later-phase
# cleanup (see render-process-isolation plan).
add_executable(olive-render-worker
render/worker/workermain.cpp
$<TARGET_OBJECTS:libolive-editor>
$<TARGET_OBJECTS:olive-version-obj>
render/worker/workermain.cpp
$<TARGET_OBJECTS:libolive-editor>
$<TARGET_OBJECTS:olive-version-obj>
)
set_target_properties(olive-render-worker PROPERTIES OUTPUT_NAME "oak-render-worker")
if (APPLE)
target_sources(olive-render-worker PRIVATE render/worker/workermain_mac.mm)
target_link_libraries(olive-render-worker PRIVATE "-framework Cocoa")
endif ()
target_include_directories(olive-render-worker PUBLIC pluginSupport)
target_link_libraries(olive-render-worker PUBLIC OfxHost)
if (OAK_ENABLE_DYNAMIC_RENDER_BACKEND)
target_compile_definitions(olive-render-worker PRIVATE OAK_ENABLE_DYNAMIC_RENDER_BACKEND)
add_dependencies(olive-render-worker oakgl)
if (TARGET oakvulkan)
add_dependencies(olive-render-worker oakvulkan)
endif()
endif()
target_compile_definitions(olive-render-worker PRIVATE OAK_ENABLE_DYNAMIC_RENDER_BACKEND)
add_dependencies(olive-render-worker oakgl)
if (TARGET oakvulkan)
add_dependencies(olive-render-worker oakvulkan)
endif ()
endif ()
# Create docs if doxygen was found
if(DOXYGEN_FOUND)
set(DOXYGEN_PROJECT_NAME "Oak Video Editor")
set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/docs")
set(DOXYGEN_EXTRACT_ALL "YES")
set(DOXYGEN_EXTRACT_PRIVATE "YES")
doxygen_add_docs(docs ALL ${OLIVE_SOURCES})
endif()
if (DOXYGEN_FOUND)
set(DOXYGEN_PROJECT_NAME "Oak Video Editor")
set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/docs")
set(DOXYGEN_EXTRACT_ALL "YES")
set(DOXYGEN_EXTRACT_PRIVATE "YES")
doxygen_add_docs(docs ALL ${OLIVE_SOURCES})
endif ()
# Platform-specific deployment preferences
if (WIN32)
# Set Windows application icon
target_sources(olive-editor PRIVATE packaging/windows/resources.rc)
# Set Windows application icon
target_sources(olive-editor PRIVATE packaging/windows/resources.rc)
# Preserve folder structure in visual studio
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${OLIVE_SOURCES})
# Preserve folder structure in visual studio
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${OLIVE_SOURCES})
elseif(APPLE)
# Set Mac application icon
set(OLIVE_ICON packaging/macos/olive.icns)
target_sources(olive-editor PRIVATE ${OLIVE_ICON})
elseif (APPLE)
# Set Mac application icon
set(OLIVE_ICON packaging/macos/oak.icns)
target_sources(olive-editor PRIVATE ${OLIVE_ICON})
# Set Mac bundle properties
set_target_properties(olive-editor PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/packaging/macos/MacOSXBundleInfo.plist.in
MACOSX_BUNDLE_GUI_IDENTIFIER org.oakvideoeditor.Oak
MACOSX_BUNDLE_ICON_FILE olive.icns
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
MACOSX_BUNDLE_BUNDLE_NAME "Oak Video Editor"
MACOSX_BUNDLE_INFO_STRING "Oak Video Editor ${PROJECT_LONG_VERSION}"
MACOSX_BUNDLE_COPYRIGHT "©2018-2021 Olive Studios LLC and others. Fork maintained by Oak Video Editor Team."
RESOURCE "${OLIVE_ICON}"
OUTPUT_NAME "Olive"
)
elseif(UNIX)
# Set Linux-specific properties for application
install(TARGETS olive-editor RUNTIME DESTINATION bin)
endif()
# Set Mac bundle properties
set_target_properties(olive-editor PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/packaging/macos/MacOSXBundleInfo.plist.in
MACOSX_BUNDLE_GUI_IDENTIFIER org.oakvideoeditor.Oak
MACOSX_BUNDLE_ICON_FILE oak.icns
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
MACOSX_BUNDLE_BUNDLE_NAME "Oak Video Editor"
MACOSX_BUNDLE_INFO_STRING "Oak Video Editor ${PROJECT_LONG_VERSION}"
MACOSX_BUNDLE_COPYRIGHT "©2018-2021 Olive Studios LLC and others. Fork maintained by Oak Video Editor Team."
RESOURCE "${OLIVE_ICON}"
OUTPUT_NAME "Oak"
)
# Copy the render worker and dynamic render backends into the app bundle.
# They are looked up in QCoreApplication::applicationDirPath(), which on
# macOS points to Oak.app/Contents/MacOS.
add_custom_command(TARGET olive-editor POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_BUNDLE_DIR:olive-editor>/Contents/MacOS
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:olive-render-worker> $<TARGET_BUNDLE_DIR:olive-editor>/Contents/MacOS/
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:oakgl> $<TARGET_BUNDLE_DIR:olive-editor>/Contents/MacOS/
COMMENT "Copying oak-render-worker and render backends into Oak.app"
)
if (TARGET oakvulkan)
add_custom_command(TARGET olive-editor POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:oakvulkan> $<TARGET_BUNDLE_DIR:olive-editor>/Contents/MacOS/
)
endif ()
elseif (UNIX)
# Set Linux-specific properties for application
install(TARGETS olive-editor RUNTIME DESTINATION bin)
endif ()
# Set link libraries
target_link_libraries(olive-editor PRIVATE ${OLIVE_LIBRARIES})
@@ -324,10 +354,10 @@ target_include_directories(olive-render-worker PRIVATE ${OLIVE_INCLUDE_DIRS})
# Install the render worker alongside the editor on Linux.
if (UNIX AND NOT APPLE)
install(TARGETS olive-render-worker RUNTIME DESTINATION bin)
endif()
install(TARGETS olive-render-worker RUNTIME DESTINATION bin)
endif ()
# Add crash handler
if (GoogleCrashpad_FOUND AND Qt${QT_VERSION_MAJOR}Network_FOUND)
add_subdirectory(crashhandler)
endif()
add_subdirectory(crashhandler)
endif ()
+14 -14
View File
@@ -15,18 +15,18 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
audio/audiolevelmeter.cpp
audio/audiolevelmeter.h
audio/audiosynchronizer.cpp
audio/audiosynchronizer.h
audio/audiowaveformsync.cpp
audio/audiowaveformsync.h
audio/audiomanager.cpp
audio/audiomanager.h
audio/audioprocessor.cpp
audio/audioprocessor.h
audio/audiovisualwaveform.cpp
audio/audiovisualwaveform.h
PARENT_SCOPE
${OLIVE_SOURCES}
audio/audiolevelmeter.cpp
audio/audiolevelmeter.h
audio/audiosynchronizer.cpp
audio/audiosynchronizer.h
audio/audiowaveformsync.cpp
audio/audiowaveformsync.h
audio/audiomanager.cpp
audio/audiomanager.h
audio/audioprocessor.cpp
audio/audioprocessor.h
audio/audiovisualwaveform.cpp
audio/audiovisualwaveform.h
PARENT_SCOPE
)
+4 -3
View File
@@ -57,7 +57,8 @@ AudioLevelMeter::AnalyzeSampleBuffer(const core::SampleBuffer &samples)
square_sum += value * value;
}
const double mean_square = square_sum / static_cast<double>(sample_count);
const double mean_square =
square_sum / static_cast<double>(sample_count);
const double rms = std::sqrt(mean_square);
ChannelStats channel_stats;
@@ -74,8 +75,8 @@ AudioLevelMeter::AnalyzeSampleBuffer(const core::SampleBuffer &samples)
}
stats.silence = qFuzzyIsNull(stats.max_peak_linear);
stats.integrated_lufs = PowerToLufs(
total_square / static_cast<double>(total_samples));
stats.integrated_lufs =
PowerToLufs(total_square / static_cast<double>(total_samples));
return stats;
}
+5 -6
View File
@@ -28,8 +28,7 @@ AudioSynchronizer::Placement AudioSynchronizer::PlaceBySourceTime(
const core::rational &reference_timeline_in)
{
Placement placement;
if (!reference.has_source_start_time ||
!candidate.has_source_start_time ||
if (!reference.has_source_start_time || !candidate.has_source_start_time ||
reference.source_start_time.isNaN() ||
candidate.source_start_time.isNaN()) {
return placement;
@@ -55,10 +54,10 @@ AudioSynchronizer::Placement AudioSynchronizer::PlaceByWaveformOffset(
return placement;
}
placement.timeline_in =
reference_timeline_in +
core::rational::fromDouble(static_cast<double>(candidate_offset_samples) /
static_cast<double>(sample_rate));
placement.timeline_in = reference_timeline_in +
core::rational::fromDouble(
static_cast<double>(candidate_offset_samples) /
static_cast<double>(sample_rate));
placement.valid = !placement.timeline_in.isNaN();
return placement;
}
+6 -6
View File
@@ -41,13 +41,13 @@ public:
bool valid = false;
};
static Placement PlaceBySourceTime(const SourceClip &reference,
const SourceClip &candidate,
const core::rational &reference_timeline_in);
static Placement
PlaceBySourceTime(const SourceClip &reference, const SourceClip &candidate,
const core::rational &reference_timeline_in);
static Placement PlaceByWaveformOffset(
const core::rational &reference_timeline_in,
int64_t candidate_offset_samples, int sample_rate);
static Placement
PlaceByWaveformOffset(const core::rational &reference_timeline_in,
int64_t candidate_offset_samples, int sample_rate);
};
}
+3 -3
View File
@@ -96,7 +96,8 @@ AudioWaveformSync::OffsetResult AudioWaveformSync::EstimateEnvelopeOffset(
int64_t best_lag = 0;
for (int64_t lag = -max_offset_windows; lag <= max_offset_windows; lag++) {
const int reference_start = static_cast<int>(std::max<int64_t>(0, -lag));
const int reference_start =
static_cast<int>(std::max<int64_t>(0, -lag));
const int candidate_start = static_cast<int>(std::max<int64_t>(0, lag));
const int overlap = std::min(reference.size() - reference_start,
candidate.size() - candidate_start);
@@ -142,8 +143,7 @@ AudioWaveformSync::OffsetResult AudioWaveformSync::EstimateEnvelopeOffset(
if (best_score > -2.0) {
result.valid = true;
result.confidence = std::max(0.0, best_score);
result.offset_samples =
best_lag * static_cast<int64_t>(window_samples);
result.offset_samples = best_lag * static_cast<int64_t>(window_samples);
}
return result;
+2 -2
View File
@@ -38,8 +38,8 @@ public:
bool valid = false;
};
static QVector<double>
ExtractRmsEnvelope(const core::SampleBuffer &samples, size_t window_samples);
static QVector<double> ExtractRmsEnvelope(const core::SampleBuffer &samples,
size_t window_samples);
static OffsetResult EstimateOffset(const core::SampleBuffer &reference,
const core::SampleBuffer &candidate,
+2 -2
View File
@@ -18,6 +18,6 @@ add_subdirectory(cliprogress)
add_subdirectory(clitask)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
PARENT_SCOPE
${OLIVE_SOURCES}
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
cli/cliprogress/cliprogressdialog.h
cli/cliprogress/cliprogressdialog.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
cli/cliprogress/cliprogressdialog.h
cli/cliprogress/cliprogressdialog.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
cli/clitask/clitaskdialog.h
cli/clitask/clitaskdialog.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
cli/clitask/clitaskdialog.h
cli/clitask/clitaskdialog.cpp
PARENT_SCOPE
)
+20 -20
View File
@@ -18,24 +18,24 @@ add_subdirectory(ffmpeg)
add_subdirectory(oiio)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
codec/conformmanager.cpp
codec/conformmanager.h
codec/decoder.cpp
codec/decoder.h
codec/encoder.cpp
codec/encoder.h
codec/exportcodec.cpp
codec/exportcodec.h
codec/exportformat.cpp
codec/exportformat.h
codec/frame.cpp
codec/frame.h
codec/planarfiledevice.cpp
codec/planarfiledevice.h
codec/proxymanager.cpp
codec/proxymanager.h
codec/timecodemetadata.cpp
codec/timecodemetadata.h
PARENT_SCOPE
${OLIVE_SOURCES}
codec/conformmanager.cpp
codec/conformmanager.h
codec/decoder.cpp
codec/decoder.h
codec/encoder.cpp
codec/encoder.h
codec/exportcodec.cpp
codec/exportcodec.h
codec/exportformat.cpp
codec/exportformat.h
codec/frame.cpp
codec/frame.h
codec/planarfiledevice.cpp
codec/planarfiledevice.h
codec/proxymanager.cpp
codec/proxymanager.h
codec/timecodemetadata.cpp
codec/timecodemetadata.h
PARENT_SCOPE
)
+1 -1
View File
@@ -32,7 +32,7 @@ extern "C" {
#include <QWaitCondition>
#include <stdint.h>
#include "codec/frame.h"
#include "codec/frame.h"
#include "node/block/block.h"
#include "node/project/footage/footagedescription.h"
#include "render/cancelatom.h"
+6 -6
View File
@@ -15,10 +15,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
codec/ffmpeg/ffmpegdecoder.cpp
codec/ffmpeg/ffmpegdecoder.h
codec/ffmpeg/ffmpegencoder.cpp
codec/ffmpeg/ffmpegencoder.h
PARENT_SCOPE
${OLIVE_SOURCES}
codec/ffmpeg/ffmpegdecoder.cpp
codec/ffmpeg/ffmpegdecoder.h
codec/ffmpeg/ffmpegencoder.cpp
codec/ffmpeg/ffmpegencoder.h
PARENT_SCOPE
)
+127 -110
View File
@@ -25,11 +25,11 @@ extern "C" {
#include <libavutil/pixdesc.h>
}
namespace olive {
namespace olive
{
static FramePtr CopyPackedAVFrameToFrame(const AVFramePtr &src,
PixelFormat format,
int channel_count,
PixelFormat format, int channel_count,
const rational &timestamp)
{
if (!src || !src->data[0]) {
@@ -48,8 +48,7 @@ static FramePtr CopyPackedAVFrameToFrame(const AVFramePtr &src,
VideoParams::GetBytesPerPixel(format, channel_count);
for (int y = 0; y < frame->height(); y++) {
memcpy(frame->data() + y * frame->linesize_bytes(),
src->data[0] + y * src->linesize[0],
size_t(row_bytes));
src->data[0] + y * src->linesize[0], size_t(row_bytes));
}
return frame;
@@ -97,7 +96,8 @@ namespace olive
QVariant Yuv2RgbShader;
QVariant DeinterlaceShader;
namespace {
namespace
{
constexpr int64_t kAnalyzeDurationUs = 5000000;
constexpr int64_t kProbeSizeBytes = 20000000;
@@ -133,8 +133,9 @@ void DiscardSubtitleStreams(AVFormatContext *ctx)
}
}
TimecodeMetadata::SourceTime ExtractSourceStartTime(
AVDictionary *metadata, const rational &timebase, int sample_rate)
TimecodeMetadata::SourceTime ExtractSourceStartTime(AVDictionary *metadata,
const rational &timebase,
int sample_rate)
{
if (!metadata) {
return TimecodeMetadata::SourceTime();
@@ -423,7 +424,7 @@ TexturePtr FFmpegDecoder::RetrieveVideoInternal(const RetrieveVideoParams &p)
// Perform any CPU processing required
AVFramePtr ptr = PreProcessFrame(f, p);
f=std::move(ptr);
f = std::move(ptr);
if (!f) {
qWarning() << "PreProcessFrame failed";
return nullptr;
@@ -458,14 +459,15 @@ FramePtr FFmpegDecoder::RetrieveVideoFrameInternal(const RetrieveVideoParams &p)
AVFramePtr dest = CreateAVFramePtr();
dest->width = f->width;
dest->height = f->height;
dest->format = p.maximum_format == PixelFormat::U8
? AV_PIX_FMT_RGBA
: AV_PIX_FMT_RGBA64;
dest->format = p.maximum_format == PixelFormat::U8 ? AV_PIX_FMT_RGBA :
AV_PIX_FMT_RGBA64;
dest->color_range = f->color_range;
dest->colorspace = f->colorspace;
if (p.divider > 1) {
dest->width = VideoParams::GetScaledDimension(dest->width, p.divider);
dest->height = VideoParams::GetScaledDimension(dest->height, p.divider);
dest->width =
VideoParams::GetScaledDimension(dest->width, p.divider);
dest->height =
VideoParams::GetScaledDimension(dest->height, p.divider);
}
int r = av_frame_get_buffer(dest.get(), 0);
@@ -504,8 +506,8 @@ FramePtr FFmpegDecoder::RetrieveVideoFrameInternal(const RetrieveVideoParams &p)
// zero-initializes the destination, leaving alpha at 0. The color
// management shader later multiplies RGB by alpha, producing black.
// Ensure alpha is opaque for source formats that have no alpha.
const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(
static_cast<AVPixelFormat>(f->format));
const AVPixFmtDescriptor *src_desc =
av_pix_fmt_desc_get(static_cast<AVPixelFormat>(f->format));
if (src_desc && !(src_desc->flags & AV_PIX_FMT_FLAG_ALPHA)) {
const int bpc = (dest->format == AV_PIX_FMT_RGBA) ? 1 : 2;
const int stride = dest->linesize[0];
@@ -522,11 +524,10 @@ FramePtr FFmpegDecoder::RetrieveVideoFrameInternal(const RetrieveVideoParams &p)
}
return CopyPackedAVFrameToFrame(dest,
dest->format == AV_PIX_FMT_RGBA
? PixelFormat::U8
: PixelFormat::U16,
VideoParams::kRGBAChannelCount,
p.time);
dest->format == AV_PIX_FMT_RGBA ?
PixelFormat::U8 :
PixelFormat::U16,
VideoParams::kRGBAChannelCount, p.time);
}
return nullptr;
@@ -580,7 +581,8 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename,
AVFormatContext *fmt_ctx = nullptr;
AVDictionary *format_opts = nullptr;
ApplyFormatOpenOptions(&format_opts);
error_code = avformat_open_input(&fmt_ctx, filename_c, nullptr, &format_opts);
error_code =
avformat_open_input(&fmt_ctx, filename_c, nullptr, &format_opts);
av_dict_free(&format_opts);
TuneFormatContext(fmt_ctx);
DiscardSubtitleStreams(fmt_ctx);
@@ -591,9 +593,8 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename,
avformat_find_stream_info(fmt_ctx, nullptr);
int64_t footage_duration = fmt_ctx->duration;
TimecodeMetadata::SourceTime source_start_time =
ExtractSourceStartTime(fmt_ctx->metadata, rational(1, AV_TIME_BASE),
0);
TimecodeMetadata::SourceTime source_start_time = ExtractSourceStartTime(
fmt_ctx->metadata, rational(1, AV_TIME_BASE), 0);
bool duration_guessed_from_bitrate =
(fmt_ctx->duration_estimation_method ==
@@ -625,78 +626,87 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename,
avstream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
if (avstream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
{
// Read at least two frames to get more information about this video stream
AVPacket *pkt = av_packet_alloc();
AVFrame *frame = av_frame_alloc();
// Read at least two frames to get more information about this video stream
AVPacket *pkt = av_packet_alloc();
AVFrame *frame = av_frame_alloc();
VideoParams::Interlacing interlacing = VideoParams::kInterlaceNone;
AVRational pixel_aspect_ratio = {1, 1};
AVRational frame_rate = avstream->avg_frame_rate;
AVPixelFormat compatible_pix_fmt =
FFmpegUtils::GetCompatiblePixelFormat(
static_cast<AVPixelFormat>(avstream->codecpar->format));
bool image_is_still = false;
VideoParams::Interlacing interlacing =
VideoParams::kInterlaceNone;
AVRational pixel_aspect_ratio = { 1, 1 };
AVRational frame_rate = avstream->avg_frame_rate;
AVPixelFormat compatible_pix_fmt =
FFmpegUtils::GetCompatiblePixelFormat(
static_cast<AVPixelFormat>(
avstream->codecpar->format));
bool image_is_still = false;
{
Instance instance;
if (instance.Open(filename_c, avstream->index) != 0)
goto cleanup;
{
Instance instance;
if (instance.Open(filename_c, avstream->index) != 0)
goto cleanup;
AVCodecContext *avctx = instance.codec_ctx();
interlacing = FFmpegFieldOrderToOlive(avctx->field_order);
AVCodecContext *avctx = instance.codec_ctx();
interlacing =
FFmpegFieldOrderToOlive(avctx->field_order);
if (instance.GetFrame(pkt, frame) >= 0) {
pixel_aspect_ratio =
av_guess_sample_aspect_ratio(instance.fmt_ctx(),
instance.avstream(), frame);
frame_rate =
av_guess_frame_rate(instance.fmt_ctx(),
instance.avstream(), frame);
}
if (instance.GetFrame(pkt, frame) >= 0) {
pixel_aspect_ratio =
av_guess_sample_aspect_ratio(
instance.fmt_ctx(), instance.avstream(),
frame);
frame_rate = av_guess_frame_rate(
instance.fmt_ctx(), instance.avstream(),
frame);
}
int ret = instance.GetFrame(pkt, frame);
if (ret == AVERROR_EOF) {
image_is_still = true;
} else if (avstream->duration == AV_NOPTS_VALUE ||
duration_guessed_from_bitrate) {
int64_t last_ts = frame->best_effort_timestamp;
while (instance.GetFrame(pkt, frame) >= 0 &&
(!cancelled || !cancelled->IsCancelled()))
last_ts = frame->best_effort_timestamp;
avstream->duration = last_ts;
}
int ret = instance.GetFrame(pkt, frame);
if (ret == AVERROR_EOF) {
image_is_still = true;
} else if (avstream->duration == AV_NOPTS_VALUE ||
duration_guessed_from_bitrate) {
int64_t last_ts = frame->best_effort_timestamp;
while (
instance.GetFrame(pkt, frame) >= 0 &&
(!cancelled || !cancelled->IsCancelled()))
last_ts = frame->best_effort_timestamp;
avstream->duration = last_ts;
}
instance.Close();
}
instance.Close();
}
cleanup:
av_frame_free(&frame);
av_packet_free(&pkt);
cleanup:
av_frame_free(&frame);
av_packet_free(&pkt);
VideoParams stream;
stream.set_stream_index(i);
stream.set_width(avstream->codecpar->width);
stream.set_height(avstream->codecpar->height);
stream.set_video_type(image_is_still ? VideoParams::kVideoTypeStill
: VideoParams::kVideoTypeVideo);
stream.set_format(GetNativePixelFormat(compatible_pix_fmt));
stream.set_channel_count(GetNativeChannelCount(compatible_pix_fmt));
stream.set_interlacing(interlacing); // <-- 已正确填充
stream.set_pixel_aspect_ratio(pixel_aspect_ratio);
stream.set_frame_rate(frame_rate);
stream.set_start_time(avstream->start_time);
stream.set_time_base(avstream->time_base);
stream.set_duration(avstream->duration);
stream.set_color_range(avstream->codecpar->color_range == AVCOL_RANGE_JPEG
? VideoParams::kColorRangeFull
: VideoParams::kColorRangeLimited);
stream.set_premultiplied_alpha(false);
VideoParams stream;
stream.set_stream_index(i);
stream.set_width(avstream->codecpar->width);
stream.set_height(avstream->codecpar->height);
stream.set_video_type(image_is_still ?
VideoParams::kVideoTypeStill :
VideoParams::kVideoTypeVideo);
stream.set_format(
GetNativePixelFormat(compatible_pix_fmt));
stream.set_channel_count(
GetNativeChannelCount(compatible_pix_fmt));
stream.set_interlacing(interlacing); // <-- 已正确填充
stream.set_pixel_aspect_ratio(pixel_aspect_ratio);
stream.set_frame_rate(frame_rate);
stream.set_start_time(avstream->start_time);
stream.set_time_base(avstream->time_base);
stream.set_duration(avstream->duration);
stream.set_color_range(
avstream->codecpar->color_range ==
AVCOL_RANGE_JPEG ?
VideoParams::kColorRangeFull :
VideoParams::kColorRangeLimited);
stream.set_premultiplied_alpha(false);
desc.AddVideoStream(stream);
image_is_still ? still_streams++ : video_streams++;
desc.AddVideoStream(stream);
image_is_still ? still_streams++ : video_streams++;
}
} else if (avstream->codecpar->codec_type ==
AVMEDIA_TYPE_AUDIO) {
// Create an audio stream object
@@ -837,7 +847,7 @@ bool FFmpegDecoder::ConformAudioInternal(const QVector<QString> &filenames,
}
// Create resampling context
AVChannelLayout layout = params.channel_layout();
SwrContext *resampler=NULL;
SwrContext *resampler = NULL;
swr_alloc_set_opts2(
&resampler, &layout,
FFmpegUtils::GetFFmpegSampleFormat(params.format()),
@@ -1270,14 +1280,14 @@ AVFramePtr FFmpegDecoder::RetrieveFrame(const rational &time,
AVFramePtr FFmpegDecoder::TransferHardwareFrame(AVFramePtr f)
{
if (!instance_.hwaccel_enabled() ||
f->format != instance_.hw_pix_fmt()) {
if (!instance_.hwaccel_enabled() || f->format != instance_.hw_pix_fmt()) {
return f;
}
AVFrame *sw_frame = av_frame_alloc();
if (!sw_frame) {
qCritical() << "Failed to allocate software frame for hardware transfer";
qCritical()
<< "Failed to allocate software frame for hardware transfer";
return nullptr;
}
@@ -1291,8 +1301,9 @@ AVFramePtr FFmpegDecoder::TransferHardwareFrame(AVFramePtr f)
ret = av_frame_copy_props(sw_frame, f.get());
if (ret < 0) {
qWarning() << "Failed to copy frame properties during hardware transfer:"
<< FFmpegError(ret);
qWarning()
<< "Failed to copy frame properties during hardware transfer:"
<< FFmpegError(ret);
}
return CreateAVFramePtr(sw_frame);
@@ -1372,7 +1383,8 @@ bool FFmpegDecoder::Instance::Open(const char *filename, int stream_index)
// Open file in a format context
AVDictionary *format_opts = nullptr;
ApplyFormatOpenOptions(&format_opts);
int error_code = avformat_open_input(&fmt_ctx_, filename, nullptr, &format_opts);
int error_code =
avformat_open_input(&fmt_ctx_, filename, nullptr, &format_opts);
av_dict_free(&format_opts);
TuneFormatContext(fmt_ctx_);
DiscardSubtitleStreams(fmt_ctx_);
@@ -1420,7 +1432,7 @@ bool FFmpegDecoder::Instance::Open(const char *filename, int stream_index)
// Handle failure to copy parameters
if (error_code < 0) {
qCritical()
<< "Failed to copy parameters from AVStream to AVCodecContext";
<< "Failed to copy parameters from AVStream to AVCodecContext";
return false;
}
@@ -1437,13 +1449,14 @@ bool FFmpegDecoder::Instance::Open(const char *filename, int stream_index)
error_code = avcodec_open2(codec_ctx_, codec, &opts_);
if (error_code == 0) {
hwaccel_enabled_ = true;
qDebug() << "Hardware decoding enabled for" << filename
<< "using" << av_hwdevice_get_type_name(hw_device_type_)
qDebug() << "Hardware decoding enabled for" << filename << "using"
<< av_hwdevice_get_type_name(hw_device_type_)
<< "pixel format" << av_get_pix_fmt_name(hw_pix_fmt_);
return true;
}
qWarning() << "Failed to open hardware codec, falling back to software decoding:";
qWarning()
<< "Failed to open hardware codec, falling back to software decoding:";
char buf[512];
av_strerror(error_code, buf, 512);
qWarning() << FFmpegError(error_code) << buf;
@@ -1454,11 +1467,13 @@ bool FFmpegDecoder::Instance::Open(const char *filename, int stream_index)
codec_ctx_ = avcodec_alloc_context3(codec);
if (codec_ctx_ == nullptr) {
qCritical() << "Failed to allocate codec context for software fallback";
qCritical()
<< "Failed to allocate codec context for software fallback";
return false;
}
error_code = avcodec_parameters_to_context(codec_ctx_, avstream_->codecpar);
error_code =
avcodec_parameters_to_context(codec_ctx_, avstream_->codecpar);
if (error_code < 0) {
qCritical()
<< "Failed to copy parameters from AVStream to AVCodecContext";
@@ -1494,25 +1509,26 @@ AVHWDeviceType FFmpegDecoder::Instance::ChooseHardwareDevice()
}
}
#elif defined(Q_OS_WIN)
for (AVHWDeviceType type : { AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DXVA2,
AV_HWDEVICE_TYPE_CUDA }) {
for (AVHWDeviceType type :
{ AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DXVA2,
AV_HWDEVICE_TYPE_CUDA }) {
if (av_hwdevice_find_type_by_name(av_hwdevice_get_type_name(type)) !=
AV_HWDEVICE_TYPE_NONE) {
return type;
}
}
#elif defined(Q_OS_MACOS)
if (av_hwdevice_find_type_by_name(
av_hwdevice_get_type_name(AV_HWDEVICE_TYPE_VIDEOTOOLBOX)) !=
AV_HWDEVICE_TYPE_NONE) {
if (av_hwdevice_find_type_by_name(av_hwdevice_get_type_name(
AV_HWDEVICE_TYPE_VIDEOTOOLBOX)) != AV_HWDEVICE_TYPE_NONE) {
return AV_HWDEVICE_TYPE_VIDEOTOOLBOX;
}
#endif
return AV_HWDEVICE_TYPE_NONE;
}
AVPixelFormat FFmpegDecoder::Instance::GetHardwareFormat(
AVCodecContext *ctx, const AVPixelFormat *pix_fmts)
AVPixelFormat
FFmpegDecoder::Instance::GetHardwareFormat(AVCodecContext *ctx,
const AVPixelFormat *pix_fmts)
{
const Instance *inst = static_cast<const Instance *>(ctx->opaque);
for (const AVPixelFormat *p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
@@ -1521,7 +1537,8 @@ AVPixelFormat FFmpegDecoder::Instance::GetHardwareFormat(
}
}
qWarning() << "Hardware pixel format not supported by decoder, using first software format";
qWarning()
<< "Hardware pixel format not supported by decoder, using first software format";
return pix_fmts[0];
}
@@ -1547,9 +1564,9 @@ bool FFmpegDecoder::Instance::InitHardwareAcceleration(const AVCodec *codec)
}
if (hw_pix_fmt_ == AV_PIX_FMT_NONE) {
qDebug() << "Codec" << codec->id
<< "does not support hardware device type"
<< av_hwdevice_get_type_name(device_type);
qDebug()
<< "Codec" << codec->id << "does not support hardware device type"
<< av_hwdevice_get_type_name(device_type);
return false;
}
+3 -2
View File
@@ -74,7 +74,8 @@ protected:
virtual bool OpenInternal() override;
virtual TexturePtr
RetrieveVideoInternal(const RetrieveVideoParams &p) override;
virtual FramePtr RetrieveVideoFrameInternal(const RetrieveVideoParams &p) override;
virtual FramePtr
RetrieveVideoFrameInternal(const RetrieveVideoParams &p) override;
virtual bool ConformAudioInternal(const QVector<QString> &filenames,
const AudioParams &params,
CancelAtom *cancelled) override;
@@ -145,7 +146,7 @@ private:
private:
static AVHWDeviceType ChooseHardwareDevice();
static AVPixelFormat GetHardwareFormat(AVCodecContext *ctx,
const AVPixelFormat *pix_fmts);
const AVPixelFormat *pix_fmts);
bool InitHardwareAcceleration(const AVCodec *codec);
void CleanupHardwareAcceleration();
+6 -6
View File
@@ -15,10 +15,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
codec/oiio/oiiodecoder.cpp
codec/oiio/oiiodecoder.h
codec/oiio/oiioencoder.cpp
codec/oiio/oiioencoder.h
PARENT_SCOPE
${OLIVE_SOURCES}
codec/oiio/oiiodecoder.cpp
codec/oiio/oiiodecoder.h
codec/oiio/oiioencoder.cpp
codec/oiio/oiioencoder.h
PARENT_SCOPE
)
+2 -1
View File
@@ -185,7 +185,8 @@ FramePtr OIIODecoder::RetrieveVideoFrameInternal(const RetrieveVideoParams &p)
if (!frame->allocate()) {
return nullptr;
}
memcpy(frame->data(), buffer_.const_data(), size_t(buffer_.allocated_size()));
memcpy(frame->data(), buffer_.const_data(),
size_t(buffer_.allocated_size()));
return frame;
}
+2 -1
View File
@@ -51,7 +51,8 @@ protected:
virtual bool OpenInternal() override;
virtual TexturePtr
RetrieveVideoInternal(const RetrieveVideoParams &p) override;
virtual FramePtr RetrieveVideoFrameInternal(const RetrieveVideoParams &p) override;
virtual FramePtr
RetrieveVideoFrameInternal(const RetrieveVideoParams &p) override;
virtual void CloseInternal() override;
private:
+13 -15
View File
@@ -52,14 +52,12 @@ QString ProxyManager::GetProxyFilename(const QString &cache_path,
const QString proxy_dir = GetProxyDirectory(cache_path);
const QString extension =
params.extension.isEmpty() ? QStringLiteral("mp4") : params.extension;
const QString filename = QStringLiteral("%1-%2.%3x%4.v%5.%6")
.arg(FileFunctions::GetUniqueFileIdentifier(
source_filename),
QString::number(stream_index),
QString::number(params.width),
QString::number(params.height),
QString::number(params.version),
extension);
const QString filename =
QStringLiteral("%1-%2.%3x%4.v%5.%6")
.arg(FileFunctions::GetUniqueFileIdentifier(source_filename),
QString::number(stream_index), QString::number(params.width),
QString::number(params.height),
QString::number(params.version), extension);
return QDir(proxy_dir).filePath(filename);
}
@@ -119,9 +117,10 @@ ProxyManager::ProxyStateFromString(const QString &state)
return kProxyMissing;
}
ProxyManager::Proxy ProxyManager::GetOrStartProxy(
const QString &cache_path, const QString &source_filename,
int stream_index, const ProxyParams &params)
ProxyManager::Proxy
ProxyManager::GetOrStartProxy(const QString &cache_path,
const QString &source_filename, int stream_index,
const ProxyParams &params)
{
QMutexLocker locker(&mutex_);
@@ -145,10 +144,9 @@ ProxyManager::Proxy ProxyManager::GetOrStartProxy(
}
const QString working_filename = GetWorkingProxyFilename(filename);
ProxyTask *task = new ProxyTask(source_filename, stream_index, params,
working_filename);
connect(task, &Task::Finished, this,
&ProxyManager::ProxyTaskFinished);
ProxyTask *task =
new ProxyTask(source_filename, stream_index, params, working_filename);
connect(task, &Task::Finished, this, &ProxyManager::ProxyTaskFinished);
task->moveToThread(TaskManager::instance()->thread());
QMetaObject::invokeMethod(TaskManager::instance(), "AddTask",
Qt::QueuedConnection, Q_ARG(Task *, task));
+1 -2
View File
@@ -90,8 +90,7 @@ public:
static ProxyState ProxyStateFromString(const QString &state);
Proxy GetOrStartProxy(const QString &cache_path,
const QString &source_filename,
int stream_index,
const QString &source_filename, int stream_index,
const ProxyParams &params);
signals:
+10 -9
View File
@@ -28,8 +28,9 @@
namespace olive
{
TimecodeMetadata::SourceTime TimecodeMetadata::FromTimecodeString(
const QString &timecode, const core::rational &timebase)
TimecodeMetadata::SourceTime
TimecodeMetadata::FromTimecodeString(const QString &timecode,
const core::rational &timebase)
{
SourceTime result;
const QString trimmed = timecode.trimmed();
@@ -39,8 +40,8 @@ TimecodeMetadata::SourceTime TimecodeMetadata::FromTimecodeString(
bool ok = false;
const core::Timecode::Display display =
trimmed.contains(';') ? core::Timecode::kTimecodeDropFrame
: core::Timecode::kTimecodeNonDropFrame;
trimmed.contains(';') ? core::Timecode::kTimecodeDropFrame :
core::Timecode::kTimecodeNonDropFrame;
result.time = core::Timecode::timecode_to_time(trimmed.toStdString(),
timebase, display, &ok);
result.valid = ok;
@@ -50,8 +51,9 @@ TimecodeMetadata::SourceTime TimecodeMetadata::FromTimecodeString(
return result;
}
TimecodeMetadata::SourceTime TimecodeMetadata::FromBwfTimeReference(
const QString &time_reference, int sample_rate)
TimecodeMetadata::SourceTime
TimecodeMetadata::FromBwfTimeReference(const QString &time_reference,
int sample_rate)
{
SourceTime result;
if (sample_rate <= 0) {
@@ -73,9 +75,8 @@ TimecodeMetadata::SourceTime TimecodeMetadata::FromBwfTimeReference(
const qulonglong rational_limit =
static_cast<qulonglong>(std::numeric_limits<int>::max());
if (numerator <= rational_limit && denominator <= rational_limit) {
result.time =
core::rational(static_cast<int>(numerator),
static_cast<int>(denominator));
result.time = core::rational(static_cast<int>(numerator),
static_cast<int>(denominator));
} else {
result.time = core::rational::fromDouble(
static_cast<double>(samples) / static_cast<double>(sample_rate));
+38 -38
View File
@@ -16,42 +16,42 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
target_sources(libolive-editor PRIVATE
cancelableobject.h
channellayout.h
commandlineparser.cpp
commandlineparser.h
crashpadinterface.cpp
crashpadinterface.h
crashpadutils.h
Current.cpp
Current.h
debug.cpp
debug.h
decibel.h
define.h
ffmpegutils.cpp
ffmpegutils.h
filefunctions.cpp
filefunctions.h
html.cpp
html.h
jobtime.cpp
jobtime.h
lerp.h
memorypool.h
ocioutils.cpp
ocioutils.h
oiioutils.cpp
oiioutils.h
otioutils.h
qtutils.cpp
qtutils.h
range.h
ratiodialog.cpp
ratiodialog.h
threadsafemap.h
tohex.h
util.h
xmlutils.cpp
xmlutils.h
cancelableobject.h
channellayout.h
commandlineparser.cpp
commandlineparser.h
crashpadinterface.cpp
crashpadinterface.h
crashpadutils.h
Current.cpp
Current.h
debug.cpp
debug.h
decibel.h
define.h
ffmpegutils.cpp
ffmpegutils.h
filefunctions.cpp
filefunctions.h
html.cpp
html.h
jobtime.cpp
jobtime.h
lerp.h
memorypool.h
ocioutils.cpp
ocioutils.h
oiioutils.cpp
oiioutils.h
otioutils.h
qtutils.cpp
qtutils.h
range.h
ratiodialog.cpp
ratiodialog.h
threadsafemap.h
tohex.h
util.h
xmlutils.cpp
xmlutils.h
)
+10 -10
View File
@@ -25,31 +25,31 @@
class Current {
public:
static Current& getInstance()
static Current &getInstance()
{
return current;
}
olive::VideoParams& currentVideoParams()
olive::VideoParams &currentVideoParams()
{
return currentVideoParams_;
}
olive::AudioParams& currentAudioParams()
olive::AudioParams &currentAudioParams()
{
return currentAudioParams_;
}
void setCurrentVideoParams(olive::VideoParams& params)
void setCurrentVideoParams(olive::VideoParams &params)
{
currentVideoParams_ = params;
}
void setCurrentAudioParams(olive::AudioParams& params)
void setCurrentAudioParams(olive::AudioParams &params)
{
currentAudioParams_ = params;
}
void setCurrentVideoParams(olive::VideoParams&& params)
void setCurrentVideoParams(olive::VideoParams &&params)
{
currentVideoParams_ = params;
}
void setCurrentAudioParams(olive::AudioParams&& params)
void setCurrentAudioParams(olive::AudioParams &&params)
{
currentAudioParams_ = params;
}
@@ -73,10 +73,12 @@ public:
return plugin_cache_;
}
void setPluginCache(std::shared_ptr<OFX::Host::ImageEffect::PluginCache> cache)
void
setPluginCache(std::shared_ptr<OFX::Host::ImageEffect::PluginCache> cache)
{
plugin_cache_ = cache;
}
private:
static Current current;
olive::VideoParams currentVideoParams_;
@@ -85,6 +87,4 @@ private:
std::shared_ptr<OFX::Host::ImageEffect::PluginCache> plugin_cache_;
};
#endif //CURRENT_H
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
config/config.h
config/config.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
config/config.h
config/config.cpp
PARENT_SCOPE
)
+2 -2
View File
@@ -341,8 +341,8 @@ void Config::Load()
// Config::Load() is called before Core (and therefore the main window)
// is constructed, so we cannot use Core::instance()->main_window() as
// the message box parent. Passing nullptr creates a top-level dialog.
QWidget *parent = Core::instance() ? Core::instance()->main_window()
: nullptr;
QWidget *parent = Core::instance() ? Core::instance()->main_window() :
nullptr;
QMessageBox::critical(
parent,
QCoreApplication::translate("Config", "Error loading settings"),
+23 -23
View File
@@ -80,37 +80,37 @@
#include "widget/menu/menushared.h"
#include "window/mainwindow/mainwindow.h"
namespace {
namespace
{
QStringList FootageVideoExtensions()
{
return QStringList{
QStringLiteral("mp4"), QStringLiteral("mov"), QStringLiteral("m4v"),
QStringLiteral("avi"), QStringLiteral("mpg"), QStringLiteral("mpeg"),
QStringLiteral("m2ts"), QStringLiteral("mts"), QStringLiteral("ts"),
QStringLiteral("webm"), QStringLiteral("wmv"), QStringLiteral("flv"),
QStringLiteral("3gp"), QStringLiteral("3g2"), QStringLiteral("mxf")
QStringLiteral("mp4"), QStringLiteral("mov"), QStringLiteral("m4v"),
QStringLiteral("avi"), QStringLiteral("mpg"), QStringLiteral("mpeg"),
QStringLiteral("m2ts"), QStringLiteral("mts"), QStringLiteral("ts"),
QStringLiteral("webm"), QStringLiteral("wmv"), QStringLiteral("flv"),
QStringLiteral("3gp"), QStringLiteral("3g2"), QStringLiteral("mxf")
};
}
QStringList FootageAudioExtensions()
{
return QStringList{
QStringLiteral("wav"), QStringLiteral("mp3"), QStringLiteral("flac"),
QStringLiteral("aac"), QStringLiteral("ogg"), QStringLiteral("opus"),
QStringLiteral("m4a"), QStringLiteral("alac"), QStringLiteral("aif"),
QStringLiteral("aiff"), QStringLiteral("aifc"), QStringLiteral("wma")
};
return QStringList{ QStringLiteral("wav"), QStringLiteral("mp3"),
QStringLiteral("flac"), QStringLiteral("aac"),
QStringLiteral("ogg"), QStringLiteral("opus"),
QStringLiteral("m4a"), QStringLiteral("alac"),
QStringLiteral("aif"), QStringLiteral("aiff"),
QStringLiteral("aifc"), QStringLiteral("wma") };
}
QStringList FootageImageExtensions()
{
return QStringList{
QStringLiteral("png"), QStringLiteral("jpg"), QStringLiteral("jpeg"),
QStringLiteral("tif"), QStringLiteral("tiff"), QStringLiteral("bmp"),
QStringLiteral("gif"), QStringLiteral("exr"), QStringLiteral("dpx"),
QStringLiteral("webp")
};
return QStringList{ QStringLiteral("png"), QStringLiteral("jpg"),
QStringLiteral("jpeg"), QStringLiteral("tif"),
QStringLiteral("tiff"), QStringLiteral("bmp"),
QStringLiteral("gif"), QStringLiteral("exr"),
QStringLiteral("dpx"), QStringLiteral("webp") };
}
QString BuildFootageFilterGroup(const QString &label,
@@ -122,8 +122,8 @@ QString BuildFootageFilterGroup(const QString &label,
patterns.append(QStringLiteral("*.%1").arg(ext));
}
return QStringLiteral("%1 (%2)")
.arg(label, patterns.join(QLatin1Char(' ')));
return QStringLiteral("%1 (%2)").arg(label,
patterns.join(QLatin1Char(' ')));
}
QString BuildFootageFileDialogFilter()
@@ -457,9 +457,9 @@ void Core::DialogAboutShow()
void Core::DialogImportShow()
{
// Open dialog for user to select files
QStringList files = QFileDialog::getOpenFileNames(
main_window_, tr("Import footage..."), QString(),
FootageFileDialogFilter());
QStringList files =
QFileDialog::getOpenFileNames(main_window_, tr("Import footage..."),
QString(), FootageFileDialogFilter());
// Check if the user actually selected files to import
if (!files.isEmpty()) {
+31 -28
View File
@@ -16,50 +16,53 @@
# Create crash handler executable
add_executable(
olive-crashhandler
crashhandler.cpp
crashhandler.h
$<TARGET_OBJECTS:olive-version-obj>
olive-crashhandler
crashhandler.cpp
crashhandler.h
$<TARGET_OBJECTS:olive-version-obj>
)
# Rename the generated binary to oak-crashhandler so it matches the Oak branding.
set_target_properties(olive-crashhandler PROPERTIES OUTPUT_NAME "oak-crashhandler")
# Disable console appearing on crash handler dialog
set_target_properties(olive-crashhandler PROPERTIES
WIN32_EXECUTABLE TRUE
WIN32_EXECUTABLE TRUE
)
# Set crash handler includes
target_include_directories(
olive-crashhandler
PRIVATE
${CMAKE_SOURCE_DIR}/app
${CRASHPAD_INCLUDE_DIRS}
olive-crashhandler
PRIVATE
${CMAKE_SOURCE_DIR}/app
${CRASHPAD_INCLUDE_DIRS}
)
# Set crash handler libs
target_link_libraries(
olive-crashhandler
PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Network
${CRASHPAD_LIBRARIES}
olive-crashhandler
PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Network
${CRASHPAD_LIBRARIES}
)
set(CRASHPAD_HANDLER "crashpad_handler${CMAKE_EXECUTABLE_SUFFIX}")
set(MINIDUMP_STACKWALK "minidump_stackwalk${CMAKE_EXECUTABLE_SUFFIX}")
if(APPLE)
# Move crash handler executables inside Mac app bundle
add_custom_command(TARGET olive-crashhandler POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different olive-crashhandler $<TARGET_FILE_DIR:olive-editor>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CRASHPAD_LIBRARY_DIRS}/${CRASHPAD_HANDLER} $<TARGET_FILE_DIR:olive-editor>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${BREAKPAD_BIN_DIR}/${MINIDUMP_STACKWALK} $<TARGET_FILE_DIR:olive-editor>
)
elseif(UNIX)
install(TARGETS olive-crashhandler RUNTIME DESTINATION bin)
install(PROGRAMS ${CRASHPAD_LIBRARY_DIRS}/${CRASHPAD_HANDLER} DESTINATION bin)
install(PROGRAMS ${BREAKPAD_BIN_DIR}/${MINIDUMP_STACKWALK} DESTINATION bin)
endif()
if (APPLE)
# Move crash handler executables inside Mac app bundle
add_custom_command(TARGET olive-crashhandler POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:olive-crashhandler> $<TARGET_FILE_DIR:olive-editor>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CRASHPAD_LIBRARY_DIRS}/${CRASHPAD_HANDLER} $<TARGET_FILE_DIR:olive-editor>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${BREAKPAD_BIN_DIR}/${MINIDUMP_STACKWALK} $<TARGET_FILE_DIR:olive-editor>
)
elseif (UNIX)
install(TARGETS olive-crashhandler RUNTIME DESTINATION bin)
install(PROGRAMS ${CRASHPAD_LIBRARY_DIRS}/${CRASHPAD_HANDLER} DESTINATION bin)
install(PROGRAMS ${BREAKPAD_BIN_DIR}/${MINIDUMP_STACKWALK} DESTINATION bin)
endif ()
target_compile_definitions(olive-crashhandler PRIVATE ${OLIVE_DEFINITIONS})
+9 -9
View File
@@ -54,9 +54,9 @@ CrashHandlerDialog::CrashHandlerDialog(const QString &report_path)
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(new QLabel(
tr("We're sorry, Oak Video Editor has crashed. Please help us fix it by "
"sending an error report.")));
layout->addWidget(new QLabel(tr(
"We're sorry, Oak Video Editor has crashed. Please help us fix it by "
"sending an error report.")));
QSplitter *splitter = new QSplitter(Qt::Vertical);
splitter->setChildrenCollapsible(false);
@@ -124,7 +124,7 @@ QString CrashHandlerDialog::GetSymbolPath()
#elif BUILDFLAG(IS_LINUX)
app_path.cdUp();
symbols_path =
app_path.filePath(QStringLiteral("share/olive-editor/symbols"));
app_path.filePath(QStringLiteral("share/oak-editor/symbols"));
#elif BUILDFLAG(IS_APPLE)
app_path.cdUp();
symbols_path = app_path.filePath(QStringLiteral("Resources/symbols"));
@@ -291,11 +291,11 @@ void CrashHandlerDialog::SendErrorReport()
QString symbol_bin_name;
#if BUILDFLAG(IS_WIN)
symbol_bin_name = QStringLiteral("olive-editor.pdb");
symbol_bin_name = QStringLiteral("oak-editor.pdb");
#elif BUILDFLAG(IS_APPLE)
symbol_bin_name = QStringLiteral("Olive");
symbol_bin_name = QStringLiteral("Oak");
#else
symbol_bin_name = QStringLiteral("olive-editor");
symbol_bin_name = QStringLiteral("oak-editor");
#endif
symbol_dir = QDir(symbol_dir.filePath(symbol_bin_name));
@@ -320,9 +320,9 @@ void CrashHandlerDialog::SendErrorReport()
// Create sym section
QString symbol_filename;
#if BUILDFLAG(IS_APPLE)
symbol_filename = QStringLiteral("Olive.sym");
symbol_filename = QStringLiteral("Oak.sym");
#else
symbol_filename = QStringLiteral("olive-editor.sym");
symbol_filename = QStringLiteral("oak-editor.sym");
#endif
QString symbol_full_path = symbol_dir.filePath(symbol_filename);
QHttpPart sym_part;
+5 -5
View File
@@ -25,9 +25,9 @@ add_subdirectory(footageproperties)
add_subdirectory(footagerelink)
add_subdirectory(keyframeproperties)
add_subdirectory(markerproperties)
if(OpenTimelineIO_FOUND)
add_subdirectory(otioproperties)
endif()
if (OpenTimelineIO_FOUND)
add_subdirectory(otioproperties)
endif ()
add_subdirectory(preferences)
add_subdirectory(progress)
add_subdirectory(projectproperties)
@@ -38,6 +38,6 @@ add_subdirectory(task)
add_subdirectory(text)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
PARENT_SCOPE
${OLIVE_SOURCES}
PARENT_SCOPE
)
+7 -7
View File
@@ -15,11 +15,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/about/about.cpp
dialog/about/about.h
dialog/about/patreon.h
dialog/about/scrollinglabel.cpp
dialog/about/scrollinglabel.h
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/about/about.cpp
dialog/about/about.h
dialog/about/patreon.h
dialog/about/scrollinglabel.cpp
dialog/about/scrollinglabel.h
PARENT_SCOPE
)
+7 -6
View File
@@ -66,12 +66,13 @@ AboutDialog::AboutDialog(bool welcome_dialog, QWidget *parent)
"<p>%3</p>" // Description
"<p>%4</p>" // Fork notice
"</body></html>")
.arg(QApplication::applicationName(),
QApplication::applicationVersion(),
tr("Oak Video Editor is a free open source non-linear video editor. "
"This software is licensed under the GNU GPL Version 3."),
tr("This project is a fork of "
"<a href=\"https://github.com/olive-editor/olive\">Olive Video Editor</a>.")));
.arg(
QApplication::applicationName(),
QApplication::applicationVersion(),
tr("Oak Video Editor is a free open source non-linear video editor. "
"This software is licensed under the GNU GPL Version 3."),
tr("This project is a fork of "
"<a href=\"https://github.com/olive-editor/olive\">Olive Video Editor</a>.")));
// Set text formatting
label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+8 -7
View File
@@ -57,7 +57,7 @@ url = 'https://www.patreon.com/api/oauth2/v2/campaigns/1478705/members?include=c
name_list = ''
while True:
member_data = requests.get(url, headers = {"authorization": "Bearer " + os.environ.get('PATREON_KEY')})
member_data = requests.get(url, headers={"authorization": "Bearer " + os.environ.get('PATREON_KEY')})
member_data_decoded = json.loads(member_data.text)
for member in member_data_decoded["data"]:
@@ -68,16 +68,17 @@ while True:
name = member["attributes"]["full_name"]
name_list += " QStringLiteral(\""
name_list += name.translate(str.maketrans({
"\"": "\\\"",
"\\": "\\\\"
}))
"\"": "\\\"",
"\\": "\\\\"
}))
name_list += "\")"
if "links" in member_data_decoded:
url = member_data_decoded["links"]["next"]
url = member_data_decoded["links"]["next"]
else:
break
break
text_file = open("patreon.h", "w", encoding="utf-8")
text_file.write("#ifndef PATREON_H\n#define PATREON_H\n\n#include <QStringList>\n\nQStringList patrons = {\n%s\n};\n\n#endif // PATREON_H\n" % name_list)
text_file.write(
"#ifndef PATREON_H\n#define PATREON_H\n\n#include <QStringList>\n\nQStringList patrons = {\n%s\n};\n\n#endif // PATREON_H\n" % name_list)
text_file.close()
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/actionsearch/actionsearch.h
dialog/actionsearch/actionsearch.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/actionsearch/actionsearch.h
dialog/actionsearch/actionsearch.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/autorecovery/autorecoverydialog.h
dialog/autorecovery/autorecoverydialog.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/autorecovery/autorecoverydialog.h
dialog/autorecovery/autorecoverydialog.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/color/colordialog.h
dialog/color/colordialog.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/color/colordialog.h
dialog/color/colordialog.cpp
PARENT_SCOPE
)
+6 -6
View File
@@ -15,10 +15,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/configbase/configdialogbase.cpp
dialog/configbase/configdialogbase.h
dialog/configbase/configdialogbasetab.cpp
dialog/configbase/configdialogbasetab.h
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/configbase/configdialogbase.cpp
dialog/configbase/configdialogbase.h
dialog/configbase/configdialogbasetab.cpp
dialog/configbase/configdialogbasetab.h
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/diskcache/diskcachedialog.h
dialog/diskcache/diskcachedialog.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/diskcache/diskcachedialog.h
dialog/diskcache/diskcachedialog.cpp
PARENT_SCOPE
)
-1
View File
@@ -26,7 +26,6 @@
#include <QLabel>
#include <QMessageBox>
namespace olive
{
+16 -16
View File
@@ -17,20 +17,20 @@
add_subdirectory(codec)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/export/export.cpp
dialog/export/export.h
dialog/export/exportadvancedvideodialog.cpp
dialog/export/exportadvancedvideodialog.h
dialog/export/exportaudiotab.cpp
dialog/export/exportaudiotab.h
dialog/export/exportformatcombobox.cpp
dialog/export/exportformatcombobox.h
dialog/export/exportsavepresetdialog.cpp
dialog/export/exportsavepresetdialog.h
dialog/export/exportsubtitlestab.cpp
dialog/export/exportsubtitlestab.h
dialog/export/exportvideotab.cpp
dialog/export/exportvideotab.h
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/export/export.cpp
dialog/export/export.h
dialog/export/exportadvancedvideodialog.cpp
dialog/export/exportadvancedvideodialog.h
dialog/export/exportaudiotab.cpp
dialog/export/exportaudiotab.h
dialog/export/exportformatcombobox.cpp
dialog/export/exportformatcombobox.h
dialog/export/exportsavepresetdialog.cpp
dialog/export/exportsavepresetdialog.h
dialog/export/exportsubtitlestab.cpp
dialog/export/exportsubtitlestab.h
dialog/export/exportvideotab.cpp
dialog/export/exportvideotab.h
PARENT_SCOPE
)
+14 -14
View File
@@ -15,18 +15,18 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/export/codec/av1section.cpp
dialog/export/codec/av1section.h
dialog/export/codec/cineformsection.cpp
dialog/export/codec/cineformsection.h
dialog/export/codec/codecsection.cpp
dialog/export/codec/codecsection.h
dialog/export/codec/codecstack.cpp
dialog/export/codec/codecstack.h
dialog/export/codec/h264section.cpp
dialog/export/codec/h264section.h
dialog/export/codec/imagesection.cpp
dialog/export/codec/imagesection.h
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/export/codec/av1section.cpp
dialog/export/codec/av1section.h
dialog/export/codec/cineformsection.cpp
dialog/export/codec/cineformsection.h
dialog/export/codec/codecsection.cpp
dialog/export/codec/codecsection.h
dialog/export/codec/codecstack.cpp
dialog/export/codec/codecstack.h
dialog/export/codec/h264section.cpp
dialog/export/codec/h264section.h
dialog/export/codec/imagesection.cpp
dialog/export/codec/imagesection.h
PARENT_SCOPE
)
-1
View File
@@ -24,7 +24,6 @@
#include <QGridLayout>
#include <QLabel>
namespace olive
{
+4 -4
View File
@@ -17,8 +17,8 @@
add_subdirectory(streamproperties)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/footageproperties/footageproperties.cpp
dialog/footageproperties/footageproperties.h
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/footageproperties/footageproperties.cpp
dialog/footageproperties/footageproperties.h
PARENT_SCOPE
)
@@ -15,12 +15,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/footageproperties/streamproperties/streamproperties.h
dialog/footageproperties/streamproperties/streamproperties.cpp
dialog/footageproperties/streamproperties/audiostreamproperties.h
dialog/footageproperties/streamproperties/audiostreamproperties.cpp
dialog/footageproperties/streamproperties/videostreamproperties.h
dialog/footageproperties/streamproperties/videostreamproperties.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/footageproperties/streamproperties/streamproperties.h
dialog/footageproperties/streamproperties/streamproperties.cpp
dialog/footageproperties/streamproperties/audiostreamproperties.h
dialog/footageproperties/streamproperties/audiostreamproperties.cpp
dialog/footageproperties/streamproperties/videostreamproperties.h
dialog/footageproperties/streamproperties/videostreamproperties.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/footagerelink/footagerelinkdialog.h
dialog/footagerelink/footagerelinkdialog.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/footagerelink/footagerelinkdialog.h
dialog/footagerelink/footagerelinkdialog.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/keyframeproperties/keyframeproperties.h
dialog/keyframeproperties/keyframeproperties.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/keyframeproperties/keyframeproperties.h
dialog/keyframeproperties/keyframeproperties.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/markerproperties/markerpropertiesdialog.h
dialog/markerproperties/markerpropertiesdialog.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/markerproperties/markerpropertiesdialog.h
dialog/markerproperties/markerpropertiesdialog.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/otioproperties/otiopropertiesdialog.h
dialog/otioproperties/otiopropertiesdialog.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/otioproperties/otiopropertiesdialog.h
dialog/otioproperties/otiopropertiesdialog.cpp
PARENT_SCOPE
)
+6 -6
View File
@@ -17,10 +17,10 @@
add_subdirectory(tabs)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/preferences/keysequenceeditor.h
dialog/preferences/keysequenceeditor.cpp
dialog/preferences/preferences.h
dialog/preferences/preferences.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/preferences/keysequenceeditor.h
dialog/preferences/keysequenceeditor.cpp
dialog/preferences/preferences.h
dialog/preferences/preferences.cpp
PARENT_SCOPE
)
+9 -6
View File
@@ -46,16 +46,19 @@ PreferencesDialog::PreferencesDialog(MainWindow *main_window, int start_tab)
AddTab(new PreferencesGeneralTab(), tr("General"));
AddTab(new PreferencesAppearanceTab(), tr("Appearance"));
AddTab(new PreferencesAudioTab(), tr("Audio"));
AddTab(new PreferencesBehaviorTab(PreferencesBehaviorTab::kCategoryTimeline),
tr("Timeline"));
AddTab(new PreferencesBehaviorTab(PreferencesBehaviorTab::kCategoryPlayback),
tr("Playback"));
AddTab(
new PreferencesBehaviorTab(PreferencesBehaviorTab::kCategoryTimeline),
tr("Timeline"));
AddTab(
new PreferencesBehaviorTab(PreferencesBehaviorTab::kCategoryPlayback),
tr("Playback"));
AddTab(new PreferencesBehaviorTab(PreferencesBehaviorTab::kCategoryProject),
tr("Project"));
AddTab(new PreferencesBehaviorTab(PreferencesBehaviorTab::kCategoryNodes),
tr("Nodes"));
AddTab(new PreferencesBehaviorTab(PreferencesBehaviorTab::kCategoryRendering),
tr("Rendering"));
AddTab(
new PreferencesBehaviorTab(PreferencesBehaviorTab::kCategoryRendering),
tr("Rendering"));
AddTab(new PreferencesDiskTab(), tr("Disk"));
AddTab(new PreferencesKeyboardTab(main_window), tr("Keyboard"));
+14 -14
View File
@@ -15,18 +15,18 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/preferences/tabs/preferencesgeneraltab.h
dialog/preferences/tabs/preferencesgeneraltab.cpp
dialog/preferences/tabs/preferencesbehaviortab.h
dialog/preferences/tabs/preferencesbehaviortab.cpp
dialog/preferences/tabs/preferencesdisktab.h
dialog/preferences/tabs/preferencesdisktab.cpp
dialog/preferences/tabs/preferencesappearancetab.h
dialog/preferences/tabs/preferencesappearancetab.cpp
dialog/preferences/tabs/preferencesaudiotab.h
dialog/preferences/tabs/preferencesaudiotab.cpp
dialog/preferences/tabs/preferenceskeyboardtab.h
dialog/preferences/tabs/preferenceskeyboardtab.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/preferences/tabs/preferencesgeneraltab.h
dialog/preferences/tabs/preferencesgeneraltab.cpp
dialog/preferences/tabs/preferencesbehaviortab.h
dialog/preferences/tabs/preferencesbehaviortab.cpp
dialog/preferences/tabs/preferencesdisktab.h
dialog/preferences/tabs/preferencesdisktab.cpp
dialog/preferences/tabs/preferencesappearancetab.h
dialog/preferences/tabs/preferencesappearancetab.cpp
dialog/preferences/tabs/preferencesaudiotab.h
dialog/preferences/tabs/preferencesaudiotab.cpp
dialog/preferences/tabs/preferenceskeyboardtab.h
dialog/preferences/tabs/preferenceskeyboardtab.cpp
PARENT_SCOPE
)
@@ -40,8 +40,7 @@ PreferencesBehaviorTab::PreferencesBehaviorTab(Category category)
AddItems({
{ tr("Auto-Seek to Imported Clips"),
QStringLiteral("EnableSeekToImport") },
{ tr("Edit Tool Also Seeks"),
QStringLiteral("EditToolAlsoSeeks") },
{ tr("Edit Tool Also Seeks"), QStringLiteral("EditToolAlsoSeeks") },
{ tr("Edit Tool Selects Links"),
QStringLiteral("EditToolSelectsLinks") },
{ tr("Enable Drag Files to Timeline"),
@@ -83,8 +82,7 @@ PreferencesBehaviorTab::PreferencesBehaviorTab(Category category)
});
break;
case kCategoryRendering:
{
case kCategoryRendering: {
QLabel *backend_label = new QLabel(tr("Graphics Backend"));
backend_label->setToolTip(
tr("Selects the graphics API Oak should request on next launch. "
@@ -94,17 +92,16 @@ PreferencesBehaviorTab::PreferencesBehaviorTab(Category category)
graphics_backend_combobox_ = new QComboBox();
graphics_backend_combobox_->addItem(tr("OpenGL"),
QStringLiteral("opengl"));
QStringLiteral("opengl"));
graphics_backend_combobox_->addItem(tr("Vulkan (experimental)"),
QStringLiteral("vulkan"));
QStringLiteral("vulkan"));
const QString current_backend =
OLIVE_CONFIG("GraphicsBackend").toString().toLower();
const int backend_index = graphics_backend_combobox_->findData(
current_backend.isEmpty() ? QStringLiteral("opengl")
: current_backend);
graphics_backend_combobox_->setCurrentIndex(backend_index >= 0
? backend_index
: 0);
current_backend.isEmpty() ? QStringLiteral("opengl") :
current_backend);
graphics_backend_combobox_->setCurrentIndex(
backend_index >= 0 ? backend_index : 0);
QHBoxLayout *backend_layout = new QHBoxLayout();
backend_layout->addWidget(backend_label);
@@ -49,7 +49,8 @@ public:
static QString BehaviorPrefTr(const char *text)
{
return QCoreApplication::translate("olive::PreferencesBehaviorTab", text);
return QCoreApplication::translate("olive::PreferencesBehaviorTab",
text);
}
private:
@@ -105,16 +105,14 @@ PreferencesDiskTab::PreferencesDiskTab()
proxy_width_slider_ = new IntegerSlider();
proxy_width_slider_->SetMinimum(160);
proxy_width_slider_->SetMaximum(4096);
proxy_width_slider_->SetValue(
OLIVE_CONFIG("ProxyWidth").value<int>());
proxy_width_slider_->SetValue(OLIVE_CONFIG("ProxyWidth").value<int>());
proxy_layout->addWidget(proxy_width_slider_, proxy_row, 1);
proxy_layout->addWidget(new QLabel(tr("Proxy Height:")), proxy_row, 2);
proxy_height_slider_ = new IntegerSlider();
proxy_height_slider_->SetMinimum(120);
proxy_height_slider_->SetMaximum(2160);
proxy_height_slider_->SetValue(
OLIVE_CONFIG("ProxyHeight").value<int>());
proxy_height_slider_->SetValue(OLIVE_CONFIG("ProxyHeight").value<int>());
proxy_layout->addWidget(proxy_height_slider_, proxy_row, 3);
proxy_row++;
@@ -123,28 +121,22 @@ PreferencesDiskTab::PreferencesDiskTab()
proxy_crf_slider_ = new IntegerSlider();
proxy_crf_slider_->SetMinimum(0);
proxy_crf_slider_->SetMaximum(51);
proxy_crf_slider_->SetValue(
OLIVE_CONFIG("ProxyCRF").value<int>());
proxy_crf_slider_->SetValue(OLIVE_CONFIG("ProxyCRF").value<int>());
proxy_layout->addWidget(proxy_crf_slider_, proxy_row, 1);
proxy_layout->addWidget(new QLabel(tr("Proxy Preset:")), proxy_row, 2);
proxy_preset_combo_ = new QComboBox();
const QStringList presets = {
QStringLiteral("ultrafast"),
QStringLiteral("superfast"),
QStringLiteral("veryfast"),
QStringLiteral("faster"),
QStringLiteral("fast"),
QStringLiteral("medium"),
QStringLiteral("slow"),
QStringLiteral("slower"),
QStringLiteral("ultrafast"), QStringLiteral("superfast"),
QStringLiteral("veryfast"), QStringLiteral("faster"),
QStringLiteral("fast"), QStringLiteral("medium"),
QStringLiteral("slow"), QStringLiteral("slower"),
QStringLiteral("veryslow"),
};
for (const QString &preset : presets) {
proxy_preset_combo_->addItem(preset);
}
proxy_preset_combo_->setCurrentText(
OLIVE_CONFIG("ProxyPreset").toString());
proxy_preset_combo_->setCurrentText(OLIVE_CONFIG("ProxyPreset").toString());
proxy_layout->addWidget(proxy_preset_combo_, proxy_row, 3);
outer_layout->addStretch();
@@ -185,8 +177,10 @@ void PreferencesDiskTab::Accept(MultiUndoCommand *command)
OLIVE_CONFIG("DiskCacheAhead") = QVariant::fromValue(
rational::fromDouble(cache_ahead_slider_->GetValue()));
OLIVE_CONFIG("ProxyWidth") = static_cast<int>(proxy_width_slider_->GetValue());
OLIVE_CONFIG("ProxyHeight") = static_cast<int>(proxy_height_slider_->GetValue());
OLIVE_CONFIG("ProxyWidth") =
static_cast<int>(proxy_width_slider_->GetValue());
OLIVE_CONFIG("ProxyHeight") =
static_cast<int>(proxy_height_slider_->GetValue());
OLIVE_CONFIG("ProxyCRF") = static_cast<int>(proxy_crf_slider_->GetValue());
OLIVE_CONFIG("ProxyPreset") = proxy_preset_combo_->currentText();
}
@@ -169,21 +169,25 @@ PreferencesGeneralTab::PreferencesGeneralTab()
}
{
QGroupBox *behavior_groupbox = new QGroupBox(PreferencesBehaviorTab::BehaviorPrefTr("Behavior"));
QGroupBox *behavior_groupbox =
new QGroupBox(PreferencesBehaviorTab::BehaviorPrefTr("Behavior"));
QVBoxLayout *behavior_layout = new QVBoxLayout(behavior_groupbox);
layout->addWidget(behavior_groupbox);
hover_focus_ = new QCheckBox(PreferencesBehaviorTab::BehaviorPrefTr("Enable hover focus"));
hover_focus_ = new QCheckBox(
PreferencesBehaviorTab::BehaviorPrefTr("Enable hover focus"));
hover_focus_->setToolTip(PreferencesBehaviorTab::BehaviorPrefTr(
"Panels will be considered focused when the mouse cursor is over them without having to click them."));
hover_focus_->setChecked(OLIVE_CONFIG("HoverFocus").toBool());
behavior_layout->addWidget(hover_focus_);
slider_ladder_ = new QCheckBox(PreferencesBehaviorTab::BehaviorPrefTr("Enable slider ladder"));
slider_ladder_ = new QCheckBox(
PreferencesBehaviorTab::BehaviorPrefTr("Enable slider ladder"));
slider_ladder_->setChecked(OLIVE_CONFIG("UseSliderLadders").toBool());
behavior_layout->addWidget(slider_ladder_);
scroll_zooms_ = new QCheckBox(PreferencesBehaviorTab::BehaviorPrefTr("Scrolling zooms by default"));
scroll_zooms_ = new QCheckBox(PreferencesBehaviorTab::BehaviorPrefTr(
"Scrolling zooms by default"));
scroll_zooms_->setToolTip(PreferencesBehaviorTab::BehaviorPrefTr(
"By default, scrolling will move the view around, and holding Ctrl/Cmd will make it zoom instead. "
"Enabling this will switch those, scrolling will zoom by default, and holding Ctrl/Cmd will move the view instead."));
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/progress/progress.h
dialog/progress/progress.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/progress/progress.h
dialog/progress/progress.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/projectproperties/projectproperties.h
dialog/projectproperties/projectproperties.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/projectproperties/projectproperties.h
dialog/projectproperties/projectproperties.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/rendercancel/rendercancel.h
dialog/rendercancel/rendercancel.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/rendercancel/rendercancel.h
dialog/rendercancel/rendercancel.cpp
PARENT_SCOPE
)
+10 -10
View File
@@ -15,14 +15,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/sequence/presetmanager.h
dialog/sequence/sequence.h
dialog/sequence/sequence.cpp
dialog/sequence/sequencedialogparametertab.h
dialog/sequence/sequencedialogparametertab.cpp
dialog/sequence/sequencedialogpresettab.h
dialog/sequence/sequencedialogpresettab.cpp
dialog/sequence/sequencepreset.h
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/sequence/presetmanager.h
dialog/sequence/sequence.h
dialog/sequence/sequence.cpp
dialog/sequence/sequencedialogparametertab.h
dialog/sequence/sequencedialogparametertab.cpp
dialog/sequence/sequencedialogpresettab.h
dialog/sequence/sequencedialogpresettab.cpp
dialog/sequence/sequencepreset.h
PARENT_SCOPE
)
@@ -23,7 +23,6 @@
#include <QPushButton>
#include <QVBoxLayout>
namespace olive
{
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/speedduration/speeddurationdialog.cpp
dialog/speedduration/speeddurationdialog.h
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/speedduration/speeddurationdialog.cpp
dialog/speedduration/speeddurationdialog.h
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/task/task.h
dialog/task/task.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/task/task.h
dialog/task/task.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/text/text.h
dialog/text/text.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
dialog/text/text.h
dialog/text/text.cpp
PARENT_SCOPE
)
-1
View File
@@ -27,7 +27,6 @@
#include <QPushButton>
#include <QVBoxLayout>
namespace olive
{
+8 -8
View File
@@ -148,14 +148,15 @@ int decompress_project(const QString &project)
int main(int argc, char *argv[])
{
// Set up debug handler
qInstallMessageHandler(olive::DebugHandler);
// Ignore SIGPIPE so that writing to a render-worker process that has
// already crashed/closed does not terminate the main application. QProcess
// will report the failure through its normal error path instead.
#if !defined(_WIN32)
signal(SIGPIPE, SIG_IGN);
#endif
// Set application metadata
QCoreApplication::setOrganizationName("oakvideoeditor.org");
@@ -227,8 +228,7 @@ int main(int argc, char *argv[])
auto no_plugin = parser.AddOption(
{ QStringLiteral("-no-plugin") },
QCoreApplication::translate("main", "Don't load plugins")
);
QCoreApplication::translate("main", "Don't load plugins"));
// Qt options re-implemented (add to this as necessary)
//
@@ -350,13 +350,13 @@ int main(int argc, char *argv[])
olive::Config::Current()[QStringLiteral("GraphicsBackend")]
.toString()
.toLower();
qputenv("QSG_RHI_BACKEND",
graphics_backend == QStringLiteral("vulkan")
? QByteArrayLiteral("vulkan")
: QByteArrayLiteral("opengl"));
qputenv("QSG_RHI_BACKEND", graphics_backend == QStringLiteral("vulkan") ?
QByteArrayLiteral("vulkan") :
QByteArrayLiteral("opengl"));
if (auto *gui_app = qobject_cast<QGuiApplication *>(a.get())) {
gui_app->setWindowIcon(QIcon(QStringLiteral(":/graphics/oak-logo.png")));
gui_app->setWindowIcon(
QIcon(QStringLiteral(":/graphics/oak-logo.png")));
}
if (load_plugins) {
+27 -27
View File
@@ -33,31 +33,31 @@ add_subdirectory(project)
add_subdirectory(time)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/factory.cpp
node/factory.h
node/globals.cpp
node/globals.h
node/inputdragger.cpp
node/inputdragger.h
node/inputimmediate.cpp
node/inputimmediate.h
node/keyframe.cpp
node/keyframe.h
node/node.cpp
node/node.h
node/nodeundo.cpp
node/nodeundo.h
node/param.cpp
node/param.h
node/project.cpp
node/project.h
node/splitvalue.h
node/traverser.cpp
node/traverser.h
node/value.cpp
node/value.h
node/valuedatabase.cpp
node/valuedatabase.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/factory.cpp
node/factory.h
node/globals.cpp
node/globals.h
node/inputdragger.cpp
node/inputdragger.h
node/inputimmediate.cpp
node/inputimmediate.h
node/keyframe.cpp
node/keyframe.h
node/node.cpp
node/node.h
node/nodeundo.cpp
node/nodeundo.h
node/param.cpp
node/param.h
node/project.cpp
node/project.h
node/splitvalue.h
node/traverser.cpp
node/traverser.h
node/value.cpp
node/value.h
node/valuedatabase.cpp
node/valuedatabase.h
PARENT_SCOPE
)
+2 -2
View File
@@ -18,6 +18,6 @@ add_subdirectory(pan)
add_subdirectory(volume)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
PARENT_SCOPE
${OLIVE_SOURCES}
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/audio/pan/pan.h
node/audio/pan/pan.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
node/audio/pan/pan.h
node/audio/pan/pan.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/audio/volume/volume.h
node/audio/volume/volume.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
node/audio/volume/volume.h
node/audio/volume/volume.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -20,8 +20,8 @@ add_subdirectory(subtitle)
add_subdirectory(transition)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/block/block.h
node/block/block.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
node/block/block.h
node/block/block.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/block/clip/clip.h
node/block/clip/clip.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
node/block/clip/clip.h
node/block/clip/clip.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/block/gap/gap.h
node/block/gap/gap.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
node/block/gap/gap.h
node/block/gap/gap.cpp
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/block/subtitle/subtitle.cpp
node/block/subtitle/subtitle.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/block/subtitle/subtitle.cpp
node/block/subtitle/subtitle.h
PARENT_SCOPE
)
+4 -4
View File
@@ -18,8 +18,8 @@ add_subdirectory(crossdissolve)
add_subdirectory(diptocolor)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/block/transition/transition.h
node/block/transition/transition.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
node/block/transition/transition.h
node/block/transition/transition.cpp
PARENT_SCOPE
)
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/block/transition/crossdissolve/crossdissolvetransition.h
node/block/transition/crossdissolve/crossdissolvetransition.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
node/block/transition/crossdissolve/crossdissolvetransition.h
node/block/transition/crossdissolve/crossdissolvetransition.cpp
PARENT_SCOPE
)
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/block/transition/diptocolor/diptocolortransition.h
node/block/transition/diptocolor/diptocolortransition.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
node/block/transition/diptocolor/diptocolortransition.h
node/block/transition/diptocolor/diptocolortransition.cpp
PARENT_SCOPE
)
+2 -2
View File
@@ -22,6 +22,6 @@ add_subdirectory(ociolut)
add_subdirectory(threewaycolor)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
PARENT_SCOPE
${OLIVE_SOURCES}
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/color/colormanager/colormanager.cpp
node/color/colormanager/colormanager.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/color/colormanager/colormanager.cpp
node/color/colormanager/colormanager.h
PARENT_SCOPE
)
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/color/displaytransform/displaytransform.cpp
node/color/displaytransform/displaytransform.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/color/displaytransform/displaytransform.cpp
node/color/displaytransform/displaytransform.h
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/color/ociobase/ociobase.cpp
node/color/ociobase/ociobase.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/color/ociobase/ociobase.cpp
node/color/ociobase/ociobase.h
PARENT_SCOPE
)
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/color/ociogradingtransformlinear/ociogradingtransformlinear.cpp
node/color/ociogradingtransformlinear/ociogradingtransformlinear.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/color/ociogradingtransformlinear/ociogradingtransformlinear.cpp
node/color/ociogradingtransformlinear/ociogradingtransformlinear.h
PARENT_SCOPE
)
+4 -4
View File
@@ -7,8 +7,8 @@
# (at your option) any later version.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/color/ociolut/ociolut.cpp
node/color/ociolut/ociolut.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/color/ociolut/ociolut.cpp
node/color/ociolut/ociolut.h
PARENT_SCOPE
)
+10 -8
View File
@@ -37,7 +37,8 @@ const QString OCIOLutNode::kDirectionInput = QStringLiteral("lut_dir_in");
#define super OCIOBaseNode
namespace {
namespace
{
bool IsSupportedLutExtension(const QString &suffix)
{
@@ -47,7 +48,8 @@ bool IsSupportedLutExtension(const QString &suffix)
bool IsMainProcess()
{
return qobject_cast<QApplication *>(QCoreApplication::instance()) != nullptr;
return qobject_cast<QApplication *>(QCoreApplication::instance()) !=
nullptr;
}
int ReadDirectionInput(const Node *node)
@@ -245,9 +247,8 @@ bool OCIOLutNode::CreateProcessorFromInputs() const
ColorProcessorPtr processor;
try {
const bool forward =
static_cast<ColorProcessor::Direction>(direction) ==
ColorProcessor::kNormal;
const bool forward = static_cast<ColorProcessor::Direction>(
direction) == ColorProcessor::kNormal;
qDebug() << "OCIOLutNode: creating processor for" << path
<< "direction=" << direction
<< "ocio_dir=" << (forward ? "FORWARD" : "INVERSE")
@@ -256,10 +257,11 @@ bool OCIOLutNode::CreateProcessorFromInputs() const
OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create();
transform->setSrc(path.toUtf8().constData());
transform->setInterpolation(OCIO::INTERP_LINEAR);
transform->setDirection(
forward ? OCIO::TRANSFORM_DIR_FORWARD : OCIO::TRANSFORM_DIR_INVERSE);
transform->setDirection(forward ? OCIO::TRANSFORM_DIR_FORWARD :
OCIO::TRANSFORM_DIR_INVERSE);
processor = ColorProcessor::Create(manager()->GetConfig()->getProcessor(transform));
processor = ColorProcessor::Create(
manager()->GetConfig()->getProcessor(transform));
} catch (const std::exception &e) {
qWarning() << "OCIO LUT processor error:" << e.what();
processor = nullptr;
+1 -1
View File
@@ -43,7 +43,7 @@ public:
virtual void Retranslate() override;
virtual void InputValueChangedEvent(const QString &input,
int element) override;
int element) override;
virtual void Value(const NodeValueRow &value, const NodeGlobals &globals,
NodeValueTable *table) const override;
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/color/threewaycolor/threewaycolor.h
node/color/threewaycolor/threewaycolor.cpp
PARENT_SCOPE
${OLIVE_SOURCES}
node/color/threewaycolor/threewaycolor.h
node/color/threewaycolor/threewaycolor.cpp
PARENT_SCOPE
)
@@ -87,8 +87,7 @@ void ThreeWayColorNode::Retranslate()
SetInputName(kHighlightsAmountInput, tr("Highlights Amount"));
}
ShaderCode
ThreeWayColorNode::GetShaderCode(const ShaderRequest &request) const
ShaderCode ThreeWayColorNode::GetShaderCode(const ShaderRequest &request) const
{
Q_UNUSED(request)
return ShaderCode(
+2 -2
View File
@@ -25,6 +25,6 @@ add_subdirectory(transform)
add_subdirectory(wave)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
PARENT_SCOPE
${OLIVE_SOURCES}
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/distort/cornerpin/cornerpindistortnode.cpp
node/distort/cornerpin/cornerpindistortnode.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/distort/cornerpin/cornerpindistortnode.cpp
node/distort/cornerpin/cornerpindistortnode.h
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/distort/crop/cropdistortnode.cpp
node/distort/crop/cropdistortnode.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/distort/crop/cropdistortnode.cpp
node/distort/crop/cropdistortnode.h
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/distort/flip/flipdistortnode.cpp
node/distort/flip/flipdistortnode.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/distort/flip/flipdistortnode.cpp
node/distort/flip/flipdistortnode.h
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/distort/mask/mask.cpp
node/distort/mask/mask.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/distort/mask/mask.cpp
node/distort/mask/mask.h
PARENT_SCOPE
)
+4 -4
View File
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/distort/ripple/rippledistortnode.cpp
node/distort/ripple/rippledistortnode.h
PARENT_SCOPE
${OLIVE_SOURCES}
node/distort/ripple/rippledistortnode.cpp
node/distort/ripple/rippledistortnode.h
PARENT_SCOPE
)

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