diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 4661a7206..3fa3bf1cd 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1aebf190..91b0ec564 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/.gitignore b/.gitignore index 7b8ac41c9..9b0d97838 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # CMake artifacts -/build*/ +/cmake-build-* build # Doxygen diff --git a/0001-Fix-include-path-for-Window_p.h-in-qtcommon-director.patch b/0001-Fix-include-path-for-Window_p.h-in-qtcommon-director.patch deleted file mode 100644 index e51c8ee8a..000000000 --- a/0001-Fix-include-path-for-Window_p.h-in-qtcommon-director.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 6b0ef44eb189411d36c739ccde8a081a3e62034a Mon Sep 17 00:00:00 2001 -From: Mike Solar -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 --- -2.52.0 - diff --git a/CMakeLists.txt b/CMakeLists.txt index e1d9b3b41..647fbcb62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba13dc1af..6fedd8155 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 diff --git a/README.md b/README.md index 72ed901b7..078875977 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/TODO-zh.md b/TODO-zh.md deleted file mode 100644 index a04b1a792..000000000 --- a/TODO-zh.md +++ /dev/null @@ -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=2–3 秒。 -- 并发限制(例如 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 纹理缓存。 diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 8700308b8..000000000 --- a/TODO.md +++ /dev/null @@ -1,92 +0,0 @@ -# TODO - -## Goal -- Add an LRU prerender cache (2–3 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 = 2–3s). -- Limit worker count (e.g., 2–3 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 (2–3 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. diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 518a81525..bffdc5688 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -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 "${QM_FILE}\n") -endforeach() +foreach (QM_FILE ${OLIVE_QM_FILES}) + get_filename_component(QM_FILENAME_COMPONENT ${QM_FILE} NAME_WE) + string(APPEND QRC_BODY "${QM_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 - $ - $ + main.cpp + $ + $ ) 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 - $ - $ + render/worker/workermain.cpp + $ + $ ) +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 $/Contents/MacOS + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/Contents/MacOS/ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/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 $ $/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 () diff --git a/app/audio/CMakeLists.txt b/app/audio/CMakeLists.txt index a9b08de04..e4b632c7d 100644 --- a/app/audio/CMakeLists.txt +++ b/app/audio/CMakeLists.txt @@ -15,18 +15,18 @@ # along with this program. If not, see . 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 ) diff --git a/app/audio/audiolevelmeter.cpp b/app/audio/audiolevelmeter.cpp index 68f03d5b5..af85abafb 100644 --- a/app/audio/audiolevelmeter.cpp +++ b/app/audio/audiolevelmeter.cpp @@ -57,7 +57,8 @@ AudioLevelMeter::AnalyzeSampleBuffer(const core::SampleBuffer &samples) square_sum += value * value; } - const double mean_square = square_sum / static_cast(sample_count); + const double mean_square = + square_sum / static_cast(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(total_samples)); + stats.integrated_lufs = + PowerToLufs(total_square / static_cast(total_samples)); return stats; } diff --git a/app/audio/audiosynchronizer.cpp b/app/audio/audiosynchronizer.cpp index 21c1ecb5e..7ce2e9a32 100644 --- a/app/audio/audiosynchronizer.cpp +++ b/app/audio/audiosynchronizer.cpp @@ -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(candidate_offset_samples) / - static_cast(sample_rate)); + placement.timeline_in = reference_timeline_in + + core::rational::fromDouble( + static_cast(candidate_offset_samples) / + static_cast(sample_rate)); placement.valid = !placement.timeline_in.isNaN(); return placement; } diff --git a/app/audio/audiosynchronizer.h b/app/audio/audiosynchronizer.h index 00dd28629..f32b6665b 100644 --- a/app/audio/audiosynchronizer.h +++ b/app/audio/audiosynchronizer.h @@ -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); }; } diff --git a/app/audio/audiowaveformsync.cpp b/app/audio/audiowaveformsync.cpp index 075dd656f..48e30f90d 100644 --- a/app/audio/audiowaveformsync.cpp +++ b/app/audio/audiowaveformsync.cpp @@ -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(std::max(0, -lag)); + const int reference_start = + static_cast(std::max(0, -lag)); const int candidate_start = static_cast(std::max(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(window_samples); + result.offset_samples = best_lag * static_cast(window_samples); } return result; diff --git a/app/audio/audiowaveformsync.h b/app/audio/audiowaveformsync.h index 539b17d1c..9aa9ee310 100644 --- a/app/audio/audiowaveformsync.h +++ b/app/audio/audiowaveformsync.h @@ -38,8 +38,8 @@ public: bool valid = false; }; - static QVector - ExtractRmsEnvelope(const core::SampleBuffer &samples, size_t window_samples); + static QVector ExtractRmsEnvelope(const core::SampleBuffer &samples, + size_t window_samples); static OffsetResult EstimateOffset(const core::SampleBuffer &reference, const core::SampleBuffer &candidate, diff --git a/app/cli/CMakeLists.txt b/app/cli/CMakeLists.txt index c261a3e00..6a21cb3e1 100644 --- a/app/cli/CMakeLists.txt +++ b/app/cli/CMakeLists.txt @@ -18,6 +18,6 @@ add_subdirectory(cliprogress) add_subdirectory(clitask) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/cli/cliprogress/CMakeLists.txt b/app/cli/cliprogress/CMakeLists.txt index 621c498da..74fbc01ce 100644 --- a/app/cli/cliprogress/CMakeLists.txt +++ b/app/cli/cliprogress/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/cli/clitask/CMakeLists.txt b/app/cli/clitask/CMakeLists.txt index 8e5f4782b..75d71fdbe 100644 --- a/app/cli/clitask/CMakeLists.txt +++ b/app/cli/clitask/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/codec/CMakeLists.txt b/app/codec/CMakeLists.txt index 5c577e26c..d832c1b0c 100644 --- a/app/codec/CMakeLists.txt +++ b/app/codec/CMakeLists.txt @@ -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 ) diff --git a/app/codec/decoder.h b/app/codec/decoder.h index ee1614be7..8b918b926 100644 --- a/app/codec/decoder.h +++ b/app/codec/decoder.h @@ -32,7 +32,7 @@ extern "C" { #include #include - #include "codec/frame.h" +#include "codec/frame.h" #include "node/block/block.h" #include "node/project/footage/footagedescription.h" #include "render/cancelatom.h" diff --git a/app/codec/ffmpeg/CMakeLists.txt b/app/codec/ffmpeg/CMakeLists.txt index 0401fba78..eb713b464 100644 --- a/app/codec/ffmpeg/CMakeLists.txt +++ b/app/codec/ffmpeg/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . 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 ) diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index de971bae4..ef8ce51b1 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -25,11 +25,11 @@ extern "C" { #include } -namespace olive { +namespace olive +{ static FramePtr CopyPackedAVFrameToFrame(const AVFramePtr &src, - PixelFormat format, - int channel_count, + PixelFormat format, int channel_count, const rational ×tamp) { 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(f->format)); + const AVPixFmtDescriptor *src_desc = + av_pix_fmt_desc_get(static_cast(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(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( + 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 &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(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; } diff --git a/app/codec/ffmpeg/ffmpegdecoder.h b/app/codec/ffmpeg/ffmpegdecoder.h index 42a44ad6f..0a54492af 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.h +++ b/app/codec/ffmpeg/ffmpegdecoder.h @@ -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 &filenames, const AudioParams ¶ms, 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(); diff --git a/app/codec/oiio/CMakeLists.txt b/app/codec/oiio/CMakeLists.txt index 33cc8e2bb..4aa2d8f10 100644 --- a/app/codec/oiio/CMakeLists.txt +++ b/app/codec/oiio/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . 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 ) diff --git a/app/codec/oiio/oiiodecoder.cpp b/app/codec/oiio/oiiodecoder.cpp index 60b2e9c98..76f03fa12 100644 --- a/app/codec/oiio/oiiodecoder.cpp +++ b/app/codec/oiio/oiiodecoder.cpp @@ -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; } diff --git a/app/codec/oiio/oiiodecoder.h b/app/codec/oiio/oiiodecoder.h index 4029e173c..662626173 100644 --- a/app/codec/oiio/oiiodecoder.h +++ b/app/codec/oiio/oiiodecoder.h @@ -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: diff --git a/app/codec/proxymanager.cpp b/app/codec/proxymanager.cpp index 8ddad7bc7..84c09a731 100644 --- a/app/codec/proxymanager.cpp +++ b/app/codec/proxymanager.cpp @@ -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 ¶ms) +ProxyManager::Proxy +ProxyManager::GetOrStartProxy(const QString &cache_path, + const QString &source_filename, int stream_index, + const ProxyParams ¶ms) { 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)); diff --git a/app/codec/proxymanager.h b/app/codec/proxymanager.h index ff6cb1a48..0b59925ec 100644 --- a/app/codec/proxymanager.h +++ b/app/codec/proxymanager.h @@ -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 ¶ms); signals: diff --git a/app/codec/timecodemetadata.cpp b/app/codec/timecodemetadata.cpp index ebaa92088..c884cf3f0 100644 --- a/app/codec/timecodemetadata.cpp +++ b/app/codec/timecodemetadata.cpp @@ -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(std::numeric_limits::max()); if (numerator <= rational_limit && denominator <= rational_limit) { - result.time = - core::rational(static_cast(numerator), - static_cast(denominator)); + result.time = core::rational(static_cast(numerator), + static_cast(denominator)); } else { result.time = core::rational::fromDouble( static_cast(samples) / static_cast(sample_rate)); diff --git a/app/common/CMakeLists.txt b/app/common/CMakeLists.txt index e09f1fce6..36c838363 100644 --- a/app/common/CMakeLists.txt +++ b/app/common/CMakeLists.txt @@ -16,42 +16,42 @@ # along with this program. If not, see . 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 ) diff --git a/app/common/Current.h b/app/common/Current.h index 8b6a50914..312b4eb77 100644 --- a/app/common/Current.h +++ b/app/common/Current.h @@ -25,31 +25,31 @@ class Current { public: - static Current& getInstance() + static Current &getInstance() { return current; } - olive::VideoParams& currentVideoParams() + olive::VideoParams ¤tVideoParams() { return currentVideoParams_; } - olive::AudioParams& currentAudioParams() + olive::AudioParams ¤tAudioParams() { return currentAudioParams_; } - void setCurrentVideoParams(olive::VideoParams& params) + void setCurrentVideoParams(olive::VideoParams ¶ms) { currentVideoParams_ = params; } - void setCurrentAudioParams(olive::AudioParams& params) + void setCurrentAudioParams(olive::AudioParams ¶ms) { currentAudioParams_ = params; } - void setCurrentVideoParams(olive::VideoParams&& params) + void setCurrentVideoParams(olive::VideoParams &¶ms) { currentVideoParams_ = params; } - void setCurrentAudioParams(olive::AudioParams&& params) + void setCurrentAudioParams(olive::AudioParams &¶ms) { currentAudioParams_ = params; } @@ -73,10 +73,12 @@ public: return plugin_cache_; } - void setPluginCache(std::shared_ptr cache) + void + setPluginCache(std::shared_ptr cache) { plugin_cache_ = cache; } + private: static Current current; olive::VideoParams currentVideoParams_; @@ -85,6 +87,4 @@ private: std::shared_ptr plugin_cache_; }; - - #endif //CURRENT_H diff --git a/app/config/CMakeLists.txt b/app/config/CMakeLists.txt index 7e1a01dd8..5c841a89c 100644 --- a/app/config/CMakeLists.txt +++ b/app/config/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - config/config.h - config/config.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + config/config.h + config/config.cpp + PARENT_SCOPE ) diff --git a/app/config/config.cpp b/app/config/config.cpp index 750bb9a80..8b248de11 100644 --- a/app/config/config.cpp +++ b/app/config/config.cpp @@ -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"), diff --git a/app/core.cpp b/app/core.cpp index 45fda3ce9..45e77d3f5 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -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()) { diff --git a/app/crashhandler/CMakeLists.txt b/app/crashhandler/CMakeLists.txt index f835c73ae..ff0b07a68 100644 --- a/app/crashhandler/CMakeLists.txt +++ b/app/crashhandler/CMakeLists.txt @@ -16,50 +16,53 @@ # Create crash handler executable add_executable( - olive-crashhandler - crashhandler.cpp - crashhandler.h - $ + olive-crashhandler + crashhandler.cpp + crashhandler.h + $ ) +# 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 $ - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CRASHPAD_LIBRARY_DIRS}/${CRASHPAD_HANDLER} $ - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${BREAKPAD_BIN_DIR}/${MINIDUMP_STACKWALK} $ - ) -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 $ $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CRASHPAD_LIBRARY_DIRS}/${CRASHPAD_HANDLER} $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${BREAKPAD_BIN_DIR}/${MINIDUMP_STACKWALK} $ + ) +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}) diff --git a/app/crashhandler/crashhandler.cpp b/app/crashhandler/crashhandler.cpp index 86291cb4d..70fa7c42b 100644 --- a/app/crashhandler/crashhandler.cpp +++ b/app/crashhandler/crashhandler.cpp @@ -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; diff --git a/app/dialog/CMakeLists.txt b/app/dialog/CMakeLists.txt index f5c628f91..adaf11b49 100644 --- a/app/dialog/CMakeLists.txt +++ b/app/dialog/CMakeLists.txt @@ -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 ) diff --git a/app/dialog/about/CMakeLists.txt b/app/dialog/about/CMakeLists.txt index 6a764829f..ba9e54939 100644 --- a/app/dialog/about/CMakeLists.txt +++ b/app/dialog/about/CMakeLists.txt @@ -15,11 +15,11 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/about/about.cpp b/app/dialog/about/about.cpp index 8aa38b1de..d13114249 100644 --- a/app/dialog/about/about.cpp +++ b/app/dialog/about/about.cpp @@ -66,12 +66,13 @@ AboutDialog::AboutDialog(bool welcome_dialog, QWidget *parent) "

%3

" // Description "

%4

" // Fork notice "") - .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 " - "Olive Video Editor."))); + .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 " + "Olive Video Editor."))); // Set text formatting label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); diff --git a/app/dialog/about/patreon.py b/app/dialog/about/patreon.py index 5fc7a232f..55cdd640d 100644 --- a/app/dialog/about/patreon.py +++ b/app/dialog/about/patreon.py @@ -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 \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 \n\nQStringList patrons = {\n%s\n};\n\n#endif // PATREON_H\n" % name_list) text_file.close() diff --git a/app/dialog/actionsearch/CMakeLists.txt b/app/dialog/actionsearch/CMakeLists.txt index c759394d2..dbebacb13 100644 --- a/app/dialog/actionsearch/CMakeLists.txt +++ b/app/dialog/actionsearch/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/autorecovery/CMakeLists.txt b/app/dialog/autorecovery/CMakeLists.txt index 6408b5822..44d17c39a 100644 --- a/app/dialog/autorecovery/CMakeLists.txt +++ b/app/dialog/autorecovery/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/color/CMakeLists.txt b/app/dialog/color/CMakeLists.txt index b0b2c90e4..0ebe2556d 100644 --- a/app/dialog/color/CMakeLists.txt +++ b/app/dialog/color/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/configbase/CMakeLists.txt b/app/dialog/configbase/CMakeLists.txt index b0da5d620..1ac8d3664 100644 --- a/app/dialog/configbase/CMakeLists.txt +++ b/app/dialog/configbase/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/diskcache/CMakeLists.txt b/app/dialog/diskcache/CMakeLists.txt index 3b11da610..745751fd9 100644 --- a/app/dialog/diskcache/CMakeLists.txt +++ b/app/dialog/diskcache/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/diskcache/diskcachedialog.cpp b/app/dialog/diskcache/diskcachedialog.cpp index 172e26adc..029950241 100644 --- a/app/dialog/diskcache/diskcachedialog.cpp +++ b/app/dialog/diskcache/diskcachedialog.cpp @@ -26,7 +26,6 @@ #include #include - namespace olive { diff --git a/app/dialog/export/CMakeLists.txt b/app/dialog/export/CMakeLists.txt index 8847c4ba4..afd8aff10 100644 --- a/app/dialog/export/CMakeLists.txt +++ b/app/dialog/export/CMakeLists.txt @@ -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 ) diff --git a/app/dialog/export/codec/CMakeLists.txt b/app/dialog/export/codec/CMakeLists.txt index d68ccd1c3..2271fed21 100644 --- a/app/dialog/export/codec/CMakeLists.txt +++ b/app/dialog/export/codec/CMakeLists.txt @@ -15,18 +15,18 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/export/exportaudiotab.cpp b/app/dialog/export/exportaudiotab.cpp index 9b1d5cb27..c8a6a056f 100644 --- a/app/dialog/export/exportaudiotab.cpp +++ b/app/dialog/export/exportaudiotab.cpp @@ -24,7 +24,6 @@ #include #include - namespace olive { diff --git a/app/dialog/footageproperties/CMakeLists.txt b/app/dialog/footageproperties/CMakeLists.txt index 25287c233..4db26c336 100644 --- a/app/dialog/footageproperties/CMakeLists.txt +++ b/app/dialog/footageproperties/CMakeLists.txt @@ -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 ) diff --git a/app/dialog/footageproperties/streamproperties/CMakeLists.txt b/app/dialog/footageproperties/streamproperties/CMakeLists.txt index 3228e9520..3d6b3041f 100644 --- a/app/dialog/footageproperties/streamproperties/CMakeLists.txt +++ b/app/dialog/footageproperties/streamproperties/CMakeLists.txt @@ -15,12 +15,12 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/footagerelink/CMakeLists.txt b/app/dialog/footagerelink/CMakeLists.txt index 797f1c6c6..72c9ef48c 100644 --- a/app/dialog/footagerelink/CMakeLists.txt +++ b/app/dialog/footagerelink/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/keyframeproperties/CMakeLists.txt b/app/dialog/keyframeproperties/CMakeLists.txt index 6d479a925..ae9530dba 100644 --- a/app/dialog/keyframeproperties/CMakeLists.txt +++ b/app/dialog/keyframeproperties/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/markerproperties/CMakeLists.txt b/app/dialog/markerproperties/CMakeLists.txt index 84a130885..c6fce066f 100644 --- a/app/dialog/markerproperties/CMakeLists.txt +++ b/app/dialog/markerproperties/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/otioproperties/CMakeLists.txt b/app/dialog/otioproperties/CMakeLists.txt index 8a07ce76a..c5896118e 100644 --- a/app/dialog/otioproperties/CMakeLists.txt +++ b/app/dialog/otioproperties/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/preferences/CMakeLists.txt b/app/dialog/preferences/CMakeLists.txt index 1636674e4..7d35a7fdf 100644 --- a/app/dialog/preferences/CMakeLists.txt +++ b/app/dialog/preferences/CMakeLists.txt @@ -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 ) diff --git a/app/dialog/preferences/preferences.cpp b/app/dialog/preferences/preferences.cpp index dd6c955a7..ad1cb7d65 100644 --- a/app/dialog/preferences/preferences.cpp +++ b/app/dialog/preferences/preferences.cpp @@ -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")); diff --git a/app/dialog/preferences/tabs/CMakeLists.txt b/app/dialog/preferences/tabs/CMakeLists.txt index c26e22fa1..9b3029a17 100644 --- a/app/dialog/preferences/tabs/CMakeLists.txt +++ b/app/dialog/preferences/tabs/CMakeLists.txt @@ -15,18 +15,18 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/preferences/tabs/preferencesbehaviortab.cpp b/app/dialog/preferences/tabs/preferencesbehaviortab.cpp index db2adb294..458100665 100644 --- a/app/dialog/preferences/tabs/preferencesbehaviortab.cpp +++ b/app/dialog/preferences/tabs/preferencesbehaviortab.cpp @@ -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); diff --git a/app/dialog/preferences/tabs/preferencesbehaviortab.h b/app/dialog/preferences/tabs/preferencesbehaviortab.h index cc2fd4f55..76d30a8ab 100644 --- a/app/dialog/preferences/tabs/preferencesbehaviortab.h +++ b/app/dialog/preferences/tabs/preferencesbehaviortab.h @@ -49,7 +49,8 @@ public: static QString BehaviorPrefTr(const char *text) { - return QCoreApplication::translate("olive::PreferencesBehaviorTab", text); + return QCoreApplication::translate("olive::PreferencesBehaviorTab", + text); } private: diff --git a/app/dialog/preferences/tabs/preferencesdisktab.cpp b/app/dialog/preferences/tabs/preferencesdisktab.cpp index 81c08a8f4..e6d71a612 100644 --- a/app/dialog/preferences/tabs/preferencesdisktab.cpp +++ b/app/dialog/preferences/tabs/preferencesdisktab.cpp @@ -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()); + proxy_width_slider_->SetValue(OLIVE_CONFIG("ProxyWidth").value()); 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()); + proxy_height_slider_->SetValue(OLIVE_CONFIG("ProxyHeight").value()); 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()); + proxy_crf_slider_->SetValue(OLIVE_CONFIG("ProxyCRF").value()); 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(proxy_width_slider_->GetValue()); - OLIVE_CONFIG("ProxyHeight") = static_cast(proxy_height_slider_->GetValue()); + OLIVE_CONFIG("ProxyWidth") = + static_cast(proxy_width_slider_->GetValue()); + OLIVE_CONFIG("ProxyHeight") = + static_cast(proxy_height_slider_->GetValue()); OLIVE_CONFIG("ProxyCRF") = static_cast(proxy_crf_slider_->GetValue()); OLIVE_CONFIG("ProxyPreset") = proxy_preset_combo_->currentText(); } diff --git a/app/dialog/preferences/tabs/preferencesgeneraltab.cpp b/app/dialog/preferences/tabs/preferencesgeneraltab.cpp index df771fb47..43e3172b9 100644 --- a/app/dialog/preferences/tabs/preferencesgeneraltab.cpp +++ b/app/dialog/preferences/tabs/preferencesgeneraltab.cpp @@ -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.")); diff --git a/app/dialog/progress/CMakeLists.txt b/app/dialog/progress/CMakeLists.txt index 1319f1e56..c1c880a66 100644 --- a/app/dialog/progress/CMakeLists.txt +++ b/app/dialog/progress/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/projectproperties/CMakeLists.txt b/app/dialog/projectproperties/CMakeLists.txt index b45092bf6..41244e413 100644 --- a/app/dialog/projectproperties/CMakeLists.txt +++ b/app/dialog/projectproperties/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/rendercancel/CMakeLists.txt b/app/dialog/rendercancel/CMakeLists.txt index 16ee46ba0..7061abc1b 100644 --- a/app/dialog/rendercancel/CMakeLists.txt +++ b/app/dialog/rendercancel/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/sequence/CMakeLists.txt b/app/dialog/sequence/CMakeLists.txt index 1d3b4fccf..6e17090b0 100644 --- a/app/dialog/sequence/CMakeLists.txt +++ b/app/dialog/sequence/CMakeLists.txt @@ -15,14 +15,14 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/sequence/sequencedialogparametertab.cpp b/app/dialog/sequence/sequencedialogparametertab.cpp index 2adf35b7c..420a111de 100644 --- a/app/dialog/sequence/sequencedialogparametertab.cpp +++ b/app/dialog/sequence/sequencedialogparametertab.cpp @@ -23,7 +23,6 @@ #include #include - namespace olive { diff --git a/app/dialog/speedduration/CMakeLists.txt b/app/dialog/speedduration/CMakeLists.txt index 51cc60a60..4bd398613 100644 --- a/app/dialog/speedduration/CMakeLists.txt +++ b/app/dialog/speedduration/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/task/CMakeLists.txt b/app/dialog/task/CMakeLists.txt index 57d46bea0..123f3ffa9 100644 --- a/app/dialog/task/CMakeLists.txt +++ b/app/dialog/task/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/text/CMakeLists.txt b/app/dialog/text/CMakeLists.txt index 8fac97e1d..ed57e5eb9 100644 --- a/app/dialog/text/CMakeLists.txt +++ b/app/dialog/text/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/dialog/text/text.cpp b/app/dialog/text/text.cpp index 6130fe69f..0b3d67f9c 100644 --- a/app/dialog/text/text.cpp +++ b/app/dialog/text/text.cpp @@ -27,7 +27,6 @@ #include #include - namespace olive { diff --git a/app/main.cpp b/app/main.cpp index e1d30edfe..3f7dba5d0 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -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(a.get())) { - gui_app->setWindowIcon(QIcon(QStringLiteral(":/graphics/oak-logo.png"))); + gui_app->setWindowIcon( + QIcon(QStringLiteral(":/graphics/oak-logo.png"))); } if (load_plugins) { diff --git a/app/node/CMakeLists.txt b/app/node/CMakeLists.txt index b1472935c..94f07b6f5 100644 --- a/app/node/CMakeLists.txt +++ b/app/node/CMakeLists.txt @@ -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 ) diff --git a/app/node/audio/CMakeLists.txt b/app/node/audio/CMakeLists.txt index 541fc3b20..a0e886b57 100644 --- a/app/node/audio/CMakeLists.txt +++ b/app/node/audio/CMakeLists.txt @@ -18,6 +18,6 @@ add_subdirectory(pan) add_subdirectory(volume) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/audio/pan/CMakeLists.txt b/app/node/audio/pan/CMakeLists.txt index b249404cd..12dd5cce9 100644 --- a/app/node/audio/pan/CMakeLists.txt +++ b/app/node/audio/pan/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/audio/volume/CMakeLists.txt b/app/node/audio/volume/CMakeLists.txt index 61e241f44..02f8eb768 100644 --- a/app/node/audio/volume/CMakeLists.txt +++ b/app/node/audio/volume/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/block/CMakeLists.txt b/app/node/block/CMakeLists.txt index b93497d47..14362faae 100644 --- a/app/node/block/CMakeLists.txt +++ b/app/node/block/CMakeLists.txt @@ -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 ) diff --git a/app/node/block/clip/CMakeLists.txt b/app/node/block/clip/CMakeLists.txt index 4a3a19828..820529a96 100644 --- a/app/node/block/clip/CMakeLists.txt +++ b/app/node/block/clip/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/block/gap/CMakeLists.txt b/app/node/block/gap/CMakeLists.txt index a29906a51..f24a2fb89 100644 --- a/app/node/block/gap/CMakeLists.txt +++ b/app/node/block/gap/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/block/subtitle/CMakeLists.txt b/app/node/block/subtitle/CMakeLists.txt index 29001e672..5d29ac15a 100644 --- a/app/node/block/subtitle/CMakeLists.txt +++ b/app/node/block/subtitle/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/block/transition/CMakeLists.txt b/app/node/block/transition/CMakeLists.txt index bb1f316a4..a1f8bfb9b 100644 --- a/app/node/block/transition/CMakeLists.txt +++ b/app/node/block/transition/CMakeLists.txt @@ -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 ) diff --git a/app/node/block/transition/crossdissolve/CMakeLists.txt b/app/node/block/transition/crossdissolve/CMakeLists.txt index 2d8b8fc11..bb91a14b9 100644 --- a/app/node/block/transition/crossdissolve/CMakeLists.txt +++ b/app/node/block/transition/crossdissolve/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/block/transition/diptocolor/CMakeLists.txt b/app/node/block/transition/diptocolor/CMakeLists.txt index 47be688c3..d66e47ad1 100644 --- a/app/node/block/transition/diptocolor/CMakeLists.txt +++ b/app/node/block/transition/diptocolor/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/color/CMakeLists.txt b/app/node/color/CMakeLists.txt index 37975cab4..fd4eb2c85 100644 --- a/app/node/color/CMakeLists.txt +++ b/app/node/color/CMakeLists.txt @@ -22,6 +22,6 @@ add_subdirectory(ociolut) add_subdirectory(threewaycolor) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/color/colormanager/CMakeLists.txt b/app/node/color/colormanager/CMakeLists.txt index d964226d2..c379f8ea9 100644 --- a/app/node/color/colormanager/CMakeLists.txt +++ b/app/node/color/colormanager/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/color/displaytransform/CMakeLists.txt b/app/node/color/displaytransform/CMakeLists.txt index bec0ddfbe..3dd88deee 100644 --- a/app/node/color/displaytransform/CMakeLists.txt +++ b/app/node/color/displaytransform/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/color/ociobase/CMakeLists.txt b/app/node/color/ociobase/CMakeLists.txt index 86a82c6cd..5bacc8f18 100644 --- a/app/node/color/ociobase/CMakeLists.txt +++ b/app/node/color/ociobase/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/color/ociogradingtransformlinear/CMakeLists.txt b/app/node/color/ociogradingtransformlinear/CMakeLists.txt index 891489c63..78053df26 100644 --- a/app/node/color/ociogradingtransformlinear/CMakeLists.txt +++ b/app/node/color/ociogradingtransformlinear/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/color/ociolut/CMakeLists.txt b/app/node/color/ociolut/CMakeLists.txt index 55a4ae8a2..7acbf9f72 100644 --- a/app/node/color/ociolut/CMakeLists.txt +++ b/app/node/color/ociolut/CMakeLists.txt @@ -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 ) diff --git a/app/node/color/ociolut/ociolut.cpp b/app/node/color/ociolut/ociolut.cpp index af63dd774..00a82e534 100644 --- a/app/node/color/ociolut/ociolut.cpp +++ b/app/node/color/ociolut/ociolut.cpp @@ -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(QCoreApplication::instance()) != nullptr; + return qobject_cast(QCoreApplication::instance()) != + nullptr; } int ReadDirectionInput(const Node *node) @@ -245,9 +247,8 @@ bool OCIOLutNode::CreateProcessorFromInputs() const ColorProcessorPtr processor; try { - const bool forward = - static_cast(direction) == - ColorProcessor::kNormal; + const bool forward = static_cast( + 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; diff --git a/app/node/color/ociolut/ociolut.h b/app/node/color/ociolut/ociolut.h index e0d60f369..a775fe9ee 100644 --- a/app/node/color/ociolut/ociolut.h +++ b/app/node/color/ociolut/ociolut.h @@ -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; diff --git a/app/node/color/threewaycolor/CMakeLists.txt b/app/node/color/threewaycolor/CMakeLists.txt index ee2ba14a2..f6307f6b2 100644 --- a/app/node/color/threewaycolor/CMakeLists.txt +++ b/app/node/color/threewaycolor/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/color/threewaycolor/threewaycolor.cpp b/app/node/color/threewaycolor/threewaycolor.cpp index 3b03df09d..676ddae18 100644 --- a/app/node/color/threewaycolor/threewaycolor.cpp +++ b/app/node/color/threewaycolor/threewaycolor.cpp @@ -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( diff --git a/app/node/distort/CMakeLists.txt b/app/node/distort/CMakeLists.txt index 2feb4ee34..f71d65b8d 100644 --- a/app/node/distort/CMakeLists.txt +++ b/app/node/distort/CMakeLists.txt @@ -25,6 +25,6 @@ add_subdirectory(transform) add_subdirectory(wave) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/distort/cornerpin/CMakeLists.txt b/app/node/distort/cornerpin/CMakeLists.txt index 7dd1b44e0..103b2f427 100644 --- a/app/node/distort/cornerpin/CMakeLists.txt +++ b/app/node/distort/cornerpin/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/distort/crop/CMakeLists.txt b/app/node/distort/crop/CMakeLists.txt index b882ad539..ad1ff7335 100644 --- a/app/node/distort/crop/CMakeLists.txt +++ b/app/node/distort/crop/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/distort/flip/CMakeLists.txt b/app/node/distort/flip/CMakeLists.txt index 414f46fec..49b77008a 100644 --- a/app/node/distort/flip/CMakeLists.txt +++ b/app/node/distort/flip/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/distort/mask/CMakeLists.txt b/app/node/distort/mask/CMakeLists.txt index ac4b0d89e..8d980848d 100644 --- a/app/node/distort/mask/CMakeLists.txt +++ b/app/node/distort/mask/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/distort/ripple/CMakeLists.txt b/app/node/distort/ripple/CMakeLists.txt index 1860986c6..a8cd1168d 100644 --- a/app/node/distort/ripple/CMakeLists.txt +++ b/app/node/distort/ripple/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . 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 ) diff --git a/app/node/distort/swirl/CMakeLists.txt b/app/node/distort/swirl/CMakeLists.txt index e41d599c4..bb2b20ba5 100644 --- a/app/node/distort/swirl/CMakeLists.txt +++ b/app/node/distort/swirl/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/distort/swirl/swirldistortnode.cpp - node/distort/swirl/swirldistortnode.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/distort/swirl/swirldistortnode.cpp + node/distort/swirl/swirldistortnode.h + PARENT_SCOPE ) diff --git a/app/node/distort/tile/CMakeLists.txt b/app/node/distort/tile/CMakeLists.txt index c2f83cbf6..97a280baa 100644 --- a/app/node/distort/tile/CMakeLists.txt +++ b/app/node/distort/tile/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/distort/tile/tiledistortnode.cpp - node/distort/tile/tiledistortnode.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/distort/tile/tiledistortnode.cpp + node/distort/tile/tiledistortnode.h + PARENT_SCOPE ) diff --git a/app/node/distort/transform/CMakeLists.txt b/app/node/distort/transform/CMakeLists.txt index 63a97c6c2..584116767 100644 --- a/app/node/distort/transform/CMakeLists.txt +++ b/app/node/distort/transform/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/distort/transform/transformdistortnode.cpp - node/distort/transform/transformdistortnode.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/distort/transform/transformdistortnode.cpp + node/distort/transform/transformdistortnode.h + PARENT_SCOPE ) diff --git a/app/node/distort/wave/CMakeLists.txt b/app/node/distort/wave/CMakeLists.txt index 5cf818d4c..7e3720914 100644 --- a/app/node/distort/wave/CMakeLists.txt +++ b/app/node/distort/wave/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/distort/wave/wavedistortnode.cpp - node/distort/wave/wavedistortnode.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/distort/wave/wavedistortnode.cpp + node/distort/wave/wavedistortnode.h + PARENT_SCOPE ) diff --git a/app/node/effect/CMakeLists.txt b/app/node/effect/CMakeLists.txt index 690dd76a5..4753fb991 100644 --- a/app/node/effect/CMakeLists.txt +++ b/app/node/effect/CMakeLists.txt @@ -17,6 +17,6 @@ add_subdirectory(opacity) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/effect/opacity/CMakeLists.txt b/app/node/effect/opacity/CMakeLists.txt index 4aac69730..7d27380f9 100644 --- a/app/node/effect/opacity/CMakeLists.txt +++ b/app/node/effect/opacity/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/effect/opacity/opacityeffect.cpp - node/effect/opacity/opacityeffect.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/effect/opacity/opacityeffect.cpp + node/effect/opacity/opacityeffect.h + PARENT_SCOPE ) diff --git a/app/node/factory.cpp b/app/node/factory.cpp index cef0be9ab..0cd4c5caa 100644 --- a/app/node/factory.cpp +++ b/app/node/factory.cpp @@ -94,7 +94,6 @@ void NodeFactory::Initialize() } RegisterPluginNodes(); - } void NodeFactory::Destroy() @@ -151,8 +150,7 @@ Menu *NodeFactory::CreateMenu(QWidget *parent, bool create_none_item, // Determine final destination (support secondary grouping) Menu *destination = top_menu; QString sub = n->SubCategory(); - if (!sub.isEmpty() && - n->Category().contains(Node::kCategoryOpenFX)) { + if (!sub.isEmpty() && n->Category().contains(Node::kCategoryOpenFX)) { QList sub_actions = top_menu->actions(); foreach (QAction *action, sub_actions) { if (action->menu() && action->menu()->title() == sub) { @@ -249,16 +247,15 @@ void NodeFactory::RegisterPluginNodes() continue; } - const QString plugin_id = QString::fromStdString( - image_effect->getIdentifier()); + const QString plugin_id = + QString::fromStdString(image_effect->getIdentifier()); if (existing_ids.contains(plugin_id)) { continue; } const auto &contexts = image_effect->getContexts(); if (contexts.empty()) { - qWarning() << "Skipping OFX plugin with no contexts:" - << plugin_id; + qWarning() << "Skipping OFX plugin with no contexts:" << plugin_id; continue; } std::string context = kOfxImageEffectContextFilter; diff --git a/app/node/filter/CMakeLists.txt b/app/node/filter/CMakeLists.txt index ea93d9320..512a56b3b 100644 --- a/app/node/filter/CMakeLists.txt +++ b/app/node/filter/CMakeLists.txt @@ -20,6 +20,6 @@ add_subdirectory(mosaic) add_subdirectory(stroke) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/filter/blur/CMakeLists.txt b/app/node/filter/blur/CMakeLists.txt index 40c6695f3..b38acb0e1 100644 --- a/app/node/filter/blur/CMakeLists.txt +++ b/app/node/filter/blur/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/filter/blur/blur.h - node/filter/blur/blur.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/filter/blur/blur.h + node/filter/blur/blur.cpp + PARENT_SCOPE ) diff --git a/app/node/filter/dropshadow/CMakeLists.txt b/app/node/filter/dropshadow/CMakeLists.txt index e86f4b95f..6ed873067 100644 --- a/app/node/filter/dropshadow/CMakeLists.txt +++ b/app/node/filter/dropshadow/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/filter/dropshadow/dropshadowfilter.h - node/filter/dropshadow/dropshadowfilter.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/filter/dropshadow/dropshadowfilter.h + node/filter/dropshadow/dropshadowfilter.cpp + PARENT_SCOPE ) diff --git a/app/node/filter/mosaic/CMakeLists.txt b/app/node/filter/mosaic/CMakeLists.txt index 07a502395..9388b6bf8 100644 --- a/app/node/filter/mosaic/CMakeLists.txt +++ b/app/node/filter/mosaic/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/filter/mosaic/mosaicfilternode.h - node/filter/mosaic/mosaicfilternode.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/filter/mosaic/mosaicfilternode.h + node/filter/mosaic/mosaicfilternode.cpp + PARENT_SCOPE ) diff --git a/app/node/filter/stroke/CMakeLists.txt b/app/node/filter/stroke/CMakeLists.txt index 71bb7c94f..8117b28d7 100644 --- a/app/node/filter/stroke/CMakeLists.txt +++ b/app/node/filter/stroke/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/filter/stroke/stroke.h - node/filter/stroke/stroke.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/filter/stroke/stroke.h + node/filter/stroke/stroke.cpp + PARENT_SCOPE ) diff --git a/app/node/generator/CMakeLists.txt b/app/node/generator/CMakeLists.txt index 424c3a0d4..bd854bba4 100644 --- a/app/node/generator/CMakeLists.txt +++ b/app/node/generator/CMakeLists.txt @@ -22,6 +22,6 @@ add_subdirectory(solid) add_subdirectory(text) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/generator/matrix/CMakeLists.txt b/app/node/generator/matrix/CMakeLists.txt index 142fdade9..48d917e90 100644 --- a/app/node/generator/matrix/CMakeLists.txt +++ b/app/node/generator/matrix/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/generator/matrix/matrix.h - node/generator/matrix/matrix.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/generator/matrix/matrix.h + node/generator/matrix/matrix.cpp + PARENT_SCOPE ) diff --git a/app/node/generator/noise/CMakeLists.txt b/app/node/generator/noise/CMakeLists.txt index 2c74d0d1c..592f05579 100644 --- a/app/node/generator/noise/CMakeLists.txt +++ b/app/node/generator/noise/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/generator/noise/noise.h - node/generator/noise/noise.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/generator/noise/noise.h + node/generator/noise/noise.cpp + PARENT_SCOPE ) diff --git a/app/node/generator/polygon/CMakeLists.txt b/app/node/generator/polygon/CMakeLists.txt index 79660d493..8b478b0e0 100644 --- a/app/node/generator/polygon/CMakeLists.txt +++ b/app/node/generator/polygon/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/generator/polygon/polygon.h - node/generator/polygon/polygon.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/generator/polygon/polygon.h + node/generator/polygon/polygon.cpp + PARENT_SCOPE ) diff --git a/app/node/generator/shape/CMakeLists.txt b/app/node/generator/shape/CMakeLists.txt index 436a49583..78d4c34ab 100644 --- a/app/node/generator/shape/CMakeLists.txt +++ b/app/node/generator/shape/CMakeLists.txt @@ -15,12 +15,12 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/generator/shape/generatorwithmerge.cpp - node/generator/shape/generatorwithmerge.h - node/generator/shape/shapenode.cpp - node/generator/shape/shapenode.h - node/generator/shape/shapenodebase.cpp - node/generator/shape/shapenodebase.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/generator/shape/generatorwithmerge.cpp + node/generator/shape/generatorwithmerge.h + node/generator/shape/shapenode.cpp + node/generator/shape/shapenode.h + node/generator/shape/shapenodebase.cpp + node/generator/shape/shapenodebase.h + PARENT_SCOPE ) diff --git a/app/node/generator/solid/CMakeLists.txt b/app/node/generator/solid/CMakeLists.txt index a194c709a..342e9c824 100644 --- a/app/node/generator/solid/CMakeLists.txt +++ b/app/node/generator/solid/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/generator/solid/solid.h - node/generator/solid/solid.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/generator/solid/solid.h + node/generator/solid/solid.cpp + PARENT_SCOPE ) diff --git a/app/node/generator/text/CMakeLists.txt b/app/node/generator/text/CMakeLists.txt index 3c03d99a1..516b545fe 100644 --- a/app/node/generator/text/CMakeLists.txt +++ b/app/node/generator/text/CMakeLists.txt @@ -15,12 +15,12 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/generator/text/textv1.cpp - node/generator/text/textv1.h - node/generator/text/textv2.cpp - node/generator/text/textv2.h - node/generator/text/textv3.cpp - node/generator/text/textv3.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/generator/text/textv1.cpp + node/generator/text/textv1.h + node/generator/text/textv2.cpp + node/generator/text/textv2.h + node/generator/text/textv3.cpp + node/generator/text/textv3.h + PARENT_SCOPE ) diff --git a/app/node/gizmo/CMakeLists.txt b/app/node/gizmo/CMakeLists.txt index c9f530d22..8c9b6aa75 100644 --- a/app/node/gizmo/CMakeLists.txt +++ b/app/node/gizmo/CMakeLists.txt @@ -15,22 +15,22 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/gizmo/draggable.cpp - node/gizmo/draggable.h - node/gizmo/gizmo.cpp - node/gizmo/gizmo.h - node/gizmo/line.cpp - node/gizmo/line.h - node/gizmo/path.cpp - node/gizmo/path.h - node/gizmo/point.cpp - node/gizmo/point.h - node/gizmo/polygon.cpp - node/gizmo/polygon.h - node/gizmo/screen.cpp - node/gizmo/screen.h - node/gizmo/text.cpp - node/gizmo/text.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/gizmo/draggable.cpp + node/gizmo/draggable.h + node/gizmo/gizmo.cpp + node/gizmo/gizmo.h + node/gizmo/line.cpp + node/gizmo/line.h + node/gizmo/path.cpp + node/gizmo/path.h + node/gizmo/point.cpp + node/gizmo/point.h + node/gizmo/polygon.cpp + node/gizmo/polygon.h + node/gizmo/screen.cpp + node/gizmo/screen.h + node/gizmo/text.cpp + node/gizmo/text.h + PARENT_SCOPE ) diff --git a/app/node/group/CMakeLists.txt b/app/node/group/CMakeLists.txt index de08d74da..9eebaf064 100644 --- a/app/node/group/CMakeLists.txt +++ b/app/node/group/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/group/group.cpp - node/group/group.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/group/group.cpp + node/group/group.h + PARENT_SCOPE ) diff --git a/app/node/input/CMakeLists.txt b/app/node/input/CMakeLists.txt index ab2b3569e..28d4d34c8 100644 --- a/app/node/input/CMakeLists.txt +++ b/app/node/input/CMakeLists.txt @@ -19,6 +19,6 @@ add_subdirectory(time) add_subdirectory(value) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/input/multicam/CMakeLists.txt b/app/node/input/multicam/CMakeLists.txt index fca12be16..a8fe63ad4 100644 --- a/app/node/input/multicam/CMakeLists.txt +++ b/app/node/input/multicam/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/input/multicam/multicamnode.h - node/input/multicam/multicamnode.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/input/multicam/multicamnode.h + node/input/multicam/multicamnode.cpp + PARENT_SCOPE ) diff --git a/app/node/input/time/CMakeLists.txt b/app/node/input/time/CMakeLists.txt index de26aba60..dcc559e66 100644 --- a/app/node/input/time/CMakeLists.txt +++ b/app/node/input/time/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/input/time/timeinput.h - node/input/time/timeinput.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/input/time/timeinput.h + node/input/time/timeinput.cpp + PARENT_SCOPE ) diff --git a/app/node/input/value/CMakeLists.txt b/app/node/input/value/CMakeLists.txt index cab50a98e..16cdc21ca 100644 --- a/app/node/input/value/CMakeLists.txt +++ b/app/node/input/value/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/input/value/valuenode.h - node/input/value/valuenode.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/input/value/valuenode.h + node/input/value/valuenode.cpp + PARENT_SCOPE ) diff --git a/app/node/keying/CMakeLists.txt b/app/node/keying/CMakeLists.txt index 1aa9910f4..dfb8f2fda 100644 --- a/app/node/keying/CMakeLists.txt +++ b/app/node/keying/CMakeLists.txt @@ -19,6 +19,6 @@ add_subdirectory(colordifferencekey) add_subdirectory(despill) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/keying/chromakey/CMakeLists.txt b/app/node/keying/chromakey/CMakeLists.txt index e7a9023dc..6107bd105 100644 --- a/app/node/keying/chromakey/CMakeLists.txt +++ b/app/node/keying/chromakey/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/keying/chromakey/chromakey.h - node/keying/chromakey/chromakey.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/keying/chromakey/chromakey.h + node/keying/chromakey/chromakey.cpp + PARENT_SCOPE ) \ No newline at end of file diff --git a/app/node/keying/colordifferencekey/CMakeLists.txt b/app/node/keying/colordifferencekey/CMakeLists.txt index f85438dc9..0e2e48980 100644 --- a/app/node/keying/colordifferencekey/CMakeLists.txt +++ b/app/node/keying/colordifferencekey/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/keying/colordifferencekey/colordifferencekey.h - node/keying/colordifferencekey/colordifferencekey.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/keying/colordifferencekey/colordifferencekey.h + node/keying/colordifferencekey/colordifferencekey.cpp + PARENT_SCOPE ) diff --git a/app/node/keying/despill/CMakeLists.txt b/app/node/keying/despill/CMakeLists.txt index 5f7c01639..69141556b 100644 --- a/app/node/keying/despill/CMakeLists.txt +++ b/app/node/keying/despill/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/keying/despill/despill.h - node/keying/despill/despill.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/keying/despill/despill.h + node/keying/despill/despill.cpp + PARENT_SCOPE ) diff --git a/app/node/math/CMakeLists.txt b/app/node/math/CMakeLists.txt index e9afde04c..9018df4d3 100644 --- a/app/node/math/CMakeLists.txt +++ b/app/node/math/CMakeLists.txt @@ -19,6 +19,6 @@ add_subdirectory(merge) add_subdirectory(trigonometry) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/math/math/CMakeLists.txt b/app/node/math/math/CMakeLists.txt index 8837a6e9d..92981e05e 100644 --- a/app/node/math/math/CMakeLists.txt +++ b/app/node/math/math/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/math/math/math.h - node/math/math/math.cpp - node/math/math/mathbase.h - node/math/math/mathbase.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/math/math/math.h + node/math/math/math.cpp + node/math/math/mathbase.h + node/math/math/mathbase.cpp + PARENT_SCOPE ) diff --git a/app/node/math/merge/CMakeLists.txt b/app/node/math/merge/CMakeLists.txt index d20bad99d..90705b220 100644 --- a/app/node/math/merge/CMakeLists.txt +++ b/app/node/math/merge/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/math/merge/merge.h - node/math/merge/merge.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/math/merge/merge.h + node/math/merge/merge.cpp + PARENT_SCOPE ) diff --git a/app/node/math/trigonometry/CMakeLists.txt b/app/node/math/trigonometry/CMakeLists.txt index e3b12573d..0d1102046 100644 --- a/app/node/math/trigonometry/CMakeLists.txt +++ b/app/node/math/trigonometry/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/math/trigonometry/trigonometry.h - node/math/trigonometry/trigonometry.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/math/trigonometry/trigonometry.h + node/math/trigonometry/trigonometry.cpp + PARENT_SCOPE ) diff --git a/app/node/node.h b/app/node/node.h index c8a2cdd48..1d8563a3d 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -182,7 +182,10 @@ public: * @brief Return a sub-category string for secondary grouping * within the primary category (e.g. "Filter" under "OpenFX"). */ - virtual QString SubCategory() const { return QString(); } + virtual QString SubCategory() const + { + return QString(); + } /** * @brief Return a description of this node's purpose (optional for subclassing, but recommended) @@ -1136,20 +1139,20 @@ public: static const QString kEnabledInput; - OFX::Host::ImageEffect::Instance* getPluginInstance() const + OFX::Host::ImageEffect::Instance *getPluginInstance() const { return plugin_instance_; } - OFX::Host::ImageEffect::ImageEffectPlugin* getPlugin() const + OFX::Host::ImageEffect::ImageEffectPlugin *getPlugin() const { return plugin_instance_ ? plugin_instance_->getPlugin() : nullptr; } + protected: - // If set, this node owns a plugin instance. - OFX::Host::ImageEffect::Instance* plugin_instance_ = nullptr; + OFX::Host::ImageEffect::Instance *plugin_instance_ = nullptr; - void setPluginInstance(OFX::Host::ImageEffect::Instance* instance) + void setPluginInstance(OFX::Host::ImageEffect::Instance *instance) { plugin_instance_ = instance; } diff --git a/app/node/output/CMakeLists.txt b/app/node/output/CMakeLists.txt index ae9e63c14..1ab4baca6 100644 --- a/app/node/output/CMakeLists.txt +++ b/app/node/output/CMakeLists.txt @@ -18,6 +18,6 @@ add_subdirectory(track) add_subdirectory(viewer) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/output/track/CMakeLists.txt b/app/node/output/track/CMakeLists.txt index a0b2b6e21..a7ff78d00 100644 --- a/app/node/output/track/CMakeLists.txt +++ b/app/node/output/track/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/output/track/track.cpp - node/output/track/track.h - node/output/track/tracklist.cpp - node/output/track/tracklist.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/output/track/track.cpp + node/output/track/track.h + node/output/track/tracklist.cpp + node/output/track/tracklist.h + PARENT_SCOPE ) diff --git a/app/node/output/viewer/CMakeLists.txt b/app/node/output/viewer/CMakeLists.txt index d77898838..876634308 100644 --- a/app/node/output/viewer/CMakeLists.txt +++ b/app/node/output/viewer/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/output/viewer/viewer.h - node/output/viewer/viewer.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/output/viewer/viewer.h + node/output/viewer/viewer.cpp + PARENT_SCOPE ) diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index 91e5a394a..1041df493 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -581,12 +581,12 @@ void ViewerOutput::set_parameters_from_footage( found_video_params = true; } - SetVideoParams(VideoParams( - s.width(), s.height(), using_timebase, - static_cast( - OLIVE_CONFIG("OfflinePixelFormat").toInt()), - VideoParams::kInternalChannelCount, s.pixel_aspect_ratio(), - s.interlacing(), 1)); + SetVideoParams( + VideoParams(s.width(), s.height(), using_timebase, + static_cast( + OLIVE_CONFIG("OfflinePixelFormat").toInt()), + VideoParams::kInternalChannelCount, + s.pixel_aspect_ratio(), s.interlacing(), 1)); if (found_video_params) { break; diff --git a/app/node/plugins/Plugin.cpp b/app/node/plugins/Plugin.cpp index cb4c5eed0..b2e4dd319 100644 --- a/app/node/plugins/Plugin.cpp +++ b/app/node/plugins/Plugin.cpp @@ -32,7 +32,8 @@ #include #include -namespace { +namespace +{ QHash> g_plugin_param_defaults; static bool IsNormalisedCoordSystem(const OFX::Host::Param::Base *param) @@ -61,8 +62,7 @@ QVariant DefaultValueForParam(const OFX::Host::Param::Base *param) const std::string &ofxType = param->getType(); const auto &props = param->getProperties(); - if (ofxType == kOfxParamTypeInteger || - ofxType == kOfxParamTypeChoice) { + if (ofxType == kOfxParamTypeInteger || ofxType == kOfxParamTypeChoice) { return props.getIntProperty(kOfxParamPropDefault); } if (ofxType == kOfxParamTypeBoolean) { @@ -77,34 +77,30 @@ QVariant DefaultValueForParam(const OFX::Host::Param::Base *param) } return val; } - if (ofxType == kOfxParamTypeString || - ofxType == kOfxParamTypeStrChoice || + if (ofxType == kOfxParamTypeString || ofxType == kOfxParamTypeStrChoice || ofxType == kOfxParamTypeCustom) { return QString::fromStdString( props.getStringProperty(kOfxParamPropDefault)); } - if (ofxType == kOfxParamTypeRGB || - ofxType == kOfxParamTypeRGBA) { + if (ofxType == kOfxParamTypeRGB || ofxType == kOfxParamTypeRGBA) { const int count = (ofxType == kOfxParamTypeRGBA) ? 4 : 3; - double values[4] = {0.0, 0.0, 0.0, 1.0}; + double values[4] = { 0.0, 0.0, 0.0, 1.0 }; props.getDoublePropertyN(kOfxParamPropDefault, values, count); const double alpha = (count == 4) ? values[3] : 1.0; return QVariant::fromValue( olive::core::Color(values[0], values[1], values[2], alpha)); } - if (ofxType == kOfxParamTypeDouble2D || - ofxType == kOfxParamTypeDouble3D || + if (ofxType == kOfxParamTypeDouble2D || ofxType == kOfxParamTypeDouble3D || ofxType == kOfxParamTypeInteger2D || ofxType == kOfxParamTypeInteger3D) { - const bool is_double = - (ofxType == kOfxParamTypeDouble2D || - ofxType == kOfxParamTypeDouble3D); + const bool is_double = (ofxType == kOfxParamTypeDouble2D || + ofxType == kOfxParamTypeDouble3D); const int count = (ofxType == kOfxParamTypeDouble2D || - ofxType == kOfxParamTypeInteger2D) - ? 2 - : 3; + ofxType == kOfxParamTypeInteger2D) ? + 2 : + 3; if (is_double) { - double values[3] = {0.0, 0.0, 0.0}; + double values[3] = { 0.0, 0.0, 0.0 }; props.getDoublePropertyN(kOfxParamPropDefault, values, count); if (IsNormalisedCoordSystem(param)) { double xSize, ySize; @@ -120,7 +116,7 @@ QVariant DefaultValueForParam(const OFX::Host::Param::Base *param) } return QVector3D(values[0], values[1], values[2]); } - int values[3] = {0, 0, 0}; + int values[3] = { 0, 0, 0 }; props.getIntPropertyN(kOfxParamPropDefault, values, count); if (count == 2) { return QVector2D(values[0], values[1]); @@ -156,8 +152,7 @@ QString DeduceColorSemantic(const OFX::Host::Param::Base *param, // Rule 1: explicit color keywords → color static const QStringList kColorKeywords = { QStringLiteral("color"), QStringLiteral("colour"), - QStringLiteral("fill"), QStringLiteral("tint"), - QStringLiteral("key") + QStringLiteral("fill"), QStringLiteral("tint"), QStringLiteral("key") }; for (const QString &kw : kColorKeywords) { if (label.contains(kw) || hint.contains(kw) || name.contains(kw)) { @@ -167,11 +162,11 @@ QString DeduceColorSemantic(const OFX::Host::Param::Base *param, // Rule 2: explicit scalar/adjustment keywords → scalar static const QStringList kScalarKeywords = { - QStringLiteral("gamma"), QStringLiteral("contrast"), - QStringLiteral("gain"), QStringLiteral("offset"), + QStringLiteral("gamma"), QStringLiteral("contrast"), + QStringLiteral("gain"), QStringLiteral("offset"), QStringLiteral("saturation"), QStringLiteral("exposure"), QStringLiteral("brightness"), QStringLiteral("lift"), - QStringLiteral("multiply"), QStringLiteral("scale"), + QStringLiteral("multiply"), QStringLiteral("scale"), QStringLiteral("pivot") }; for (const QString &kw : kScalarKeywords) { @@ -183,8 +178,8 @@ QString DeduceColorSemantic(const OFX::Host::Param::Base *param, // Rule 3: display range significantly outside/asymmetric to [0,1] → scalar const auto &props = param->getProperties(); const int dim = (ofxType == kOfxParamTypeRGBA) ? 4 : 3; - double dmin[4] = {0, 0, 0, 0}; - double dmax[4] = {1, 1, 1, 1}; + double dmin[4] = { 0, 0, 0, 0 }; + double dmax[4] = { 1, 1, 1, 1 }; props.getDoublePropertyN(kOfxParamPropDisplayMin, dmin, dim); props.getDoublePropertyN(kOfxParamPropDisplayMax, dmax, dim); bool range_looks_scalar = false; @@ -199,7 +194,7 @@ QString DeduceColorSemantic(const OFX::Host::Param::Base *param, } // Rule 4: default values all equal → scalar (lean) - double defs[4] = {0, 0, 0, 1}; + double defs[4] = { 0, 0, 0, 1 }; props.getDoublePropertyN(kOfxParamPropDefault, defs, dim); bool all_equal = true; for (int i = 1; i < dim; ++i) { @@ -227,14 +222,13 @@ QString DeduceColorSemantic(const OFX::Host::Param::Base *param, return QStringLiteral("color"); } -QHash -BuildDefaultValues(const std::map ¶ms) +QHash BuildDefaultValues( + const std::map ¶ms) { QHash defaults; for (const auto ¶m : params) { const std::string &ofxType = param.second->getType(); - if (ofxType == kOfxParamTypeGroup || - ofxType == kOfxParamTypePage || + if (ofxType == kOfxParamTypeGroup || ofxType == kOfxParamTypePage || ofxType == kOfxParamTypePushButton) { continue; } @@ -254,8 +248,9 @@ BuildDefaultValues(const std::map &pa return defaults; } } -static QString ClipLabelForName(const std::string &name, - const OFX::Host::ImageEffect::ClipDescriptor *desc) +static QString +ClipLabelForName(const std::string &name, + const OFX::Host::ImageEffect::ClipDescriptor *desc) { if (name == kOfxImageEffectSimpleSourceClipName) { return olive::plugin::PluginNode::tr("Source"); @@ -278,10 +273,9 @@ static QString ClipLabelForName(const std::string &name, return QString::fromStdString(name); } -olive::plugin::PluginNode::PluginNode( - OFX::Host::ImageEffect::Instance *plugin) +olive::plugin::PluginNode::PluginNode(OFX::Host::ImageEffect::Instance *plugin) { - plugin_instance_=plugin; + plugin_instance_ = plugin; const std::string &ctx = plugin_instance_->getContext(); if (ctx == kOfxImageEffectContextFilter) { @@ -299,16 +293,16 @@ olive::plugin::PluginNode::PluginNode( QHash page_labels; QHash page_for_param; - auto params=plugin_instance_->getParams(); - const QString plugin_id = QString::fromStdString( - plugin_instance_->getPlugin()->getIdentifier()); + auto params = plugin_instance_->getParams(); + const QString plugin_id = + QString::fromStdString(plugin_instance_->getPlugin()->getIdentifier()); auto defaults_iter = g_plugin_param_defaults.find(plugin_id); if (defaults_iter == g_plugin_param_defaults.end()) { g_plugin_param_defaults.insert(plugin_id, BuildDefaultValues(params)); defaults_iter = g_plugin_param_defaults.find(plugin_id); } const QHash &defaults = defaults_iter.value(); - for (auto param: params) { + for (auto param : params) { const std::string &ofxType = param.second->getType(); if (ofxType == kOfxParamTypeGroup) { const QString name = QString::fromStdString(param.first); @@ -336,8 +330,7 @@ olive::plugin::PluginNode::PluginNode( } } - for (auto param: params) { - + for (auto param : params) { NodeValue::Type type = NodeValue::kNone; const std::string &ofxType = param.second->getType(); @@ -355,26 +348,27 @@ olive::plugin::PluginNode::PluginNode( } else if (ofxType == kOfxParamTypeChoice) { type = NodeValue::kCombo; } else if (ofxType == kOfxParamTypeDouble2D || - ofxType == kOfxParamTypeInteger2D){ - type = NodeValue::kVec2;} - else if (ofxType == kOfxParamTypeDouble3D || - ofxType == kOfxParamTypeInteger3D){ + ofxType == kOfxParamTypeInteger2D) { + type = NodeValue::kVec2; + } else if (ofxType == kOfxParamTypeDouble3D || + ofxType == kOfxParamTypeInteger3D) { type = NodeValue::kVec3; - } else if (ofxType == kOfxParamTypeStrChoice){ + } else if (ofxType == kOfxParamTypeStrChoice) { type = NodeValue::kStrCombo; - }else if (ofxType == kOfxParamTypeBytes - || ofxType == kOfxParamTypeCustom) { + } else if (ofxType == kOfxParamTypeBytes || + ofxType == kOfxParamTypeCustom) { type = NodeValue::kBinary; } else if (ofxType == kOfxParamTypePushButton) { type = NodeValue::kPushButton; } else if (ofxType == kOfxParamTypeGroup || ofxType == kOfxParamTypePage) { continue; - }else { + } else { type = NodeValue::kNone; } - const QString input_id = QString::fromStdString(param.second->getName()); + const QString input_id = + QString::fromStdString(param.second->getName()); if (input_id.isEmpty()) { continue; } @@ -395,8 +389,7 @@ olive::plugin::PluginNode::PluginNode( if (is_secret) { SetInputFlag(input_id, kInputFlagHidden); } - const QString label = - QString::fromStdString(param.second->getLabel()); + const QString label = QString::fromStdString(param.second->getLabel()); if (!label.isEmpty()) { SetInputName(input_id, label); } else { @@ -413,33 +406,22 @@ olive::plugin::PluginNode::PluginNode( page_for_param.value(input_id)); } if (type == NodeValue::kColor) { - QString semantic = - DeduceColorSemantic(param.second, group_labels); - SetInputProperty(input_id, - QStringLiteral("color_semantic"), + QString semantic = DeduceColorSemantic(param.second, group_labels); + SetInputProperty(input_id, QStringLiteral("color_semantic"), semantic); - const int dim = - (ofxType == kOfxParamTypeRGBA) ? 4 : 3; - double dmin[4] = {0, 0, 0, 0}; - double dmax[4] = {1, 1, 1, 1}; - props.getDoublePropertyN(kOfxParamPropDisplayMin, - dmin, dim); - props.getDoublePropertyN(kOfxParamPropDisplayMax, - dmax, dim); - SetInputProperty(input_id, - QStringLiteral("min"), - dmin[0]); - SetInputProperty(input_id, - QStringLiteral("max"), - dmax[0]); + const int dim = (ofxType == kOfxParamTypeRGBA) ? 4 : 3; + double dmin[4] = { 0, 0, 0, 0 }; + double dmax[4] = { 1, 1, 1, 1 }; + props.getDoublePropertyN(kOfxParamPropDisplayMin, dmin, dim); + props.getDoublePropertyN(kOfxParamPropDisplayMax, dmax, dim); + SetInputProperty(input_id, QStringLiteral("min"), dmin[0]); + SetInputProperty(input_id, QStringLiteral("max"), dmax[0]); - const QString hint = QString::fromStdString( - param.second->getHint()); + const QString hint = + QString::fromStdString(param.second->getHint()); if (!hint.isEmpty()) { - SetInputProperty(input_id, - QStringLiteral("tooltip"), - hint); + SetInputProperty(input_id, QStringLiteral("tooltip"), hint); } } if (type == NodeValue::kCombo || type == NodeValue::kStrCombo) { @@ -447,8 +429,7 @@ olive::plugin::PluginNode::PluginNode( QStringList option_values; const int label_count = props.getDimension(kOfxParamPropChoiceOption); - const int value_count = - props.getDimension(kOfxParamPropChoiceEnum); + const int value_count = props.getDimension(kOfxParamPropChoiceEnum); for (int i = 0; i < label_count; ++i) { const std::string &label = @@ -478,15 +459,13 @@ olive::plugin::PluginNode::PluginNode( indices[i] = i; } - std::stable_sort(indices.begin(), indices.end(), - [&](int a, int b) { - return props.getIntProperty( - kOfxParamPropChoiceOrder, - a) < - props.getIntProperty( - kOfxParamPropChoiceOrder, - b); - }); + std::stable_sort( + indices.begin(), indices.end(), [&](int a, int b) { + return props.getIntProperty(kOfxParamPropChoiceOrder, + a) < + props.getIntProperty(kOfxParamPropChoiceOrder, + b); + }); QStringList ordered_labels; QStringList ordered_values; @@ -519,7 +498,6 @@ olive::plugin::PluginNode::PluginNode( SetInputName(input_id, ClipLabelForName(entry.first, entry.second)); has_texture_input = true; } - const QString source_id = QString::fromUtf8(kOfxImageEffectSimpleSourceClipName); @@ -527,8 +505,7 @@ olive::plugin::PluginNode::PluginNode( SetEffectInput(source_id); } else if (HasInputWithID(kTextureInput)) { SetEffectInput(kTextureInput); - } - else { + } else { if (has_texture_input) { AddInput(kTextureInput, NodeValue::kTexture); SetInputName(kTextureInput, tr("Texture")); @@ -545,7 +522,6 @@ QString olive::plugin::PluginNode::Name() const .getProps() .getStringProperty(kOfxPropLabel) .data(); - } QVector olive::plugin::PluginNode::Category() const @@ -565,7 +541,6 @@ QString olive::plugin::PluginNode::Description() const .getProps() .getStringProperty(kOfxPropPluginDescription) .data(); - } void olive::plugin::PluginNode::ProcessSamples(const NodeValueRow &values, const SampleBuffer &input, @@ -655,7 +630,7 @@ void olive::plugin::PluginNode::Value(const NodeValueRow &value, } if (tex && plugin_instance_) { PluginJob job(plugin_instance_, this, value, globals.time().in()); - + table->Push(NodeValue::kTexture, tex->toJob(job), this); } } @@ -669,30 +644,29 @@ QString olive::plugin::PluginNode::id() const return plugin->getIdentifier().data(); } - olive::Node *olive::plugin::PluginNode::copy() const - { - if (!plugin_instance_) { - return nullptr; - } - - const auto &contexts = plugin_instance_->getPlugin()->getContexts(); - std::string context = kOfxImageEffectContextFilter; - if (!contexts.empty() && - contexts.find(kOfxImageEffectContextFilter) == contexts.end()) { - context = *contexts.begin(); - } - - auto *instance = - plugin_instance_->getPlugin()->createInstance(context, nullptr); - if (!instance) { - return nullptr; - } - - auto *node = new PluginNode(instance); - if (auto *olive_instance = - dynamic_cast(instance)) { - olive_instance->setNode( - std::shared_ptr(node, [](PluginNode *) {})); - } - return node; +olive::Node *olive::plugin::PluginNode::copy() const +{ + if (!plugin_instance_) { + return nullptr; } + + const auto &contexts = plugin_instance_->getPlugin()->getContexts(); + std::string context = kOfxImageEffectContextFilter; + if (!contexts.empty() && + contexts.find(kOfxImageEffectContextFilter) == contexts.end()) { + context = *contexts.begin(); + } + + auto *instance = + plugin_instance_->getPlugin()->createInstance(context, nullptr); + if (!instance) { + return nullptr; + } + + auto *node = new PluginNode(instance); + if (auto *olive_instance = dynamic_cast(instance)) { + olive_instance->setNode( + std::shared_ptr(node, [](PluginNode *) {})); + } + return node; +} diff --git a/app/node/plugins/Plugin.h b/app/node/plugins/Plugin.h index 063c64c03..27ec3e094 100644 --- a/app/node/plugins/Plugin.h +++ b/app/node/plugins/Plugin.h @@ -29,12 +29,11 @@ namespace plugin { const QString kTextureInput = QStringLiteral("tex_in"); -class PluginNode : public olive::Node{ +class PluginNode : public olive::Node { public: - PluginNode(OFX::Host::ImageEffect::Instance* plugin) ; + PluginNode(OFX::Host::ImageEffect::Instance *plugin); ~PluginNode() override; - QString Name() const override; QString id() const override; QVector Category() const override; @@ -58,8 +57,8 @@ public: * corresponding output if it's connected to one. If your node doesn't directly deal with time, the default behavior * of the NodeParam objects will handle everything related to it automatically. */ - void Value(const NodeValueRow &value, - const NodeGlobals &globals, NodeValueTable *table) const override; + void Value(const NodeValueRow &value, const NodeGlobals &globals, + NodeValueTable *table) const override; /** * @brief If Value() pushes a ShaderJob, this is the function that will process them. @@ -82,11 +81,9 @@ private: public slots: void pushButtonClicked(QString name); - }; } } - #endif //PLUGIN_H diff --git a/app/node/project.cpp b/app/node/project.cpp index 4f22b535a..9dc140f0e 100644 --- a/app/node/project.cpp +++ b/app/node/project.cpp @@ -121,9 +121,8 @@ SerializedData Project::Load(QXmlStreamReader *reader) } } - const QString path = bundle_path.isEmpty() - ? file_path - : bundle_path; + const QString path = bundle_path.isEmpty() ? file_path : + bundle_path; if (!path.isEmpty()) { plugin_paths.insert(path); } @@ -239,19 +238,18 @@ void Project::Save(QXmlStreamWriter *writer) const } const QString key = QStringLiteral("%1|%2|%3|%4|%5") - .arg(QString::fromStdString(id)) - .arg(major) - .arg(minor) - .arg(bundle_path) - .arg(file_path); + .arg(QString::fromStdString(id)) + .arg(major) + .arg(minor) + .arg(bundle_path) + .arg(file_path); if (seen.contains(key)) { continue; } seen.insert(key); QMap attrs; - attrs.insert(QStringLiteral("id"), - QString::fromStdString(id)); + attrs.insert(QStringLiteral("id"), QString::fromStdString(id)); attrs.insert(QStringLiteral("major"), QString::number(major)); attrs.insert(QStringLiteral("minor"), QString::number(minor)); if (!bundle_path.isEmpty()) { @@ -269,8 +267,8 @@ void Project::Save(QXmlStreamWriter *writer) const writer->writeStartElement(QStringLiteral("plugins")); for (const auto &entry : plugins_to_save) { writer->writeStartElement(QStringLiteral("plugin")); - for (auto it = entry.second.cbegin(); - it != entry.second.cend(); ++it) { + for (auto it = entry.second.cbegin(); it != entry.second.cend(); + ++it) { writer->writeAttribute(it.key(), it.value()); } writer->writeEndElement(); diff --git a/app/node/project/CMakeLists.txt b/app/node/project/CMakeLists.txt index 81b41c183..4818d21e5 100644 --- a/app/node/project/CMakeLists.txt +++ b/app/node/project/CMakeLists.txt @@ -20,6 +20,6 @@ add_subdirectory(sequence) add_subdirectory(serializer) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/project/folder/CMakeLists.txt b/app/node/project/folder/CMakeLists.txt index d04701644..d106632f4 100644 --- a/app/node/project/folder/CMakeLists.txt +++ b/app/node/project/folder/CMakeLists.txt @@ -16,8 +16,8 @@ set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/project/folder/folder.h - node/project/folder/folder.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/project/folder/folder.h + node/project/folder/folder.cpp + PARENT_SCOPE ) diff --git a/app/node/project/footage/CMakeLists.txt b/app/node/project/footage/CMakeLists.txt index 4d277e07a..579557064 100644 --- a/app/node/project/footage/CMakeLists.txt +++ b/app/node/project/footage/CMakeLists.txt @@ -16,10 +16,10 @@ set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/project/footage/footage.cpp - node/project/footage/footage.h - node/project/footage/footagedescription.cpp - node/project/footage/footagedescription.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/project/footage/footage.cpp + node/project/footage/footage.h + node/project/footage/footagedescription.cpp + node/project/footage/footagedescription.h + PARENT_SCOPE ) diff --git a/app/node/project/footage/footage.cpp b/app/node/project/footage/footage.cpp index efd8238b5..3e1ed542c 100644 --- a/app/node/project/footage/footage.cpp +++ b/app/node/project/footage/footage.cpp @@ -242,11 +242,8 @@ void Footage::set_proxy_enabled(bool enabled) } } -void Footage::SetProxy(const QString &path, - ProxyManager::ProxyState state, - int video_stream_index, - int preset_version, - bool enabled) +void Footage::SetProxy(const QString &path, ProxyManager::ProxyState state, + int video_stream_index, int preset_version, bool enabled) { qDebug() << "Footage::SetProxy:" << filename() << "enabled=" << enabled << "state=" << ProxyManager::ProxyStateToString(state) @@ -598,11 +595,10 @@ void Footage::SaveCustom(QXmlStreamWriter *writer) const if (!proxy_path_.isEmpty() || proxy_enabled_) { writer->writeStartElement(QStringLiteral("proxy")); writer->writeAttribute(QStringLiteral("enabled"), - proxy_enabled_ ? QStringLiteral("1") - : QStringLiteral("0")); + proxy_enabled_ ? QStringLiteral("1") : + QStringLiteral("0")); writer->writeAttribute(QStringLiteral("state"), - ProxyManager::ProxyStateToString( - proxy_state_)); + ProxyManager::ProxyStateToString(proxy_state_)); writer->writeAttribute(QStringLiteral("stream"), QString::number(proxy_video_stream_index_)); writer->writeAttribute(QStringLiteral("preset"), diff --git a/app/node/project/footage/footage.h b/app/node/project/footage/footage.h index 9e697135d..416fe8fc5 100644 --- a/app/node/project/footage/footage.h +++ b/app/node/project/footage/footage.h @@ -200,11 +200,8 @@ public: return proxy_state_; } - void SetProxy(const QString &path, - ProxyManager::ProxyState state, - int video_stream_index, - int preset_version, - bool enabled); + void SetProxy(const QString &path, ProxyManager::ProxyState state, + int video_stream_index, int preset_version, bool enabled); void ClearProxy(); diff --git a/app/node/project/footage/footagedescription.cpp b/app/node/project/footage/footagedescription.cpp index 66efe2370..81848cc63 100644 --- a/app/node/project/footage/footagedescription.cpp +++ b/app/node/project/footage/footagedescription.cpp @@ -78,10 +78,9 @@ bool FootageDescription::Load(const QString &filename) const QStringList split = reader.readElementText().split('/'); if (split.size() == 2) { - SetSourceStartTime( - rational(split.at(0).toInt(), - split.at(1).toInt()), - source); + SetSourceStartTime(rational(split.at(0).toInt(), + split.at(1).toInt()), + source); } } else if (reader.name() == QStringLiteral("streams")) { { diff --git a/app/node/project/sequence/CMakeLists.txt b/app/node/project/sequence/CMakeLists.txt index 4da66c716..7778e502c 100644 --- a/app/node/project/sequence/CMakeLists.txt +++ b/app/node/project/sequence/CMakeLists.txt @@ -16,8 +16,8 @@ set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/project/sequence/sequence.h - node/project/sequence/sequence.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + node/project/sequence/sequence.h + node/project/sequence/sequence.cpp + PARENT_SCOPE ) diff --git a/app/node/project/serializer/CMakeLists.txt b/app/node/project/serializer/CMakeLists.txt index df529037c..8b5ae03f5 100644 --- a/app/node/project/serializer/CMakeLists.txt +++ b/app/node/project/serializer/CMakeLists.txt @@ -16,25 +16,25 @@ set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/project/serializer/serializer.cpp - node/project/serializer/serializer.h - node/project/serializer/serializer190219.cpp - node/project/serializer/serializer190219.h - node/project/serializer/serializer210528.cpp - node/project/serializer/serializer210528.h - node/project/serializer/serializer210907.cpp - node/project/serializer/serializer210907.h - node/project/serializer/serializer211228.cpp - node/project/serializer/serializer211228.h - node/project/serializer/serializer220403.cpp - node/project/serializer/serializer220403.h - node/project/serializer/serializer230220.cpp - node/project/serializer/serializer230220.h + ${OLIVE_SOURCES} + node/project/serializer/serializer.cpp + node/project/serializer/serializer.h + node/project/serializer/serializer190219.cpp + node/project/serializer/serializer190219.h + node/project/serializer/serializer210528.cpp + node/project/serializer/serializer210528.h + node/project/serializer/serializer210907.cpp + node/project/serializer/serializer210907.h + node/project/serializer/serializer211228.cpp + node/project/serializer/serializer211228.h + node/project/serializer/serializer220403.cpp + node/project/serializer/serializer220403.h + node/project/serializer/serializer230220.cpp + node/project/serializer/serializer230220.h - node/project/serializer/typeserializer.cpp - node/project/serializer/typeserializer.h + node/project/serializer/typeserializer.cpp + node/project/serializer/typeserializer.h - PARENT_SCOPE + PARENT_SCOPE ) diff --git a/app/node/project/serializer/serializer.cpp b/app/node/project/serializer/serializer.cpp index f682997be..699634068 100644 --- a/app/node/project/serializer/serializer.cpp +++ b/app/node/project/serializer/serializer.cpp @@ -96,7 +96,10 @@ ProjectSerializer::Result ProjectSerializer::Load(Project *project, return inner_result; } } else { - return kFileError; + Result r(kFileError); + r.SetDetails(QStringLiteral("Unable to open '%1': %2") + .arg(filename, project_file.errorString())); + return r; } } diff --git a/app/node/time/CMakeLists.txt b/app/node/time/CMakeLists.txt index 9f3aa1dc5..7d7fe59ae 100644 --- a/app/node/time/CMakeLists.txt +++ b/app/node/time/CMakeLists.txt @@ -19,6 +19,6 @@ add_subdirectory(timeoffset) add_subdirectory(timeremap) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/node/time/timeformat/CMakeLists.txt b/app/node/time/timeformat/CMakeLists.txt index 552649a6d..665bca754 100644 --- a/app/node/time/timeformat/CMakeLists.txt +++ b/app/node/time/timeformat/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/time/timeformat/timeformat.cpp - node/time/timeformat/timeformat.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/time/timeformat/timeformat.cpp + node/time/timeformat/timeformat.h + PARENT_SCOPE ) diff --git a/app/node/time/timeoffset/CMakeLists.txt b/app/node/time/timeoffset/CMakeLists.txt index 03afa72c3..602c2276a 100644 --- a/app/node/time/timeoffset/CMakeLists.txt +++ b/app/node/time/timeoffset/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/time/timeoffset/timeoffsetnode.cpp - node/time/timeoffset/timeoffsetnode.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/time/timeoffset/timeoffsetnode.cpp + node/time/timeoffset/timeoffsetnode.h + PARENT_SCOPE ) diff --git a/app/node/time/timeremap/CMakeLists.txt b/app/node/time/timeremap/CMakeLists.txt index f15e4dc03..cfc6b5e80 100644 --- a/app/node/time/timeremap/CMakeLists.txt +++ b/app/node/time/timeremap/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/time/timeremap/timeremap.cpp - node/time/timeremap/timeremap.h - PARENT_SCOPE + ${OLIVE_SOURCES} + node/time/timeremap/timeremap.cpp + node/time/timeremap/timeremap.h + PARENT_SCOPE ) diff --git a/app/node/traverser.cpp b/app/node/traverser.cpp index 5a7fed0a8..7d3c8bbea 100644 --- a/app/node/traverser.cpp +++ b/app/node/traverser.cpp @@ -502,19 +502,20 @@ void NodeTraverser::ResolveJobs(NodeValue &val) } val.set_value(tex); - } - else if (plugin::PluginJob* plugin_job=dynamic_cast(base_job)) { + } else if (plugin::PluginJob *plugin_job = + dynamic_cast( + base_job)) { VideoParams tex_params = job_tex->params(); // Force internal working format (F32) for plugin processing, // matching FootageJob/GenerateJob behavior. tex_params.set_format(GetCacheVideoParams().format()); - tex_params.set_channel_count(VideoParams::kRGBAChannelCount); + tex_params.set_channel_count( + VideoParams::kRGBAChannelCount); TexturePtr tex = CreateTexture(tex_params); ProcessPluginJob(job_tex, tex, val.source()); val.set_value(tex); - } // Cache resolved value diff --git a/app/node/traverser.h b/app/node/traverser.h index 18bf5a973..ad6c2720a 100644 --- a/app/node/traverser.h +++ b/app/node/traverser.h @@ -147,7 +147,9 @@ protected: return SampleBuffer(); } - virtual TexturePtr ProcessPluginJob(TexturePtr texture, TexturePtr destination, const Node *node); + virtual TexturePtr ProcessPluginJob(TexturePtr texture, + TexturePtr destination, + const Node *node); SampleBuffer CreateSampleBuffer(const AudioParams ¶ms, const rational &length) { diff --git a/app/packaging/CMakeLists.txt b/app/packaging/CMakeLists.txt index aa007f6d7..11eb7cb52 100644 --- a/app/packaging/CMakeLists.txt +++ b/app/packaging/CMakeLists.txt @@ -14,6 +14,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -if(UNIX AND NOT APPLE) - add_subdirectory(linux) -endif() +if (UNIX AND NOT APPLE) + add_subdirectory(linux) +endif () diff --git a/app/packaging/arch/PKGBUILD.in b/app/packaging/arch/PKGBUILD.in new file mode 100644 index 000000000..3111b55d0 --- /dev/null +++ b/app/packaging/arch/PKGBUILD.in @@ -0,0 +1,27 @@ +# Maintainer: Oak Video Editor Team +pkgname=oak-video-editor +pkgver=@VERSION@ +pkgrel=1 +pkgdesc="Oak - Non-linear video editor" +arch=('x86_64') +url="https://oakvideoeditor.org" +license=('GPL3') +depends=('qt6-base' 'qt6-tools' 'ffmpeg' 'openimageio' 'opencolorio' 'openexr' 'expat' 'portaudio' 'mesa' 'vulkan-icd-loader' 'libxkbcommon' 'fmt') +makedepends=('cmake' 'ninja' 'git' 'pkgconf') +source=("${pkgname}-${pkgver}.tar.gz") +md5sums=('SKIP') + +build() { + cd "${srcdir}/${pkgname}-${pkgver}" + 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 +} + +package() { + cd "${srcdir}/${pkgname}-${pkgver}" + DESTDIR="${pkgdir}" cmake --install build +} diff --git a/app/packaging/linux/AppRun b/app/packaging/linux/AppRun index 78498db05..e2381bb3f 100755 --- a/app/packaging/linux/AppRun +++ b/app/packaging/linux/AppRun @@ -20,16 +20,16 @@ APPDIR=$(readlink -f $(dirname "$0")) -# Custom AppRun that ensures the AppImage doesn't dismount before olive-crashhandler exits +# Custom AppRun that ensures the AppImage doesn't dismount before oak-crashhandler exits # Run main program -"$APPDIR/usr/bin/olive-editor" "$@" +"$APPDIR/usr/bin/oak-editor" "$@" # Wait arbitrary amount of time sleep 5 -# While olive-crashhandler exists, keep sleeping -while [[ $(ps -aux | grep olive-crashhandler | grep -v grep) ]] +# While oak-crashhandler exists, keep sleeping +while [[ $(ps -aux | grep oak-crashhandler | grep -v grep) ]] do sleep 5 done diff --git a/app/packaging/linux/CMakeLists.txt b/app/packaging/linux/CMakeLists.txt index c45dae139..ffaa0a12d 100644 --- a/app/packaging/linux/CMakeLists.txt +++ b/app/packaging/linux/CMakeLists.txt @@ -15,34 +15,34 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -if(GIT_FOUND) - set(APPDATA_RELEASE_VERSION ${PROJECT_VERSION}-${GIT_HASH}) - execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --pretty=%cd --date=short - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE APPDATA_RELEASE_DATE - OUTPUT_STRIP_TRAILING_WHITESPACE - ) -else() - set(APPDATA_RELEASE_VERSION ${PROJECT_VERSION}) - file(TIMESTAMP "${CMAKE_SOURCE_DIR}/CMakeLists.txt" APPDATA_RELEASE_DATE "%Y-%m-%d") -endif() +if (GIT_FOUND) + set(APPDATA_RELEASE_VERSION ${PROJECT_VERSION}-${GIT_HASH}) + execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --pretty=%cd --date=short + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE APPDATA_RELEASE_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +else () + set(APPDATA_RELEASE_VERSION ${PROJECT_VERSION}) + file(TIMESTAMP "${CMAKE_SOURCE_DIR}/CMakeLists.txt" APPDATA_RELEASE_DATE "%Y-%m-%d") +endif () configure_file( - org.oakvideoeditor.Oak.appdata.xml.in - org.oakvideoeditor.Oak.appdata.xml + org.oakvideoeditor.Oak.appdata.xml.in + org.oakvideoeditor.Oak.appdata.xml ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.oakvideoeditor.Oak.appdata.xml DESTINATION share/metainfo) install(FILES org.oakvideoeditor.Oak.desktop DESTINATION share/applications) install(FILES org.oakvideoeditor.Oak.xml DESTINATION share/mime/packages) -foreach(size 16 32 48 64 128 256 512) - install( - FILES icons/${size}x${size}/org.oakvideoeditor.Oak.png - DESTINATION share/icons/hicolor/${size}x${size}/apps - ) - install( - FILES icons/${size}x${size}/application-vnd.olive-project.png - DESTINATION share/icons/hicolor/${size}x${size}/mimetypes - ) -endforeach() +foreach (size 16 32 48 64 128 256 512) + install( + FILES icons/${size}x${size}/org.oakvideoeditor.Oak.png + DESTINATION share/icons/hicolor/${size}x${size}/apps + ) + install( + FILES icons/${size}x${size}/application-vnd.olive-project.png + DESTINATION share/icons/hicolor/${size}x${size}/mimetypes + ) +endforeach () diff --git a/app/packaging/linux/org.oakvideoeditor.Oak.appdata.xml.in b/app/packaging/linux/org.oakvideoeditor.Oak.appdata.xml.in index 834e13018..a93fb73e7 100644 --- a/app/packaging/linux/org.oakvideoeditor.Oak.appdata.xml.in +++ b/app/packaging/linux/org.oakvideoeditor.Oak.appdata.xml.in @@ -28,8 +28,8 @@

Oak Video Editor adalah aplikasi edit video bersifat non-linier yang bebas dan gratis, bertujuan untuk memberikan alternatif yang lengkap untuk aplikasi edit video profesional. Ini adalah fork komunitas dari Olive Video Editor.

Oak Video Editor est un éditeur vidéo non linéaire libre visant à fournir une alternative complète aux logiciels de montage vidéo professionnels haut de gamme. Il s'agit d'un fork communautaire d'Olive Video Editor.

- https://github.com/olive-editor/olive - https://github.com/olive-editor/olive/issues + https://github.com/OakVideoEditorCommunity/oak + https://github.com/OakVideoEditorCommunity/oak/issues https://olivevideoeditor.org/img/screenshot.1600.jpg diff --git a/app/packaging/linux/org.oakvideoeditor.Oak.desktop b/app/packaging/linux/org.oakvideoeditor.Oak.desktop index 22d7fbff1..977deff49 100644 --- a/app/packaging/linux/org.oakvideoeditor.Oak.desktop +++ b/app/packaging/linux/org.oakvideoeditor.Oak.desktop @@ -4,7 +4,7 @@ Comment=Professional open-source non-linear video editor Comment[fr]=Éditeur vidéo non-linéaire open-source professionnel Comment[it]=Programma di montaggio video professionale open-source Comment[id]=Aplikasi edit video yang non-linier, profesional serta sumbernya terbuka. -Exec=olive-editor %f +Exec=oak-editor %f Icon=org.oakvideoeditor.Oak Terminal=false Type=Application diff --git a/app/packaging/linux/org.oakvideoeditor.Oak.xml b/app/packaging/linux/org.oakvideoeditor.Oak.xml index a85eebc89..ac05ef440 100644 --- a/app/packaging/linux/org.oakvideoeditor.Oak.xml +++ b/app/packaging/linux/org.oakvideoeditor.Oak.xml @@ -18,8 +18,8 @@ --> - - Oak project - - + + Oak project + + diff --git a/app/packaging/macos/olive.icns b/app/packaging/macos/oak.icns similarity index 100% rename from app/packaging/macos/olive.icns rename to app/packaging/macos/oak.icns diff --git a/app/packaging/windows/nsis/olive.nsi b/app/packaging/windows/nsis/oak.nsi similarity index 85% rename from app/packaging/windows/nsis/olive.nsi rename to app/packaging/windows/nsis/oak.nsi index f88de86ef..c379823f4 100644 --- a/app/packaging/windows/nsis/olive.nsi +++ b/app/packaging/windows/nsis/oak.nsi @@ -4,9 +4,9 @@ !define MUI_UNICON "uninstall icon.ico" !define APP_NAME "Oak Video Editor" -!define APP_TARGET "olive-editor" +!define APP_TARGET "oak-editor" -!define MUI_FINISHPAGE_RUN "$INSTDIR\olive-editor.exe" +!define MUI_FINISHPAGE_RUN "$INSTDIR\oak-editor.exe" SetCompressor lzma @@ -38,7 +38,15 @@ InstallDir "$PROGRAMFILES32\${APP_NAME}" Section "Oak Video Editor" SectionIn RO SetOutPath $INSTDIR - File /r olive-editor\* + File /r oak-editor\* + + # Render worker process must live next to the editor binary + File "oak-editor\oak-render-worker.exe" + + # Render backends must also live next to the editor binary + File "oak-editor\oakgl.dll" + File /nonfatal "oak-editor\oakvulkan.dll" + WriteUninstaller "$INSTDIR\uninstall.exe" # Install Visual C++ 2010 Redistributable @@ -61,8 +69,8 @@ Section "Associate *.ove files with Oak Video Editor" WriteRegStr HKCR ".ove" "" "OakEditor.OVEFile" WriteRegStr HKCR ".ove" "Content Type" "application/vnd.olive-project" WriteRegStr HKCR "OakEditor.OVEFile" "" "Oak project file" - WriteRegStr HKCR "OakEditor.OVEFile\DefaultIcon" "" "$INSTDIR\olive-editor.exe,1" - WriteRegStr HKCR "OakEditor.OVEFile\shell\open\command" "" "$\"$INSTDIR\olive-editor.exe$\" $\"%1$\"" + WriteRegStr HKCR "OakEditor.OVEFile\DefaultIcon" "" "$INSTDIR\oak-editor.exe,1" + WriteRegStr HKCR "OakEditor.OVEFile\shell\open\command" "" "$\"$INSTDIR\oak-editor.exe$\" $\"%1$\"" System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' SectionEnd diff --git a/app/panel/CMakeLists.txt b/app/panel/CMakeLists.txt index 0f4c9348f..bf3b748e9 100644 --- a/app/panel/CMakeLists.txt +++ b/app/panel/CMakeLists.txt @@ -33,10 +33,10 @@ add_subdirectory(tool) add_subdirectory(viewer) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/panel.h - panel/panel.cpp - panel/panelmanager.h - panel/panelmanager.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/panel.h + panel/panel.cpp + panel/panelmanager.h + panel/panelmanager.cpp + PARENT_SCOPE ) diff --git a/app/panel/audiomonitor/CMakeLists.txt b/app/panel/audiomonitor/CMakeLists.txt index 0fcf37b09..e72e6ffd4 100644 --- a/app/panel/audiomonitor/CMakeLists.txt +++ b/app/panel/audiomonitor/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/audiomonitor/audiomonitor.h - panel/audiomonitor/audiomonitor.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/audiomonitor/audiomonitor.h + panel/audiomonitor/audiomonitor.cpp + PARENT_SCOPE ) diff --git a/app/panel/curve/CMakeLists.txt b/app/panel/curve/CMakeLists.txt index b7a2ad77a..c892071db 100644 --- a/app/panel/curve/CMakeLists.txt +++ b/app/panel/curve/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/curve/curve.h - panel/curve/curve.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/curve/curve.h + panel/curve/curve.cpp + PARENT_SCOPE ) diff --git a/app/panel/footageviewer/CMakeLists.txt b/app/panel/footageviewer/CMakeLists.txt index c8fd5d56d..faee2dbb9 100644 --- a/app/panel/footageviewer/CMakeLists.txt +++ b/app/panel/footageviewer/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/footageviewer/footageviewer.h - panel/footageviewer/footageviewer.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/footageviewer/footageviewer.h + panel/footageviewer/footageviewer.cpp + PARENT_SCOPE ) diff --git a/app/panel/history/CMakeLists.txt b/app/panel/history/CMakeLists.txt index 811a1333d..93f9eb07c 100644 --- a/app/panel/history/CMakeLists.txt +++ b/app/panel/history/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/history/historypanel.h - panel/history/historypanel.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/history/historypanel.h + panel/history/historypanel.cpp + PARENT_SCOPE ) diff --git a/app/panel/multicam/CMakeLists.txt b/app/panel/multicam/CMakeLists.txt index 89062f21e..f29abe741 100644 --- a/app/panel/multicam/CMakeLists.txt +++ b/app/panel/multicam/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/multicam/multicampanel.h - panel/multicam/multicampanel.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/multicam/multicampanel.h + panel/multicam/multicampanel.cpp + PARENT_SCOPE ) diff --git a/app/panel/node/CMakeLists.txt b/app/panel/node/CMakeLists.txt index 5acf9e114..04e37c012 100644 --- a/app/panel/node/CMakeLists.txt +++ b/app/panel/node/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/node/node.h - panel/node/node.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/node/node.h + panel/node/node.cpp + PARENT_SCOPE ) diff --git a/app/panel/panel.cpp b/app/panel/panel.cpp index 441b9a578..fa1399f58 100644 --- a/app/panel/panel.cpp +++ b/app/panel/panel.cpp @@ -131,8 +131,7 @@ void PanelWidget::changeEvent(QEvent *e) if (e->type() == QEvent::WindowStateChange) { if (isVisible() && !isMinimized()) { emit shown(Qt::OtherFocusReason); - } - else { + } else { emit hidden(); } } diff --git a/app/panel/panel.h b/app/panel/panel.h index 9add206bd..6a400a3b1 100644 --- a/app/panel/panel.h +++ b/app/panel/panel.h @@ -287,6 +287,7 @@ signals: void CloseRequested(); void shown(Qt::FocusReason reason); void hidden(); + protected: /** * @brief paintEvent diff --git a/app/panel/param/CMakeLists.txt b/app/panel/param/CMakeLists.txt index 5c8aaaa08..133ac7fbd 100644 --- a/app/panel/param/CMakeLists.txt +++ b/app/panel/param/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/param/param.h - panel/param/param.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/param/param.h + panel/param/param.cpp + PARENT_SCOPE ) diff --git a/app/panel/pixelsampler/CMakeLists.txt b/app/panel/pixelsampler/CMakeLists.txt index 2be528575..960cee367 100644 --- a/app/panel/pixelsampler/CMakeLists.txt +++ b/app/panel/pixelsampler/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/pixelsampler/pixelsamplerpanel.h - panel/pixelsampler/pixelsamplerpanel.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/pixelsampler/pixelsamplerpanel.h + panel/pixelsampler/pixelsamplerpanel.cpp + PARENT_SCOPE ) diff --git a/app/panel/project/CMakeLists.txt b/app/panel/project/CMakeLists.txt index 17008939e..381d92431 100644 --- a/app/panel/project/CMakeLists.txt +++ b/app/panel/project/CMakeLists.txt @@ -15,9 +15,9 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/project/footagemanagementpanel.h - panel/project/project.h - panel/project/project.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/project/footagemanagementpanel.h + panel/project/project.h + panel/project/project.cpp + PARENT_SCOPE ) diff --git a/app/panel/scope/CMakeLists.txt b/app/panel/scope/CMakeLists.txt index 997f26d42..3a256a1bf 100644 --- a/app/panel/scope/CMakeLists.txt +++ b/app/panel/scope/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/scope/scope.h - panel/scope/scope.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/scope/scope.h + panel/scope/scope.cpp + PARENT_SCOPE ) diff --git a/app/panel/sequenceviewer/CMakeLists.txt b/app/panel/sequenceviewer/CMakeLists.txt index 067b7a046..404a902fc 100644 --- a/app/panel/sequenceviewer/CMakeLists.txt +++ b/app/panel/sequenceviewer/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/sequenceviewer/sequenceviewer.h - panel/sequenceviewer/sequenceviewer.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/sequenceviewer/sequenceviewer.h + panel/sequenceviewer/sequenceviewer.cpp + PARENT_SCOPE ) diff --git a/app/panel/table/CMakeLists.txt b/app/panel/table/CMakeLists.txt index 9afcbf2fa..ea479ed4c 100644 --- a/app/panel/table/CMakeLists.txt +++ b/app/panel/table/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/table/table.h - panel/table/table.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/table/table.h + panel/table/table.cpp + PARENT_SCOPE ) diff --git a/app/panel/taskmanager/CMakeLists.txt b/app/panel/taskmanager/CMakeLists.txt index cb56c2366..a6a793093 100644 --- a/app/panel/taskmanager/CMakeLists.txt +++ b/app/panel/taskmanager/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/taskmanager/taskmanager.h - panel/taskmanager/taskmanager.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/taskmanager/taskmanager.h + panel/taskmanager/taskmanager.cpp + PARENT_SCOPE ) diff --git a/app/panel/timebased/CMakeLists.txt b/app/panel/timebased/CMakeLists.txt index 928f80e8f..5e24bded9 100644 --- a/app/panel/timebased/CMakeLists.txt +++ b/app/panel/timebased/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/timebased/timebased.h - panel/timebased/timebased.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/timebased/timebased.h + panel/timebased/timebased.cpp + PARENT_SCOPE ) diff --git a/app/panel/timeline/CMakeLists.txt b/app/panel/timeline/CMakeLists.txt index 67a6c3ca7..6bde5965b 100644 --- a/app/panel/timeline/CMakeLists.txt +++ b/app/panel/timeline/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/timeline/timeline.h - panel/timeline/timeline.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/timeline/timeline.h + panel/timeline/timeline.cpp + PARENT_SCOPE ) diff --git a/app/panel/tool/CMakeLists.txt b/app/panel/tool/CMakeLists.txt index 4a115b032..52a1d4ce7 100644 --- a/app/panel/tool/CMakeLists.txt +++ b/app/panel/tool/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/tool/tool.h - panel/tool/tool.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/tool/tool.h + panel/tool/tool.cpp + PARENT_SCOPE ) diff --git a/app/panel/viewer/CMakeLists.txt b/app/panel/viewer/CMakeLists.txt index 1265ef695..b62eefe56 100644 --- a/app/panel/viewer/CMakeLists.txt +++ b/app/panel/viewer/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - panel/viewer/viewer.h - panel/viewer/viewer.cpp - panel/viewer/viewerbase.h - panel/viewer/viewerbase.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + panel/viewer/viewer.h + panel/viewer/viewer.cpp + panel/viewer/viewerbase.h + panel/viewer/viewerbase.cpp + PARENT_SCOPE ) diff --git a/app/pluginSupport/OliveClip.cpp b/app/pluginSupport/OliveClip.cpp index cb9f71e76..f34bc5ed6 100644 --- a/app/pluginSupport/OliveClip.cpp +++ b/app/pluginSupport/OliveClip.cpp @@ -41,7 +41,8 @@ extern "C" { #include #include } -namespace { +namespace +{ const std::string kBitDepthNoneStr(kOfxBitDepthNone); const std::string kBitDepthByteStr(kOfxBitDepthByte); const std::string kBitDepthShortStr(kOfxBitDepthShort); @@ -117,16 +118,16 @@ static bool PackedDstInfo(AVPixelFormat fmt, int *channels, } } -static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, - const olive::VideoParams ¶ms) +static olive::AVFramePtr +ReadbackTextureToFrame(olive::TexturePtr texture, + const olive::VideoParams ¶ms) { if (!texture || texture->IsDummy() || !texture->renderer()) { return nullptr; } - AVPixelFormat pix_fmt = - olive::FFmpegUtils::GetFFmpegPixelFormat(params.format(), - params.channel_count()); + AVPixelFormat pix_fmt = olive::FFmpegUtils::GetFFmpegPixelFormat( + params.format(), params.channel_count()); if (pix_fmt == AV_PIX_FMT_NONE) { return nullptr; } @@ -145,15 +146,15 @@ static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, return nullptr; } const int linesize_pixels = BytesToPixels(frame->linesize[0], params); - texture->renderer()->DownloadFromTexture(texture->id(), params, - frame->data[0], - linesize_pixels); + texture->renderer()->DownloadFromTexture( + texture->id(), params, frame->data[0], linesize_pixels); return frame; } - olive::VideoParams rgba_params( - params.width(), params.height(), olive::core::PixelFormat::U8, 4, - params.pixel_aspect_ratio(), params.interlacing(), params.divider()); + olive::VideoParams rgba_params(params.width(), params.height(), + olive::core::PixelFormat::U8, 4, + params.pixel_aspect_ratio(), + params.interlacing(), params.divider()); olive::AVFramePtr rgba_frame = olive::CreateAVFramePtr(); rgba_frame->format = AV_PIX_FMT_RGBA; @@ -165,9 +166,8 @@ static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, const int linesize_pixels = BytesToPixels(rgba_frame->linesize[0], rgba_params); - texture->renderer()->DownloadFromTexture(texture->id(), rgba_params, - rgba_frame->data[0], - linesize_pixels); + texture->renderer()->DownloadFromTexture( + texture->id(), rgba_params, rgba_frame->data[0], linesize_pixels); olive::AVFramePtr dst = olive::CreateAVFramePtr(); dst->format = pix_fmt; @@ -179,9 +179,8 @@ static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, SwsContext *sws_ctx = sws_getContext( rgba_frame->width, rgba_frame->height, - static_cast(rgba_frame->format), - dst->width, dst->height, pix_fmt, SWS_POINT, - nullptr, nullptr, nullptr); + static_cast(rgba_frame->format), dst->width, dst->height, + pix_fmt, SWS_POINT, nullptr, nullptr, nullptr); if (!sws_ctx) { return rgba_frame; } @@ -218,9 +217,7 @@ static olive::AVFramePtr ConvertPackedFloatFrame(olive::AVFramePtr src, return nullptr; } - auto clamp01 = [](float v) -> float { - return std::clamp(v, 0.0f, 1.0f); - }; + auto clamp01 = [](float v) -> float { return std::clamp(v, 0.0f, 1.0f); }; for (int y = 0; y < src->height; ++y) { const float *src_row = reinterpret_cast( @@ -242,18 +239,14 @@ static olive::AVFramePtr ConvertPackedFloatFrame(olive::AVFramePtr src, continue; } dst_row_u16[x * dst_channels + 0] = - static_cast( - std::lround(clamp01(r) * 65535.0f)); + static_cast(std::lround(clamp01(r) * 65535.0f)); dst_row_u16[x * dst_channels + 1] = - static_cast( - std::lround(clamp01(g) * 65535.0f)); + static_cast(std::lround(clamp01(g) * 65535.0f)); dst_row_u16[x * dst_channels + 2] = - static_cast( - std::lround(clamp01(b) * 65535.0f)); + static_cast(std::lround(clamp01(b) * 65535.0f)); if (dst_channels == 4) { - dst_row_u16[x * dst_channels + 3] = - static_cast( - std::lround(clamp01(a) * 65535.0f)); + dst_row_u16[x * dst_channels + 3] = static_cast( + std::lround(clamp01(a) * 65535.0f)); } } } else { @@ -270,18 +263,14 @@ static olive::AVFramePtr ConvertPackedFloatFrame(olive::AVFramePtr src, continue; } dst_row[x * dst_channels + 0] = - static_cast( - std::lround(clamp01(r) * 255.0f)); + static_cast(std::lround(clamp01(r) * 255.0f)); dst_row[x * dst_channels + 1] = - static_cast( - std::lround(clamp01(g) * 255.0f)); + static_cast(std::lround(clamp01(g) * 255.0f)); dst_row[x * dst_channels + 2] = - static_cast( - std::lround(clamp01(b) * 255.0f)); + static_cast(std::lround(clamp01(b) * 255.0f)); if (dst_channels == 4) { dst_row[x * dst_channels + 3] = - static_cast( - std::lround(clamp01(a) * 255.0f)); + static_cast(std::lround(clamp01(a) * 255.0f)); } } } @@ -385,7 +374,7 @@ bool olive::plugin::OliveClipInstance::getConnected() const return true; } #endif - if(images_.empty()) + if (images_.empty()) return false; return true; } @@ -394,7 +383,7 @@ bool olive::plugin::OliveClipInstance::getConnected() const return true; } #endif - if(images_.empty()) + if (images_.empty()) return false; return true; } @@ -427,8 +416,9 @@ olive::plugin::OliveClipInstance::getImage(OfxTime time, if (name_ == "Output") { if (!images_.contains(time)) { // make a new ref counted image - images_.insert(time, new Image(*const_cast(this), - params_, bounds, rod, true)); + images_.insert(time, + new Image(*const_cast(this), + params_, bounds, rod, true)); } // add another reference to the member image for this fetch @@ -443,7 +433,7 @@ olive::plugin::OliveClipInstance::getImage(OfxTime time, return images_[time]; } else { if (images_.contains(time)) { - Image* image = images_.value(time); + Image *image = images_.value(time); image->EnsureAllocatedFromParams(params_, bounds, rod, false); image->addReference(); return image; @@ -468,13 +458,13 @@ olive::plugin::OliveClipInstance::getImage(OfxTime time, preferred_params.channel_count() <= 0) { return nullptr; } - + Image *image = new Image(*this, preferred_params, bounds, rod, true); return image; } } -OFX::Host::ImageEffect::Image* +OFX::Host::ImageEffect::Image * olive::plugin::OliveClipInstance::getOutputImage(OfxTime time) { if (images_.contains(time)) { @@ -504,10 +494,11 @@ olive::plugin::OliveClipInstance::getOutputImage(OfxTime time) return image; } -olive::VideoParams olive::plugin::OliveClipInstance::getPluginPreferredParams() const +olive::VideoParams +olive::plugin::OliveClipInstance::getPluginPreferredParams() const { VideoParams result = params_; - + // Get format from base class _pixelDepth (set by getClipPreferences) const std::string &depth = getPixelDepth(); if (!depth.empty()) { @@ -521,7 +512,7 @@ olive::VideoParams olive::plugin::OliveClipInstance::getPluginPreferredParams() result.set_format(core::PixelFormat::F32); } } - + // Get channel count from base class _components (set by getClipPreferences) const std::string &comp = getComponents(); if (!comp.empty()) { @@ -533,7 +524,7 @@ olive::VideoParams olive::plugin::OliveClipInstance::getPluginPreferredParams() result.set_channel_count(1); } } - + return result; } OfxRectD @@ -584,21 +575,24 @@ void olive::plugin::OliveClipInstance::setParams(const VideoParams ¶ms) setComponents(getUnmappedComponents()); } -void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, OfxTime time, bool readback_cpu){ +void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, + OfxTime time, + bool readback_cpu) +{ if (!texture) { return; } VideoParams incoming = texture->params(); - + // Preserve time-related properties from the host/project. // The frame rate of an OFX clip should reflect the project's frame rate, // not the individual input texture's frame rate. If different inputs // have different frame rates, setupClipPreferencesArgs throws an exception. rational saved_frame_rate = params_.frame_rate(); rational saved_time_base = params_.time_base(); - + this->params_ = incoming; - + params_.set_frame_rate(saved_frame_rate); params_.set_time_base(saved_time_base); // Note: We do NOT call setPixelDepth/setComponents here because @@ -622,9 +616,8 @@ void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, OfxTi if (!frame || !frame->data[0]) { frame = ReadbackTextureToFrame(texture, params_); } - AVPixelFormat expected_fmt = - FFmpegUtils::GetFFmpegPixelFormat(params_.format(), - params_.channel_count()); + AVPixelFormat expected_fmt = FFmpegUtils::GetFFmpegPixelFormat( + params_.format(), params_.channel_count()); if (expected_fmt == AV_PIX_FMT_NONE) { return; } @@ -635,21 +628,20 @@ void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, OfxTi static_cast(std::ceil(rod_d.x2)), static_cast(std::ceil(rod_d.y2)) }; - Image* image; + Image *image; if (images_.contains(time)) { image = images_.value(time); image->EnsureAllocatedFromParams(params_, bounds, regionOfDefinition, false); } else { pruneImagesCache(); - image = new Image(*this, params_, bounds, - regionOfDefinition, false); + image = new Image(*this, params_, bounds, regionOfDefinition, false); image->EnsureAllocatedFromParams(params_, bounds, regionOfDefinition, false); images_.insert(time, image); } - uint8_t *dst = (uint8_t*)image->data(); + uint8_t *dst = (uint8_t *)image->data(); if (!dst) { return; } @@ -665,36 +657,38 @@ void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, OfxTi // and SIGSEGV on Apple Silicon (where (int)NaN often evaluates to 0 or // INT_MIN, causing huge offsets into bgrid._data). if (params_.format() == core::PixelFormat::F32) { - const float *fptr = reinterpret_cast(frame->data[0]); + const float *fptr = reinterpret_cast(frame->data[0]); int row_floats = frame->linesize[0] / static_cast(sizeof(float)); bool has_nan = false; for (int y = 0; y < params_.height() && !has_nan; ++y) { - for (int x = 0; x < params_.width() * params_.channel_count(); ++x) { + for (int x = 0; x < params_.width() * params_.channel_count(); + ++x) { float v = fptr[y * row_floats + x]; if (std::isnan(v) || std::isinf(v)) { - qWarning() << "[PLUGIN] NaN/Inf detected in input frame at pixel (" - << x / params_.channel_count() << "," << y - << ") channel=" << (x % params_.channel_count()) - << " value=" << v; + qWarning() + << "[PLUGIN] NaN/Inf detected in input frame at pixel (" + << x / params_.channel_count() << "," << y + << ") channel=" << (x % params_.channel_count()) + << " value=" << v; has_nan = true; break; } } } if (has_nan) { - qWarning() << "[PLUGIN] Filling corrupted input frame with black to avoid CImg crash"; + qWarning() + << "[PLUGIN] Filling corrupted input frame with black to avoid CImg crash"; std::memset(dst, 0, image->row_bytes() * image->height()); return; } } AVFramePtr src_frame = frame; - if (frame->format != expected_fmt || - frame->width != params_.width() || + if (frame->format != expected_fmt || frame->width != params_.width() || frame->height != params_.height()) { - if (PackedFloatChannels(static_cast(frame->format)) > 0) { - AVFramePtr converted = - ConvertPackedFloatFrame(frame, expected_fmt); + if (PackedFloatChannels(static_cast(frame->format)) > + 0) { + AVFramePtr converted = ConvertPackedFloatFrame(frame, expected_fmt); if (converted) { src_frame = converted; goto copy_pixels; @@ -710,9 +704,8 @@ void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, OfxTi SwsContext *sws_ctx = sws_getContext( frame->width, frame->height, - static_cast(frame->format), - converted->width, converted->height, - static_cast(converted->format), + static_cast(frame->format), converted->width, + converted->height, static_cast(converted->format), SWS_POINT, nullptr, nullptr, nullptr); if (!sws_ctx) { return; @@ -727,18 +720,18 @@ void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, OfxTi copy_pixels: int bytes_per_component = params_.format().byte_count(); - int bytes_per_row = params_.width() * params_.channel_count() * - bytes_per_component; + int bytes_per_row = + params_.width() * params_.channel_count() * bytes_per_component; int src_row_bytes = src_frame->linesize[0]; int dst_row_bytes = image->row_bytes(); - int copy_bytes = std::min(bytes_per_row, - std::min(src_row_bytes, dst_row_bytes)); + int copy_bytes = + std::min(bytes_per_row, std::min(src_row_bytes, dst_row_bytes)); int copy_height = std::min(image->height(), src_frame->height); const uint8_t *src = src_frame->data[0]; if (params_.format() == core::PixelFormat::F32) { - const float *src_f = reinterpret_cast(src); - float *dst_f = reinterpret_cast(dst); + const float *src_f = reinterpret_cast(src); + float *dst_f = reinterpret_cast(dst); int src_stride = src_row_bytes / static_cast(sizeof(float)); int dst_stride = dst_row_bytes / static_cast(sizeof(float)); int floats_per_row = copy_bytes / static_cast(sizeof(float)); @@ -754,7 +747,8 @@ copy_pixels: } } if (has_nan) { - qWarning() << "[PLUGIN] NaN/Inf scrubbed from input frame data during copy"; + qWarning() + << "[PLUGIN] NaN/Inf scrubbed from input frame data during copy"; } } else if (dst_row_bytes == src_row_bytes && src_row_bytes == copy_bytes) { std::memcpy(dst, src, copy_bytes * copy_height); @@ -764,8 +758,6 @@ copy_pixels: copy_bytes); } } - - } void olive::plugin::OliveClipInstance::setOutputTexture(TexturePtr texture, @@ -818,18 +810,18 @@ olive::plugin::OliveClipInstance::loadTexture(OfxTime time, const char *format, bounds.x2 = std::min(bounds.x2, rod.x2); bounds.y2 = std::min(bounds.y2, rod.y2); - const int bytes_per_row = - params_.width() * params_.channel_count() * params_.format().byte_count(); + const int bytes_per_row = params_.width() * params_.channel_count() * + params_.format().byte_count(); const std::string &field = getFieldOrder(); - const std::string unique_id = std::to_string( - reinterpret_cast(gl_texture.get())) + "_" + + const std::string unique_id = + std::to_string(reinterpret_cast(gl_texture.get())) + "_" + std::to_string(static_cast(time)); const int texture_id = gl_texture->id().value(); OFX::Host::ImageEffect::Texture *texture = - new OFX::Host::ImageEffect::Texture( - *this, 1.0, 1.0, texture_id, GL_TEXTURE_2D, bounds, rod, - bytes_per_row, field, unique_id); + new OFX::Host::ImageEffect::Texture(*this, 1.0, 1.0, texture_id, + GL_TEXTURE_2D, bounds, rod, + bytes_per_row, field, unique_id); texture->addReference(); return texture; } diff --git a/app/pluginSupport/OliveClip.h b/app/pluginSupport/OliveClip.h index 12fb7bd49..a61dd3009 100644 --- a/app/pluginSupport/OliveClip.h +++ b/app/pluginSupport/OliveClip.h @@ -35,17 +35,18 @@ namespace olive { namespace plugin { -class OliveClipInstance: public OFX::Host::ImageEffect::ClipInstance { +class OliveClipInstance : public OFX::Host::ImageEffect::ClipInstance { public: - OliveClipInstance(OFX::Host::ImageEffect::Instance* effectInstance, - OFX::Host::ImageEffect::ClipDescriptor& desc,VideoParams ¶ms) + OliveClipInstance(OFX::Host::ImageEffect::Instance *effectInstance, + OFX::Host::ImageEffect::ClipDescriptor &desc, + VideoParams ¶ms) : ClipInstance(effectInstance, desc) , params_(params) - , defaultRegionOfDefinitions_{0, 0, 0, 0} + , defaultRegionOfDefinitions_{ 0, 0, 0, 0 } , name_(desc.getName()) { } - OFX::Host::ImageEffect::Image* getOutputImage(OfxTime time); + OFX::Host::ImageEffect::Image *getOutputImage(OfxTime time); const std::string &getUnmappedBitDepth() const override; const std::string &getUnmappedComponents() const override; @@ -56,21 +57,24 @@ public: const std::string &getFieldOrder() const override; bool getConnected() const override; double getUnmappedFrameRate() const override; - void getUnmappedFrameRange(double &startFrame, double &endFrame) const override; + void getUnmappedFrameRange(double &startFrame, + double &endFrame) const override; bool getContinuousSamples() const override; - OFX::Host::ImageEffect::Image* getImage(OfxTime time, const OfxRectD *optionalBounds) override; + OFX::Host::ImageEffect::Image * + getImage(OfxTime time, const OfxRectD *optionalBounds) override; OfxRectD getRegionOfDefinition(OfxTime time) const override; void setRegionOfDefinition(OfxRectD regionOfDefinition, OfxTime time); void setDefaultRegionOfDefinition(OfxRectD regionOfDefinition); void setParams(const VideoParams ¶ms); -# ifdef OFX_SUPPORTS_OPENGLRENDER - OFX::Host::ImageEffect::Texture* loadTexture(OfxTime time, - const char *format, - const OfxRectD *optionalBounds) override; -# endif +#ifdef OFX_SUPPORTS_OPENGLRENDER + OFX::Host::ImageEffect::Texture * + loadTexture(OfxTime time, const char *format, + const OfxRectD *optionalBounds) override; +#endif - void setInputTexture(TexturePtr texture, OfxTime time, bool readback_cpu = true); + void setInputTexture(TexturePtr texture, OfxTime time, + bool readback_cpu = true); void setOutputTexture(TexturePtr texture, OfxTime time); // Get the plugin-preferred VideoParams based on base class _pixelDepth/_components @@ -90,7 +94,7 @@ private: OfxRectD defaultRegionOfDefinitions_; std::string name_; - QMap images_; + QMap images_; #ifdef OFX_SUPPORTS_OPENGLRENDER QMap input_textures_; QMap output_textures_; @@ -99,6 +103,4 @@ private: } } - - #endif //OLIVECLIP_H diff --git a/app/pluginSupport/OliveHost.cpp b/app/pluginSupport/OliveHost.cpp index 570e24448..da2aac90e 100644 --- a/app/pluginSupport/OliveHost.cpp +++ b/app/pluginSupport/OliveHost.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -37,14 +37,18 @@ using namespace OFX::Host; using namespace olive::plugin; -namespace olive { -namespace plugin { +namespace olive +{ +namespace plugin +{ class PluginNode; } } -namespace { -void AddPluginPath(OFX::Host::PluginCache *cache, const QString &path, bool recurse = true) +namespace +{ +void AddPluginPath(OFX::Host::PluginCache *cache, const QString &path, + bool recurse = true) { if (!cache || path.isEmpty()) { return; @@ -80,7 +84,8 @@ void olive::plugin::loadPlugins(QString path) host = std::make_shared(); Current::getInstance().setPluginHost(host); - imageEffectPluginCache = std::make_shared(*host); + imageEffectPluginCache = + std::make_shared(*host); Current::getInstance().setPluginCache(imageEffectPluginCache); imageEffectPluginCache->registerInCache( @@ -92,7 +97,8 @@ void olive::plugin::loadPlugins(QString path) const QString home_path = QDir::homePath(); AddPluginPath(cache, QDir(home_path).filePath(".OFX/Plugins")); AddPluginPath(cache, QDir(home_path).filePath(".local/share/OFX/Plugins")); - AddPluginPath(cache, QDir(home_path).filePath(".local/share/olive/ofx/Plugins")); + AddPluginPath(cache, + QDir(home_path).filePath(".local/share/olive/ofx/Plugins")); const QString app_dir = QCoreApplication::applicationDirPath(); AddPluginPath(cache, QDir(app_dir).filePath("../OFX/Plugins")); @@ -109,10 +115,9 @@ void olive::plugin::loadPlugins(QString path) } OliveHost::~OliveHost() { - } -void OliveHost::destroyInstance(OFX::Host::ImageEffect::Instance* instance) +void OliveHost::destroyInstance(OFX::Host::ImageEffect::Instance *instance) { if (!instance) { return; @@ -151,11 +156,12 @@ OliveHost::makeDescriptor(const std::string &bundlePath, return desc; } -ImageEffect::Instance* OliveHost::newInstance(void *clientData, - ImageEffect::ImageEffectPlugin* plugin, - ImageEffect::Descriptor& desc, - const std::string& context){ - auto* instance = new OlivePluginInstance( +ImageEffect::Instance * +OliveHost::newInstance(void *clientData, ImageEffect::ImageEffectPlugin *plugin, + ImageEffect::Descriptor &desc, + const std::string &context) +{ + auto *instance = new OlivePluginInstance( plugin, desc, context, Current::getInstance().interactive()); if (clientData) { auto *node = static_cast(clientData); @@ -165,8 +171,9 @@ ImageEffect::Instance* OliveHost::newInstance(void *clientData, instances_.append(std::shared_ptr(instance)); return instance; }; -OfxStatus olive::plugin::OliveHost::vmessage(const char *type, const char *id, const char *format, - va_list args){ +OfxStatus olive::plugin::OliveHost::vmessage(const char *type, const char *id, + const char *format, va_list args) +{ if (!type || !format) { return kOfxStatFailed; } @@ -178,8 +185,7 @@ OfxStatus olive::plugin::OliveHost::vmessage(const char *type, const char *id, c auto *app = qobject_cast(QCoreApplication::instance()); if (!app) { - qWarning().noquote() - << "OFX message:" << type << message; + qWarning().noquote() << "OFX message:" << type << message; if (strcmp(type, kOfxMessageQuestion) == 0) { return kOfxStatReplyNo; } @@ -187,8 +193,8 @@ OfxStatus olive::plugin::OliveHost::vmessage(const char *type, const char *id, c } if (strcmp(type, kOfxMessageQuestion) == 0) { - auto ret = QMessageBox::question(nullptr, "", message, - QMessageBox::Ok, QMessageBox::Cancel); + auto ret = QMessageBox::question(nullptr, "", message, QMessageBox::Ok, + QMessageBox::Cancel); return (ret == QMessageBox::Ok) ? kOfxStatReplyYes : kOfxStatReplyNo; } @@ -203,8 +209,10 @@ OfxStatus olive::plugin::OliveHost::vmessage(const char *type, const char *id, c return kOfxStatOK; } // TODO: Persistent messages shouldn't use pop-up window. -OfxStatus olive::plugin::OliveHost::setPersistentMessage( - const char *type, const char *id, const char *format, va_list args) +OfxStatus olive::plugin::OliveHost::setPersistentMessage(const char *type, + const char *id, + const char *format, + va_list args) { if (!type || !format) { return kOfxStatFailed; @@ -216,13 +224,13 @@ OfxStatus olive::plugin::OliveHost::setPersistentMessage( QString message(buffer); if (strcmp(type, kOfxMessageError) == 0) { - persistent_messages_.append({HostMessageType::Error, message}); + persistent_messages_.append({ HostMessageType::Error, message }); QMessageBox::critical(nullptr, "", message); } else if (strcmp(type, kOfxMessageWarning) == 0) { - persistent_messages_.append({HostMessageType::Warning, message}); + persistent_messages_.append({ HostMessageType::Warning, message }); QMessageBox::warning(nullptr, "", message); } else if (strcmp(type, kOfxMessageMessage) == 0) { - persistent_messages_.append({HostMessageType::Message, message}); + persistent_messages_.append({ HostMessageType::Message, message }); QMessageBox::information(nullptr, "", message); } else { return kOfxStatFailed; diff --git a/app/pluginSupport/OlivePluginInstance.cpp b/app/pluginSupport/OlivePluginInstance.cpp index eb1033ff2..5b79b4e0f 100644 --- a/app/pluginSupport/OlivePluginInstance.cpp +++ b/app/pluginSupport/OlivePluginInstance.cpp @@ -43,7 +43,8 @@ namespace olive { namespace plugin { -namespace { +namespace +{ const std::string kImageFieldNoneStr(kOfxImageFieldNone); const std::string kImageFieldUpperStr(kOfxImageFieldUpper); const std::string kImageFieldLowerStr(kOfxImageFieldLower); @@ -62,7 +63,8 @@ QString FormatOfxMessage(const char *format, va_list args) return QString::fromUtf8(buffer); } QByteArray dynamic_buffer(needed + 1, 0); - const int written = vsnprintf(dynamic_buffer.data(), dynamic_buffer.size(), format, args); + const int written = + vsnprintf(dynamic_buffer.data(), dynamic_buffer.size(), format, args); if (written < 0) { return QString(); } @@ -136,7 +138,8 @@ ViewerOutput *GetActiveViewerOutput() } } - QList timelines = manager->GetPanelsOfType(); + QList timelines = + manager->GetPanelsOfType(); for (TimelinePanel *panel : timelines) { if (panel && panel->GetConnectedViewer()) { return panel->GetConnectedViewer(); @@ -166,7 +169,7 @@ void OlivePluginInstance::setNode(std::shared_ptr node) } OfxStatus OlivePluginInstance::vmessage(const char *type, const char *id, - const char *format, va_list args) + const char *format, va_list args) { const QString message = FormatOfxMessage(format, args); if (message.isEmpty()) { @@ -180,7 +183,8 @@ OfxStatus OlivePluginInstance::vmessage(const char *type, const char *id, if (is_question) { const auto ret = QMessageBox::question( nullptr, "", message, QMessageBox::Ok, QMessageBox::Cancel); - result = (ret == QMessageBox::Ok) ? kOfxStatReplyYes : kOfxStatReplyNo; + result = (ret == QMessageBox::Ok) ? kOfxStatReplyYes : + kOfxStatReplyNo; } else { QMessageBox::information(nullptr, "", message); result = kOfxStatOK; @@ -191,7 +195,8 @@ OfxStatus OlivePluginInstance::vmessage(const char *type, const char *id, show_message(); } else if (auto *app = QCoreApplication::instance()) { if (is_question) { - QMetaObject::invokeMethod(app, show_message, Qt::BlockingQueuedConnection); + QMetaObject::invokeMethod(app, show_message, + Qt::BlockingQueuedConnection); } else { QMetaObject::invokeMethod(app, show_message, Qt::QueuedConnection); } @@ -201,8 +206,10 @@ OfxStatus OlivePluginInstance::vmessage(const char *type, const char *id, return result; } -OfxStatus OlivePluginInstance::setPersistentMessage(const char *type, const char *id, - const char *format, va_list args) +OfxStatus OlivePluginInstance::setPersistentMessage(const char *type, + const char *id, + const char *format, + va_list args) { const QString message = FormatOfxMessage(format, args); if (message.isEmpty()) { @@ -215,11 +222,13 @@ OfxStatus OlivePluginInstance::setPersistentMessage(const char *type, const char error_type = ErrorType::Error; } // A warning - else if (strncmp(type, kOfxMessageWarning, strlen(kOfxMessageWarning)) == 0) { + else if (strncmp(type, kOfxMessageWarning, strlen(kOfxMessageWarning)) == + 0) { error_type = ErrorType::Warning; } // A simple information - else if (strncmp(type, kOfxMessageMessage, strlen(kOfxMessageMessage)) == 0) { + else if (strncmp(type, kOfxMessageMessage, strlen(kOfxMessageMessage)) == + 0) { error_type = ErrorType::Message; } else { return kOfxStatFailed; @@ -272,7 +281,8 @@ void OlivePluginInstance::getProjectSize(double &xSize, double &ySize) const xSize = params_.width() * par; ySize = params_.height(); } -void OlivePluginInstance::getProjectOffset(double &xOffset, double &yOffset) const +void OlivePluginInstance::getProjectOffset(double &xOffset, + double &yOffset) const { double par = params_.pixel_aspect_ratio().toDouble(); xOffset = params_.x() * par; @@ -317,7 +327,7 @@ void OlivePluginInstance::getRenderScaleRecursive(double &x, double &y) const } OFX::Host::Param::Instance * OlivePluginInstance::newParam(const std::string &name, - OFX::Host::Param::Descriptor &desc) + OFX::Host::Param::Descriptor &desc) { const std::string &type = desc.getType(); @@ -343,8 +353,7 @@ OlivePluginInstance::newParam(const std::string &name, return new Double3DInstance(node_, name, desc, this); } else if (type == kOfxParamTypeInteger3D) { return new Integer3DInstance(node_, name, desc, this); - } else if (type == kOfxParamTypeCustom || - type == kOfxParamTypeBytes) { + } else if (type == kOfxParamTypeCustom || type == kOfxParamTypeBytes) { return new CustomInstance(node_, name, desc, this); } else if (type == kOfxParamTypeGroup) { return new GroupInstance(desc, this); @@ -366,8 +375,7 @@ OfxStatus OlivePluginInstance::editBegin(const std::string &name) edit_param_count_ = 0; if (!name.empty()) { edit_first_label_ = - QCoreApplication::translate( - "OlivePluginInstance", "Change %1") + QCoreApplication::translate("OlivePluginInstance", "Change %1") .arg(QString::fromStdString(name)); } } @@ -383,15 +391,14 @@ OfxStatus OlivePluginInstance::editEnd() if (label.isEmpty()) { if (edit_param_count_ <= 1 && !edit_first_label_.isEmpty()) { label = edit_first_label_; - } else if (edit_param_count_ > 1 && - !edit_first_label_.isEmpty()) { - label = QCoreApplication::translate( - "OlivePluginInstance", "%1 (+%2)") + } else if (edit_param_count_ > 1 && !edit_first_label_.isEmpty()) { + label = QCoreApplication::translate("OlivePluginInstance", + "%1 (+%2)") .arg(edit_first_label_) .arg(edit_param_count_ - 1); } else { - label = QCoreApplication::translate( - "OlivePluginInstance", "Edit Parameters"); + label = QCoreApplication::translate("OlivePluginInstance", + "Edit Parameters"); } } Core::instance()->undo_stack()->push(edit_command_, label); @@ -450,9 +457,8 @@ void OlivePluginInstance::progressStart(const std::string &message, progress_dialog_->deleteLater(); } - QString dialog_message = message.empty() - ? QStringLiteral("Processing...") - : QString::fromStdString(message); + QString dialog_message = message.empty() ? QStringLiteral("Processing...") : + QString::fromStdString(message); progress_dialog_ = new ::olive::ProgressDialog( dialog_message, QStringLiteral("OpenFX"), nullptr); @@ -547,17 +553,17 @@ void OlivePluginInstance::setCustomInArgs(const std::string &action, OFX::Host::ImageEffect::ClipInstance *OlivePluginInstance::newClipInstance( OFX::Host::ImageEffect::Instance *plugin, - OFX::Host::ImageEffect::ClipDescriptor *descriptor, - int index) + OFX::Host::ImageEffect::ClipDescriptor *descriptor, int index) { // Create a new clip instance - OliveClipInstance* clipInstance = new OliveClipInstance(plugin, *descriptor, params_); + OliveClipInstance *clipInstance = + new OliveClipInstance(plugin, *descriptor, params_); // Initialize base class clip properties from VideoParams so that // setupClipPreferencesArgs and plugin constructors (which may fetch // clips and query their properties before getClipPreferences is called) // have valid defaults instead of kOfxImageComponentNone / kOfxBitDepthNone. - std::string depth = kOfxBitDepthFloat; // host default + std::string depth = kOfxBitDepthFloat; // host default std::string comp = kOfxImageComponentRGBA; // host default switch (params_.format()) { diff --git a/app/pluginSupport/OlivePluginInstance.h b/app/pluginSupport/OlivePluginInstance.h index 477ecd40f..9dc95d189 100644 --- a/app/pluginSupport/OlivePluginInstance.h +++ b/app/pluginSupport/OlivePluginInstance.h @@ -33,7 +33,8 @@ #include #include -namespace olive { +namespace olive +{ inline bool IsGuiThread() { @@ -43,48 +44,44 @@ inline bool IsGuiThread() return true; } class ProgressDialog; -namespace plugin { +namespace plugin +{ class PluginNode; -enum class ErrorType{ - Error, - Warning, - Message -}; -struct PersistentErrors{ +enum class ErrorType { Error, Warning, Message }; +struct PersistentErrors { ErrorType type; QString message; }; class OlivePluginInstance : public OFX::Host::ImageEffect::Instance { public: - OlivePluginInstance( - OFX::Host::ImageEffect::ImageEffectPlugin* plugin, - OFX::Host::ImageEffect::Descriptor& desc, - const std::string& context, - bool interactive) + OlivePluginInstance(OFX::Host::ImageEffect::ImageEffectPlugin *plugin, + OFX::Host::ImageEffect::Descriptor &desc, + const std::string &context, bool interactive) : OFX::Host::ImageEffect::Instance(plugin, desc, context, interactive) { } - OlivePluginInstance(OlivePluginInstance& instance) + OlivePluginInstance(OlivePluginInstance &instance) : Instance(instance._plugin, *instance._descriptor, instance._context, instance._interactive) { // Do NOT shallow-copy _clips: Instance::~Instance() deletes them, // which would cause a double-free. Clips are re-created in populate(). - _created=instance._created; - _clipPrefsDirty=instance._clipPrefsDirty; - _continuousSamples=instance._continuousSamples; - _frameVarying=instance._frameVarying; - _outputPreMultiplication=instance._outputPreMultiplication; - _outputFielding=instance._outputFielding; - _outputFrameRate=instance._outputFrameRate; + _created = instance._created; + _clipPrefsDirty = instance._clipPrefsDirty; + _continuousSamples = instance._continuousSamples; + _frameVarying = instance._frameVarying; + _outputPreMultiplication = instance._outputPreMultiplication; + _outputFielding = instance._outputFielding; + _outputFrameRate = instance._outputFrameRate; } - explicit OlivePluginInstance(Instance & instance):Instance(instance){}; + explicit OlivePluginInstance(Instance &instance) + : Instance(instance) {}; ~OlivePluginInstance() override; const std::string &getDefaultOutputFielding() const override; void setVideoParam(VideoParams params) { - this->params_=params; + this->params_ = params; } void setNode(std::shared_ptr node); std::shared_ptr node() const @@ -99,21 +96,17 @@ public: { return _created; } - OFX::Host::ImageEffect::ClipInstance *newClipInstance( - OFX::Host::ImageEffect::Instance *plugin, - OFX::Host::ImageEffect::ClipDescriptor *descriptor, - int index) override; + OFX::Host::ImageEffect::ClipInstance * + newClipInstance(OFX::Host::ImageEffect::Instance *plugin, + OFX::Host::ImageEffect::ClipDescriptor *descriptor, + int index) override; - OfxStatus vmessage(const char* type, - const char* id, - const char* format, - va_list args) override; + OfxStatus vmessage(const char *type, const char *id, const char *format, + va_list args) override; + + OfxStatus setPersistentMessage(const char *type, const char *id, + const char *format, va_list args) override; - OfxStatus setPersistentMessage(const char* type, - const char* id, - const char* format, - va_list args) override; - OfxStatus clearPersistentMessage() override; int persistentMessageCount() const { @@ -124,21 +117,21 @@ public: return persistentErrors_; } - void getProjectSize(double& xSize, double& ySize) const override; - void getProjectOffset(double& xOffset, double& yOffset) const override; - void getProjectExtent(double& xSize, double& ySize) const override; - // The pixel aspect ratio of the current project + void getProjectSize(double &xSize, double &ySize) const override; + void getProjectOffset(double &xOffset, double &yOffset) const override; + void getProjectExtent(double &xSize, double &ySize) const override; + // The pixel aspect ratio of the current project double getProjectPixelAspectRatio() const override; - // The duration of the effect - // This contains the duration of the plug-in effect, in frames. + // The duration of the effect + // This contains the duration of the plug-in effect, in frames. double getEffectDuration() const override; - // For an instance, this is the frame rate of the project the effect is in. + // For an instance, this is the frame rate of the project the effect is in. double getFrameRate() const override; /// This is called whenever a param is changed by the plugin so that - /// the recursive instanceChangedAction will be fed the correct frame + /// the recursive instanceChangedAction will be fed the correct frame double getFrameRecursive() const override; /// This is called whenever a param is changed by the plugin so that @@ -153,14 +146,16 @@ public: /// make a parameter instance /// /// Client host code needs to implement this - OFX::Host::Param::Instance* newParam(const std::string& name, OFX::Host::Param::Descriptor& Descriptor) override; + OFX::Host::Param::Instance * + newParam(const std::string &name, + OFX::Host::Param::Descriptor &Descriptor) override; void SubmitUndoCommand(UndoCommand *command, const QString &label); /// Triggered when the plug-in calls OfxParameterSuiteV1::paramEditBegin /// /// Client host code needs to implement this - virtual OfxStatus editBegin(const std::string& name) override; + virtual OfxStatus editBegin(const std::string &name) override; /// Triggered when the plug-in calls OfxParameterSuiteV1::paramEditEnd /// @@ -210,7 +205,6 @@ public: void setCustomInArgs(const std::string &action, OFX::Host::Property::Set &inArgs) override; - private: QList persistentErrors_; VideoParams params_; @@ -224,8 +218,13 @@ private: bool progress_cancelled_ = false; bool progress_active_ = false; bool open_gl_enabled_ = false; + public: - std::mutex& mutex() { return mutex_; } + std::mutex &mutex() + { + return mutex_; + } + private: std::mutex mutex_; }; diff --git a/app/pluginSupport/image.cpp b/app/pluginSupport/image.cpp index 5adad973a..0d55b7352 100644 --- a/app/pluginSupport/image.cpp +++ b/app/pluginSupport/image.cpp @@ -23,8 +23,10 @@ #include -namespace olive { -namespace plugin { +namespace olive +{ +namespace plugin +{ static const char *PixelDepthToOfx(core::PixelFormat format) { @@ -69,16 +71,14 @@ Image::Image(OFX::Host::ImageEffect::ClipInstance &clip_instance) , premultiplied_alpha_(false) , channel_count_(0) , row_bytes_(0) - , bounds_{0, 0, 0, 0} - , rod_{0, 0, 0, 0} + , bounds_{ 0, 0, 0, 0 } + , rod_{ 0, 0, 0, 0 } { } Image::Image(OFX::Host::ImageEffect::ClipInstance &clip_instance, - const VideoParams ¶ms, - const OfxRectI &bounds, - const OfxRectI &rod, - bool clear) + const VideoParams ¶ms, const OfxRectI &bounds, + const OfxRectI &rod, bool clear) : OFX::Host::ImageEffect::Image(clip_instance) , width_(0) , height_(0) @@ -86,8 +86,8 @@ Image::Image(OFX::Host::ImageEffect::ClipInstance &clip_instance, , premultiplied_alpha_(false) , channel_count_(0) , row_bytes_(0) - , bounds_{0, 0, 0, 0} - , rod_{0, 0, 0, 0} + , bounds_{ 0, 0, 0, 0 } + , rod_{ 0, 0, 0, 0 } { AllocateFromParams(params, bounds, rod, clear); } @@ -97,24 +97,17 @@ Image::~Image() } void Image::AllocateFromParams(const VideoParams ¶ms, - const OfxRectI &bounds, - const OfxRectI &rod, + const OfxRectI &bounds, const OfxRectI &rod, bool clear) { - Allocate(bounds.x2 - bounds.x1, - bounds.y2 - bounds.y1, - params.format(), - params.channel_count(), - params.premultiplied_alpha(), - bounds, - rod, + Allocate(bounds.x2 - bounds.x1, bounds.y2 - bounds.y1, params.format(), + params.channel_count(), params.premultiplied_alpha(), bounds, rod, clear); } void Image::EnsureAllocatedFromParams(const VideoParams ¶ms, const OfxRectI &bounds, - const OfxRectI &rod, - bool clear) + const OfxRectI &rod, bool clear) { bool same = (width_ == bounds.x2 - bounds.x1) && (height_ == bounds.y2 - bounds.y1) && @@ -133,14 +126,9 @@ void Image::EnsureAllocatedFromParams(const VideoParams ¶ms, } } -void Image::Allocate(int width, - int height, - core::PixelFormat format, - int channel_count, - bool premultiplied_alpha, - const OfxRectI &bounds, - const OfxRectI &rod, - bool clear) +void Image::Allocate(int width, int height, core::PixelFormat format, + int channel_count, bool premultiplied_alpha, + const OfxRectI &bounds, const OfxRectI &rod, bool clear) { width_ = width; height_ = height; @@ -173,12 +161,11 @@ void Image::Allocate(int width, setIntProperty(kOfxImagePropRegionOfDefinition, rod.x2, 2); setIntProperty(kOfxImagePropRegionOfDefinition, rod.y2, 3); setStringProperty(kOfxImageEffectPropComponents, - ComponentsToOfx(channel_count_)); - setStringProperty(kOfxImageEffectPropPixelDepth, - PixelDepthToOfx(format_)); + ComponentsToOfx(channel_count_)); + setStringProperty(kOfxImageEffectPropPixelDepth, PixelDepthToOfx(format_)); setStringProperty(kOfxImageEffectPropPreMultiplication, - premultiplied_alpha_ ? kOfxImagePreMultiplied - : kOfxImageUnPreMultiplied); + premultiplied_alpha_ ? kOfxImagePreMultiplied : + kOfxImageUnPreMultiplied); } core::PixelFormat Image::pixel_format() @@ -212,7 +199,7 @@ bool Image::premultiplied_alpha() int Image::width() { - int bounds[4] = {0}; + int bounds[4] = { 0 }; getIntPropertyN(kOfxImagePropBounds, bounds, 4); width_ = bounds[2] - bounds[0]; return width_; @@ -220,7 +207,7 @@ int Image::width() int Image::height() { - int bounds[4] = {0}; + int bounds[4] = { 0 }; getIntPropertyN(kOfxImagePropBounds, bounds, 4); height_ = bounds[3] - bounds[1]; return height_; diff --git a/app/pluginSupport/image.h b/app/pluginSupport/image.h index 7ea5e6658..c210c1aa0 100644 --- a/app/pluginSupport/image.h +++ b/app/pluginSupport/image.h @@ -37,12 +37,11 @@ class Image : public OFX::Host::ImageEffect::Image { public: Image(OFX::Host::ImageEffect::ClipInstance &clip_instance); Image(OFX::Host::ImageEffect::ClipInstance &clip_instance, - const VideoParams ¶ms, - const OfxRectI &bounds, - const OfxRectI &rod, - bool clear = true); + const VideoParams ¶ms, const OfxRectI &bounds, + const OfxRectI &rod, bool clear = true); ~Image(); - uint8_t *data() { + uint8_t *data() + { return (uint8_t *)getPointerProperty(kOfxImagePropData); } int width(); @@ -51,26 +50,20 @@ public: bool premultiplied_alpha(); int channel_count(); - void AllocateFromParams(const VideoParams ¶ms, - const OfxRectI &bounds, - const OfxRectI &rod, - bool clear = true); + void AllocateFromParams(const VideoParams ¶ms, const OfxRectI &bounds, + const OfxRectI &rod, bool clear = true); void EnsureAllocatedFromParams(const VideoParams ¶ms, - const OfxRectI &bounds, - const OfxRectI &rod, + const OfxRectI &bounds, const OfxRectI &rod, bool clear = false); - void Allocate(int width, - int height, - core::PixelFormat format, - int channel_count, - bool premultiplied_alpha, - const OfxRectI &bounds, - const OfxRectI &rod, + void Allocate(int width, int height, core::PixelFormat format, + int channel_count, bool premultiplied_alpha, + const OfxRectI &bounds, const OfxRectI &rod, bool clear = true); int row_bytes() const { return row_bytes_; } + protected: std::vector image_; int width_; diff --git a/app/pluginSupport/paraminstance.cpp b/app/pluginSupport/paraminstance.cpp index d69ef98dd..c01056c1a 100644 --- a/app/pluginSupport/paraminstance.cpp +++ b/app/pluginSupport/paraminstance.cpp @@ -17,7 +17,6 @@ * */ - #include "paraminstance.h" #include "OlivePluginInstance.h" @@ -35,8 +34,7 @@ void SubmitUndoCommand(const std::shared_ptr &node, if (node) { auto *instance = node->getPluginInstance(); - auto *olive_instance = - dynamic_cast(instance); + auto *olive_instance = dynamic_cast(instance); if (olive_instance) { olive_instance->SubmitUndoCommand(command, label); return; diff --git a/app/pluginSupport/paraminstance.h b/app/pluginSupport/paraminstance.h index 355236204..47fab5f1d 100644 --- a/app/pluginSupport/paraminstance.h +++ b/app/pluginSupport/paraminstance.h @@ -34,14 +34,15 @@ #include "undo/undocommand.h" #include "common/Current.h" #include +#include #include namespace olive { namespace plugin { -inline bool IsNormalisedCoordinateSystem( - const OFX::Host::Param::Descriptor &descriptor) +inline bool +IsNormalisedCoordinateSystem(const OFX::Host::Param::Descriptor &descriptor) { return descriptor.getDefaultCoordinateSystem() == kOfxParamCoordinatesNormalised; @@ -79,12 +80,14 @@ public: }; class PushbuttonInstance : public OFX::Host::Param::PushbuttonInstance, - public NodeBoundParam { + public NodeBoundParam { protected: - std::shared_ptr node; + std::shared_ptr node; OFX::Host::Param::Descriptor *_descriptor; + public: - PushbuttonInstance(std::shared_ptr effect, const std::string &name, + PushbuttonInstance(std::shared_ptr effect, + const std::string &name, OFX::Host::Param::Descriptor &descriptor, OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::PushbuttonInstance(descriptor, paramSet) @@ -101,21 +104,25 @@ public: class IntegerInstance : public OFX::Host::Param::IntegerInstance, public NodeBoundParam { protected: - std::shared_ptr _node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr _node; + OFX::Host::Param::Descriptor &_descriptor; QString id; + mutable std::mutex no_node_mutex_; bool has_value_ = false; int value_ = 0; + public: - IntegerInstance(std::shared_ptrnode, OFX::Host::Param::Descriptor &descriptor, - OFX::Host::Param::SetInstance *paramSet = nullptr) + IntegerInstance(std::shared_ptr node, + OFX::Host::Param::Descriptor &descriptor, + OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::IntegerInstance(descriptor, paramSet) , _node(node) , _descriptor(descriptor) , id(_descriptor.getName().c_str()) { try { - value_ = _descriptor.getProperties().getIntProperty(kOfxParamPropDefault); + value_ = _descriptor.getProperties().getIntProperty( + kOfxParamPropDefault); has_value_ = true; } catch (...) { value_ = 0; @@ -129,41 +136,45 @@ public: OfxStatus get(int &a) { if (!_node) { + std::lock_guard lock(no_node_mutex_); a = has_value_ ? value_ : 0; return kOfxStatOK; } if (id.isEmpty()) { return kOfxStatErrBadHandle; } - QVariant variant=_node->GetStandardValue(id); + QVariant variant = _node->GetStandardValue(id); if (variant.canConvert()) { - a=variant.toInt(); + a = variant.toInt(); return kOfxStatOK; } - a=0; + a = 0; return kOfxStatErrValue; } OfxStatus get(OfxTime time, int &data) { if (!_node) { + std::lock_guard lock(no_node_mutex_); data = has_value_ ? value_ : 0; return kOfxStatOK; } if (id.isEmpty()) { return kOfxStatErrBadHandle; } - QVariant variant=_node->GetValueAtTime(id, rational::fromDouble(time)); + QVariant variant = + _node->GetValueAtTime(id, rational::fromDouble(time)); if (variant.canConvert()) { - data=variant.toInt(); + data = variant.toInt(); return kOfxStatOK; } - data=0; + data = 0; return kOfxStatErrValue; } OfxStatus set(int data) { if (!_node) { + std::lock_guard lock(no_node_mutex_); value_ = data; has_value_ = true; return kOfxStatOK; @@ -179,6 +190,7 @@ public: OfxStatus set(OfxTime time, int data) { if (!_node) { + std::lock_guard lock(no_node_mutex_); value_ = data; has_value_ = true; return kOfxStatOK; @@ -195,20 +207,23 @@ public: class DoubleInstance : public OFX::Host::Param::DoubleInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; double value_ = 0.0; + public: - DoubleInstance(std::shared_ptr effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor, - OFX::Host::Param::SetInstance *paramSet = nullptr) + DoubleInstance(std::shared_ptr effect, const std::string &name, + OFX::Host::Param::Descriptor &descriptor, + OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::DoubleInstance(descriptor, paramSet) , node(effect) , _descriptor(descriptor) { (void)name; try { - value_ = _descriptor.getProperties().getDoubleProperty(kOfxParamPropDefault); + value_ = _descriptor.getProperties().getDoubleProperty( + kOfxParamPropDefault); has_value_ = true; } catch (...) { value_ = 0.0; @@ -219,13 +234,14 @@ public: { node = new_node; } - OfxStatus get(double& data) + OfxStatus get(double &data) { if (!node) { data = has_value_ ? value_ : 0.0; return kOfxStatOK; } - QVariant variant = node->GetStandardValue(_descriptor.getName().c_str()); + QVariant variant = + node->GetStandardValue(_descriptor.getName().c_str()); if (variant.canConvert()) { data = variant.toDouble(); if (IsNormalisedCoordinateSystem(_descriptor)) { @@ -238,15 +254,14 @@ public: data = 0.0; return kOfxStatErrValue; } - OfxStatus get(OfxTime time, double& data) + OfxStatus get(OfxTime time, double &data) { if (!node) { data = has_value_ ? value_ : 0.0; return kOfxStatOK; } - QVariant variant = - node->GetValueAtTime(_descriptor.getName().c_str(), - rational::fromDouble(time)); + QVariant variant = node->GetValueAtTime(_descriptor.getName().c_str(), + rational::fromDouble(time)); if (variant.canConvert()) { data = variant.toDouble(); if (IsNormalisedCoordinateSystem(_descriptor)) { @@ -293,17 +308,17 @@ public: val = ToCanonical(val, xSize); } auto command = new MultiUndoCommand(); - Node::SetValueAtTime( - NodeInput(node.get(), _descriptor.getName().c_str()), - rational::fromDouble(time), val, 0, command, true); + Node::SetValueAtTime(NodeInput(node.get(), + _descriptor.getName().c_str()), + rational::fromDouble(time), val, 0, command, true); SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } - OfxStatus derive(OfxTime, double&) + OfxStatus derive(OfxTime, double &) { return kOfxStatErrUnsupported; } - OfxStatus integrate(OfxTime, OfxTime, double&) + OfxStatus integrate(OfxTime, OfxTime, double &) { return kOfxStatErrUnsupported; } @@ -312,18 +327,20 @@ public: class BooleanInstance : public OFX::Host::Param::BooleanInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; bool value_ = false; bool DefaultValue() const { - return _descriptor.getProperties() - .getIntProperty(kOfxParamPropDefault) != 0; + return _descriptor.getProperties().getIntProperty( + kOfxParamPropDefault) != 0; } + public: - BooleanInstance(std::shared_ptr effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor, - OFX::Host::Param::SetInstance *paramSet = nullptr) + BooleanInstance(std::shared_ptr effect, const std::string &name, + OFX::Host::Param::Descriptor &descriptor, + OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::BooleanInstance(descriptor, paramSet) , node(effect) , _descriptor(descriptor) @@ -336,13 +353,14 @@ public: { node = new_node; } - OfxStatus get(bool& data) + OfxStatus get(bool &data) { if (!node) { data = has_value_ ? value_ : false; return kOfxStatOK; } - QVariant variant = node->GetStandardValue(_descriptor.getName().c_str()); + QVariant variant = + node->GetStandardValue(_descriptor.getName().c_str()); if (variant.canConvert()) { data = variant.toBool(); return kOfxStatOK; @@ -350,17 +368,18 @@ public: data = DefaultValue(); return kOfxStatOK; } - OfxStatus get(OfxTime time, bool& data) + OfxStatus get(OfxTime time, bool &data) { if (!node) { data = has_value_ ? value_ : false; return kOfxStatOK; } - QVariant variant = - node->GetValueAtTime(_descriptor.getName().c_str(), - rational::fromDouble(time)); - if (variant.isNull()){ - qWarning().noquote()<<"Boolean get failed: Varient is null" << time << rational::fromDouble(time).toDouble(); + QVariant variant = node->GetValueAtTime(_descriptor.getName().c_str(), + rational::fromDouble(time)); + if (variant.isNull()) { + qWarning().noquote() + << "Boolean get failed: Varient is null" << time + << rational::fromDouble(time).toDouble(); } if (!variant.isValid()) { qWarning().noquote() @@ -407,20 +426,23 @@ public: class ChoiceInstance : public OFX::Host::Param::ChoiceInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; int value_ = 0; + public: - ChoiceInstance(std::shared_ptr effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor, - OFX::Host::Param::SetInstance *paramSet = nullptr) + ChoiceInstance(std::shared_ptr effect, const std::string &name, + OFX::Host::Param::Descriptor &descriptor, + OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::ChoiceInstance(descriptor, paramSet) , node(effect) , _descriptor(descriptor) { (void)name; try { - value_ = _descriptor.getProperties().getIntProperty(kOfxParamPropDefault); + value_ = _descriptor.getProperties().getIntProperty( + kOfxParamPropDefault); has_value_ = true; } catch (...) { value_ = 0; @@ -431,13 +453,14 @@ public: { node = new_node; } - OfxStatus get(int& data) + OfxStatus get(int &data) { if (!node) { data = has_value_ ? value_ : 0; return kOfxStatOK; } - QVariant variant = node->GetStandardValue(_descriptor.getName().c_str()); + QVariant variant = + node->GetStandardValue(_descriptor.getName().c_str()); if (variant.canConvert()) { data = variant.toInt(); return kOfxStatOK; @@ -445,15 +468,14 @@ public: data = 0; return kOfxStatErrValue; } - OfxStatus get(OfxTime time, int& data) + OfxStatus get(OfxTime time, int &data) { if (!node) { data = has_value_ ? value_ : 0; return kOfxStatOK; } - QVariant variant = - node->GetValueAtTime(_descriptor.getName().c_str(), - rational::fromDouble(time)); + QVariant variant = node->GetValueAtTime(_descriptor.getName().c_str(), + rational::fromDouble(time)); if (variant.canConvert()) { data = variant.toInt(); return kOfxStatOK; @@ -494,12 +516,14 @@ public: class RGBAInstance : public OFX::Host::Param::RGBAInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; - double value_[4] = {0.0, 0.0, 0.0, 0.0}; + double value_[4] = { 0.0, 0.0, 0.0, 0.0 }; + public: - RGBAInstance(std::shared_ptr effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor, + RGBAInstance(std::shared_ptr effect, const std::string &name, + OFX::Host::Param::Descriptor &descriptor, OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::RGBAInstance(descriptor, paramSet) , node(effect) @@ -511,7 +535,7 @@ public: { node = new_node; } - OfxStatus get(double& r,double& g,double& b,double& a) + OfxStatus get(double &r, double &g, double &b, double &a) { if (!node) { if (has_value_) { @@ -534,7 +558,7 @@ public: a = static_cast(c.alpha()); return kOfxStatOK; } - OfxStatus get(OfxTime time, double& r,double& g,double& b,double& a) + OfxStatus get(OfxTime time, double &r, double &g, double &b, double &a) { if (!node) { if (has_value_) { @@ -558,7 +582,7 @@ public: a = static_cast(c.alpha()); return kOfxStatOK; } - OfxStatus set(double r,double g,double b,double a) + OfxStatus set(double r, double g, double b, double a) { if (!node) { value_[0] = r; @@ -576,7 +600,7 @@ public: SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } - OfxStatus set(OfxTime time, double r,double g,double b,double a) + OfxStatus set(OfxTime time, double r, double g, double b, double a) { if (!node) { value_[0] = r; @@ -588,29 +612,30 @@ public: } auto command = new MultiUndoCommand(); const QString name = _descriptor.getName().c_str(); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - r, 0, command, true); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - g, 1, command, true); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - b, 2, command, true); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - a, 3, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), r, 0, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), g, 1, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), b, 2, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), a, 3, command, true); SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } }; - class RGBInstance : public OFX::Host::Param::RGBInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; - double value_[3] = {0.0, 0.0, 0.0}; + double value_[3] = { 0.0, 0.0, 0.0 }; + public: - RGBInstance(std::shared_ptr effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor, + RGBInstance(std::shared_ptr effect, const std::string &name, + OFX::Host::Param::Descriptor &descriptor, OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::RGBInstance(descriptor, paramSet) , node(effect) @@ -622,7 +647,7 @@ public: { node = new_node; } - OfxStatus get(double& r,double& g,double& b) + OfxStatus get(double &r, double &g, double &b) { if (!node) { if (has_value_) { @@ -643,7 +668,7 @@ public: b = static_cast(c.blue()); return kOfxStatOK; } - OfxStatus get(OfxTime time, double& r,double& g,double& b) + OfxStatus get(OfxTime time, double &r, double &g, double &b) { if (!node) { if (has_value_) { @@ -665,7 +690,7 @@ public: b = static_cast(c.blue()); return kOfxStatOK; } - OfxStatus set(double r,double g,double b) + OfxStatus set(double r, double g, double b) { if (!node) { value_[0] = r; @@ -682,7 +707,7 @@ public: SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } - OfxStatus set(OfxTime time, double r,double g,double b) + OfxStatus set(OfxTime time, double r, double g, double b) { if (!node) { value_[0] = r; @@ -693,12 +718,12 @@ public: } auto command = new MultiUndoCommand(); const QString name = _descriptor.getName().c_str(); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - r, 0, command, true); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - g, 1, command, true); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - b, 2, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), r, 0, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), g, 1, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), b, 2, command, true); SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } @@ -707,12 +732,15 @@ public: class Double2DInstance : public OFX::Host::Param::Double2DInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; - double value_[2] = {0.0, 0.0}; + double value_[2] = { 0.0, 0.0 }; + public: - Double2DInstance(std::shared_ptr effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor, + Double2DInstance(std::shared_ptr effect, + const std::string &name, + OFX::Host::Param::Descriptor &descriptor, OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::Double2DInstance(descriptor, paramSet) , node(effect) @@ -724,7 +752,7 @@ public: { node = new_node; } - OfxStatus get(double& x,double& y) + OfxStatus get(double &x, double &y) { if (!node) { if (has_value_) { @@ -735,9 +763,8 @@ public: } return kOfxStatOK; } - QVector2D vec = - node->GetStandardValue(_descriptor.getName().c_str()) - .value(); + QVector2D vec = node->GetStandardValue(_descriptor.getName().c_str()) + .value(); x = static_cast(vec.x()); y = static_cast(vec.y()); if (IsNormalisedCoordinateSystem(_descriptor)) { @@ -748,7 +775,7 @@ public: } return kOfxStatOK; } - OfxStatus get(OfxTime time,double& x,double& y) + OfxStatus get(OfxTime time, double &x, double &y) { if (!node) { if (has_value_) { @@ -759,10 +786,9 @@ public: } return kOfxStatOK; } - QVector2D vec = - node->GetValueAtTime(_descriptor.getName().c_str(), - rational::fromDouble(time)) - .value(); + QVector2D vec = node->GetValueAtTime(_descriptor.getName().c_str(), + rational::fromDouble(time)) + .value(); x = static_cast(vec.x()); y = static_cast(vec.y()); if (IsNormalisedCoordinateSystem(_descriptor)) { @@ -773,7 +799,7 @@ public: } return kOfxStatOK; } - OfxStatus set(double x,double y) + OfxStatus set(double x, double y) { if (!node) { value_[0] = x; @@ -795,7 +821,7 @@ public: SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } - OfxStatus set(OfxTime time,double x,double y) + OfxStatus set(OfxTime time, double x, double y) { if (!node) { value_[0] = x; @@ -812,10 +838,10 @@ public: } auto command = new MultiUndoCommand(); const QString name = _descriptor.getName().c_str(); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - xv, 0, command, true); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - yv, 1, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), xv, 0, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), yv, 1, command, true); SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } @@ -824,12 +850,15 @@ public: class Integer2DInstance : public OFX::Host::Param::Integer2DInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; - int value_[2] = {0, 0}; + int value_[2] = { 0, 0 }; + public: - Integer2DInstance(std::shared_ptr effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor, + Integer2DInstance(std::shared_ptr effect, + const std::string &name, + OFX::Host::Param::Descriptor &descriptor, OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::Integer2DInstance(descriptor, paramSet) , node(effect) @@ -841,7 +870,7 @@ public: { node = new_node; } - OfxStatus get(int& x,int& y) + OfxStatus get(int &x, int &y) { if (!node) { if (has_value_) { @@ -852,14 +881,13 @@ public: } return kOfxStatOK; } - QVector2D vec = - node->GetStandardValue(_descriptor.getName().c_str()) - .value(); + QVector2D vec = node->GetStandardValue(_descriptor.getName().c_str()) + .value(); x = static_cast(vec.x()); y = static_cast(vec.y()); return kOfxStatOK; } - OfxStatus get(OfxTime time,int& x,int& y) + OfxStatus get(OfxTime time, int &x, int &y) { if (!node) { if (has_value_) { @@ -870,15 +898,14 @@ public: } return kOfxStatOK; } - QVector2D vec = - node->GetValueAtTime(_descriptor.getName().c_str(), - rational::fromDouble(time)) - .value(); + QVector2D vec = node->GetValueAtTime(_descriptor.getName().c_str(), + rational::fromDouble(time)) + .value(); x = static_cast(vec.x()); y = static_cast(vec.y()); return kOfxStatOK; } - OfxStatus set(int x,int y) + OfxStatus set(int x, int y) { if (!node) { value_[0] = x; @@ -893,7 +920,7 @@ public: SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } - OfxStatus set(OfxTime time,int x,int y) + OfxStatus set(OfxTime time, int x, int y) { if (!node) { value_[0] = x; @@ -903,10 +930,10 @@ public: } auto command = new MultiUndoCommand(); const QString name = _descriptor.getName().c_str(); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - x, 0, command, true); - Node::SetValueAtTime(NodeInput(node.get(), name), rational::fromDouble(time), - y, 1, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), x, 0, command, true); + Node::SetValueAtTime(NodeInput(node.get(), name), + rational::fromDouble(time), y, 1, command, true); SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } @@ -915,13 +942,15 @@ public: class Double3DInstance : public OFX::Host::Param::Double3DInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; - double value_[3] = {0.0, 0.0, 0.0}; + double value_[3] = { 0.0, 0.0, 0.0 }; + public: - Double3DInstance(std::shared_ptr effect, const std::string& name, - OFX::Host::Param::Descriptor& descriptor, + Double3DInstance(std::shared_ptr effect, + const std::string &name, + OFX::Host::Param::Descriptor &descriptor, OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::Double3DInstance(descriptor, paramSet) , node(effect) @@ -933,7 +962,7 @@ public: { node = new_node; } - OfxStatus get(double& x,double& y,double& z) + OfxStatus get(double &x, double &y, double &z) { if (!node) { if (has_value_) { @@ -945,9 +974,8 @@ public: } return kOfxStatOK; } - QVector3D vec = - node->GetStandardValue(_descriptor.getName().c_str()) - .value(); + QVector3D vec = node->GetStandardValue(_descriptor.getName().c_str()) + .value(); x = static_cast(vec.x()); y = static_cast(vec.y()); z = static_cast(vec.z()); @@ -960,7 +988,7 @@ public: } return kOfxStatOK; } - OfxStatus get(OfxTime time,double& x,double& y,double& z) + OfxStatus get(OfxTime time, double &x, double &y, double &z) { if (!node) { if (has_value_) { @@ -972,10 +1000,9 @@ public: } return kOfxStatOK; } - QVector3D vec = - node->GetValueAtTime(_descriptor.getName().c_str(), - rational::fromDouble(time)) - .value(); + QVector3D vec = node->GetValueAtTime(_descriptor.getName().c_str(), + rational::fromDouble(time)) + .value(); x = static_cast(vec.x()); y = static_cast(vec.y()); z = static_cast(vec.z()); @@ -988,7 +1015,7 @@ public: } return kOfxStatOK; } - OfxStatus set(double x,double y,double z) + OfxStatus set(double x, double y, double z) { if (!node) { value_[0] = x; @@ -1012,7 +1039,7 @@ public: SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } - OfxStatus set(OfxTime time,double x,double y,double z) + OfxStatus set(OfxTime time, double x, double y, double z) { if (!node) { value_[0] = x; @@ -1045,13 +1072,15 @@ public: class Integer3DInstance : public OFX::Host::Param::Integer3DInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; - int value_[3] = {0, 0, 0}; + int value_[3] = { 0, 0, 0 }; + public: - Integer3DInstance(std::shared_ptr effect, const std::string& name, - OFX::Host::Param::Descriptor& descriptor, + Integer3DInstance(std::shared_ptr effect, + const std::string &name, + OFX::Host::Param::Descriptor &descriptor, OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::Integer3DInstance(descriptor, paramSet) , node(effect) @@ -1063,7 +1092,7 @@ public: { node = new_node; } - OfxStatus get(int& x,int& y,int& z) + OfxStatus get(int &x, int &y, int &z) { if (!node) { if (has_value_) { @@ -1075,15 +1104,14 @@ public: } return kOfxStatOK; } - QVector3D vec = - node->GetStandardValue(_descriptor.getName().c_str()) - .value(); + QVector3D vec = node->GetStandardValue(_descriptor.getName().c_str()) + .value(); x = static_cast(vec.x()); y = static_cast(vec.y()); z = static_cast(vec.z()); return kOfxStatOK; } - OfxStatus get(OfxTime time,int& x,int& y,int& z) + OfxStatus get(OfxTime time, int &x, int &y, int &z) { if (!node) { if (has_value_) { @@ -1095,16 +1123,15 @@ public: } return kOfxStatOK; } - QVector3D vec = - node->GetValueAtTime(_descriptor.getName().c_str(), - rational::fromDouble(time)) - .value(); + QVector3D vec = node->GetValueAtTime(_descriptor.getName().c_str(), + rational::fromDouble(time)) + .value(); x = static_cast(vec.x()); y = static_cast(vec.y()); z = static_cast(vec.z()); return kOfxStatOK; } - OfxStatus set(int x,int y,int z) + OfxStatus set(int x, int y, int z) { if (!node) { value_[0] = x; @@ -1120,7 +1147,7 @@ public: SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } - OfxStatus set(OfxTime time,int x,int y,int z) + OfxStatus set(OfxTime time, int x, int y, int z) { if (!node) { value_[0] = x; @@ -1145,13 +1172,14 @@ public: class StringInstance : public OFX::Host::Param::StringInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; std::string value_; + public: - StringInstance(std::shared_ptr effect, const std::string& name, - OFX::Host::Param::Descriptor& descriptor, + StringInstance(std::shared_ptr effect, const std::string &name, + OFX::Host::Param::Descriptor &descriptor, OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::StringInstance(descriptor, paramSet) , node(effect) @@ -1159,7 +1187,8 @@ public: { (void)name; try { - value_ = _descriptor.getProperties().getStringProperty(kOfxParamPropDefault); + value_ = _descriptor.getProperties().getStringProperty( + kOfxParamPropDefault); has_value_ = true; } catch (...) { value_.clear(); @@ -1176,7 +1205,8 @@ public: data = has_value_ ? value_ : std::string(); return kOfxStatOK; } - QVariant variant = node->GetStandardValue(_descriptor.getName().c_str()); + QVariant variant = + node->GetStandardValue(_descriptor.getName().c_str()); if (variant.canConvert()) { data = variant.toString().toStdString(); return kOfxStatOK; @@ -1190,9 +1220,8 @@ public: data = has_value_ ? value_ : std::string(); return kOfxStatOK; } - QVariant variant = - node->GetValueAtTime(_descriptor.getName().c_str(), - rational::fromDouble(time)); + QVariant variant = node->GetValueAtTime(_descriptor.getName().c_str(), + rational::fromDouble(time)); if (variant.canConvert()) { data = variant.toString().toStdString(); return kOfxStatOK; @@ -1223,9 +1252,10 @@ public: return kOfxStatOK; } auto command = new MultiUndoCommand(); - Node::SetValueAtTime( - NodeInput(node.get(), _descriptor.getName().c_str()), - rational::fromDouble(time), QString::fromUtf8(data), 0, command, true); + Node::SetValueAtTime(NodeInput(node.get(), + _descriptor.getName().c_str()), + rational::fromDouble(time), + QString::fromUtf8(data), 0, command, true); SubmitUndoCommand(node, command, ParamChangeLabel(_descriptor)); return kOfxStatOK; } @@ -1234,13 +1264,14 @@ public: class CustomInstance : public OFX::Host::Param::CustomInstance, public NodeBoundParam { protected: - std::shared_ptr node; - OFX::Host::Param::Descriptor& _descriptor; + std::shared_ptr node; + OFX::Host::Param::Descriptor &_descriptor; bool has_value_ = false; std::string value_; + public: - CustomInstance(std::shared_ptr effect, const std::string& name, - OFX::Host::Param::Descriptor& descriptor, + CustomInstance(std::shared_ptr effect, const std::string &name, + OFX::Host::Param::Descriptor &descriptor, OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::CustomInstance(descriptor, paramSet) , node(effect) @@ -1258,7 +1289,8 @@ public: data = has_value_ ? value_ : std::string(); return kOfxStatOK; } - QVariant variant = node->GetStandardValue(_descriptor.getName().c_str()); + QVariant variant = + node->GetStandardValue(_descriptor.getName().c_str()); if (variant.canConvert()) { data = variant.toByteArray().toStdString(); return kOfxStatOK; @@ -1276,9 +1308,8 @@ public: data = has_value_ ? value_ : std::string(); return kOfxStatOK; } - QVariant variant = - node->GetValueAtTime(_descriptor.getName().c_str(), - rational::fromDouble(time)); + QVariant variant = node->GetValueAtTime(_descriptor.getName().c_str(), + rational::fromDouble(time)); if (variant.canConvert()) { data = variant.toByteArray().toStdString(); return kOfxStatOK; @@ -1323,8 +1354,8 @@ public: class GroupInstance : public OFX::Host::Param::GroupInstance { public: - GroupInstance(OFX::Host::Param::Descriptor& descriptor, - OFX::Host::Param::SetInstance *paramSet = nullptr) + GroupInstance(OFX::Host::Param::Descriptor &descriptor, + OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::GroupInstance(descriptor, paramSet) { } @@ -1332,8 +1363,8 @@ public: class PageInstance : public OFX::Host::Param::PageInstance { public: - PageInstance(OFX::Host::Param::Descriptor& descriptor, - OFX::Host::Param::SetInstance *paramSet = nullptr) + PageInstance(OFX::Host::Param::Descriptor &descriptor, + OFX::Host::Param::SetInstance *paramSet = nullptr) : OFX::Host::Param::PageInstance(descriptor, paramSet) { } @@ -1341,6 +1372,4 @@ public: } } - - #endif // HOST_DEMO_PARAM_INSTANCE_H diff --git a/app/render/CMakeLists.txt b/app/render/CMakeLists.txt index c3bfbcfb5..69a60d657 100644 --- a/app/render/CMakeLists.txt +++ b/app/render/CMakeLists.txt @@ -21,62 +21,62 @@ add_subdirectory(ocioconf) add_subdirectory(opengl) add_subdirectory(plugin) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - render/audioplaybackcache.cpp - render/audioplaybackcache.h - render/audiowaveformcache.cpp - render/audiowaveformcache.h - render/backend/dynamicrenderer.cpp - render/backend/dynamicrenderer.h - render/backend/renderbackend_c.h - render/cancelatom.h - render/colormanagement.cpp - render/colorprocessor.cpp - render/colorprocessor.h - render/colorprocessorcache.h - render/diskmanager.cpp - render/diskmanager.h - render/framehashcache.cpp - render/framehashcache.h - render/framemanager.cpp - render/framemanager.h - render/interlacetexture.cpp - render/loopmode.h - render/managedcolor.cpp - render/managedcolor.h - render/playbackcache.cpp - render/playbackcache.h - render/previewaudiodevice.cpp - render/previewaudiodevice.h - render/previewautocacher.cpp - render/previewautocacher.h - render/projectcopier.cpp - render/projectcopier.h - render/renderer.cpp - render/renderer.h - render/rendercache.h - render/renderjobtracker.cpp - render/renderjobtracker.h - render/rendermanager.cpp - render/rendermanager.h - render/renderworkerpool.cpp - render/renderworkerpool.h - render/rendermodes.h - render/renderprocessor.cpp - render/renderprocessor.h - render/renderticket.cpp - render/renderticket.h - render/shadercode.h - render/subtitleparams.cpp - render/subtitleparams.h - render/texture.cpp - render/texture.h - render/videoparams.cpp - render/videoparams.h - PARENT_SCOPE + ${OLIVE_SOURCES} + render/audioplaybackcache.cpp + render/audioplaybackcache.h + render/audiowaveformcache.cpp + render/audiowaveformcache.h + render/backend/dynamicrenderer.cpp + render/backend/dynamicrenderer.h + render/backend/renderbackend_c.h + render/cancelatom.h + render/colormanagement.cpp + render/colorprocessor.cpp + render/colorprocessor.h + render/colorprocessorcache.h + render/diskmanager.cpp + render/diskmanager.h + render/framehashcache.cpp + render/framehashcache.h + render/framemanager.cpp + render/framemanager.h + render/interlacetexture.cpp + render/loopmode.h + render/managedcolor.cpp + render/managedcolor.h + render/playbackcache.cpp + render/playbackcache.h + render/previewaudiodevice.cpp + render/previewaudiodevice.h + render/previewautocacher.cpp + render/previewautocacher.h + render/projectcopier.cpp + render/projectcopier.h + render/renderer.cpp + render/renderer.h + render/rendercache.h + render/renderjobtracker.cpp + render/renderjobtracker.h + render/rendermanager.cpp + render/rendermanager.h + render/renderworkerpool.cpp + render/renderworkerpool.h + render/rendermodes.h + render/renderprocessor.cpp + render/renderprocessor.h + render/renderticket.cpp + render/renderticket.h + render/shadercode.h + render/subtitleparams.cpp + render/subtitleparams.h + render/texture.cpp + render/texture.h + render/videoparams.cpp + render/videoparams.h + PARENT_SCOPE ) set(OLIVE_RESOURCES - ${OLIVE_RESOURCES} - PARENT_SCOPE + ${OLIVE_RESOURCES} + PARENT_SCOPE ) diff --git a/app/render/backend/dynamicrenderer.cpp b/app/render/backend/dynamicrenderer.cpp index eaeb8ab55..9683a1bb0 100644 --- a/app/render/backend/dynamicrenderer.cpp +++ b/app/render/backend/dynamicrenderer.cpp @@ -37,21 +37,24 @@ DynamicRenderer::~DynamicRenderer() // system libGL/libvulkan loader is never mistaken for an Oak render backend. QString DynamicRenderer::LibraryFilename() const { - const QString base = backend_ == QStringLiteral("vulkan") - ? QStringLiteral("oakvulkan") - : QStringLiteral("oakgl"); + const QString base = backend_ == QStringLiteral("vulkan") ? + QStringLiteral("oakvulkan") : + QStringLiteral("oakgl"); #if defined(Q_OS_WIN) const QString filename = base + QStringLiteral(".dll"); #elif defined(Q_OS_MAC) - const QString filename = QStringLiteral("lib") + base + QStringLiteral(".dylib"); + const QString filename = + QStringLiteral("lib") + base + QStringLiteral(".dylib"); #else - const QString filename = QStringLiteral("lib") + base + QStringLiteral(".so"); + const QString filename = + QStringLiteral("lib") + base + QStringLiteral(".so"); #endif const QDir app_dir(QCoreApplication::applicationDirPath()); const QStringList candidates = { app_dir.filePath(filename), - app_dir.filePath(QDir(QStringLiteral("render_backends")).filePath(filename)), + app_dir.filePath( + QDir(QStringLiteral("render_backends")).filePath(filename)), app_dir.filePath(QDir(QStringLiteral("../lib")).filePath(filename)), app_dir.filePath(QDir(QStringLiteral("../../lib")).filePath(filename)), app_dir.filePath(QDir(QStringLiteral("../app")).filePath(filename)), @@ -77,9 +80,9 @@ bool DynamicRenderer::Load() library_.setFileName(LibraryFilename()); if (!library_.load()) { if (backend_ == QStringLiteral("vulkan")) { - qWarning() << "Failed to load Vulkan render backend" - << library_.fileName() << library_.errorString() - << "falling back to OpenGL backend"; + qWarning() + << "Failed to load Vulkan render backend" << library_.fileName() + << library_.errorString() << "falling back to OpenGL backend"; backend_ = QStringLiteral("opengl"); library_.setFileName(LibraryFilename()); } @@ -126,9 +129,10 @@ bool DynamicRenderer::Load() bool DynamicRenderer::ResolveFunctions() { ResetFunctions(); -#define RESOLVE(member, type, symbol) \ +#define RESOLVE(member, type, symbol) \ member = reinterpret_cast(library_.resolve(symbol)); \ - if (!member) return false + if (!member) \ + return false RESOLVE(create_, OakBackendCreateFn, "oak_renderer_create"); RESOLVE(destroy_, OakBackendDestroyFn, "oak_renderer_destroy"); @@ -259,7 +263,7 @@ void DynamicRenderer::PostInit() // Forwards render target clearing through the C ABI. void DynamicRenderer::ClearDestination(Texture *texture, double r, double g, - double b, double a) + double b, double a) { clear_destination_(handle_, texture, r, g, b, a); } @@ -281,16 +285,16 @@ void DynamicRenderer::DestroyNativeShader(QVariant shader) // Uploads CPU pixel data into a backend texture through the dynamic ABI. void DynamicRenderer::UploadToTexture(const QVariant &handle, - const VideoParams ¶ms, const void *data, - int linesize) + const VideoParams ¶ms, + const void *data, int linesize) { upload_to_texture_(handle_, &handle, ¶ms, data, linesize); } // Downloads backend texture data into a caller-provided CPU buffer. void DynamicRenderer::DownloadFromTexture(const QVariant &handle, - const VideoParams ¶ms, void *data, - int linesize) + const VideoParams ¶ms, void *data, + int linesize) { download_from_texture_(handle_, &handle, ¶ms, data, linesize); } @@ -313,9 +317,9 @@ Color DynamicRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt) // null so callers can avoid GL-only paths. QOpenGLContext *DynamicRenderer::OpenGLContext() const { - return opengl_context_ && handle_ - ? static_cast(opengl_context_(handle_)) - : nullptr; + return opengl_context_ && handle_ ? + static_cast(opengl_context_(handle_)) : + nullptr; } // Reports the effective backend after any load-time fallback has completed. @@ -331,8 +335,8 @@ bool DynamicRenderer::IsVulkan() const // Dispatches a shader blit to the loaded backend. void DynamicRenderer::Blit(QVariant shader, AcceleratedJob &job, - Texture *destination, VideoParams destination_params, - bool clear_destination) + Texture *destination, VideoParams destination_params, + bool clear_destination) { blit_(handle_, &shader, &job, destination, &destination_params, clear_destination); @@ -340,12 +344,13 @@ void DynamicRenderer::Blit(QVariant shader, AcceleratedJob &job, // Allocates a backend-native texture and wraps its opaque handle in QVariant. QVariant DynamicRenderer::CreateNativeTexture(int width, int height, int depth, - PixelFormat format, int channel_count, - const void *data, int linesize) + PixelFormat format, + int channel_count, + const void *data, int linesize) { QVariant out; create_native_texture_(handle_, width, height, depth, format, channel_count, - data, linesize, &out); + data, linesize, &out); return out; } diff --git a/app/render/backend/dynamicrenderer.h b/app/render/backend/dynamicrenderer.h index 2a0705a53..5ea0b684b 100644 --- a/app/render/backend/dynamicrenderer.h +++ b/app/render/backend/dynamicrenderer.h @@ -42,26 +42,26 @@ public: // Runs backend post-init setup. virtual void PostInit() override; // Clears either a native texture destination or the backend output target. - virtual void ClearDestination(Texture *texture = nullptr, - double r = 0.0, double g = 0.0, - double b = 0.0, double a = 0.0) override; + virtual void ClearDestination(Texture *texture = nullptr, double r = 0.0, + double g = 0.0, double b = 0.0, + double a = 0.0) override; // Creates a native shader through the dynamic backend. virtual QVariant CreateNativeShader(ShaderCode code) override; // Destroys a native shader through the dynamic backend. virtual void DestroyNativeShader(QVariant shader) override; // Uploads CPU pixels to a backend texture. virtual void UploadToTexture(const QVariant &handle, - const VideoParams ¶ms, const void *data, - int linesize) override; + const VideoParams ¶ms, const void *data, + int linesize) override; // Downloads backend texture pixels to CPU memory. virtual void DownloadFromTexture(const QVariant &handle, - const VideoParams ¶ms, void *data, - int linesize) override; + const VideoParams ¶ms, void *data, + int linesize) override; // Waits for backend work to complete. virtual void Flush() override; // Reads one pixel from a backend texture. virtual Color GetPixelFromTexture(Texture *texture, - const QPointF &pt) override; + const QPointF &pt) override; // Returns the wrapped OpenGL context for OpenGL backends. virtual QOpenGLContext *OpenGLContext() const override; @@ -79,13 +79,13 @@ public: protected: // Dispatches a shader blit through the dynamic backend. virtual void Blit(QVariant shader, AcceleratedJob &job, - Texture *destination, VideoParams destination_params, - bool clear_destination) override; + Texture *destination, VideoParams destination_params, + bool clear_destination) override; // Allocates a native texture through the dynamic backend. virtual QVariant CreateNativeTexture(int width, int height, int depth, - PixelFormat format, int channel_count, - const void *data = nullptr, - int linesize = 0) override; + PixelFormat format, int channel_count, + const void *data = nullptr, + int linesize = 0) override; // Releases a native texture through the dynamic backend. virtual void DestroyNativeTexture(QVariant texture) override; // Releases backend-owned renderer resources. diff --git a/app/render/backend/renderbackend_c.h b/app/render/backend/renderbackend_c.h index 173f55d6c..11ebc0ea3 100644 --- a/app/render/backend/renderbackend_c.h +++ b/app/render/backend/renderbackend_c.h @@ -7,7 +7,8 @@ #ifdef _WIN32 #define OAK_RENDER_BACKEND_EXPORT extern "C" __declspec(dllexport) #else -#define OAK_RENDER_BACKEND_EXPORT extern "C" __attribute__((visibility("default"))) +#define OAK_RENDER_BACKEND_EXPORT \ + extern "C" __attribute__((visibility("default"))) #endif #ifdef __cplusplus @@ -50,14 +51,14 @@ typedef OakRenderBackendHandle (*OakBackendCreateFn)(void *parent); typedef void (*OakBackendDestroyFn)(OakRenderBackendHandle handle); /* Queries backend metadata and capability bits. */ typedef bool (*OakBackendGetInfoFn)(OakRenderBackendHandle handle, - struct OakRenderBackendInfo *out_info); + struct OakRenderBackendInfo *out_info); /* Checks whether the backend can run on the current machine. */ typedef bool (*OakBackendIsAvailableFn)(OakRenderBackendHandle handle); /* Initializes backend-owned device/context resources. */ typedef bool (*OakBackendInitFn)(OakRenderBackendHandle handle); /* Initializes the backend against a caller-supplied GL context when applicable. */ typedef void (*OakBackendInitWithContextFn)(OakRenderBackendHandle handle, - void *context); + void *context); /* Runs backend post-initialization after the device/context exists. */ typedef void (*OakBackendPostInitFn)(OakRenderBackendHandle handle); /* Runs backend post-destroy cleanup before the library unloads. */ @@ -66,40 +67,39 @@ typedef void (*OakBackendPostDestroyFn)(OakRenderBackendHandle handle); typedef void (*OakBackendDestroyInternalFn)(OakRenderBackendHandle handle); /* Clears a texture destination or implicit output target. */ typedef void (*OakBackendClearDestinationFn)(OakRenderBackendHandle handle, - void *texture, double r, double g, - double b, double a); + void *texture, double r, double g, + double b, double a); /* Creates a native texture and writes a QVariant-compatible handle. */ -typedef void (*OakBackendCreateNativeTextureFn)(OakRenderBackendHandle handle, - int width, int height, int depth, - int format, int channel_count, - const void *data, int linesize, - void *out_variant); +typedef void (*OakBackendCreateNativeTextureFn)( + OakRenderBackendHandle handle, int width, int height, int depth, int format, + int channel_count, const void *data, int linesize, void *out_variant); /* Destroys a native texture represented by a QVariant-compatible handle. */ typedef void (*OakBackendDestroyNativeTextureFn)(OakRenderBackendHandle handle, - const void *variant); + const void *variant); /* Creates a native shader and writes a QVariant-compatible handle. */ typedef void (*OakBackendCreateNativeShaderFn)(OakRenderBackendHandle handle, - const void *shader_code, - void *out_variant); + const void *shader_code, + void *out_variant); /* Destroys a native shader represented by a QVariant-compatible handle. */ typedef void (*OakBackendDestroyNativeShaderFn)(OakRenderBackendHandle handle, - const void *variant); + const void *variant); /* Uploads CPU pixel data to a native texture. */ typedef void (*OakBackendUploadToTextureFn)(OakRenderBackendHandle handle, - const void *variant, - const void *video_params, - const void *data, int linesize); + const void *variant, + const void *video_params, + const void *data, int linesize); /* Downloads native texture pixels into caller-owned CPU memory. */ typedef void (*OakBackendDownloadFromTextureFn)(OakRenderBackendHandle handle, - const void *variant, - const void *video_params, - void *data, int linesize); + const void *variant, + const void *video_params, + void *data, int linesize); /* Waits for backend work that must be visible to later operations. */ typedef void (*OakBackendFlushFn)(OakRenderBackendHandle handle); /* Reads one pixel from a texture. */ typedef void (*OakBackendGetPixelFromTextureFn)(OakRenderBackendHandle handle, - void *texture, const void *point, - void *out_color); + void *texture, + const void *point, + void *out_color); /* Executes a shader blit job. */ typedef void (*OakBackendBlitFn)(OakRenderBackendHandle handle, const void *shader, void *job, @@ -108,7 +108,7 @@ typedef void (*OakBackendBlitFn)(OakRenderBackendHandle handle, bool clear_destination); /* Attaches an output texture for OFX OpenGL rendering when supported. */ typedef void (*OakBackendAttachOutputTextureFn)(OakRenderBackendHandle handle, - const void *texture_id); + const void *texture_id); /* Detaches an OFX output texture when supported. */ typedef void (*OakBackendDetachOutputTextureFn)(OakRenderBackendHandle handle); /* Returns the backend OpenGL context, or null for non-OpenGL backends. */ diff --git a/app/render/colormanagement.cpp b/app/render/colormanagement.cpp index 2a7751f9a..de57bd8b4 100644 --- a/app/render/colormanagement.cpp +++ b/app/render/colormanagement.cpp @@ -114,7 +114,7 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, color_ctx.lut3d_textures[i].name = sampler_name; color_ctx.lut3d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : - Texture::kLinear; + Texture::kLinear; } color_ctx.lut1d_textures.resize(shader_desc->getNumTextures()); @@ -125,7 +125,8 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, OCIO::GpuShaderDesc::TextureType channel = OCIO::GpuShaderDesc::TEXTURE_RGB_CHANNEL; OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR; -#if OCIO_VERSION_MAJOR > 2 || (OCIO_VERSION_MAJOR == 2 && OCIO_VERSION_MINOR >= 3) +#if OCIO_VERSION_MAJOR > 2 || \ + (OCIO_VERSION_MAJOR == 2 && OCIO_VERSION_MINOR >= 3) OCIO::GpuShaderDesc::TextureDimensions dimensions = OCIO::GpuShaderDesc::TEXTURE_2D; shader_desc->getTexture(i, tex_name, sampler_name, width, height, @@ -149,16 +150,18 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, } // Allocate 1D LUT - int lut_channels = (channel == - OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? - 1 : - VideoParams::kRGBChannelCount; - VideoParams lut_params(width, height, PixelFormat::F32, lut_channels); - color_ctx.lut1d_textures[i].texture = CreateTexture(lut_params, values); + int lut_channels = + (channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? + 1 : + VideoParams::kRGBChannelCount; + VideoParams lut_params(width, height, PixelFormat::F32, + lut_channels); + color_ctx.lut1d_textures[i].texture = + CreateTexture(lut_params, values); color_ctx.lut1d_textures[i].name = sampler_name; color_ctx.lut1d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : - Texture::kLinear; + Texture::kLinear; } locker.relock(); @@ -176,9 +179,9 @@ void Renderer::BlitColorManaged(const ColorTransformJob &color_job, ShaderJob fallback_job; fallback_job.Insert(QStringLiteral("ove_maintex"), color_job.GetInputTexture()); - fallback_job.Insert( - QStringLiteral("ove_mvpmat"), - NodeValue(NodeValue::kMatrix, color_job.GetTransformMatrix())); + fallback_job.Insert(QStringLiteral("ove_mvpmat"), + NodeValue(NodeValue::kMatrix, + color_job.GetTransformMatrix())); if (destination) { BlitToTexture(GetDefaultShader(), fallback_job, destination, @@ -206,12 +209,12 @@ void Renderer::BlitColorManaged(const ColorTransformJob &color_job, foreach (const ColorContext::LUT &l, color_ctx.lut3d_textures) { job.Insert(l.name, NodeValue(NodeValue::kTexture, - QVariant::fromValue(l.texture))); + QVariant::fromValue(l.texture))); job.SetInterpolation(l.name, l.interpolation); } foreach (const ColorContext::LUT &l, color_ctx.lut1d_textures) { job.Insert(l.name, NodeValue(NodeValue::kTexture, - QVariant::fromValue(l.texture))); + QVariant::fromValue(l.texture))); job.SetInterpolation(l.name, l.interpolation); } diff --git a/app/render/colorprocessor.cpp b/app/render/colorprocessor.cpp index 6f6d8b487..e9a5cd4c5 100644 --- a/app/render/colorprocessor.cpp +++ b/app/render/colorprocessor.cpp @@ -29,8 +29,8 @@ namespace olive { ColorProcessor::ColorProcessor(ColorManager *config, const QString &input, - const ColorTransform &transform, - Direction direction) + const ColorTransform &transform, + Direction direction) { processor_ = nullptr; cpu_processor_ = nullptr; @@ -59,17 +59,18 @@ ColorProcessor::ColorProcessor(ColorManager *config, const QString &input, display_transform->setDisplay(output.toUtf8()); display_transform->setView(view.toUtf8()); display_transform->setDirection(direction == kNormal ? - OCIO::TRANSFORM_DIR_FORWARD : - OCIO::TRANSFORM_DIR_INVERSE); + OCIO::TRANSFORM_DIR_FORWARD : + OCIO::TRANSFORM_DIR_INVERSE); if (transform.look().isEmpty()) { processor_ = ocio_config->getProcessor(display_transform); } else { auto group = OCIO::GroupTransform::Create(); - const char *out_cs = OCIO::LookTransform::GetLooksResultColorSpace( - ocio_config, ocio_config->getCurrentContext(), - transform.look().toUtf8()); + const char *out_cs = + OCIO::LookTransform::GetLooksResultColorSpace( + ocio_config, ocio_config->getCurrentContext(), + transform.look().toUtf8()); auto lt = OCIO::LookTransform::Create(); lt->setSrc(resolved_input.toUtf8()); @@ -105,7 +106,8 @@ ColorProcessor::ColorProcessor(ColorManager *config, const QString &input, ColorProcessor::ColorProcessor(OCIO::ConstProcessorRcPtr processor) { processor_ = processor; - cpu_processor_ = processor_ ? processor_->getDefaultCPUProcessor() : nullptr; + cpu_processor_ = processor_ ? processor_->getDefaultCPUProcessor() : + nullptr; } void ColorProcessor::ConvertFrame(Frame *f) @@ -151,7 +153,7 @@ ColorProcessorPtr ColorProcessor::Create(ColorManager *config, Direction direction) { return std::make_shared(config, input, transform, - direction); + direction); } ColorProcessorPtr ColorProcessor::Create(OCIO::ConstProcessorRcPtr processor) diff --git a/app/render/ipc/CMakeLists.txt b/app/render/ipc/CMakeLists.txt index ef1cdaaa7..1fa59d3f5 100644 --- a/app/render/ipc/CMakeLists.txt +++ b/app/render/ipc/CMakeLists.txt @@ -15,13 +15,13 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - render/ipc/frameslotpool.cpp - render/ipc/frameslotpool.h - render/ipc/ipcmessage.cpp - render/ipc/ipcmessage.h - render/ipc/sharedmemoryregion.cpp - render/ipc/sharedmemoryregion.h - render/ipc/spscringbuffer.h - PARENT_SCOPE + ${OLIVE_SOURCES} + render/ipc/frameslotpool.cpp + render/ipc/frameslotpool.h + render/ipc/ipcmessage.cpp + render/ipc/ipcmessage.h + render/ipc/sharedmemoryregion.cpp + render/ipc/sharedmemoryregion.h + render/ipc/spscringbuffer.h + PARENT_SCOPE ) \ No newline at end of file diff --git a/app/render/ipc/frameslotpool.cpp b/app/render/ipc/frameslotpool.cpp index da9345e3c..218d54a33 100644 --- a/app/render/ipc/frameslotpool.cpp +++ b/app/render/ipc/frameslotpool.cpp @@ -36,18 +36,21 @@ size_t AlignUp(size_t value, size_t align) return (value + (align - 1)) & ~(align - 1); } -constexpr size_t kAlign = 64; // Cache-line alignment for each sub-region. +constexpr size_t kAlign = 64; // Cache-line alignment for each sub-region. -} // namespace +} // namespace size_t FrameSlotPool::BytesNeeded(uint32_t slot_count, size_t slot_data_bytes) { const uint32_t ring_cap = RingCapacity(slot_count); size_t total = AlignUp(sizeof(Header), kAlign); - total += AlignUp(SpscRingBuffer::BytesNeeded(ring_cap), kAlign); // free ring - total += AlignUp(SpscRingBuffer::BytesNeeded(ring_cap), kAlign); // ready ring - total += AlignUp(sizeof(FrameSlotMeta) * slot_count, kAlign); // metadata array - total += AlignUp(slot_data_bytes, kAlign) * slot_count; // pixel data blocks + total += + AlignUp(SpscRingBuffer::BytesNeeded(ring_cap), kAlign); // free ring + total += + AlignUp(SpscRingBuffer::BytesNeeded(ring_cap), kAlign); // ready ring + total += + AlignUp(sizeof(FrameSlotMeta) * slot_count, kAlign); // metadata array + total += AlignUp(slot_data_bytes, kAlign) * slot_count; // pixel data blocks return total; } @@ -111,9 +114,12 @@ FrameSlotPool FrameSlotPool::Attach(void *mem) return pool; } - pool.free_ring_ = SpscRingBuffer::Attach(pool.base_ + pool.header_->free_ring_offset); - pool.ready_ring_ = SpscRingBuffer::Attach(pool.base_ + pool.header_->ready_ring_offset); - pool.meta_ = reinterpret_cast(pool.base_ + pool.header_->meta_offset); + pool.free_ring_ = + SpscRingBuffer::Attach(pool.base_ + pool.header_->free_ring_offset); + pool.ready_ring_ = + SpscRingBuffer::Attach(pool.base_ + pool.header_->ready_ring_offset); + pool.meta_ = reinterpret_cast(pool.base_ + + pool.header_->meta_offset); pool.data_ = pool.base_ + pool.header_->data_offset; return pool; @@ -169,5 +175,5 @@ bool FrameSlotPool::Release(uint32_t index) return free_ring_->Push(index); } -} // namespace ipc -} // namespace olive \ No newline at end of file +} // namespace ipc +} // namespace olive \ No newline at end of file diff --git a/app/render/ipc/frameslotpool.h b/app/render/ipc/frameslotpool.h index be08131ed..39020fd9d 100644 --- a/app/render/ipc/frameslotpool.h +++ b/app/render/ipc/frameslotpool.h @@ -40,16 +40,16 @@ namespace ipc * not guaranteed shared-memory-safe). */ struct FrameSlotMeta { - int64_t id; ///< Caller-defined tag (e.g. ticket id, or footage stream hash). - int64_t time_num; ///< Frame timestamp numerator. - int64_t time_den; ///< Frame timestamp denominator. + int64_t id; ///< Caller-defined tag (e.g. ticket id, or footage stream hash). + int64_t time_num; ///< Frame timestamp numerator. + int64_t time_den; ///< Frame timestamp denominator. int32_t width; int32_t height; - int32_t format; ///< olive::PixelFormat::Format value. + int32_t format; ///< olive::PixelFormat::Format value. int32_t channel_count; - int32_t linesize; ///< Bytes per scanline (stride). - int32_t data_size; ///< Valid bytes written into the slot's data block. - char colorspace[128]; ///< Input colorspace name for color-managed footage. + int32_t linesize; ///< Bytes per scanline (stride). + int32_t data_size; ///< Valid bytes written into the slot's data block. + char colorspace[128]; ///< Input colorspace name for color-managed footage. }; /** @@ -90,7 +90,8 @@ public: * Initializes both rings, seeds the free ring with every slot index, and zeroes metadata. * `mem` must provide at least BytesNeeded(slot_count, slot_data_bytes) bytes. */ - static FrameSlotPool Create(void *mem, uint32_t slot_count, size_t slot_data_bytes); + static FrameSlotPool Create(void *mem, uint32_t slot_count, + size_t slot_data_bytes); /** * @brief Map an existing, already-initialized pool (peer side). @@ -148,7 +149,6 @@ public: FrameSlotPool() = default; private: - struct Header { uint32_t magic; uint32_t slot_count; @@ -160,7 +160,7 @@ private: uint64_t data_offset; }; - static constexpr uint32_t kMagic = 0x4F4B5350; // 'OKSP' + static constexpr uint32_t kMagic = 0x4F4B5350; // 'OKSP' // Ring capacity must exceed slot_count by one because a ring can hold at most capacity-1 entries // and we need to be able to enqueue every slot at once. @@ -177,7 +177,7 @@ private: uint8_t *data_ = nullptr; }; -} // namespace ipc -} // namespace olive +} // namespace ipc +} // namespace olive -#endif // IPC_FRAMESLOTPOOL_H \ No newline at end of file +#endif // IPC_FRAMESLOTPOOL_H \ No newline at end of file diff --git a/app/render/ipc/ipcmessage.cpp b/app/render/ipc/ipcmessage.cpp index f8790ae68..a5ec9a984 100644 --- a/app/render/ipc/ipcmessage.cpp +++ b/app/render/ipc/ipcmessage.cpp @@ -227,5 +227,5 @@ bool LoadGraphMsg::FromJson(const QJsonObject &o, LoadGraphMsg *out) return true; } -} // namespace ipc -} // namespace olive +} // namespace ipc +} // namespace olive diff --git a/app/render/ipc/ipcmessage.h b/app/render/ipc/ipcmessage.h index 316088c27..f822dd2e4 100644 --- a/app/render/ipc/ipcmessage.h +++ b/app/render/ipc/ipcmessage.h @@ -63,7 +63,7 @@ constexpr const char *kCancel = "cancel"; constexpr const char *kGraphUpdate = "graph_update"; constexpr const char *kShutdown = "shutdown"; constexpr const char *kError = "error"; -} // namespace msgtype +} // namespace msgtype /** * @brief Write one NDJSON message line to `device`. @@ -92,29 +92,34 @@ bool ReadMessage(QByteArray *buffer, QJsonObject *out, bool *ok = nullptr); struct HandshakeMsg { int protocol_version = 0; - QString shm_key; ///< Worker->main output shared-memory segment key. - QString input_shm_key; ///< Main->worker input shared-memory segment key (optional). - int input_slots = 0; ///< Number of main->worker input frame slots. - int output_slots = 0; ///< Number of worker->main output frame slots. - qint64 slot_data_bytes = 0; ///< Per-output-slot pixel block size. - qint64 input_slot_data_bytes = 0; ///< Per-input-slot pixel block size. + QString shm_key; ///< Worker->main output shared-memory segment key. + QString + input_shm_key; ///< Main->worker input shared-memory segment key (optional). + int input_slots = 0; ///< Number of main->worker input frame slots. + int output_slots = 0; ///< Number of worker->main output frame slots. + qint64 slot_data_bytes = 0; ///< Per-output-slot pixel block size. + qint64 input_slot_data_bytes = 0; ///< Per-input-slot pixel block size. QJsonObject ToJson() const; static bool FromJson(const QJsonObject &o, HandshakeMsg *out); }; struct RenderFrameMsg { - qint64 ticket_id = 0; ///< Correlates this request with the eventual frame_ready. - QString node_uuid; ///< Output/viewer node to render, by stable uuid in the loaded graph. + qint64 ticket_id = + 0; ///< Correlates this request with the eventual frame_ready. + QString + node_uuid; ///< Output/viewer node to render, by stable uuid in the loaded graph. qint64 time_num = 0; qint64 time_den = 1; - int width = 0; ///< Forced output size (0 = use graph default). + int width = 0; ///< Forced output size (0 = use graph default). int height = 0; - int format = -1; ///< Forced PixelFormat::Format (-1 = default/INVALID). - int channel_count = 0; ///< 0 = default. - int mode = 0; ///< RenderMode::Mode. - int input_slot = -1; ///< Optional main->worker decoded input slot for footage nodes. - QVector input_slots; ///< Optional ordered decoded input slots for footage nodes. + int format = -1; ///< Forced PixelFormat::Format (-1 = default/INVALID). + int channel_count = 0; ///< 0 = default. + int mode = 0; ///< RenderMode::Mode. + int input_slot = + -1; ///< Optional main->worker decoded input slot for footage nodes. + QVector + input_slots; ///< Optional ordered decoded input slots for footage nodes. // Output color transform to apply before returning the frame. When empty, // the worker returns the image in the project's reference space. @@ -130,7 +135,7 @@ struct RenderFrameMsg { struct FrameReadyMsg { qint64 ticket_id = 0; - int output_slot = 0; ///< Index into the worker->main output FrameSlotPool. + int output_slot = 0; ///< Index into the worker->main output FrameSlotPool. QJsonObject ToJson() const; static bool FromJson(const QJsonObject &o, FrameReadyMsg *out); @@ -144,13 +149,13 @@ struct CancelMsg { }; struct LoadGraphMsg { - QString path; ///< Temporary file holding the serialized node graph. + QString path; ///< Temporary file holding the serialized node graph. QJsonObject ToJson() const; static bool FromJson(const QJsonObject &o, LoadGraphMsg *out); }; -} // namespace ipc -} // namespace olive +} // namespace ipc +} // namespace olive -#endif // IPC_IPCMESSAGE_H +#endif // IPC_IPCMESSAGE_H diff --git a/app/render/ipc/sharedmemoryregion.cpp b/app/render/ipc/sharedmemoryregion.cpp index ee6e6a8cd..c671f5a0c 100644 --- a/app/render/ipc/sharedmemoryregion.cpp +++ b/app/render/ipc/sharedmemoryregion.cpp @@ -75,16 +75,20 @@ bool SharedMemoryRegion::Open(const QString &key, size_t size, Mode mode) const std::wstring wname = mapping_name.toStdWString(); if (mode == kCreate) { - const DWORD size_high = static_cast((quint64(size) >> 32) & 0xFFFFFFFF); + const DWORD size_high = + static_cast((quint64(size) >> 32) & 0xFFFFFFFF); const DWORD size_low = static_cast(quint64(size) & 0xFFFFFFFF); - handle_ = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, - size_high, size_low, wname.c_str()); + handle_ = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, + PAGE_READWRITE, size_high, size_low, + wname.c_str()); if (!handle_) { - error_ = QStringLiteral("CreateFileMapping failed: %1").arg(GetLastError()); + error_ = QStringLiteral("CreateFileMapping failed: %1") + .arg(GetLastError()); return false; } if (GetLastError() == ERROR_ALREADY_EXISTS) { - error_ = QStringLiteral("Shared memory key already exists: %1").arg(key); + error_ = + QStringLiteral("Shared memory key already exists: %1").arg(key); CloseHandle(handle_); handle_ = nullptr; return false; @@ -92,7 +96,8 @@ bool SharedMemoryRegion::Open(const QString &key, size_t size, Mode mode) } else { handle_ = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, wname.c_str()); if (!handle_) { - error_ = QStringLiteral("OpenFileMapping failed: %1").arg(GetLastError()); + error_ = + QStringLiteral("OpenFileMapping failed: %1").arg(GetLastError()); return false; } } @@ -124,7 +129,7 @@ void SharedMemoryRegion::Close() size_ = 0; } -#else // POSIX +#else // POSIX bool SharedMemoryRegion::Open(const QString &key, size_t size, Mode mode) { @@ -165,7 +170,8 @@ bool SharedMemoryRegion::Open(const QString &key, size_t size, Mode mode) data_ = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0); if (data_ == MAP_FAILED) { - error_ = QStringLiteral("mmap failed: %1").arg(QString::fromUtf8(strerror(errno))); + error_ = QStringLiteral("mmap failed: %1") + .arg(QString::fromUtf8(strerror(errno))); data_ = nullptr; ::close(fd_); fd_ = -1; @@ -201,5 +207,5 @@ void SharedMemoryRegion::Close() #endif -} // namespace ipc -} // namespace olive \ No newline at end of file +} // namespace ipc +} // namespace olive \ No newline at end of file diff --git a/app/render/ipc/sharedmemoryregion.h b/app/render/ipc/sharedmemoryregion.h index 2a867284e..31437b5e2 100644 --- a/app/render/ipc/sharedmemoryregion.h +++ b/app/render/ipc/sharedmemoryregion.h @@ -110,14 +110,14 @@ private: QString error_; #if defined(Q_OS_WIN) - void *handle_; // HANDLE from CreateFileMapping/OpenFileMapping + void *handle_; // HANDLE from CreateFileMapping/OpenFileMapping #else - int fd_; // file descriptor from shm_open - QString shm_name_; // the platform-prefixed name actually passed to shm_open + int fd_; // file descriptor from shm_open + QString shm_name_; // the platform-prefixed name actually passed to shm_open #endif }; -} // namespace ipc -} // namespace olive +} // namespace ipc +} // namespace olive -#endif // IPC_SHAREDMEMORYREGION_H \ No newline at end of file +#endif // IPC_SHAREDMEMORYREGION_H \ No newline at end of file diff --git a/app/render/ipc/spscringbuffer.h b/app/render/ipc/spscringbuffer.h index a6e62eeb1..200eb8fb6 100644 --- a/app/render/ipc/spscringbuffer.h +++ b/app/render/ipc/spscringbuffer.h @@ -174,11 +174,12 @@ private: std::atomic tail_; uint32_t capacity_; - static_assert(sizeof(std::atomic) == sizeof(uint32_t), - "atomic must be lock-free POD-sized for shared memory use"); + static_assert( + sizeof(std::atomic) == sizeof(uint32_t), + "atomic must be lock-free POD-sized for shared memory use"); }; -} // namespace ipc -} // namespace olive +} // namespace ipc +} // namespace olive -#endif // IPC_SPSCRINGBUFFER_H +#endif // IPC_SPSCRINGBUFFER_H diff --git a/app/render/job/CMakeLists.txt b/app/render/job/CMakeLists.txt index 58d8a225d..d8362864c 100644 --- a/app/render/job/CMakeLists.txt +++ b/app/render/job/CMakeLists.txt @@ -16,14 +16,14 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - render/job/acceleratedjob.cpp - render/job/acceleratedjob.h - render/job/footagejob.h - render/job/generatejob.h - render/job/samplejob.h - render/job/shaderjob.h - render/job/pluginjob.h - render/job/pluginjob.cpp + ${OLIVE_SOURCES} + render/job/acceleratedjob.cpp + render/job/acceleratedjob.h + render/job/footagejob.h + render/job/generatejob.h + render/job/samplejob.h + render/job/shaderjob.h + render/job/pluginjob.h + render/job/pluginjob.cpp PARENT_SCOPE ) diff --git a/app/render/job/pluginjob.cpp b/app/render/job/pluginjob.cpp index 20961d70d..000cfd068 100644 --- a/app/render/job/pluginjob.cpp +++ b/app/render/job/pluginjob.cpp @@ -19,7 +19,9 @@ #include "pluginjob.h" -namespace olive { -namespace plugin { +namespace olive +{ +namespace plugin +{ } // plugin } // olive \ No newline at end of file diff --git a/app/render/job/pluginjob.h b/app/render/job/pluginjob.h index 28831779b..985c303cc 100644 --- a/app/render/job/pluginjob.h +++ b/app/render/job/pluginjob.h @@ -26,47 +26,52 @@ #include #include -namespace olive { -namespace plugin { +namespace olive +{ +namespace plugin +{ -class PluginJob :public AcceleratedJob{ +class PluginJob : public AcceleratedJob { public: - explicit PluginJob(const OFX::Host::ImageEffect::Instance* pluginInstance, - const PluginNode* node, NodeValueRow row, + explicit PluginJob(const OFX::Host::ImageEffect::Instance *pluginInstance, + const PluginNode *node, NodeValueRow row, const olive::core::rational &time) : AcceleratedJob() , time_seconds_(time.toDouble()) { this->pluginInstance_ = pluginInstance; - this->node_=node; + this->node_ = node; Insert(row); } - explicit PluginJob(const OFX::Host::ImageEffect::Instance* pluginInstance, - const PluginNode* node, NodeValueRow row) + explicit PluginJob(const OFX::Host::ImageEffect::Instance *pluginInstance, + const PluginNode *node, NodeValueRow row) : PluginJob(pluginInstance, node, row, olive::core::rational(0)) { } - PluginNode *node() const { + PluginNode *node() const + { return const_cast(node_); } - OFX::Host::ImageEffect::Instance* pluginInstance() { - return const_cast(pluginInstance_); + OFX::Host::ImageEffect::Instance *pluginInstance() + { + return const_cast(pluginInstance_); } - double time_seconds() const { + double time_seconds() const + { return time_seconds_; } private: - const OFX::Host::ImageEffect::Instance *pluginInstance_=nullptr; + const OFX::Host::ImageEffect::Instance *pluginInstance_ = nullptr; QHash> paramsOnTime; QHash params; - const PluginNode *node_=nullptr; + const PluginNode *node_ = nullptr; double time_seconds_ = 0.0; }; diff --git a/app/render/ocioconf/CMakeLists.txt b/app/render/ocioconf/CMakeLists.txt index 51099b161..2bf7dc531 100644 --- a/app/render/ocioconf/CMakeLists.txt +++ b/app/render/ocioconf/CMakeLists.txt @@ -16,14 +16,14 @@ file(GLOB_RECURSE OCIOCONF_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.ocio *.spi3d *.spi1d) set(QRC_BODY "") -foreach(OCIOCONF_FILE ${OCIOCONF_RESOURCES}) - string(APPEND QRC_BODY "${OCIOCONF_FILE}\n") - configure_file(${OCIOCONF_FILE} ${OCIOCONF_FILE} COPYONLY) -endforeach() +foreach (OCIOCONF_FILE ${OCIOCONF_RESOURCES}) + string(APPEND QRC_BODY "${OCIOCONF_FILE}\n") + configure_file(${OCIOCONF_FILE} ${OCIOCONF_FILE} COPYONLY) +endforeach () configure_file(ocioconf.qrc.in ocioconf.qrc @ONLY) set(OLIVE_RESOURCES - ${OLIVE_RESOURCES} - ${CMAKE_CURRENT_BINARY_DIR}/ocioconf.qrc - PARENT_SCOPE + ${OLIVE_RESOURCES} + ${CMAKE_CURRENT_BINARY_DIR}/ocioconf.qrc + PARENT_SCOPE ) diff --git a/app/render/opengl/CMakeLists.txt b/app/render/opengl/CMakeLists.txt index f5ab4f652..4920c5e23 100644 --- a/app/render/opengl/CMakeLists.txt +++ b/app/render/opengl/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - render/opengl/openglrenderer.cpp - render/opengl/openglrenderer.h - PARENT_SCOPE + ${OLIVE_SOURCES} + render/opengl/openglrenderer.cpp + render/opengl/openglrenderer.h + PARENT_SCOPE ) diff --git a/app/render/opengl/openglbackend_c.cpp b/app/render/opengl/openglbackend_c.cpp index c1896f739..754b1620b 100644 --- a/app/render/opengl/openglbackend_c.cpp +++ b/app/render/opengl/openglbackend_c.cpp @@ -10,7 +10,8 @@ #include "render/texture.h" #include "render/videoparams.h" -namespace { +namespace +{ class BackendOpenGLRenderer : public olive::OpenGLRenderer { public: @@ -39,29 +40,32 @@ const QVariant &VariantRef(const void *variant) } // namespace // Creates the backend object and returns it as an opaque C handle. -OAK_RENDER_BACKEND_EXPORT OakRenderBackendHandle oak_renderer_create(void *parent) +OAK_RENDER_BACKEND_EXPORT OakRenderBackendHandle +oak_renderer_create(void *parent) { return new BackendOpenGLRenderer(static_cast(parent)); } // Destroys the opaque backend object created by oak_renderer_create(). -OAK_RENDER_BACKEND_EXPORT void oak_renderer_destroy(OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_destroy(OakRenderBackendHandle handle) { delete Renderer(handle); } // Reports static OpenGL backend capabilities to the adapter. -OAK_RENDER_BACKEND_EXPORT bool oak_renderer_get_info( - OakRenderBackendHandle handle, OakRenderBackendInfo *out_info) +OAK_RENDER_BACKEND_EXPORT bool +oak_renderer_get_info(OakRenderBackendHandle handle, + OakRenderBackendInfo *out_info) { if (!handle || !out_info) { return false; } out_info->abi_version = 1; out_info->kind = OAK_RENDER_BACKEND_OPENGL; - out_info->capabilities = OAK_RENDER_BACKEND_CAP_TEXTURES | - OAK_RENDER_BACKEND_CAP_SHADERS | OAK_RENDER_BACKEND_CAP_BLIT | - OAK_RENDER_BACKEND_CAP_READBACK | + out_info->capabilities = + OAK_RENDER_BACKEND_CAP_TEXTURES | OAK_RENDER_BACKEND_CAP_SHADERS | + OAK_RENDER_BACKEND_CAP_BLIT | OAK_RENDER_BACKEND_CAP_READBACK | OAK_RENDER_BACKEND_CAP_VIEWER_CONTEXT; out_info->name = "opengl"; out_info->status = "available"; @@ -70,8 +74,8 @@ OAK_RENDER_BACKEND_EXPORT bool oak_renderer_get_info( // OpenGL availability is context-dependent, so object creation is the minimum // availability signal for this backend. -OAK_RENDER_BACKEND_EXPORT bool oak_renderer_is_available( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT bool +oak_renderer_is_available(OakRenderBackendHandle handle) { return handle != nullptr; } @@ -83,38 +87,40 @@ OAK_RENDER_BACKEND_EXPORT bool oak_renderer_init(OakRenderBackendHandle handle) } // Initializes the backend against a caller-owned viewer OpenGL context. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_init_with_context( - OakRenderBackendHandle handle, void *context) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_init_with_context(OakRenderBackendHandle handle, void *context) { Renderer(handle)->Init(static_cast(context)); } // Runs renderer post-initialization once the GL context is available. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_post_init(OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_post_init(OakRenderBackendHandle handle) { Renderer(handle)->PostInit(); } // Releases post-init OpenGL surface/context state. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_post_destroy(OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_post_destroy(OakRenderBackendHandle handle) { Renderer(handle)->PostDestroy(); } // Releases renderer-owned GL resources before object destruction. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_destroy_internal( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_destroy_internal(OakRenderBackendHandle handle) { Renderer(handle)->DestroyInternal(); } // Clears either the widget framebuffer or a texture destination. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_clear_destination( - OakRenderBackendHandle handle, void *texture, double r, double g, double b, - double a) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_clear_destination(OakRenderBackendHandle handle, void *texture, + double r, double g, double b, double a) { Renderer(handle)->ClearDestination(static_cast(texture), - r, g, b, a); + r, g, b, a); } // Creates an OpenGL texture and writes its QVariant handle to out_variant. @@ -122,51 +128,58 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_create_native_texture( OakRenderBackendHandle handle, int width, int height, int depth, int format, int channel_count, const void *data, int linesize, void *out_variant) { - *static_cast(out_variant) = Renderer(handle)->CreateNativeTexture( - width, height, depth, static_cast(format), - channel_count, data, linesize); + *static_cast(out_variant) = + Renderer(handle)->CreateNativeTexture( + width, height, depth, + static_cast(format), channel_count, + data, linesize); } // Destroys an OpenGL texture represented by a QVariant handle. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_destroy_native_texture( - OakRenderBackendHandle handle, const void *variant) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_destroy_native_texture(OakRenderBackendHandle handle, + const void *variant) { Renderer(handle)->DestroyNativeTexture(VariantRef(variant)); } // Compiles an OpenGL shader program and returns its QVariant handle. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_create_native_shader( - OakRenderBackendHandle handle, const void *shader_code, void *out_variant) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_create_native_shader(OakRenderBackendHandle handle, + const void *shader_code, void *out_variant) { - *static_cast(out_variant) = Renderer(handle)->CreateNativeShader( - *static_cast(shader_code)); + *static_cast(out_variant) = + Renderer(handle)->CreateNativeShader( + *static_cast(shader_code)); } // Destroys an OpenGL shader program represented by a QVariant handle. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_destroy_native_shader( - OakRenderBackendHandle handle, const void *variant) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_destroy_native_shader(OakRenderBackendHandle handle, + const void *variant) { Renderer(handle)->DestroyNativeShader(VariantRef(variant)); } // Uploads CPU pixel data into an OpenGL texture. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_upload_to_texture( - OakRenderBackendHandle handle, const void *variant, const void *video_params, - const void *data, int linesize) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_upload_to_texture(OakRenderBackendHandle handle, + const void *variant, const void *video_params, + const void *data, int linesize) { Renderer(handle)->UploadToTexture( - VariantRef(variant), *static_cast(video_params), - data, linesize); + VariantRef(variant), + *static_cast(video_params), data, linesize); } // Reads an OpenGL texture back to CPU memory. OAK_RENDER_BACKEND_EXPORT void oak_renderer_download_from_texture( - OakRenderBackendHandle handle, const void *variant, const void *video_params, - void *data, int linesize) + OakRenderBackendHandle handle, const void *variant, + const void *video_params, void *data, int linesize) { Renderer(handle)->DownloadFromTexture( - VariantRef(variant), *static_cast(video_params), - data, linesize); + VariantRef(variant), + *static_cast(video_params), data, linesize); } // Flushes/waits for pending OpenGL work as required by the renderer. @@ -176,18 +189,23 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_flush(OakRenderBackendHandle handle) } // Reads one pixel from an OpenGL texture. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_get_pixel_from_texture( - OakRenderBackendHandle handle, void *texture, const void *point, - void *out_color) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_get_pixel_from_texture(OakRenderBackendHandle handle, + void *texture, const void *point, + void *out_color) { - *static_cast(out_color) = Renderer(handle)->GetPixelFromTexture( - static_cast(texture), *static_cast(point)); + *static_cast(out_color) = + Renderer(handle)->GetPixelFromTexture( + static_cast(texture), + *static_cast(point)); } // Executes a shader blit through the wrapped C++ OpenGL renderer. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_blit( - OakRenderBackendHandle handle, const void *shader, void *job, - void *destination, const void *destination_params, bool clear_destination) +OAK_RENDER_BACKEND_EXPORT void oak_renderer_blit(OakRenderBackendHandle handle, + const void *shader, void *job, + void *destination, + const void *destination_params, + bool clear_destination) { Renderer(handle)->Blit( VariantRef(shader), *static_cast(job), @@ -197,22 +215,23 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_blit( } // Exposes the wrapped OpenGL context for GL-specific integrations. -OAK_RENDER_BACKEND_EXPORT void *oak_renderer_opengl_context( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void * +oak_renderer_opengl_context(OakRenderBackendHandle handle) { return Renderer(handle)->context(); } // Binds an output texture for OFX OpenGL rendering. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_attach_output_texture( - OakRenderBackendHandle handle, const void *texture_id) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_attach_output_texture(OakRenderBackendHandle handle, + const void *texture_id) { Renderer(handle)->AttachTextureAsDestination(VariantRef(texture_id)); } // Detaches any OFX OpenGL output texture binding. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_detach_output_texture( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_detach_output_texture(OakRenderBackendHandle handle) { Renderer(handle)->DetachTextureAsDestination(); } diff --git a/app/render/opengl/openglrenderer.cpp b/app/render/opengl/openglrenderer.cpp index 01f875f4d..ef7ed021a 100644 --- a/app/render/opengl/openglrenderer.cpp +++ b/app/render/opengl/openglrenderer.cpp @@ -265,8 +265,8 @@ void OpenGLRenderer::AttachTextureAsDestination(const QVariant &texture) void OpenGLRenderer::DetachTextureAsDestination() { // QOpenGLWidget renders to a non-zero default FBO. - const GLuint default_fbo = - context_ ? context_->defaultFramebufferObject() : 0; + const GLuint default_fbo = context_ ? context_->defaultFramebufferObject() : + 0; functions_->glBindFramebuffer(GL_FRAMEBUFFER, default_fbo); } @@ -504,8 +504,8 @@ struct TextureToBind { Texture::Interpolation interpolation; }; -void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destination, - VideoParams destination_params, +void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job, + Texture *destination, VideoParams destination_params, bool clear_destination) { GL_PREAMBLE; @@ -519,7 +519,7 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio functions_->glBindFramebuffer(GL_FRAMEBUFFER, fbo); } - ShaderJob &s_job=dynamic_cast(a_job); + ShaderJob &s_job = dynamic_cast(a_job); ShaderJob job(s_job); // If this node is iterative, we'll pick up which input here QMap texture_index_map; @@ -585,7 +585,8 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio case NodeValue::kColor: { Color color = value.toColor(); functions_->glUniform4f(variable_location, color.red(), - color.green(), color.blue(), color.alpha()); + color.green(), color.blue(), + color.alpha()); break; } case NodeValue::kBoolean: @@ -595,7 +596,8 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio TexturePtr texture = value.toTexture(); // Set value to bound texture - functions_->glUniform1i(variable_location, textures_to_bind.size()); + functions_->glUniform1i(variable_location, + textures_to_bind.size()); texture_index_map.insert(it.key(), textures_to_bind.size()); @@ -605,8 +607,10 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio // Set enable flag if shader wants it GLuint tex_id = texture ? texture->id().value() : 0; int enable_param_location = functions_->glGetUniformLocation( - shader, - QStringLiteral("%1_enabled").arg(it.key()).toUtf8().constData()); + shader, QStringLiteral("%1_enabled") + .arg(it.key()) + .toUtf8() + .constData()); if (enable_param_location > -1) { functions_->glUniform1i(enable_param_location, tex_id > 0); } @@ -637,8 +641,9 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio functions_->glActiveTexture(GL_TEXTURE0 + i); - GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D : - GL_TEXTURE_2D; + GLenum target = (texture && texture->params().is_3d()) ? + GL_TEXTURE_3D : + GL_TEXTURE_2D; functions_->glBindTexture(target, tex_id); if (tex_id) { @@ -647,12 +652,12 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio if (texture->channel_count() == 1 && destination_params.channel_count() != 1) { // Interpret this texture as a grayscale texture - functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, - GL_RED); - functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, - GL_RED); - functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, - GL_RED); + functions_->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_SWIZZLE_R, GL_RED); + functions_->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_SWIZZLE_G, GL_RED); + functions_->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_SWIZZLE_B, GL_RED); } } } @@ -683,7 +688,8 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio if (!job.GetVertexCoordinates().isEmpty()) { Q_ASSERT(job.GetVertexCoordinates().size() == 18); vert_vbo_.allocate(job.GetVertexCoordinates().constData(), - job.GetVertexCoordinates().size() * sizeof(float)); + job.GetVertexCoordinates().size() * + sizeof(float)); } else { vert_vbo_.allocate(blit_vertices.constData(), blit_vertices.size() * sizeof(GLfloat)); @@ -707,12 +713,13 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio vert_vbo_.release(); } - GLint tex_location = functions_->glGetAttribLocation(shader, "a_texcoord"); + GLint tex_location = + functions_->glGetAttribLocation(shader, "a_texcoord"); if (tex_location != -1) { frag_vbo_.bind(); functions_->glEnableVertexAttribArray(tex_location); - functions_->glVertexAttribPointer(tex_location, 2, GL_FLOAT, GL_FALSE, - 0, nullptr); + functions_->glVertexAttribPointer(tex_location, 2, GL_FLOAT, + GL_FALSE, 0, nullptr); frag_vbo_.release(); } @@ -788,9 +795,9 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio // Blit this texture through this shader { PRINT_GL_ERRORS; - functions_->glDrawArrays(GL_TRIANGLES, 0, blit_vertices.size() / 3); + functions_->glDrawArrays(GL_TRIANGLES, 0, + blit_vertices.size() / 3); } - } if (destination) { @@ -801,8 +808,9 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio // Release any textures we bound before for (int i = textures_to_bind.size() - 1; i >= 0; i--) { TexturePtr texture = textures_to_bind.at(i).texture; - GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D : - GL_TEXTURE_2D; + GLenum target = (texture && texture->params().is_3d()) ? + GL_TEXTURE_3D : + GL_TEXTURE_2D; functions_->glActiveTexture(GL_TEXTURE0 + i); functions_->glBindTexture(target, 0); } @@ -815,9 +823,8 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destinatio vert_vbo_.destroy(); vao_.release(); vao_.destroy(); + } catch (std::bad_cast e) { } - catch (std::bad_cast e){} - } GLint OpenGLRenderer::GetInternalFormat(PixelFormat format, int channel_layout) @@ -965,12 +972,12 @@ GLuint OpenGLRenderer::CompileShader(GLenum type, const QString &code) const int major = context_ ? context_->format().majorVersion() : 0; const int minor = context_ ? context_->format().minorVersion() : 0; const bool is_gles2 = is_gles && (major < 3); - const QString gles_preamble = is_gles2 - ? QStringLiteral("#version 100\n\n" - "precision highp float;\n\n" - "#define frag_color gl_FragColor\n") - : QStringLiteral("#version 300 es\n\n" - "precision highp float;\n\n"); + const QString gles_preamble = + is_gles2 ? QStringLiteral("#version 100\n\n" + "precision highp float;\n\n" + "#define frag_color gl_FragColor\n") : + QStringLiteral("#version 300 es\n\n" + "precision highp float;\n\n"); const QString desktop_preamble = // Use appropriate GL 3.2 shader header QStringLiteral("#version 150\n\n" @@ -991,7 +998,8 @@ GLuint OpenGLRenderer::CompileShader(GLenum type, const QString &code) QString complete_code; if (base_code.startsWith(QStringLiteral("#version"))) { - if (is_gles || !desktop_preamble.startsWith(QStringLiteral("#version"))) { + if (is_gles || + !desktop_preamble.startsWith(QStringLiteral("#version"))) { int newline = base_code.indexOf('\n'); if (newline >= 0) { complete_code = shader_preamble + base_code.mid(newline + 1); @@ -1007,18 +1015,22 @@ GLuint OpenGLRenderer::CompileShader(GLenum type, const QString &code) if (is_gles2) { if (type == GL_VERTEX_SHADER) { - complete_code.replace(QRegularExpression(QStringLiteral("\\bin\\b")), - QStringLiteral("attribute")); - complete_code.replace(QRegularExpression(QStringLiteral("\\bout\\b")), - QStringLiteral("varying")); + complete_code.replace( + QRegularExpression(QStringLiteral("\\bin\\b")), + QStringLiteral("attribute")); + complete_code.replace( + QRegularExpression(QStringLiteral("\\bout\\b")), + QStringLiteral("varying")); } else if (type == GL_FRAGMENT_SHADER) { - complete_code.replace(QRegularExpression(QStringLiteral("\\bin\\b")), - QStringLiteral("varying")); - complete_code.replace(QRegularExpression( - QStringLiteral("\\bout\\s+vec4\\s+frag_color\\s*;")), + complete_code.replace( + QRegularExpression(QStringLiteral("\\bin\\b")), + QStringLiteral("varying")); + complete_code.replace(QRegularExpression(QStringLiteral( + "\\bout\\s+vec4\\s+frag_color\\s*;")), QStringLiteral("// frag_color output")); - complete_code.replace(QRegularExpression(QStringLiteral("\\btexture\\b")), - QStringLiteral("texture2D")); + complete_code.replace( + QRegularExpression(QStringLiteral("\\btexture\\b")), + QStringLiteral("texture2D")); } } @@ -1058,7 +1070,8 @@ bool OpenGLRenderer::EnsureContextCurrent(const char *caller) // paint code can receive textures produced by a render-thread OpenGL // renderer, so guard here before makeCurrent() can crash inside Qt/GL. if (context_->thread() != QThread::currentThread()) { - qWarning() << caller << "called from the wrong thread for this OpenGL context"; + qWarning() + << caller << "called from the wrong thread for this OpenGL context"; return false; } diff --git a/app/render/opengl/openglrenderer.h b/app/render/opengl/openglrenderer.h index 327a58ce8..42b77f401 100644 --- a/app/render/opengl/openglrenderer.h +++ b/app/render/opengl/openglrenderer.h @@ -94,7 +94,7 @@ public: bool EnsureContextCurrent(const char *caller); protected: - virtual void Blit(QVariant shader, olive::AcceleratedJob& job, + virtual void Blit(QVariant shader, olive::AcceleratedJob &job, olive::Texture *destination, olive::VideoParams destination_params, bool clear_destination) override; diff --git a/app/render/plugin/pluginrenderer.cpp b/app/render/plugin/pluginrenderer.cpp index 550ae461d..03decea34 100644 --- a/app/render/plugin/pluginrenderer.cpp +++ b/app/render/plugin/pluginrenderer.cpp @@ -51,20 +51,22 @@ #include "ofxhUtilities.h" #include "ofxGPURender.h" #include "olive/core/util/color.h" -extern "C"{ +extern "C" { #include #include #include } - // 作用:从 OFX Image 属性推导 FFmpeg 像素格式,并返回每像素字节数。 // Purpose: Infer FFmpeg pixel format from OFX image properties and return bytes-per-pixel. -static AVPixelFormat GetOfxAVPixelFormat(const OFX::Host::ImageEffect::Image &image, - int *bytes_per_pixel) +static AVPixelFormat +GetOfxAVPixelFormat(const OFX::Host::ImageEffect::Image &image, + int *bytes_per_pixel) { - const std::string &depth = image.getStringProperty(kOfxImageEffectPropPixelDepth); - const std::string &components = image.getStringProperty(kOfxImageEffectPropComponents); + const std::string &depth = + image.getStringProperty(kOfxImageEffectPropPixelDepth); + const std::string &components = + image.getStringProperty(kOfxImageEffectPropComponents); olive::core::PixelFormat pixel_format = olive::core::PixelFormat::INVALID; if (depth == kOfxBitDepthByte) { @@ -86,7 +88,8 @@ static AVPixelFormat GetOfxAVPixelFormat(const OFX::Host::ImageEffect::Image &im channel_count = 1; } - AVPixelFormat pix_fmt = olive::FFmpegUtils::GetFFmpegPixelFormat(pixel_format, channel_count); + AVPixelFormat pix_fmt = + olive::FFmpegUtils::GetFFmpegPixelFormat(pixel_format, channel_count); if (pix_fmt == AV_PIX_FMT_NONE && channel_count == 1) { if (pixel_format == olive::core::PixelFormat::U8) { pix_fmt = AV_PIX_FMT_GRAY8; @@ -123,8 +126,7 @@ static AVPixelFormat GetOfxAVPixelFormat(const OFX::Host::ImageEffect::Image &im // 作用:为插件实例注入当前帧的参数值,避免依赖节点实时回读。 static void ApplyParamOverrides(OFX::Host::ImageEffect::Instance &instance, - const olive::NodeValueRow &values, - OfxTime time) + const olive::NodeValueRow &values, OfxTime time) { const auto ¶ms = instance.getParams(); for (const auto &entry : params) { @@ -144,17 +146,15 @@ static void ApplyParamOverrides(OFX::Host::ImageEffect::Instance &instance, const std::string &type = entry.second->getType(); if (type == kOfxParamTypeInteger) { - if (auto *param = - dynamic_cast( - entry.second)) { + if (auto *param = dynamic_cast( + entry.second)) { param->set(time, value.data().toInt()); } continue; } if (type == kOfxParamTypeDouble) { - if (auto *param = - dynamic_cast( - entry.second)) { + if (auto *param = dynamic_cast( + entry.second)) { double v = value.data().toDouble(); if (std::isnan(v) || std::isinf(v)) { qWarning() << "[PLUGIN] NaN/Inf in double param" << key @@ -181,35 +181,31 @@ static void ApplyParamOverrides(OFX::Host::ImageEffect::Instance &instance, continue; } if (type == kOfxParamTypeBoolean) { - if (auto *param = - dynamic_cast( - entry.second)) { + if (auto *param = dynamic_cast( + entry.second)) { param->set(time, value.data().toBool()); } continue; } if (type == kOfxParamTypeChoice) { - if (auto *param = - dynamic_cast( - entry.second)) { + if (auto *param = dynamic_cast( + entry.second)) { param->set(time, value.data().toInt()); } continue; } if (type == kOfxParamTypeString || type == kOfxParamTypeCustom || type == kOfxParamTypeBytes || type == kOfxParamTypeStrChoice) { - if (auto *param = - dynamic_cast( - entry.second)) { + if (auto *param = dynamic_cast( + entry.second)) { const QByteArray utf8 = value.data().toString().toUtf8(); param->set(time, utf8.constData()); } continue; } if (type == kOfxParamTypeRGBA) { - if (auto *param = - dynamic_cast( - entry.second)) { + if (auto *param = dynamic_cast( + entry.second)) { if (value.data().canConvert()) { const auto c = value.data().value(); param->set(time, c.red(), c.green(), c.blue(), c.alpha()); @@ -224,9 +220,8 @@ static void ApplyParamOverrides(OFX::Host::ImageEffect::Instance &instance, continue; } if (type == kOfxParamTypeRGB) { - if (auto *param = - dynamic_cast( - entry.second)) { + if (auto *param = dynamic_cast( + entry.second)) { if (value.data().canConvert()) { const auto c = value.data().value(); param->set(time, c.red(), c.green(), c.blue()); @@ -290,13 +285,14 @@ static void ApplyParamOverrides(OFX::Host::ImageEffect::Instance &instance, } } -static AVPixelFormat GetDestinationAVPixelFormat(const olive::VideoParams ¶ms); +static AVPixelFormat +GetDestinationAVPixelFormat(const olive::VideoParams ¶ms); // 作用:读取 clip 偏好(像素深度与分量)并更新 VideoParams。 // Purpose: Apply clip preferences (depth/components) into VideoParams. -static bool ApplyClipPreferencesToParams( - const OFX::Host::ImageEffect::ClipInstance &clip, - olive::VideoParams *params) +static bool +ApplyClipPreferencesToParams(const OFX::Host::ImageEffect::ClipInstance &clip, + olive::VideoParams *params) { if (!params) { return false; @@ -335,8 +331,8 @@ static bool ApplyClipPreferencesToParams( // 作用:将 OFX bit depth 字符串映射为内部 PixelFormat。 // Purpose: Map OFX bit depth string to internal PixelFormat. -static olive::core::PixelFormat PixelFormatFromOfxDepth( - const std::string &depth) +static olive::core::PixelFormat +PixelFormatFromOfxDepth(const std::string &depth) { if (depth == kOfxBitDepthByte) { return olive::core::PixelFormat::U8; @@ -408,9 +404,9 @@ static const char *OfxComponentsFromChannels(int channel_count) // 作用:判断插件是否支持指定像素深度。 // Purpose: Check whether effect supports a given pixel depth. -static bool EffectSupportsPixelDepth( - const OFX::Host::ImageEffect::Instance &instance, - const std::string &depth) +static bool +EffectSupportsPixelDepth(const OFX::Host::ImageEffect::Instance &instance, + const std::string &depth) { const auto &effect_props = instance.getDescriptor().getProps(); const int depth_count = @@ -426,9 +422,9 @@ static bool EffectSupportsPixelDepth( // 作用:判断 clip 是否支持指定组件格式。 // Purpose: Check whether clip supports a given components string. -static bool ClipSupportsComponents( - const OFX::Host::ImageEffect::ClipInstance &clip, - const std::string &components) +static bool +ClipSupportsComponents(const OFX::Host::ImageEffect::ClipInstance &clip, + const std::string &components) { const auto &supported_components = clip.getSupportedComponents(); for (const auto &comp : supported_components) { @@ -465,11 +461,11 @@ static bool ParamsConvertible(const olive::VideoParams ¶ms) // 作用:在 clip 偏好无效时,选择一个插件支持的输出格式。 // Purpose: Pick a supported output format when clip preferences are invalid. -static void ChooseSupportedOutputParams( - const OFX::Host::ImageEffect::Instance &instance, - const OFX::Host::ImageEffect::ClipInstance &clip, - const olive::VideoParams &preferred, - olive::VideoParams *out) +static void +ChooseSupportedOutputParams(const OFX::Host::ImageEffect::Instance &instance, + const OFX::Host::ImageEffect::ClipInstance &clip, + const olive::VideoParams &preferred, + olive::VideoParams *out) { if (!out) { return; @@ -502,8 +498,8 @@ static void ChooseSupportedOutputParams( if (candidate == olive::core::PixelFormat::INVALID) { continue; } - if (!EffectSupportsPixelDepth( - instance, OfxDepthFromPixelFormat(candidate))) { + if (!EffectSupportsPixelDepth(instance, + OfxDepthFromPixelFormat(candidate))) { continue; } olive::VideoParams test_params = *out; @@ -517,21 +513,22 @@ static void ChooseSupportedOutputParams( } // Forward declarations for functions defined later in this file. -static olive::AVFramePtr ConvertFrameIfNeeded(olive::AVFramePtr src, - const olive::VideoParams &dst_params, - olive::Renderer *renderer); -static olive::TexturePtr ConvertTextureForParams(olive::TexturePtr src, - const olive::VideoParams &dst_params); +static olive::AVFramePtr +ConvertFrameIfNeeded(olive::AVFramePtr src, + const olive::VideoParams &dst_params, + olive::Renderer *renderer); +static olive::TexturePtr +ConvertTextureForParams(olive::TexturePtr src, + const olive::VideoParams &dst_params); // 作用:根据插件能力与偏好选择输入格式并执行转换。 // Purpose: Select a supported input format and convert texture for the clip. -static olive::TexturePtr ConvertTextureForClip( - const OFX::Host::ImageEffect::Instance &instance, - const OFX::Host::ImageEffect::ClipInstance &clip, - olive::TexturePtr src, - const olive::VideoParams &preferred_params, - bool force_preferred, - olive::VideoParams *out_params) +static olive::TexturePtr +ConvertTextureForClip(const OFX::Host::ImageEffect::Instance &instance, + const OFX::Host::ImageEffect::ClipInstance &clip, + olive::TexturePtr src, + const olive::VideoParams &preferred_params, + bool force_preferred, olive::VideoParams *out_params) { if (!src || !out_params) { return nullptr; @@ -554,8 +551,7 @@ static olive::TexturePtr ConvertTextureForClip( for (const auto &comp : supported_components) { int channels = ChannelCountFromOfxComponent(comp); if (channels > 0 && - std::find(channel_candidates.begin(), - channel_candidates.end(), + std::find(channel_candidates.begin(), channel_candidates.end(), channels) == channel_candidates.end()) { channel_candidates.push_back(channels); } @@ -573,8 +569,7 @@ static olive::TexturePtr ConvertTextureForClip( PixelFormatFromOfxDepth(effect_props.getStringProperty( kOfxImageEffectPropSupportedPixelDepths, i)); if (fmt != olive::core::PixelFormat::INVALID && - std::find(format_candidates.begin(), - format_candidates.end(), + std::find(format_candidates.begin(), format_candidates.end(), fmt) == format_candidates.end()) { format_candidates.push_back(fmt); } @@ -620,40 +615,43 @@ static olive::TexturePtr ConvertTextureForClip( return nullptr; } - std::stable_sort(candidates.begin(), candidates.end(), - [&src_params, &preferred_params, prefer_rgba8, force_preferred](const auto &a, - const auto &b) { - if (force_preferred) { - const bool a_pref = (a.format() == preferred_params.format() && - a.channel_count() == preferred_params.channel_count()); - const bool b_pref = (b.format() == preferred_params.format() && - b.channel_count() == preferred_params.channel_count()); - if (a_pref != b_pref) { - return a_pref; + std::stable_sort( + candidates.begin(), candidates.end(), + [&src_params, &preferred_params, prefer_rgba8, + force_preferred](const auto &a, const auto &b) { + if (force_preferred) { + const bool a_pref = + (a.format() == preferred_params.format() && + a.channel_count() == preferred_params.channel_count()); + const bool b_pref = + (b.format() == preferred_params.format() && + b.channel_count() == preferred_params.channel_count()); + if (a_pref != b_pref) { + return a_pref; + } } - } - if (prefer_rgba8) { - const bool a_rgba8 = - a.format() == olive::core::PixelFormat::U8 && - a.channel_count() == 4; - const bool b_rgba8 = - b.format() == olive::core::PixelFormat::U8 && - b.channel_count() == 4; - if (a_rgba8 != b_rgba8) { - return a_rgba8; + if (prefer_rgba8) { + const bool a_rgba8 = a.format() == + olive::core::PixelFormat::U8 && + a.channel_count() == 4; + const bool b_rgba8 = b.format() == + olive::core::PixelFormat::U8 && + b.channel_count() == 4; + if (a_rgba8 != b_rgba8) { + return a_rgba8; + } } - } - const int cost_a = ConversionCost(src_params, a); - const int cost_b = ConversionCost(src_params, b); - if (cost_a != cost_b) { - return cost_a < cost_b; - } - if (a.format() == preferred_params.format() && - a.channel_count() == preferred_params.channel_count()) { - return true; - } - return false; - }); + const int cost_a = ConversionCost(src_params, a); + const int cost_b = ConversionCost(src_params, b); + if (cost_a != cost_b) { + return cost_a < cost_b; + } + if (a.format() == preferred_params.format() && + a.channel_count() == preferred_params.channel_count()) { + return true; + } + return false; + }); for (const auto &candidate : candidates) { if (candidate.format() == src_params.format() && @@ -661,8 +659,7 @@ static olive::TexturePtr ConvertTextureForClip( *out_params = src_params; return src; } - olive::TexturePtr converted = - ConvertTextureForParams(src, candidate); + olive::TexturePtr converted = ConvertTextureForParams(src, candidate); if (converted) { *out_params = candidate; return converted; @@ -674,7 +671,8 @@ static olive::TexturePtr ConvertTextureForClip( // 作用:从 OFX Image 复制数据到 AVFrame(按图像属性推导格式)。 // Purpose: Copy OFX Image data into an AVFrame with inferred format. -static olive::AVFramePtr create_avframe_from_ofx_image(OFX::Host::ImageEffect::Image &image) +static olive::AVFramePtr +create_avframe_from_ofx_image(OFX::Host::ImageEffect::Image &image) { void *data_ptr = image.getPointerProperty(kOfxImagePropData); if (!data_ptr) { @@ -682,14 +680,14 @@ static olive::AVFramePtr create_avframe_from_ofx_image(OFX::Host::ImageEffect::I return nullptr; } - int bounds[4] = {0, 0, 0, 0}; + int bounds[4] = { 0, 0, 0, 0 }; image.getIntPropertyN(kOfxImagePropBounds, bounds, 4); int width = bounds[2] - bounds[0]; int height = bounds[3] - bounds[1]; if (width <= 0 || height <= 0) { qWarning().noquote() - << "OFX output image has invalid bounds" - << bounds[0] << bounds[1] << bounds[2] << bounds[3]; + << "OFX output image has invalid bounds" << bounds[0] << bounds[1] + << bounds[2] << bounds[3]; return nullptr; } @@ -698,8 +696,8 @@ static olive::AVFramePtr create_avframe_from_ofx_image(OFX::Host::ImageEffect::I if (pix_fmt == AV_PIX_FMT_NONE || bytes_per_pixel <= 0) { qWarning().noquote() << "OFX output image has unsupported pixel format depth=" - << QString::fromStdString(image.getStringProperty( - kOfxImageEffectPropPixelDepth)) + << QString::fromStdString( + image.getStringProperty(kOfxImageEffectPropPixelDepth)) << "components=" << QString::fromStdString( image.getStringProperty(kOfxImageEffectPropComponents)); @@ -729,8 +727,7 @@ static olive::AVFramePtr create_avframe_from_ofx_image(OFX::Host::ImageEffect::I } else { for (int y = 0; y < height; ++y) { std::memcpy(frame->data[0] + y * frame->linesize[0], - src + y * row_bytes, - copy_bytes); + src + y * row_bytes, copy_bytes); } } @@ -742,17 +739,17 @@ static olive::AVFramePtr create_avframe_from_ofx_image(OFX::Host::ImageEffect::I // 作用:按指定 VideoParams 复制 OFX Image 到 AVFrame,必要时做格式转换。 // Purpose: Copy OFX Image data into an AVFrame using target VideoParams with format conversion. -static olive::AVFramePtr create_avframe_from_ofx_image_with_params( - OFX::Host::ImageEffect::Image &image, - const olive::VideoParams ¶ms, - olive::Renderer *renderer = nullptr) +static olive::AVFramePtr +create_avframe_from_ofx_image_with_params(OFX::Host::ImageEffect::Image &image, + const olive::VideoParams ¶ms, + olive::Renderer *renderer = nullptr) { void *data_ptr = image.getPointerProperty(kOfxImagePropData); if (!data_ptr) { return nullptr; } - int bounds[4] = {0, 0, 0, 0}; + int bounds[4] = { 0, 0, 0, 0 }; image.getIntPropertyN(kOfxImagePropBounds, bounds, 4); int width = bounds[2] - bounds[0]; int height = bounds[3] - bounds[1]; @@ -761,22 +758,30 @@ static olive::AVFramePtr create_avframe_from_ofx_image_with_params( } // Get ACTUAL source format from image properties - std::string image_depth = image.getStringProperty(kOfxImageEffectPropPixelDepth); - std::string image_comp = image.getStringProperty(kOfxImageEffectPropComponents); + std::string image_depth = + image.getStringProperty(kOfxImageEffectPropPixelDepth); + std::string image_comp = + image.getStringProperty(kOfxImageEffectPropComponents); int src_channel_count = 4; - if (image_comp == kOfxImageComponentRGB) src_channel_count = 3; - else if (image_comp == kOfxImageComponentAlpha) src_channel_count = 1; + if (image_comp == kOfxImageComponentRGB) + src_channel_count = 3; + else if (image_comp == kOfxImageComponentAlpha) + src_channel_count = 1; // NOTE: FP16 (Half) format handling has been removed. // FP16 data is now treated as U16 (2 bytes per component) and converted via FFmpeg. int src_bytes_per_component = 1; - if (image_depth == kOfxBitDepthShort) src_bytes_per_component = 2; - else if (image_depth == kOfxBitDepthHalf) src_bytes_per_component = 2; // Treat as U16 - else if (image_depth == kOfxBitDepthFloat) src_bytes_per_component = 4; + if (image_depth == kOfxBitDepthShort) + src_bytes_per_component = 2; + else if (image_depth == kOfxBitDepthHalf) + src_bytes_per_component = 2; // Treat as U16 + else if (image_depth == kOfxBitDepthFloat) + src_bytes_per_component = 4; const int src_bytes_per_pixel = src_channel_count * src_bytes_per_component; - const int dst_bytes_per_pixel = params.channel_count() * params.format().byte_count(); + const int dst_bytes_per_pixel = + params.channel_count() * params.format().byte_count(); int row_bytes = image.getIntProperty(kOfxImagePropRowBytes); if (row_bytes <= 0) { @@ -795,31 +800,38 @@ static olive::AVFramePtr create_avframe_from_ofx_image_with_params( AVPixelFormat src_fmt = AV_PIX_FMT_NONE; if (src_channel_count == 4) { - if (src_bytes_per_component == 1) src_fmt = AV_PIX_FMT_RGBA; - else if (src_bytes_per_component == 2) src_fmt = AV_PIX_FMT_RGBA64LE; - else if (src_bytes_per_component == 4) src_fmt = AV_PIX_FMT_RGBAF32LE; + if (src_bytes_per_component == 1) + src_fmt = AV_PIX_FMT_RGBA; + else if (src_bytes_per_component == 2) + src_fmt = AV_PIX_FMT_RGBA64LE; + else if (src_bytes_per_component == 4) + src_fmt = AV_PIX_FMT_RGBAF32LE; } else if (src_channel_count == 3) { - if (src_bytes_per_component == 1) src_fmt = AV_PIX_FMT_RGB24; - else if (src_bytes_per_component == 2) src_fmt = AV_PIX_FMT_RGB48LE; - else if (src_bytes_per_component == 4) src_fmt = AV_PIX_FMT_RGBF32LE; + if (src_bytes_per_component == 1) + src_fmt = AV_PIX_FMT_RGB24; + else if (src_bytes_per_component == 2) + src_fmt = AV_PIX_FMT_RGB48LE; + else if (src_bytes_per_component == 4) + src_fmt = AV_PIX_FMT_RGBF32LE; } else if (src_channel_count == 1) { - if (src_bytes_per_component == 1) src_fmt = AV_PIX_FMT_GRAY8; - else if (src_bytes_per_component == 2) src_fmt = AV_PIX_FMT_GRAY16LE; - else if (src_bytes_per_component == 4) src_fmt = AV_PIX_FMT_GRAYF32LE; + if (src_bytes_per_component == 1) + src_fmt = AV_PIX_FMT_GRAY8; + else if (src_bytes_per_component == 2) + src_fmt = AV_PIX_FMT_GRAY16LE; + else if (src_bytes_per_component == 4) + src_fmt = AV_PIX_FMT_GRAYF32LE; } - - if (src_fmt != AV_PIX_FMT_NONE) { olive::AVFramePtr src_frame = olive::CreateAVFramePtr(); src_frame->width = width; src_frame->height = height; src_frame->format = src_fmt; if (av_frame_get_buffer(src_frame.get(), 0) >= 0) { - // Copy source data row by row (or as a single block if strides match) const int copy_bytes = width * src_bytes_per_pixel; - if (src_frame->linesize[0] == row_bytes && row_bytes == copy_bytes) { + if (src_frame->linesize[0] == row_bytes && + row_bytes == copy_bytes) { memcpy(src_frame->data[0], src, copy_bytes * height); } else { for (int y = 0; y < height; ++y) { @@ -830,11 +842,13 @@ static olive::AVFramePtr create_avframe_from_ofx_image_with_params( // Convert to destination format return ConvertFrameIfNeeded(src_frame, params, renderer); } else { - qWarning().noquote() << "[WARN] av_frame_get_buffer failed for src_fmt=" << src_fmt; + qWarning().noquote() + << "[WARN] av_frame_get_buffer failed for src_fmt=" + << src_fmt; } } else { - qWarning().noquote() - << "[WARN] src_fmt is NONE for depth=" << QString::fromStdString(image_depth); + qWarning().noquote() << "[WARN] src_fmt is NONE for depth=" + << QString::fromStdString(image_depth); } } @@ -853,10 +867,11 @@ static olive::AVFramePtr create_avframe_from_ofx_image_with_params( return nullptr; } - const int copy_bytes = width * std::min(src_bytes_per_pixel, dst_bytes_per_pixel); + const int copy_bytes = + width * std::min(src_bytes_per_pixel, dst_bytes_per_pixel); for (int y = 0; y < height; ++y) { - memcpy(frame->data[0] + y * frame->linesize[0], - src + y * row_bytes, copy_bytes); + memcpy(frame->data[0] + y * frame->linesize[0], src + y * row_bytes, + copy_bytes); } return frame; @@ -864,11 +879,11 @@ static olive::AVFramePtr create_avframe_from_ofx_image_with_params( // 作用:将 VideoParams 映射为最终输出的 AVPixelFormat。 // Purpose: Map VideoParams to the final AVPixelFormat. -static AVPixelFormat GetDestinationAVPixelFormat(const olive::VideoParams ¶ms) +static AVPixelFormat +GetDestinationAVPixelFormat(const olive::VideoParams ¶ms) { - AVPixelFormat pix_fmt = - olive::FFmpegUtils::GetFFmpegPixelFormat(params.format(), - params.channel_count()); + AVPixelFormat pix_fmt = olive::FFmpegUtils::GetFFmpegPixelFormat( + params.format(), params.channel_count()); if (pix_fmt == AV_PIX_FMT_NONE && params.channel_count() == 1) { if (params.format() == olive::core::PixelFormat::U8) { pix_fmt = AV_PIX_FMT_GRAY8; @@ -903,8 +918,9 @@ static const char *GetRenderFieldForParams(const olive::VideoParams ¶ms) // 作用:从 GPU 纹理回读到 AVFrame(必要时做格式转换)。 // Purpose: Read back GPU texture into AVFrame with format conversion if needed. -static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, - const olive::VideoParams ¶ms) +static olive::AVFramePtr +ReadbackTextureToFrame(olive::TexturePtr texture, + const olive::VideoParams ¶ms) { if (!texture || texture->IsDummy()) { return nullptr; @@ -930,9 +946,8 @@ static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, } if (texture->renderer()) { - const int linesize_pixels = - olive::plugin::detail::BytesToPixels(frame->linesize[0], - params); + const int linesize_pixels = olive::plugin::detail::BytesToPixels( + frame->linesize[0], params); texture->renderer()->DownloadFromTexture( texture->id(), params, frame->data[0], linesize_pixels); } @@ -940,9 +955,10 @@ static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, } // Planar formats: read back as RGBA and convert. - olive::VideoParams rgba_params( - params.width(), params.height(), olive::core::PixelFormat::U8, 4, - params.pixel_aspect_ratio(), params.interlacing(), params.divider()); + olive::VideoParams rgba_params(params.width(), params.height(), + olive::core::PixelFormat::U8, 4, + params.pixel_aspect_ratio(), + params.interlacing(), params.divider()); olive::AVFramePtr rgba_frame = olive::CreateAVFramePtr(); rgba_frame->format = AV_PIX_FMT_RGBA; @@ -953,9 +969,8 @@ static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, } if (texture->renderer()) { - const int linesize_pixels = - olive::plugin::detail::BytesToPixels(rgba_frame->linesize[0], - rgba_params); + const int linesize_pixels = olive::plugin::detail::BytesToPixels( + rgba_frame->linesize[0], rgba_params); texture->renderer()->DownloadFromTexture( texture->id(), rgba_params, rgba_frame->data[0], linesize_pixels); } @@ -970,9 +985,8 @@ static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, SwsContext *sws_ctx = sws_getContext( rgba_frame->width, rgba_frame->height, - static_cast(rgba_frame->format), - dst->width, dst->height, pix_fmt, SWS_POINT, - nullptr, nullptr, nullptr); + static_cast(rgba_frame->format), dst->width, dst->height, + pix_fmt, SWS_POINT, nullptr, nullptr, nullptr); if (!sws_ctx) { return rgba_frame; } @@ -989,9 +1003,8 @@ static olive::AVFramePtr ReadbackTextureToFrame(olive::TexturePtr texture, int olive::plugin::detail::BytesToPixels(int byte_linesize, const olive::VideoParams ¶ms) { - const int bytes_per_pixel = - olive::VideoParams::GetBytesPerPixel(params.format(), - params.channel_count()); + const int bytes_per_pixel = olive::VideoParams::GetBytesPerPixel( + params.format(), params.channel_count()); if (byte_linesize <= 0 || bytes_per_pixel <= 0) { return 0; } @@ -999,44 +1012,66 @@ int olive::plugin::detail::BytesToPixels(int byte_linesize, } // 作用:将 AVPixelFormat 映射为 Olive 的 PixelFormat 和通道数(仅常见 packed 格式)。 -static void GetOliveFormatFromAV(AVPixelFormat fmt, olive::core::PixelFormat *out_fmt, int *out_ch) +static void GetOliveFormatFromAV(AVPixelFormat fmt, + olive::core::PixelFormat *out_fmt, int *out_ch) { switch (fmt) { case AV_PIX_FMT_GRAY8: - *out_fmt = olive::core::PixelFormat::U8; *out_ch = 1; return; + *out_fmt = olive::core::PixelFormat::U8; + *out_ch = 1; + return; case AV_PIX_FMT_RGB24: - *out_fmt = olive::core::PixelFormat::U8; *out_ch = 3; return; + *out_fmt = olive::core::PixelFormat::U8; + *out_ch = 3; + return; case AV_PIX_FMT_RGBA: - *out_fmt = olive::core::PixelFormat::U8; *out_ch = 4; return; + *out_fmt = olive::core::PixelFormat::U8; + *out_ch = 4; + return; case AV_PIX_FMT_GRAY16LE: case AV_PIX_FMT_GRAY16BE: - *out_fmt = olive::core::PixelFormat::U16; *out_ch = 1; return; + *out_fmt = olive::core::PixelFormat::U16; + *out_ch = 1; + return; case AV_PIX_FMT_RGB48LE: case AV_PIX_FMT_RGB48BE: - *out_fmt = olive::core::PixelFormat::U16; *out_ch = 3; return; + *out_fmt = olive::core::PixelFormat::U16; + *out_ch = 3; + return; case AV_PIX_FMT_RGBA64LE: case AV_PIX_FMT_RGBA64BE: - *out_fmt = olive::core::PixelFormat::U16; *out_ch = 4; return; + *out_fmt = olive::core::PixelFormat::U16; + *out_ch = 4; + return; case AV_PIX_FMT_GRAYF32LE: case AV_PIX_FMT_GRAYF32BE: - *out_fmt = olive::core::PixelFormat::F32; *out_ch = 1; return; + *out_fmt = olive::core::PixelFormat::F32; + *out_ch = 1; + return; case AV_PIX_FMT_RGBF32LE: case AV_PIX_FMT_RGBF32BE: - *out_fmt = olive::core::PixelFormat::F32; *out_ch = 3; return; + *out_fmt = olive::core::PixelFormat::F32; + *out_ch = 3; + return; case AV_PIX_FMT_RGBAF32LE: case AV_PIX_FMT_RGBAF32BE: - *out_fmt = olive::core::PixelFormat::F32; *out_ch = 4; return; + *out_fmt = olive::core::PixelFormat::F32; + *out_ch = 4; + return; default: - *out_fmt = olive::core::PixelFormat::INVALID; *out_ch = 0; return; + *out_fmt = olive::core::PixelFormat::INVALID; + *out_ch = 0; + return; } } // 作用:必要时将 AVFrame 转换为目标 VideoParams 对应格式。 // 优先使用 FFmpeg sws_scale;若不支持且 renderer 可用,则走 GPU 路径。 // 删除所有手写 CPU 像素循环,避免精度损失与性能瓶颈。 -static olive::AVFramePtr ConvertFrameIfNeeded(olive::AVFramePtr src, - const olive::VideoParams &dst_params, - olive::Renderer *renderer = nullptr) +static olive::AVFramePtr +ConvertFrameIfNeeded(olive::AVFramePtr src, + const olive::VideoParams &dst_params, + olive::Renderer *renderer = nullptr) { if (!src) { return nullptr; @@ -1048,8 +1083,7 @@ static olive::AVFramePtr ConvertFrameIfNeeded(olive::AVFramePtr src, } // Same format & size, no conversion needed - if (src->format == dst_fmt && - src->width == dst_params.width() && + if (src->format == dst_fmt && src->width == dst_params.width() && src->height == dst_params.height()) { return src; } @@ -1059,15 +1093,15 @@ static olive::AVFramePtr ConvertFrameIfNeeded(olive::AVFramePtr src, dst->width = dst_params.width(); dst->height = dst_params.height(); if (av_frame_get_buffer(dst.get(), 0) < 0) { - qWarning().noquote() << "[WARN] av_frame_get_buffer failed for dst_fmt=" << dst_fmt; + qWarning().noquote() + << "[WARN] av_frame_get_buffer failed for dst_fmt=" << dst_fmt; return src; } // Try FFmpeg sws_scale first SwsContext *sws_ctx = sws_getContext( src->width, src->height, static_cast(src->format), - dst->width, dst->height, dst_fmt, SWS_POINT, - nullptr, nullptr, nullptr); + dst->width, dst->height, dst_fmt, SWS_POINT, nullptr, nullptr, nullptr); if (sws_ctx) { int ret = sws_scale(sws_ctx, src->data, src->linesize, 0, src->height, dst->data, dst->linesize); @@ -1081,7 +1115,8 @@ static olive::AVFramePtr ConvertFrameIfNeeded(olive::AVFramePtr src, if (renderer && src->data[0]) { olive::core::PixelFormat src_fmt; int src_ch; - GetOliveFormatFromAV(static_cast(src->format), &src_fmt, &src_ch); + GetOliveFormatFromAV(static_cast(src->format), &src_fmt, + &src_ch); if (src_fmt != olive::core::PixelFormat::INVALID && src_ch > 0) { // Ensure renderer's OpenGL context is current before GPU operations. // The context may have been switched by upstream DownloadFromTexture calls. @@ -1092,7 +1127,8 @@ static olive::AVFramePtr ConvertFrameIfNeeded(olive::AVFramePtr src, olive::VideoParams src_vp(src->width, src->height, src_fmt, src_ch); int src_bpp = olive::VideoParams::GetBytesPerPixel(src_fmt, src_ch); - int src_linesize_pixels = (src_bpp > 0) ? src->linesize[0] / src_bpp : src->width; + int src_linesize_pixels = + (src_bpp > 0) ? src->linesize[0] / src_bpp : src->width; olive::TexturePtr src_tex = renderer->CreateTexture( src_vp, src->data[0], src_linesize_pixels); @@ -1108,7 +1144,8 @@ static olive::AVFramePtr ConvertFrameIfNeeded(olive::AVFramePtr src, // Download result back to AVFrame int dst_bpp = dst_params.GetBytesPerPixel(); - int dst_linesize_pixels = (dst_bpp > 0) ? dst->linesize[0] / dst_bpp : dst->width; + int dst_linesize_pixels = + (dst_bpp > 0) ? dst->linesize[0] / dst_bpp : dst->width; dst_tex->Download(dst->data[0], dst_linesize_pixels); return dst; } @@ -1125,7 +1162,8 @@ static olive::AVFramePtr ConvertFrameIfNeeded(olive::AVFramePtr src, // 作用:从字节行跨度换算像素行跨度。 // Purpose: Convert byte line size to pixel line size. -static int LinesizeToPixels(const olive::VideoParams ¶ms, int linesize_bytes) +static int LinesizeToPixels(const olive::VideoParams ¶ms, + int linesize_bytes) { const int bytes_per_pixel = params.channel_count() * params.format().byte_count(); @@ -1137,8 +1175,9 @@ static int LinesizeToPixels(const olive::VideoParams ¶ms, int linesize_bytes // 作用:将纹理转换为指定 VideoParams。优先使用 GPU shader 做格式转换, // 避免 CPU 回读/转换/上传的性能损失和精度损失。 -static olive::TexturePtr ConvertTextureForParams(olive::TexturePtr src, - const olive::VideoParams &dst_params) +static olive::TexturePtr +ConvertTextureForParams(olive::TexturePtr src, + const olive::VideoParams &dst_params) { if (!src) { return nullptr; @@ -1161,8 +1200,8 @@ static olive::TexturePtr ConvertTextureForParams(olive::TexturePtr src, job.Insert(QStringLiteral("ove_maintex"), olive::NodeValue(olive::NodeValue::kTexture, QVariant::fromValue(src))); - renderer->BlitToTexture(renderer->GetDefaultShader(), job, dst.get(), - false); + renderer->BlitToTexture(renderer->GetDefaultShader(), job, + dst.get(), false); return dst; } } @@ -1176,7 +1215,8 @@ static olive::TexturePtr ConvertTextureForParams(olive::TexturePtr src, return nullptr; } - olive::AVFramePtr converted = ConvertFrameIfNeeded(frame, dst_params, nullptr); + olive::AVFramePtr converted = + ConvertFrameIfNeeded(frame, dst_params, nullptr); if (!converted || !converted->data[0]) { return nullptr; } @@ -1208,10 +1248,10 @@ static olive::TexturePtr ConvertTextureForParams(olive::TexturePtr src, return dst; } - // 作用:安全获取插件标识符,便于日志输出。 // Purpose: Safely fetch plugin identifier for logging. -static QString PluginIdForInstance(const OFX::Host::ImageEffect::Instance *instance) +static QString +PluginIdForInstance(const OFX::Host::ImageEffect::Instance *instance) { if (!instance) { return QStringLiteral(""); @@ -1234,8 +1274,7 @@ static void LogOfxFailure(const char *action, OfxStatus stat, qWarning().noquote() << "OFX action failed:" << action << "plugin=" << PluginIdForInstance(instance) - << "status=" << OFX::StatStr(stat) - << "(" << stat << ")"; + << "status=" << OFX::StatStr(stat) << "(" << stat << ")"; } // 作用:输出 clip 的声明属性与关联 VideoParams,辅助定位格式不一致。 @@ -1255,8 +1294,7 @@ static void LogClipState(const char *label, << "components=" << QString::fromStdString(clip->getComponents()); if (params) { qWarning().noquote() - << "OFX clip params" << label - << "width=" << params->width() + << "OFX clip params" << label << "width=" << params->width() << "height=" << params->height() << "format=" << static_cast(params->format()) << "channels=" << params->channel_count(); @@ -1272,8 +1310,8 @@ static void LogImageProps(const char *label, /*qWarning().noquote() << "OFX image props" << label << ""; return;*/ } - int bounds[4] = {0, 0, 0, 0}; - int rod[4] = {0, 0, 0, 0}; + int bounds[4] = { 0, 0, 0, 0 }; + int rod[4] = { 0, 0, 0, 0 }; image->getIntPropertyN(kOfxImagePropBounds, bounds, 4); image->getIntPropertyN(kOfxImagePropRegionOfDefinition, rod, 4); const int row_bytes = image->getIntProperty(kOfxImagePropRowBytes); @@ -1295,7 +1333,8 @@ static void LogImageProps(const char *label, static void MarkRenderFailure(olive::TexturePtr destination) { if (destination && destination->renderer()) { - destination->renderer()->ClearDestination(destination.get(), 1.0, 0.0, 1.0, 1.0); + destination->renderer()->ClearDestination(destination.get(), 1.0, 0.0, + 1.0, 1.0); } } @@ -1316,9 +1355,9 @@ static void ShowErrorDialogAndUndo(const QString &message) static void ScheduleErrorDialogAndUndo(const QString &message) { if (auto *app = QCoreApplication::instance()) { - QMetaObject::invokeMethod(app, [message]() { - ShowErrorDialogAndUndo(message); - }, Qt::QueuedConnection); + QMetaObject::invokeMethod( + app, [message]() { ShowErrorDialogAndUndo(message); }, + Qt::QueuedConnection); } } @@ -1330,19 +1369,18 @@ static olive::AVFramePtr DownloadTextureToFrame(const olive::TexturePtr &tex) const olive::VideoParams ¶ms = tex->params(); return ReadbackTextureToFrame(tex, params); } -inline std::vector GetPluginSupportedDepths(const OFX::Host::ImageEffect::Descriptor& desc) +inline std::vector +GetPluginSupportedDepths(const OFX::Host::ImageEffect::Descriptor &desc) { std::vector depths; - const OFX::Host::Property::Set& props = desc.getProps(); + const OFX::Host::Property::Set &props = desc.getProps(); // 获取数组维度(支持几种深度) int dim = props.getDimension(kOfxImageEffectPropSupportedPixelDepths); for (int i = 0; i < dim; ++i) { // Host Support Library 返回 const std::string& - const std::string& val = props.getStringProperty( - kOfxImageEffectPropSupportedPixelDepths, - i - ); + const std::string &val = + props.getStringProperty(kOfxImageEffectPropSupportedPixelDepths, i); if (!val.empty() && val != kOfxBitDepthNone) { depths.push_back(val); } @@ -1351,11 +1389,13 @@ inline std::vector GetPluginSupportedDepths(const OFX::Host::ImageE } // 查询插件/宿主是否支持「各 clip 不同深度」 -inline bool SupportsMultipleClipDepths(const OFX::Host::ImageEffect::Descriptor& desc) +inline bool +SupportsMultipleClipDepths(const OFX::Host::ImageEffect::Descriptor &desc) { - const OFX::Host::Property::Set& props = desc.getProps(); + const OFX::Host::Property::Set &props = desc.getProps(); // 这是单值 int 属性(0 或 1),n = 0 - int val = props.getIntProperty(kOfxImageEffectPropSupportsMultipleClipDepths, 0); + int val = + props.getIntProperty(kOfxImageEffectPropSupportsMultipleClipDepths, 0); return val != 0; } @@ -1364,20 +1404,20 @@ inline bool SupportsMultipleClipDepths(const OFX::Host::ImageEffect::Descriptor& // 参考 OpenFX API: OfxImageEffectPropSupportedPixelDepths // Purpose: Select best input pixel format from plugin descriptor's supported // depth list. Priority: F32 > U16 > U8 > F16. -static PixelFormat SelectBestPluginInputFormat( - const OFX::Host::ImageEffect::Descriptor& desc) +static PixelFormat +SelectBestPluginInputFormat(const OFX::Host::ImageEffect::Descriptor &desc) { - const OFX::Host::Property::Set& props = desc.getProps(); + const OFX::Host::Property::Set &props = desc.getProps(); int dim = props.getDimension(kOfxImageEffectPropSupportedPixelDepths); bool supports_f32 = false; bool supports_u16 = false; - bool supports_u8 = false; + bool supports_u8 = false; bool supports_f16 = false; for (int i = 0; i < dim; ++i) { - const std::string& depth = props.getStringProperty( - kOfxImageEffectPropSupportedPixelDepths, i); + const std::string &depth = + props.getStringProperty(kOfxImageEffectPropSupportedPixelDepths, i); if (depth == kOfxBitDepthFloat) { supports_f32 = true; } else if (depth == kOfxBitDepthShort) { @@ -1390,20 +1430,24 @@ static PixelFormat SelectBestPluginInputFormat( } // 优先级:F32 > U16 > U8 > F16 - if (supports_f32) return PixelFormat::F32; - if (supports_u16) return PixelFormat::U16; - if (supports_u8) return PixelFormat::U8; - if (supports_f16) return PixelFormat::F16; + if (supports_f32) + return PixelFormat::F32; + if (supports_u16) + return PixelFormat::U16; + if (supports_u8) + return PixelFormat::U8; + if (supports_f16) + return PixelFormat::F16; return PixelFormat::INVALID; } // 作用:执行 OFX 插件渲染全流程(准备输入、调用动作、处理输出)。 // Purpose: Run full OFX plugin render flow (inputs, actions, outputs). -void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::PluginJob& job, - olive::TexturePtr destination, - olive::VideoParams destination_params, - bool clear_destination, bool interactive) +void olive::plugin::PluginRenderer::RenderPlugin( + TexturePtr src, olive::plugin::PluginJob &job, + olive::TexturePtr destination, olive::VideoParams destination_params, + bool clear_destination, bool interactive) { - auto instance=job.pluginInstance(); + auto instance = job.pluginInstance(); if (!instance) { return; } @@ -1414,7 +1458,8 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: // internal QMap/images_ and params_, leading to invalid pointers being // passed to CImg and subsequent SIGSEGV. std::mutex *instance_mutex = nullptr; - if (auto *olive_inst = dynamic_cast(instance)) { + if (auto *olive_inst = + dynamic_cast(instance)) { instance_mutex = &olive_inst->mutex(); } else { static std::mutex fallback_mutex; @@ -1453,11 +1498,11 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: OfxPointD renderScale; renderScale.x = renderScale.y = 1.0; - - int numFramesToRender=1; + int numFramesToRender = 1; // Output Clip - OliveClipInstance *output_clip=dynamic_cast(instance->getClip("Output")); + OliveClipInstance *output_clip = + dynamic_cast(instance->getClip("Output")); if (!output_clip) { return; } @@ -1466,14 +1511,13 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: OfxStatus stat = kOfxStatOK; if (olive_instance && !olive_instance->isCreated()) { stat = instance->createInstanceAction(); - if(stat != kOfxStatOK && stat != kOfxStatReplyDefault) { + if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) { LogOfxFailure("createInstance", stat, instance); MarkRenderFailure(destination); return; } } - OfxTime frame = job.time_seconds(); const auto &clips = olive_instance->getDescriptor().getClips(); @@ -1544,19 +1588,20 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: ok = true; } } catch (const OFX::Host::Property::Exception &e) { - qWarning().noquote() << "OFX getClipPreferences threw exception for plugin=" - << PluginIdForInstance(instance) - << "stat=" << e.getStatus(); + qWarning().noquote() + << "OFX getClipPreferences threw exception for plugin=" + << PluginIdForInstance(instance) << "stat=" << e.getStatus(); MarkRenderFailure(destination); ScheduleErrorDialogAndUndo( - QObject::tr("Plugin %1 failed because connected inputs have different frame rates.\n" - "The last operation has been undone.") + QObject::tr( + "Plugin %1 failed because connected inputs have different frame rates.\n" + "The last operation has been undone.") .arg(PluginIdForInstance(instance))); return; } catch (const std::exception &e) { - qWarning().noquote() << "OFX getClipPreferences threw exception for plugin=" - << PluginIdForInstance(instance) - << "what=" << e.what(); + qWarning().noquote() + << "OFX getClipPreferences threw exception for plugin=" + << PluginIdForInstance(instance) << "what=" << e.what(); MarkRenderFailure(destination); ScheduleErrorDialogAndUndo( QObject::tr("Plugin %1 encountered an error: %2\n" @@ -1579,7 +1624,8 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: OfxRectD regionOfInterest; regionOfInterest.x1 = 0.0; regionOfInterest.y1 = 0.0; - regionOfInterest.x2 = destination_params.width() * destination_params.pixel_aspect_ratio().toDouble(); + regionOfInterest.x2 = destination_params.width() * + destination_params.pixel_aspect_ratio().toDouble(); regionOfInterest.y2 = destination_params.height(); OfxRectD regionOfDefinition = regionOfInterest; @@ -1594,7 +1640,6 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: // // In our example we are doing full frame fetches regardless. - // set correct format for input // Ensure all input textures are fully rendered before CPU readback. @@ -1626,7 +1671,8 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: PixelFormat chosen_fmt = SelectBestPluginInputFormat(descriptor); VideoParams params = input_tex->params(); - if (chosen_fmt != PixelFormat::INVALID && params.format() != chosen_fmt) { + if (chosen_fmt != PixelFormat::INVALID && + params.format() != chosen_fmt) { params.set_format(chosen_fmt); TexturePtr converted_tex = ConvertTextureForParams(input_tex, params); @@ -1656,8 +1702,7 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: if (stat == kOfxStatErrBadHandle) { qWarning().noquote() << "OFX getRegionOfInterest returned BadHandle for plugin=" - << PluginIdForInstance(instance) - << "- using default RoI"; + << PluginIdForInstance(instance) << "- using default RoI"; } else { LogOfxFailure("getRegionOfInterest", stat, instance); MarkRenderFailure(destination); @@ -1689,10 +1734,8 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: renderWindow.x2 = destination_params.width(); renderWindow.y2 = destination_params.height(); - - stat = instance->beginRenderAction(frame, numFramesToRender, - 1.0, false, renderScale, true, - interactive); + stat = instance->beginRenderAction(frame, numFramesToRender, 1.0, false, + renderScale, true, interactive); if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) { LogOfxFailure("beginRender", stat, instance); MarkRenderFailure(destination); @@ -1706,7 +1749,6 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: } #endif - if (!output_params.is_valid()) { qWarning().noquote() << "OFX render skipped due to invalid output params for plugin=" @@ -1723,25 +1765,25 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: // render a frame const char *render_field = GetRenderFieldForParams(output_params); - stat = instance->renderAction(frame, render_field, renderWindow, renderScale, - true, interactive, interactive); + stat = instance->renderAction(frame, render_field, renderWindow, + renderScale, true, interactive, interactive); if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) { LogOfxFailure("render", stat, instance); LogClipState("output", output_clip, &output_params); for (const auto &entry : input_clips) { const auto params_it = input_params.find(entry.first); const olive::VideoParams *params = - (params_it != input_params.end()) ? ¶ms_it->second - : nullptr; + (params_it != input_params.end()) ? ¶ms_it->second : + nullptr; LogClipState("input", entry.second, params); OFX::Host::ImageEffect::Image *image = entry.second->getImage(frame, nullptr); LogImageProps("input", image); //if (image) { - //image->releaseReference(); + //image->releaseReference(); //} } - OFX::Host::ImageEffect::Image* output_image = + OFX::Host::ImageEffect::Image *output_image = output_clip->getOutputImage(frame); LogImageProps("output", output_image); MarkRenderFailure(destination); @@ -1751,7 +1793,7 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: } // get the output image buffer (CPU path only) - OFX::Host::ImageEffect::Image* output_image; + OFX::Host::ImageEffect::Image *output_image; if (!use_opengl) { output_image = output_clip->getOutputImage(frame); if (!output_image) { @@ -1759,8 +1801,9 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: << "OFX getOutputImage returned null for plugin=" << PluginIdForInstance(instance); MarkRenderFailure(destination); - instance->endRenderAction(frame, numFramesToRender, 1.0, interactive, - renderScale, true, interactive); + instance->endRenderAction(frame, numFramesToRender, 1.0, + interactive, renderScale, true, + interactive); return; } // Diagnostic: peek at first few pixels @@ -1775,31 +1818,33 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: } } } - } else { + } else { if (!destination || !destination->id().isValid()) { #ifdef OFX_SUPPORTS_OPENGLRENDER DetachOutputTexture(); instance->contextDetachedAction(); #endif - instance->endRenderAction(frame, numFramesToRender, 1.0, interactive, - renderScale, true, interactive); + instance->endRenderAction(frame, numFramesToRender, 1.0, + interactive, renderScale, true, + interactive); return; } } if (!use_opengl) { - AVFramePtr frame_ptr = - create_avframe_from_ofx_image_with_params(*output_image, - output_params); + AVFramePtr frame_ptr = create_avframe_from_ofx_image_with_params( + *output_image, output_params); if (!frame_ptr) { qWarning().noquote() << "OFX output image conversion failed for plugin=" << PluginIdForInstance(instance); - instance->endRenderAction(frame, numFramesToRender, 1.0, interactive, - renderScale, true, interactive); + instance->endRenderAction(frame, numFramesToRender, 1.0, + interactive, renderScale, true, + interactive); return; } - AVFramePtr converted = ConvertFrameIfNeeded(frame_ptr, destination_params, renderer_); + AVFramePtr converted = + ConvertFrameIfNeeded(frame_ptr, destination_params, renderer_); const AVPixelFormat expected_fmt = GetDestinationAVPixelFormat(destination_params); destination->handleFrame(converted); @@ -1829,14 +1874,14 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: return; } - instance->endRenderAction(frame, numFramesToRender, 1.0, interactive, renderScale, true,interactive - ); - + instance->endRenderAction(frame, numFramesToRender, 1.0, interactive, + renderScale, true, interactive); } // 作用:绑定输出纹理到 OFX 的 GL 输出路径。 // Purpose: Attach output texture for OFX GL rendering. -void olive::plugin::PluginRenderer::AttachOutputTexture(olive::TexturePtr texture) +void olive::plugin::PluginRenderer::AttachOutputTexture( + olive::TexturePtr texture) { if (renderer_) { renderer_->AttachOutputTexture(texture.get()); diff --git a/app/render/plugin/pluginrenderer.h b/app/render/plugin/pluginrenderer.h index b0b62855d..cc08b52cb 100644 --- a/app/render/plugin/pluginrenderer.h +++ b/app/render/plugin/pluginrenderer.h @@ -31,8 +31,10 @@ namespace olive { -namespace plugin{ -namespace detail { +namespace plugin +{ +namespace detail +{ // 作用:将字节行跨度转换为像素跨度,便于纹理读写。 // Purpose: Convert byte stride to pixel stride for texture I/O. int BytesToPixels(int byte_linesize, const olive::VideoParams ¶ms); @@ -46,9 +48,15 @@ int BytesToPixels(int byte_linesize, const olive::VideoParams ¶ms); class PluginRenderer : public QObject { Q_OBJECT public: - explicit PluginRenderer(olive::Renderer *renderer, QObject *parent = nullptr) - : QObject(parent), renderer_(renderer) {} - virtual ~PluginRenderer() override {} + explicit PluginRenderer(olive::Renderer *renderer, + QObject *parent = nullptr) + : QObject(parent) + , renderer_(renderer) + { + } + virtual ~PluginRenderer() override + { + } olive::Renderer *renderer() const { @@ -63,7 +71,7 @@ public: void DetachOutputTexture(); // 作用:执行插件渲染流程(参数配置、输入/输出、调用渲染动作)。 // Purpose: Execute plugin render flow (params, inputs/outputs, render actions). - void RenderPlugin(TexturePtr src, olive::plugin::PluginJob& job, + void RenderPlugin(TexturePtr src, olive::plugin::PluginJob &job, olive::TexturePtr destination, olive::VideoParams destination_params, bool clear_destination, bool interactive); @@ -74,6 +82,4 @@ private: } } - - #endif //PLUGINRENDERER_H diff --git a/app/render/previewautocacher.cpp b/app/render/previewautocacher.cpp index 1c42a327b..193528109 100644 --- a/app/render/previewautocacher.cpp +++ b/app/render/previewautocacher.cpp @@ -561,7 +561,8 @@ void PreviewAutoCacher::TryRender() video_immediate_passthroughs_[watcher].append(t); } } else { - qWarning() << "Failed to find copied node for SFR ticket, requeueing"; + qWarning() + << "Failed to find copied node for SFR ticket, requeueing"; single_frame_render_ = t; if (!delayed_requeue_timer_.isActive()) { delayed_requeue_timer_.start(); @@ -594,7 +595,8 @@ void PreviewAutoCacher::TryRender() } } } else { - qWarning() << "Failed to find node copy for video job, retrying"; + qWarning() + << "Failed to find node copy for video job, retrying"; if (!delayed_requeue_timer_.isActive()) { delayed_requeue_timer_.start(); } @@ -636,7 +638,8 @@ void PreviewAutoCacher::TryRender() RenderAudio(copy, d.context, use_range, d.cache); } else { - qWarning() << "Failed to find node copy for audio job, retrying"; + qWarning() + << "Failed to find node copy for audio job, retrying"; pop = false; if (!delayed_requeue_timer_.isActive()) { delayed_requeue_timer_.start(); diff --git a/app/render/projectcopier.cpp b/app/render/projectcopier.cpp index cc406cc6d..1219596ae 100644 --- a/app/render/projectcopier.cpp +++ b/app/render/projectcopier.cpp @@ -265,7 +265,9 @@ void ProjectCopier::InsertIntoCopyMap(Node *node, Node *copy) if (Footage *src_footage = dynamic_cast(node)) { if (dynamic_cast(copy)) { connect(src_footage, &Footage::ProxySettingsChanged, this, - [this, src_footage]() { SyncFootageProxySettings(src_footage); }); + [this, src_footage]() { + SyncFootageProxySettings(src_footage); + }); SyncFootageProxySettings(src_footage); } } @@ -279,14 +281,15 @@ void ProjectCopier::SyncFootageProxySettings(Footage *source) Footage *copy = GetCopy(source); if (!copy) { qWarning() << "ProjectCopier::SyncFootageProxySettings: no copy for" - << source->filename(); + << source->filename(); return; } - qDebug() << "ProjectCopier::SyncFootageProxySettings:" << source->filename() - << "enabled=" << source->proxy_enabled() << "->" - << copy->proxy_enabled() << "state=" - << ProxyManager::ProxyStateToString(source->proxy_state()); + qDebug() + << "ProjectCopier::SyncFootageProxySettings:" << source->filename() + << "enabled=" << source->proxy_enabled() << "->" + << copy->proxy_enabled() + << "state=" << ProxyManager::ProxyStateToString(source->proxy_state()); copy->SetProxy(source->proxy_path(), source->proxy_state(), source->proxy_video_stream_index(), diff --git a/app/render/renderer.h b/app/render/renderer.h index 9d7ce2c75..f0e9c2cee 100644 --- a/app/render/renderer.h +++ b/app/render/renderer.h @@ -34,7 +34,8 @@ #include "texture.h" // Forward declarations to keep the render core header lightweight -namespace olive { +namespace olive +{ class ColorTransformJob; class Node; } @@ -57,17 +58,16 @@ public: void DestroyTexture(Texture *texture); - virtual void BlitToTexture(QVariant shader, olive::AcceleratedJob& job, - olive::Texture *destination, - bool clear_destination = true) + virtual void BlitToTexture(QVariant shader, olive::AcceleratedJob &job, + olive::Texture *destination, + bool clear_destination = true) { Blit(shader, job, destination, destination->params(), clear_destination); - } - void Blit(QVariant shader, olive::AcceleratedJob& job, olive::VideoParams params, - bool clear_destination = true) + void Blit(QVariant shader, olive::AcceleratedJob &job, + olive::VideoParams params, bool clear_destination = true) { Blit(shader, job, nullptr, params, clear_destination); } @@ -147,10 +147,12 @@ public: * * Default implementation is a no-op. */ - virtual void DetachOutputTexture() {} + virtual void DetachOutputTexture() + { + } protected: - virtual void Blit(QVariant shader, olive::AcceleratedJob& job, + virtual void Blit(QVariant shader, olive::AcceleratedJob &job, olive::Texture *destination, olive::VideoParams destination_params, bool clear_destination) = 0; @@ -164,7 +166,7 @@ protected: virtual void DestroyInternal() = 0; private: - std::atomic destroyed_{false}; + std::atomic destroyed_{ false }; std::shared_ptr lifetime_; struct ColorContext { struct LUT { diff --git a/app/render/rendermanager.cpp b/app/render/rendermanager.cpp index bbe62f7a4..5bd808695 100644 --- a/app/render/rendermanager.cpp +++ b/app/render/rendermanager.cpp @@ -78,24 +78,26 @@ QString RenderManager::BackendToString(Backend backend) } RenderManager::RenderManager(QObject *parent) - : backend_(BackendFromString( - OLIVE_CONFIG("GraphicsBackend").toString())) + : backend_(BackendFromString(OLIVE_CONFIG("GraphicsBackend").toString())) , requested_backend_(backend_) , aggressive_gc_(0) , worker_pool_(nullptr) { if (backend_ == kVulkan) { #ifndef OAK_ENABLE_DYNAMIC_RENDER_BACKEND - qWarning() << "Vulkan backend requested but dynamic render backend is not enabled. Falling back to OpenGL."; + qWarning() + << "Vulkan backend requested but dynamic render backend is not enabled. Falling back to OpenGL."; backend_ = kOpenGL; #endif } if (backend_ == kOpenGL || backend_ == kVulkan) { #ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND - auto *dynamic_renderer = new DynamicRenderer(BackendToString(requested_backend_)); + auto *dynamic_renderer = + new DynamicRenderer(BackendToString(requested_backend_)); if (!dynamic_renderer->Load()) { - qWarning() << "Failed to load dynamic render backend" << BackendToString(requested_backend_) + qWarning() << "Failed to load dynamic render backend" + << BackendToString(requested_backend_) << ", falling back to OpenGL"; delete dynamic_renderer; backend_ = kOpenGL; @@ -104,7 +106,8 @@ RenderManager::RenderManager(QObject *parent) context_ = dynamic_renderer; // DynamicRenderer may internally fall back (e.g. Vulkan -> OpenGL). // Synchronize RenderManager's view of the actual runtime backend. - Backend actual_backend = BackendFromString(dynamic_renderer->backend_name()); + Backend actual_backend = + BackendFromString(dynamic_renderer->backend_name()); if (actual_backend != backend_) { qWarning() << "Dynamic render backend fell back from" << BackendToString(backend_) << "to" @@ -218,11 +221,13 @@ RenderTicketPtr RenderManager::RenderFrame(const RenderVideoParams ¶ms) if (worker_params.return_type == ReturnType::kNull) { dry_run_thread_->AddTicket(ticket); - } else if (worker_pool_ && worker_pool_->SubmitFrame(ticket, worker_params)) { + } else if (worker_pool_ && + worker_pool_->SubmitFrame(ticket, worker_params)) { return ticket; } else { - qWarning() << "RenderManager: worker pool unavailable, finishing ticket " - "without result"; + qWarning() + << "RenderManager: worker pool unavailable, finishing ticket " + "without result"; ticket->Finish(); } diff --git a/app/render/rendermanager.h b/app/render/rendermanager.h index 33d40f2ff..dbf96be1c 100644 --- a/app/render/rendermanager.h +++ b/app/render/rendermanager.h @@ -82,7 +82,7 @@ public: /// Vulkan requested by the user. Falls back to OpenGL until VulkanRenderer is implemented. kVulkan, - /// Video frames are rendered by an external olive-render-worker process. + /// Video frames are rendered by an external oak-render-worker process. kMultiProcess, /// No graphics rendering - used to test core threading logic diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index 7b13e5f89..1c096b1b4 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -28,7 +28,6 @@ #include #include - #include "audio/audioprocessor.h" #include "node/block/clip/clip.h" #include "node/block/transition/transition.h" @@ -159,7 +158,6 @@ FramePtr RenderProcessor::GenerateFrame(TexturePtr texture, QString::fromUtf8(output_color_transform->id())); frame->set_video_params(display_params); } - } return frame; @@ -173,7 +171,7 @@ void RenderProcessor::Run() SetCancelPointer(ticket_->GetCancelAtom()); - VideoParams params=ticket_->property("vparam").value(); + VideoParams params = ticket_->property("vparam").value(); params.set_format(PixelFormat::F32); SetCacheVideoParams(params); SetCacheAudioParams(ticket_->property("aparam").value()); @@ -416,27 +414,29 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, } if (using_colorspace.isEmpty()) { - qWarning() << "RenderProcessor ProcessVideoFootage: no input colorspace available"; + qWarning() + << "RenderProcessor ProcessVideoFootage: no input colorspace available"; } auto blit_color_managed = [&](const TexturePtr &unmanaged_texture, - const VideoParams &texture_params) { + const VideoParams &texture_params) { if (!render_ctx_ || !unmanaged_texture || IsCancelled()) { return; } // We convert to our rendering pixel format, since that will always be float-based which // is necessary for correct color conversion - ColorProcessorPtr processor = ColorProcessor::Create( - color_manager, using_colorspace, - color_manager->GetReferenceColorSpace()); + ColorProcessorPtr processor = + ColorProcessor::Create(color_manager, using_colorspace, + color_manager->GetReferenceColorSpace()); ColorTransformJob job; job.SetColorProcessor(processor); job.SetInputTexture(unmanaged_texture); if (texture_params.channel_count() != VideoParams::kRGBAChannelCount || - texture_params.colorspace() == color_manager->GetReferenceColorSpace()) { + texture_params.colorspace() == + color_manager->GetReferenceColorSpace()) { job.SetInputAlphaAssociation(kAlphaNone); } else if (texture_params.premultiplied_alpha()) { job.SetInputAlphaAssociation(kAlphaAssociated); @@ -450,12 +450,14 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, render_ctx_->Flush(); }; - auto *input_pool = - QtUtils::ValueToPtr(ticket_->property("ipc_input_pool")); + auto *input_pool = QtUtils::ValueToPtr( + ticket_->property("ipc_input_pool")); int input_slot = -1; - const QVariantList input_slots = ticket_->property("ipc_input_slots").toList(); + const QVariantList input_slots = + ticket_->property("ipc_input_slots").toList(); if (!input_slots.isEmpty()) { - const QVariant cursor_value = ticket_->property("ipc_input_slot_cursor"); + const QVariant cursor_value = + ticket_->property("ipc_input_slot_cursor"); const int cursor = cursor_value.isValid() ? cursor_value.toInt() : 0; if (cursor >= 0 && cursor < input_slots.size()) { input_slot = input_slots.at(cursor).toInt(); @@ -467,25 +469,26 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, } if (render_ctx_ && input_pool && input_slot >= 0) { if (input_slot >= int(input_pool->slot_count())) { - qWarning() << "RenderProcessor received out-of-range IPC input frame slot" - << input_slot; + qWarning() + << "RenderProcessor received out-of-range IPC input frame slot" + << input_slot; return; } const ipc::FrameSlotMeta *meta = input_pool->Meta(uint32_t(input_slot)); - if (meta && meta->width > 0 && meta->height > 0 && meta->data_size > 0 && + if (meta && meta->width > 0 && meta->height > 0 && + meta->data_size > 0 && meta->data_size <= int(input_pool->slot_data_bytes())) { VideoParams input_params = stream_data; input_params.set_width(meta->width); input_params.set_height(meta->height); input_params.set_format(PixelFormat::Format(meta->format)); input_params.set_channel_count(meta->channel_count); - // The decoder may leave depth at 0 for 2D frames, but the renderer - // needs depth >= 1 to compute image size and upload the texture. - if (input_params.depth() <= 0) { - input_params.set_depth(1); - } - + // The decoder may leave depth at 0 for 2D frames, but the renderer + // needs depth >= 1 to compute image size and upload the texture. + if (input_params.depth() <= 0) { + input_params.set_depth(1); + } // Prefer the colorspace that the main process used when decoding this // frame. The FootageJob reconstructed in the worker may have stale or @@ -498,9 +501,9 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, } const int bytes_per_pixel = input_params.GetBytesPerPixel(); - const int linesize_pixels = bytes_per_pixel > 0 - ? meta->linesize / bytes_per_pixel - : input_params.effective_width(); + const int linesize_pixels = bytes_per_pixel > 0 ? + meta->linesize / bytes_per_pixel : + input_params.effective_width(); const void *slot_data = input_pool->SlotData(uint32_t(input_slot)); TexturePtr unmanaged_texture = render_ctx_->CreateTexture( @@ -509,13 +512,15 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, blit_color_managed(unmanaged_texture, input_params); return; } - qWarning() << "RenderProcessor received invalid IPC input frame slot" << input_slot; + qWarning() << "RenderProcessor received invalid IPC input frame slot" + << input_slot; return; } if (!decoder_cache_) { - qWarning() << "RenderProcessor has no decoder cache or IPC input frame for" - << stream->filename(); + qWarning() + << "RenderProcessor has no decoder cache or IPC input frame for" + << stream->filename(); return; } @@ -523,15 +528,15 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, static_cast(ticket_->property("mode").toInt()) == RenderMode::kOffline && stream->has_proxy() && QFileInfo::exists(stream->proxy_filename()); - const QString decode_filename = - use_proxy ? stream->proxy_filename() : stream->filename(); - const QString decoder_id = - use_proxy ? stream->proxy_decoder() : stream->decoder(); - const int stream_index = - use_proxy ? stream->proxy_stream_index() : stream_data.stream_index(); + const QString decode_filename = use_proxy ? stream->proxy_filename() : + stream->filename(); + const QString decoder_id = use_proxy ? stream->proxy_decoder() : + stream->decoder(); + const int stream_index = use_proxy ? stream->proxy_stream_index() : + stream_data.stream_index(); - Decoder::CodecStream default_codec_stream( - decode_filename, stream_index, GetCurrentBlock()); + Decoder::CodecStream default_codec_stream(decode_filename, stream_index, + GetCurrentBlock()); DecoderPtr decoder = nullptr; @@ -553,8 +558,8 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, decode_filename, frame_number); // Decoder will close automatically since it's a stream_ptr - decoder->Open(Decoder::CodecStream( - frame_filename, stream_index, GetCurrentBlock())); + decoder->Open(Decoder::CodecStream(frame_filename, stream_index, + GetCurrentBlock())); } break; } @@ -643,7 +648,8 @@ void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node, locker.unlock(); // Run shader - render_ctx_->BlitToTexture(shader, const_cast(*job), destination.get()); + render_ctx_->BlitToTexture(shader, const_cast(*job), + destination.get()); } void RenderProcessor::ProcessSamples(SampleBuffer &destination, @@ -720,8 +726,7 @@ TexturePtr RenderProcessor::ProcessPluginJob(TexturePtr texture, return destination; } - auto *plugin_job = - dynamic_cast(texture->job()); + auto *plugin_job = dynamic_cast(texture->job()); if (!plugin_job) { return destination; } @@ -779,13 +784,8 @@ TexturePtr RenderProcessor::ProcessPluginJob(TexturePtr texture, } } - plugin_renderer.RenderPlugin( - src, - *plugin_job, - destination, - destination->params(), - true, - false); + plugin_renderer.RenderPlugin(src, *plugin_job, destination, + destination->params(), true, false); return destination; } @@ -797,7 +797,8 @@ TexturePtr RenderProcessor::ProcessVideoCacheJob(const CacheJob *val) // Auto-detect and discard black/empty cached frames (macOS TBDR artifact) bool all_black = true; if (frame->data() && frame->allocated_size() > 0) { - const uint8_t *pixels = reinterpret_cast(frame->data()); + const uint8_t *pixels = + reinterpret_cast(frame->data()); size_t alloc_size = static_cast(frame->allocated_size()); size_t check_bytes = std::min(alloc_size, size_t(4096)); for (size_t i = 0; i < check_bytes; ++i) { @@ -808,7 +809,8 @@ TexturePtr RenderProcessor::ProcessVideoCacheJob(const CacheJob *val) } } if (all_black) { - qWarning() << "[CACHE] Discarding black cached frame:" << val->GetFilename() + qWarning() << "[CACHE] Discarding black cached frame:" + << val->GetFilename() << "time=" << frame->timestamp().toDouble() << "size=" << frame->allocated_size(); QFile::remove(val->GetFilename()); diff --git a/app/render/renderprocessor.h b/app/render/renderprocessor.h index d72d8b0af..2a58c690f 100644 --- a/app/render/renderprocessor.h +++ b/app/render/renderprocessor.h @@ -32,7 +32,8 @@ namespace olive { -namespace plugin { +namespace plugin +{ class PluginRenderer; } diff --git a/app/render/renderworkerpool.cpp b/app/render/renderworkerpool.cpp index d5d20dbe1..958e59058 100644 --- a/app/render/renderworkerpool.cpp +++ b/app/render/renderworkerpool.cpp @@ -62,8 +62,8 @@ struct FootageInput { class FootageInputCollector : public NodeTraverser { public: - QVector Collect(const RenderManager::RenderVideoParams ¶ms, - CancelAtom *cancel) + QVector + Collect(const RenderManager::RenderVideoParams ¶ms, CancelAtom *cancel) { SetCancelPointer(cancel); VideoParams cache_params = params.video_params; @@ -75,17 +75,15 @@ public: if (cache_params.interlacing() != VideoParams::kInterlaceNone) { frame_length /= 2; } - NodeValueTable table = GenerateTable(params.node, - TimeRange(params.time, - params.time + frame_length)); + NodeValueTable table = GenerateTable( + params.node, TimeRange(params.time, params.time + frame_length)); NodeValue texture = table.Get(NodeValue::kTexture); ResolveJobs(texture); if (cache_params.interlacing() != VideoParams::kInterlaceNone) { - NodeValueTable second_table = - GenerateTable(params.node, - TimeRange(params.time + frame_length, - params.time + frame_length * 2)); + NodeValueTable second_table = GenerateTable( + params.node, TimeRange(params.time + frame_length, + params.time + frame_length * 2)); NodeValue second_texture = second_table.Get(NodeValue::kTexture); ResolveJobs(second_texture); } @@ -94,13 +92,12 @@ public: } protected: - void ProcessVideoFootage(TexturePtr destination, - const FootageJob *stream, + void ProcessVideoFootage(TexturePtr destination, const FootageJob *stream, const rational &input_time) override { Q_UNUSED(destination) if (stream) { - inputs_.append({*stream, input_time}); + inputs_.append({ *stream, input_time }); } } @@ -140,8 +137,7 @@ DecoderPtr ResolveDecoderFromCache(DecoderCache *decoder_cache, } FramePtr DecodeInputFrame(DecoderCache *decoder_cache, - const FootageInput &input, - CancelAtom *cancel) + const FootageInput &input, CancelAtom *cancel) { VideoParams stream_data = input.job.video_params(); QString filename = input.job.filename(); @@ -162,19 +158,17 @@ FramePtr DecodeInputFrame(DecoderCache *decoder_cache, case VideoParams::kVideoTypeVideo: case VideoParams::kVideoTypeStill: decoder = ResolveDecoderFromCache( - decoder_cache, - decoder_id, + decoder_cache, decoder_id, Decoder::CodecStream(filename, stream_index, nullptr)); break; case VideoParams::kVideoTypeImageSequence: { const int64_t frame_number = stream_data.get_time_in_timebase_units(input.time); - filename = Decoder::TransformImageSequenceFileName(filename, frame_number); + filename = + Decoder::TransformImageSequenceFileName(filename, frame_number); decoder = Decoder::CreateFromID(decoder_id); - if (decoder && - !decoder->Open(Decoder::CodecStream(filename, - stream_index, - nullptr))) { + if (decoder && !decoder->Open(Decoder::CodecStream( + filename, stream_index, nullptr))) { decoder = nullptr; } break; @@ -188,9 +182,9 @@ FramePtr DecodeInputFrame(DecoderCache *decoder_cache, Decoder::RetrieveVideoParams retrieve; retrieve.divider = stream_data.divider(); retrieve.maximum_format = PixelFormat::U16; - retrieve.time = stream_data.video_type() == VideoParams::kVideoTypeVideo - ? input.time - : Decoder::kAnyTimecode; + retrieve.time = stream_data.video_type() == VideoParams::kVideoTypeVideo ? + input.time : + Decoder::kAnyTimecode; retrieve.cancelled = cancel; retrieve.force_range = stream_data.color_range(); retrieve.src_interlacing = stream_data.interlacing(); @@ -207,15 +201,13 @@ FramePtr DecodeInputFrame(DecoderCache *decoder_cache, frame_params.set_colorspace(stream_data.colorspace()); frame->set_video_params(frame_params); } - } return frame; } bool DecodeInputFrames(DecoderCache *decoder_cache, const RenderManager::RenderVideoParams ¶ms, - CancelAtom *cancel, - QVector *frames) + CancelAtom *cancel, QVector *frames) { frames->clear(); @@ -241,9 +233,9 @@ bool DecodeInputFrames(DecoderCache *decoder_cache, QString WorkerProgramPath() { #if defined(Q_OS_WIN) - const QString file = QStringLiteral("olive-render-worker.exe"); + const QString file = QStringLiteral("oak-render-worker.exe"); #else - const QString file = QStringLiteral("olive-render-worker"); + const QString file = QStringLiteral("oak-render-worker"); #endif const QString app_dir = QCoreApplication::applicationDirPath(); @@ -271,7 +263,8 @@ bool WriteControlMessage(QProcess *process, const QJsonObject &obj) return false; } - const QByteArray line = QJsonDocument(obj).toJson(QJsonDocument::Compact) + '\n'; + const QByteArray line = + QJsonDocument(obj).toJson(QJsonDocument::Compact) + '\n'; const qint64 written = process->write(line); if (written != line.size()) { return false; @@ -285,7 +278,8 @@ void TryWriteControlMessage(QProcess *process, const QJsonObject &obj) return; } - const QByteArray line = QJsonDocument(obj).toJson(QJsonDocument::Compact) + '\n'; + const QByteArray line = + QJsonDocument(obj).toJson(QJsonDocument::Compact) + '\n'; process->write(line); } @@ -315,12 +309,14 @@ bool IsProcessAlive(qint64 process_id) } #if defined(Q_OS_WIN) - HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, DWORD(process_id)); + HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, + DWORD(process_id)); if (!handle) { return false; } DWORD exit_code = 0; - const bool alive = GetExitCodeProcess(handle, &exit_code) && exit_code == STILL_ACTIVE; + const bool alive = GetExitCodeProcess(handle, &exit_code) && + exit_code == STILL_ACTIVE; CloseHandle(handle); return alive; #else @@ -334,11 +330,11 @@ QString WorkerProcessDetails(const QProcess *process) return QStringLiteral("worker process unavailable"); } - const QString exit_status = - process->exitStatus() == QProcess::CrashExit - ? QStringLiteral("crash") - : QStringLiteral("normal"); - return QStringLiteral("state=%1 exit_status=%2 exit_code=%3 process_error=%4 error=\"%5\"") + const QString exit_status = process->exitStatus() == QProcess::CrashExit ? + QStringLiteral("crash") : + QStringLiteral("normal"); + return QStringLiteral( + "state=%1 exit_status=%2 exit_code=%3 process_error=%4 error=\"%5\"") .arg(int(process->state())) .arg(exit_status) .arg(process->exitCode()) @@ -355,8 +351,9 @@ bool ReadControlMessage(QProcess *process, QJsonObject *out, QString *error, *error = QStringLiteral("worker exited before response: %1") .arg(WorkerProcessDetails(process)); } else { - *error = QStringLiteral("timeout waiting for worker response: %1") - .arg(WorkerProcessDetails(process)); + *error = + QStringLiteral("timeout waiting for worker response: %1") + .arg(WorkerProcessDetails(process)); } } return false; @@ -372,7 +369,8 @@ bool ReadControlMessage(QProcess *process, QJsonObject *out, QString *error, const QJsonDocument doc = QJsonDocument::fromJson(line, &parse_error); if (parse_error.error != QJsonParseError::NoError || !doc.isObject()) { if (error) { - *error = QStringLiteral("worker emitted malformed control JSON"); + *error = + QStringLiteral("worker emitted malformed control JSON"); } return false; } @@ -394,11 +392,10 @@ bool ReadControlMessage(QProcess *process, QJsonObject *out, QString *error, return false; } -} // namespace +} // namespace RenderWorkerPool::RenderWorkerPool(DecoderCache *decoder_cache, - const QString &gpu_backend, - QObject *parent) + const QString &gpu_backend, QObject *parent) : QThread(parent) , decoder_cache_(decoder_cache) , gpu_backend_(gpu_backend) @@ -410,8 +407,8 @@ RenderWorkerPool::~RenderWorkerPool() Shutdown(); } -bool RenderWorkerPool::SubmitFrame(RenderTicketPtr ticket, - const RenderManager::RenderVideoParams ¶ms) +bool RenderWorkerPool::SubmitFrame( + RenderTicketPtr ticket, const RenderManager::RenderVideoParams ¶ms) { Job job(ticket, params); if (!PrepareJob(ticket, params, &job)) { @@ -460,7 +457,7 @@ bool RenderWorkerPool::RemoveTicket(RenderTicketPtr ticket) } if (!queued_graph_path.isEmpty()) { - CleanupGraphFile(queued_graph_path); + ReleaseGraphPathRef(queued_graph_path); return true; } @@ -469,8 +466,6 @@ bool RenderWorkerPool::RemoveTicket(RenderTicketPtr ticket) void RenderWorkerPool::Shutdown() { - QVector graph_paths_to_clean; - { QMutexLocker locker(&mutex_); stopping_ = true; @@ -478,6 +473,7 @@ void RenderWorkerPool::Shutdown() if (job.ticket) { job.ticket->Cancel(); } + ReleaseGraphPathRefLocked(job.graph_path); } queue_.clear(); for (ActiveJob &active : active_jobs_) { @@ -487,16 +483,12 @@ void RenderWorkerPool::Shutdown() } } for (auto it = graph_cache_.begin(); it != graph_cache_.end(); ++it) { - graph_paths_to_clean.append(it->path); + SetGraphPathCachedLocked(it->path, false); } graph_cache_.clear(); wait_.wakeAll(); } - for (const QString &path : graph_paths_to_clean) { - CleanupGraphFile(path); - } - if (isRunning()) { wait(); } @@ -510,13 +502,13 @@ void RenderWorkerPool::run() active_jobs_.resize(worker_count); } - std::vector>> local_pools(worker_count); + std::vector>> local_pools( + worker_count); std::vector workers; workers.reserve(size_t(worker_count)); for (int i = 0; i < worker_count; i++) { - workers.emplace_back([this, i, &local_pools]() { - WorkerLoop(i, &local_pools[i]); - }); + workers.emplace_back( + [this, i, &local_pools]() { WorkerLoop(i, &local_pools[i]); }); } for (std::thread &worker : workers) { @@ -534,8 +526,7 @@ void RenderWorkerPool::run() } void RenderWorkerPool::WorkerLoop( - int worker_index, - std::vector> *local_pool) + int worker_index, std::vector> *local_pool) { while (true) { mutex_.lock(); @@ -552,6 +543,7 @@ void RenderWorkerPool::WorkerLoop( mutex_.unlock(); ProcessJob(job, worker_index, local_pool); + ReleaseGraphPathRef(job.graph_path); } } @@ -565,7 +557,8 @@ bool RenderWorkerPool::PrepareJob(RenderTicketPtr ticket, Project *project = Project::GetProjectFromObject(params.node); if (!project) { - qWarning() << "RenderWorkerPool could not resolve project for render node"; + qWarning() + << "RenderWorkerPool could not resolve project for render node"; return false; } @@ -585,13 +578,16 @@ bool RenderWorkerPool::PrepareJob(RenderTicketPtr ticket, auto it = graph_cache_.find(project_uuid); if (it != graph_cache_.end() && !project->is_modified()) { graph_path = it->path; - //qDebug() << "RenderWorkerPool::PrepareJob: using cached graph snapshot" - // << graph_path; + AddGraphPathRefLocked(graph_path); + qDebug() + << "RenderWorkerPool::PrepareJob: using cached graph snapshot" + << graph_path; } else { if (it != graph_cache_.end()) { - qDebug() << "RenderWorkerPool::PrepareJob: graph stale, rewriting" - << project->is_modified(); - CleanupGraphFile(it->path); + qDebug() + << "RenderWorkerPool::PrepareJob: graph stale, rewriting" + << project->is_modified(); + SetGraphPathCachedLocked(it->path, false); graph_cache_.erase(it); } locker.unlock(); @@ -606,7 +602,9 @@ bool RenderWorkerPool::PrepareJob(RenderTicketPtr ticket, project->set_modified(false); } locker.relock(); - graph_cache_.insert(project_uuid, {graph_path}); + graph_cache_.insert(project_uuid, { graph_path }); + SetGraphPathCachedLocked(graph_path, true); + AddGraphPathRefLocked(graph_path); } } @@ -621,17 +619,26 @@ bool RenderWorkerPool::PrepareJob(RenderTicketPtr ticket, bool RenderWorkerPool::WriteGraphSnapshot(Project *project, QString *path) { - QTemporaryFile file(QDir::temp().filePath(QStringLiteral("oak-render-graph-XXXXXX.ove"))); + // Keep snapshots in the system temp directory. The previous bug was not the + // temp location itself, but stale snapshots being deleted while queued jobs + // still referenced them. + const QString graph_dir = QDir::tempPath(); + + QTemporaryFile file(QDir(graph_dir).filePath( + QStringLiteral("oak-render-graph-XXXXXX.ove"))); file.setAutoRemove(false); if (!file.open()) { - qWarning() << "RenderWorkerPool failed to create graph snapshot temp file" - << file.errorString(); + qWarning() + << "RenderWorkerPool failed to create graph snapshot temp file" + << file.errorString(); return false; } QXmlStreamWriter writer(&file); - ProjectSerializer::SaveData data(ProjectSerializer::kProject, project, file.fileName()); - const ProjectSerializer::Result result = ProjectSerializer::Save(&writer, data); + ProjectSerializer::SaveData data(ProjectSerializer::kProject, project, + file.fileName()); + const ProjectSerializer::Result result = + ProjectSerializer::Save(&writer, data); file.close(); if (result.code() != ProjectSerializer::kSuccess || writer.hasError()) { @@ -641,11 +648,15 @@ bool RenderWorkerPool::WriteGraphSnapshot(Project *project, QString *path) return false; } + qDebug() << "RenderWorkerPool wrote graph snapshot" << file.fileName() + << "size" << QFileInfo(file.fileName()).size(); + *path = file.fileName(); return true; } -bool RenderWorkerPool::IsSupported(const RenderManager::RenderVideoParams ¶ms) const +bool RenderWorkerPool::IsSupported( + const RenderManager::RenderVideoParams ¶ms) const { return params.node && params.return_type == RenderManager::kFrame && params.video_params.is_valid(); @@ -655,7 +666,8 @@ void RenderWorkerPool::ProcessJob( const Job &job, int worker_index, std::vector> *local_pool) { - const qint64 ticket_id = qint64(reinterpret_cast(job.ticket.get())); + const qint64 ticket_id = + qint64(reinterpret_cast(job.ticket.get())); SetActiveWorker(worker_index, job.ticket, nullptr, ticket_id); job.ticket->Start(); @@ -665,7 +677,8 @@ void RenderWorkerPool::ProcessJob( return; } - std::unique_ptr worker = AcquireWorker(local_pool, job.graph_path); + std::unique_ptr worker = + AcquireWorker(local_pool, job.graph_path); if (!worker) { qWarning() << "RenderWorkerPool failed to acquire worker for ticket" << ticket_id; @@ -678,22 +691,24 @@ void RenderWorkerPool::ProcessJob( if (attempt > 0) { worker = AcquireWorker(local_pool, job.graph_path); if (!worker) { - qWarning() << "RenderWorkerPool failed to acquire worker for retry" - << ticket_id; + qWarning() + << "RenderWorkerPool failed to acquire worker for retry" + << ticket_id; break; } } - const JobResult result = ProcessJobAttempt(job, worker_index, attempt, - worker.get()); - const qint64 worker_pid = worker && worker->process - ? worker->process->processId() - : 0; + const JobResult result = + ProcessJobAttempt(job, worker_index, attempt, worker.get()); + const qint64 worker_pid = + worker && worker->process ? worker->process->processId() : 0; const bool process_state_running = worker && worker->process && - worker->process->state() == QProcess::Running; + worker->process->state() == + QProcess::Running; const bool os_alive = worker_pid > 0 && IsProcessAlive(worker_pid); const bool worker_healthy = process_state_running || os_alive; - const bool keep_alive = (result == JobResult::kFinished) && worker_healthy; + const bool keep_alive = (result == JobResult::kFinished) && + worker_healthy; ReturnWorker(local_pool, std::move(worker), keep_alive); worker.reset(); @@ -726,11 +741,12 @@ void RenderWorkerPool::ProcessJob( ClearActiveWorker(worker_index, 0); } -RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( - const Job &job, int worker_index, int attempt_index, - PooledWorker *worker) +RenderWorkerPool::JobResult +RenderWorkerPool::ProcessJobAttempt(const Job &job, int worker_index, + int attempt_index, PooledWorker *worker) { - const qint64 ticket_id = qint64(reinterpret_cast(job.ticket.get())); + const qint64 ticket_id = + qint64(reinterpret_cast(job.ticket.get())); if (job.ticket->IsCancelled()) { return JobResult::kCancelled; } @@ -741,27 +757,25 @@ RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( const qint64 worker_process_id = worker->process->processId(); - const int output_width = job.params.force_size.width() > 0 - ? job.params.force_size.width() - : job.params.video_params.effective_width(); - const int output_height = job.params.force_size.height() > 0 - ? job.params.force_size.height() - : job.params.video_params.effective_height(); + const int output_width = job.params.force_size.width() > 0 ? + job.params.force_size.width() : + job.params.video_params.effective_width(); + const int output_height = job.params.force_size.height() > 0 ? + job.params.force_size.height() : + job.params.video_params.effective_height(); const PixelFormat::Format output_format = - job.params.force_format != PixelFormat::INVALID - ? PixelFormat::Format(job.params.force_format) - : PixelFormat::F32; - const int output_channels = job.params.force_channel_count > 0 - ? job.params.force_channel_count - : VideoParams::kRGBAChannelCount; - const int output_linesize = - Frame::generate_linesize_bytes(output_width, output_format, - output_channels); + job.params.force_format != PixelFormat::INVALID ? + PixelFormat::Format(job.params.force_format) : + PixelFormat::F32; + const int output_channels = job.params.force_channel_count > 0 ? + job.params.force_channel_count : + VideoParams::kRGBAChannelCount; + const int output_linesize = Frame::generate_linesize_bytes( + output_width, output_format, output_channels); const size_t estimated_output_slot_bytes = size_t(output_linesize) * size_t(output_height); - const int f32_rgba_linesize = - Frame::generate_linesize_bytes(output_width, PixelFormat::F32, - VideoParams::kRGBAChannelCount); + const int f32_rgba_linesize = Frame::generate_linesize_bytes( + output_width, PixelFormat::F32, VideoParams::kRGBAChannelCount); const size_t f32_rgba_slot_bytes = size_t(f32_rgba_linesize) * size_t(output_height); const size_t output_slot_bytes = @@ -788,10 +802,11 @@ RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( QStringLiteral("-out"); } if (!worker->output_region.Open(worker->output_shm_key, - output_region_bytes, - ipc::SharedMemoryRegion::kCreate)) { - qWarning() << "RenderWorkerPool failed to create output shared memory" - << worker->output_region.error(); + output_region_bytes, + ipc::SharedMemoryRegion::kCreate)) { + qWarning() + << "RenderWorkerPool failed to create output shared memory" + << worker->output_region.error(); return JobResult::kFatalFailure; } worker->output_pool = ipc::FrameSlotPool::Create( @@ -816,17 +831,19 @@ RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( ipc::SharedMemoryRegion::MakeKey(worker_process_id, 1) + QStringLiteral("-in"); } - const size_t input_region_bytes = - ipc::FrameSlotPool::BytesNeeded(input_slot_count, input_slot_bytes); + const size_t input_region_bytes = ipc::FrameSlotPool::BytesNeeded( + input_slot_count, input_slot_bytes); if (!worker->input_region.Open(worker->input_shm_key, - input_region_bytes, - ipc::SharedMemoryRegion::kCreate)) { - qWarning() << "RenderWorkerPool failed to create input shared memory" - << worker->input_region.error(); + input_region_bytes, + ipc::SharedMemoryRegion::kCreate)) { + qWarning() + << "RenderWorkerPool failed to create input shared memory" + << worker->input_region.error(); return JobResult::kFatalFailure; } - worker->input_pool = ipc::FrameSlotPool::Create( - worker->input_region.data(), input_slot_count, input_slot_bytes); + worker->input_pool = + ipc::FrameSlotPool::Create(worker->input_region.data(), + input_slot_count, input_slot_bytes); worker->input_slot_bytes = input_slot_bytes; } } @@ -836,7 +853,8 @@ RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( if (input_slot_count > 0) { for (const FramePtr &frame : job.input_frames) { if (frame->allocated_size() > int(worker->input_slot_bytes)) { - qWarning() << "RenderWorkerPool decoded input frame exceeds slot size"; + qWarning() + << "RenderWorkerPool decoded input frame exceeds slot size"; return JobResult::kFatalFailure; } @@ -862,9 +880,9 @@ RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( const QString cs = frame->video_params().colorspace(); if (!cs.isEmpty()) { const QByteArray cs_utf8 = cs.toUtf8(); - const size_t copy_len = qMin( - static_cast(cs_utf8.size()), - sizeof(meta->colorspace) - 1); + const size_t copy_len = + qMin(static_cast(cs_utf8.size()), + sizeof(meta->colorspace) - 1); memcpy(meta->colorspace, cs_utf8.constData(), copy_len); meta->colorspace[copy_len] = '\0'; } @@ -898,16 +916,16 @@ RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( handshake.input_slots = input_slots.size(); handshake.output_slots = int(kOutputSlots); handshake.slot_data_bytes = qint64(output_slot_bytes); - handshake.input_slot_data_bytes = input_slots.isEmpty() - ? 0 - : qint64(input_slot_bytes); + handshake.input_slot_data_bytes = + input_slots.isEmpty() ? 0 : qint64(input_slot_bytes); if (!WriteControlMessage(worker->process, handshake.ToJson())) { if (!job.ticket->IsCancelled()) { - qWarning() << "RenderWorkerPool failed to send shared-memory handshake"; + qWarning() + << "RenderWorkerPool failed to send shared-memory handshake"; } ClearActiveWorker(worker_index, worker_process_id); - return job.ticket->IsCancelled() ? JobResult::kCancelled - : JobResult::kRetryableFailure; + return job.ticket->IsCancelled() ? JobResult::kCancelled : + JobResult::kRetryableFailure; } if (worker->loaded_graph_path != job.graph_path) { @@ -922,12 +940,11 @@ RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( << error << worker->process->readAllStandardError(); } ClearActiveWorker(worker_index, worker_process_id); - return job.ticket->IsCancelled() ? JobResult::kCancelled - : JobResult::kRetryableFailure; + return job.ticket->IsCancelled() ? JobResult::kCancelled : + JobResult::kRetryableFailure; } worker->loaded_graph_path = job.graph_path; - -} + } ipc::RenderFrameMsg render; render.ticket_id = ticket_id; render.node_uuid = job.node_token; @@ -953,8 +970,8 @@ RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( qWarning() << "RenderWorkerPool failed to send render_frame"; } ClearActiveWorker(worker_index, worker_process_id); - return job.ticket->IsCancelled() ? JobResult::kCancelled - : JobResult::kRetryableFailure; + return job.ticket->IsCancelled() ? JobResult::kCancelled : + JobResult::kRetryableFailure; } QString error; @@ -967,8 +984,8 @@ RenderWorkerPool::JobResult RenderWorkerPool::ProcessJobAttempt( << error << worker->process->readAllStandardError(); } ClearActiveWorker(worker_index, worker_process_id); - return job.ticket->IsCancelled() ? JobResult::kCancelled - : JobResult::kRetryableFailure; + return job.ticket->IsCancelled() ? JobResult::kCancelled : + JobResult::kRetryableFailure; } if (ipc::FrameReadyMsg::FromJson(response, &ready)) { @@ -1061,8 +1078,8 @@ std::unique_ptr RenderWorkerPool::AcquireWorker( local_pool->erase(local_pool->begin() + i); continue; } - const bool candidate_state_running = - candidate->process->state() == QProcess::Running; + const bool candidate_state_running = candidate->process->state() == + QProcess::Running; const bool candidate_os_alive = IsProcessAlive(candidate->process->processId()); if (!candidate_state_running && !candidate_os_alive) { @@ -1078,7 +1095,8 @@ std::unique_ptr RenderWorkerPool::AcquireWorker( if (best_index < 0 || (!candidate->loaded_graph_path.isEmpty() && candidate->loaded_graph_path == graph_path && - ((*local_pool)[size_t(best_index)]->loaded_graph_path != graph_path))) { + ((*local_pool)[size_t(best_index)]->loaded_graph_path != + graph_path))) { best_index = int(i); } ++i; @@ -1093,16 +1111,16 @@ std::unique_ptr RenderWorkerPool::AcquireWorker( return worker; } - // No idle worker available: start a new one. auto *process = new QProcess(); process->setProgram(WorkerProgramPath()); - process->setArguments({QStringLiteral("--backend"), gpu_backend_}); + process->setArguments({ QStringLiteral("--backend"), gpu_backend_ }); - const QString worker_stderr_path = QDir(QDir::tempPath()).filePath( - QStringLiteral("oak-render-worker-%1-%2.stderr.log") - .arg(QCoreApplication::applicationPid()) - .arg(QDateTime::currentMSecsSinceEpoch())); + const QString worker_stderr_path = + QDir(QDir::tempPath()) + .filePath(QStringLiteral("oak-render-worker-%1-%2.stderr.log") + .arg(QCoreApplication::applicationPid()) + .arg(QDateTime::currentMSecsSinceEpoch())); process->setStandardErrorFile(worker_stderr_path); process->start(); @@ -1133,8 +1151,7 @@ std::unique_ptr RenderWorkerPool::AcquireWorker( void RenderWorkerPool::ReturnWorker( std::vector> *local_pool, - std::unique_ptr worker, - bool keep_alive) + std::unique_ptr worker, bool keep_alive) { if (!worker || !worker->process) { return; @@ -1190,9 +1207,11 @@ void RenderWorkerPool::ClearGraphCache() { QMutexLocker locker(&mutex_); for (auto it = graph_cache_.begin(); it != graph_cache_.end(); ++it) { - CleanupGraphFile(it->path); + SetGraphPathCachedLocked(it->path, false); } graph_cache_.clear(); + graph_path_ref_count_.clear(); + cached_graph_paths_.clear(); } void RenderWorkerPool::FinishWithFrame(RenderTicketPtr ticket, @@ -1207,8 +1226,7 @@ void RenderWorkerPool::FinishWithFrame(RenderTicketPtr ticket, } VideoParams params(meta->width, meta->height, - PixelFormat::Format(meta->format), - meta->channel_count); + PixelFormat::Format(meta->format), meta->channel_count); FramePtr frame = Frame::Create(); frame->set_timestamp(rational(int(meta->time_num), int(meta->time_den))); frame->set_video_params(params); @@ -1224,8 +1242,68 @@ void RenderWorkerPool::FinishWithFrame(RenderTicketPtr ticket, void RenderWorkerPool::CleanupGraphFile(const QString &path) { if (!path.isEmpty()) { + qDebug() << "RenderWorkerPool cleaning up graph file" << path; QFile::remove(path); } } -} // namespace olive +void RenderWorkerPool::AddGraphPathRef(const QString &path) +{ + QMutexLocker locker(&mutex_); + AddGraphPathRefLocked(path); +} + +void RenderWorkerPool::AddGraphPathRefLocked(const QString &path) +{ + if (path.isEmpty()) { + return; + } + ++graph_path_ref_count_[path]; +} + +void RenderWorkerPool::ReleaseGraphPathRef(const QString &path) +{ + QMutexLocker locker(&mutex_); + ReleaseGraphPathRefLocked(path); +} + +void RenderWorkerPool::ReleaseGraphPathRefLocked(const QString &path) +{ + if (path.isEmpty()) { + return; + } + auto it = graph_path_ref_count_.find(path); + if (it == graph_path_ref_count_.end()) { + return; + } + if (--(*it) <= 0) { + graph_path_ref_count_.erase(it); + if (!cached_graph_paths_.contains(path)) { + CleanupGraphFile(path); + } + } +} + +void RenderWorkerPool::SetGraphPathCached(const QString &path, bool cached) +{ + QMutexLocker locker(&mutex_); + SetGraphPathCachedLocked(path, cached); +} + +void RenderWorkerPool::SetGraphPathCachedLocked(const QString &path, + bool cached) +{ + if (path.isEmpty()) { + return; + } + if (cached) { + cached_graph_paths_.insert(path); + } else { + cached_graph_paths_.remove(path); + if (!graph_path_ref_count_.contains(path)) { + CleanupGraphFile(path); + } + } +} + +} // namespace olive diff --git a/app/render/renderworkerpool.h b/app/render/renderworkerpool.h index 929a52151..fa5be97a7 100644 --- a/app/render/renderworkerpool.h +++ b/app/render/renderworkerpool.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -113,8 +114,7 @@ private: }; bool PrepareJob(RenderTicketPtr ticket, - const RenderManager::RenderVideoParams ¶ms, - Job *job); + const RenderManager::RenderVideoParams ¶ms, Job *job); bool WriteGraphSnapshot(Project *project, QString *path); bool IsSupported(const RenderManager::RenderVideoParams ¶ms) const; @@ -123,24 +123,30 @@ private: void ProcessJob(const Job &job, int worker_index, std::vector> *local_pool); JobResult ProcessJobAttempt(const Job &job, int worker_index, - int attempt_index, - PooledWorker *worker); + int attempt_index, PooledWorker *worker); void FinishWithFrame(RenderTicketPtr ticket, const ipc::FrameSlotPool &pool, uint32_t slot); void CleanupGraphFile(const QString &path); + void AddGraphPathRef(const QString &path); + void AddGraphPathRefLocked(const QString &path); + void ReleaseGraphPathRef(const QString &path); + void ReleaseGraphPathRefLocked(const QString &path); + void SetGraphPathCached(const QString &path, bool cached); + void SetGraphPathCachedLocked(const QString &path, bool cached); void CancelActiveProcess(qint64 process_id); void SetActiveWorker(int worker_index, RenderTicketPtr ticket, QProcess *worker, qint64 ticket_id); void ClearActiveWorker(int worker_index, qint64 process_id); int WorkerCount() const; - std::unique_ptr AcquireWorker( - std::vector> *local_pool, - const QString &graph_path); + std::unique_ptr + AcquireWorker(std::vector> *local_pool, + const QString &graph_path); void ReturnWorker(std::vector> *local_pool, std::unique_ptr worker, bool keep_alive); void ShutdownWorker(PooledWorker *worker); - void ShutdownLocalPool(std::vector> *local_pool); + void + ShutdownLocalPool(std::vector> *local_pool); void ClearGraphCache(); DecoderCache *decoder_cache_; @@ -151,6 +157,8 @@ private: bool stopping_ = false; QVector active_jobs_; QHash graph_cache_; + QHash graph_path_ref_count_; + QSet cached_graph_paths_; static constexpr uint32_t kOutputSlots = 2; static constexpr int kMaxAttempts = 2; diff --git a/app/render/texture.h b/app/render/texture.h index 01592bff7..38522eccc 100644 --- a/app/render/texture.h +++ b/app/render/texture.h @@ -36,7 +36,7 @@ namespace olive class AcceleratedJob; class Renderer; struct RendererLifetime { - std::atomic alive{true}; + std::atomic alive{ true }; }; class Texture; @@ -162,16 +162,18 @@ public: } void handleFrame(AVFramePtr ptr) { - frame_=ptr; + frame_ = ptr; } - AVFramePtr frame(){ + AVFramePtr frame() + { return frame_; } + private: bool IsRendererAlive() const { return renderer_ && - (!renderer_lifetime_ || renderer_lifetime_->alive.load()); + (!renderer_lifetime_ || renderer_lifetime_->alive.load()); } Renderer *renderer_; diff --git a/app/render/videoparams.cpp b/app/render/videoparams.cpp index 7ad44107b..6e5b54536 100644 --- a/app/render/videoparams.cpp +++ b/app/render/videoparams.cpp @@ -259,8 +259,8 @@ QString VideoParams::GetFormatName(PixelFormat format) break; } - return QCoreApplication::translate("VideoParams", "Unknown (0x%1)") - .arg(static_cast(format), 0, 16); + return QCoreApplication::translate("VideoParams", "Unknown (0x%1)") + .arg(static_cast(format), 0, 16); } int VideoParams::GetDividerForTargetResolution(int src_width, int src_height, diff --git a/app/render/vulkan/vulkanbackend_c.cpp b/app/render/vulkan/vulkanbackend_c.cpp index 0b80850e5..135c54984 100644 --- a/app/render/vulkan/vulkanbackend_c.cpp +++ b/app/render/vulkan/vulkanbackend_c.cpp @@ -11,7 +11,8 @@ #include "render/videoparams.h" #include "render/vulkan/vulkanrenderer.h" -namespace { +namespace +{ class BackendVulkanRenderer : public olive::VulkanRenderer { public: @@ -38,38 +39,42 @@ const QVariant &VariantRef(const void *variant) } // namespace // Creates the Vulkan backend object and returns it as an opaque C handle. -OAK_RENDER_BACKEND_EXPORT OakRenderBackendHandle oak_renderer_create(void *parent) +OAK_RENDER_BACKEND_EXPORT OakRenderBackendHandle +oak_renderer_create(void *parent) { return new BackendVulkanRenderer(static_cast(parent)); } // Destroys the opaque backend object created by oak_renderer_create(). -OAK_RENDER_BACKEND_EXPORT void oak_renderer_destroy(OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_destroy(OakRenderBackendHandle handle) { delete Renderer(handle); } // Reports Vulkan backend capabilities and runtime availability status. -OAK_RENDER_BACKEND_EXPORT bool oak_renderer_get_info( - OakRenderBackendHandle handle, OakRenderBackendInfo *out_info) +OAK_RENDER_BACKEND_EXPORT bool +oak_renderer_get_info(OakRenderBackendHandle handle, + OakRenderBackendInfo *out_info) { if (!handle || !out_info) { return false; } out_info->abi_version = 1; out_info->kind = OAK_RENDER_BACKEND_VULKAN; - out_info->capabilities = OAK_RENDER_BACKEND_CAP_TEXTURES | - OAK_RENDER_BACKEND_CAP_SHADERS | OAK_RENDER_BACKEND_CAP_BLIT | - OAK_RENDER_BACKEND_CAP_READBACK; + out_info->capabilities = + OAK_RENDER_BACKEND_CAP_TEXTURES | OAK_RENDER_BACKEND_CAP_SHADERS | + OAK_RENDER_BACKEND_CAP_BLIT | OAK_RENDER_BACKEND_CAP_READBACK; out_info->name = "vulkan"; - out_info->status = Renderer(handle)->IsAvailable() ? "available" : "unavailable"; + out_info->status = Renderer(handle)->IsAvailable() ? "available" : + "unavailable"; return true; } // Probes runtime availability by trying Init() once; this lets missing ICDs or // unusable drivers fall back before normal rendering starts. -OAK_RENDER_BACKEND_EXPORT bool oak_renderer_is_available( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT bool +oak_renderer_is_available(OakRenderBackendHandle handle) { auto *r = Renderer(handle); if (!r || r->IsAvailable()) { @@ -89,41 +94,41 @@ OAK_RENDER_BACKEND_EXPORT bool oak_renderer_init(OakRenderBackendHandle handle) } // Vulkan does not use a QOpenGLContext; the argument is accepted for ABI parity. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_init_with_context( - OakRenderBackendHandle handle, void *context) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_init_with_context(OakRenderBackendHandle handle, void *context) { Q_UNUSED(context) Renderer(handle)->Init(); } // Creates reusable Vulkan resources after device initialization. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_post_init( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_post_init(OakRenderBackendHandle handle) { Renderer(handle)->PostInit(); } // Reserved for API symmetry; Vulkan cleanup is handled by destroy_internal. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_post_destroy( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_post_destroy(OakRenderBackendHandle handle) { Renderer(handle)->PostDestroy(); } // Releases all Vulkan resources owned by the renderer. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_destroy_internal( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_destroy_internal(OakRenderBackendHandle handle) { Renderer(handle)->DestroyInternal(); } // Clears a Vulkan texture destination. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_clear_destination( - OakRenderBackendHandle handle, void *texture, double r, double g, double b, - double a) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_clear_destination(OakRenderBackendHandle handle, void *texture, + double r, double g, double b, double a) { Renderer(handle)->ClearDestination(static_cast(texture), - r, g, b, a); + r, g, b, a); } // Creates a Vulkan texture and writes its QVariant handle to out_variant. @@ -131,51 +136,58 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_create_native_texture( OakRenderBackendHandle handle, int width, int height, int depth, int format, int channel_count, const void *data, int linesize, void *out_variant) { - *static_cast(out_variant) = Renderer(handle)->CreateNativeTexture( - width, height, depth, static_cast(format), - channel_count, data, linesize); + *static_cast(out_variant) = + Renderer(handle)->CreateNativeTexture( + width, height, depth, + static_cast(format), channel_count, + data, linesize); } // Destroys a Vulkan texture represented by a QVariant handle. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_destroy_native_texture( - OakRenderBackendHandle handle, const void *variant) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_destroy_native_texture(OakRenderBackendHandle handle, + const void *variant) { Renderer(handle)->DestroyNativeTexture(VariantRef(variant)); } // Compiles a Vulkan shader and returns its QVariant handle. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_create_native_shader( - OakRenderBackendHandle handle, const void *shader_code, void *out_variant) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_create_native_shader(OakRenderBackendHandle handle, + const void *shader_code, void *out_variant) { - *static_cast(out_variant) = Renderer(handle)->CreateNativeShader( - *static_cast(shader_code)); + *static_cast(out_variant) = + Renderer(handle)->CreateNativeShader( + *static_cast(shader_code)); } // Destroys a Vulkan shader represented by a QVariant handle. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_destroy_native_shader( - OakRenderBackendHandle handle, const void *variant) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_destroy_native_shader(OakRenderBackendHandle handle, + const void *variant) { Renderer(handle)->DestroyNativeShader(VariantRef(variant)); } // Uploads CPU pixel data into a Vulkan texture. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_upload_to_texture( - OakRenderBackendHandle handle, const void *variant, const void *video_params, - const void *data, int linesize) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_upload_to_texture(OakRenderBackendHandle handle, + const void *variant, const void *video_params, + const void *data, int linesize) { Renderer(handle)->UploadToTexture( - VariantRef(variant), *static_cast(video_params), - data, linesize); + VariantRef(variant), + *static_cast(video_params), data, linesize); } // Downloads a Vulkan texture to CPU memory. OAK_RENDER_BACKEND_EXPORT void oak_renderer_download_from_texture( - OakRenderBackendHandle handle, const void *variant, const void *video_params, - void *data, int linesize) + OakRenderBackendHandle handle, const void *variant, + const void *video_params, void *data, int linesize) { Renderer(handle)->DownloadFromTexture( - VariantRef(variant), *static_cast(video_params), - data, linesize); + VariantRef(variant), + *static_cast(video_params), data, linesize); } // Waits for all queued Vulkan work to finish. @@ -185,18 +197,23 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_flush(OakRenderBackendHandle handle) } // Reads one pixel from a Vulkan texture. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_get_pixel_from_texture( - OakRenderBackendHandle handle, void *texture, const void *point, - void *out_color) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_get_pixel_from_texture(OakRenderBackendHandle handle, + void *texture, const void *point, + void *out_color) { - *static_cast(out_color) = Renderer(handle)->GetPixelFromTexture( - static_cast(texture), *static_cast(point)); + *static_cast(out_color) = + Renderer(handle)->GetPixelFromTexture( + static_cast(texture), + *static_cast(point)); } // Executes a shader blit through the wrapped Vulkan renderer. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_blit( - OakRenderBackendHandle handle, const void *shader, void *job, - void *destination, const void *destination_params, bool clear_destination) +OAK_RENDER_BACKEND_EXPORT void oak_renderer_blit(OakRenderBackendHandle handle, + const void *shader, void *job, + void *destination, + const void *destination_params, + bool clear_destination) { Renderer(handle)->Blit( VariantRef(shader), *static_cast(job), @@ -206,16 +223,17 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_blit( } // Vulkan has no OpenGL context; return null so callers avoid GL-only paths. -OAK_RENDER_BACKEND_EXPORT void *oak_renderer_opengl_context( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void * +oak_renderer_opengl_context(OakRenderBackendHandle handle) { Q_UNUSED(handle) return nullptr; } // OFX OpenGL output attachment is unsupported in Vulkan and intentionally no-op. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_attach_output_texture( - OakRenderBackendHandle handle, const void *texture_id) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_attach_output_texture(OakRenderBackendHandle handle, + const void *texture_id) { Q_UNUSED(handle) Q_UNUSED(texture_id) @@ -223,8 +241,8 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_attach_output_texture( } // OFX OpenGL output detachment is unsupported in Vulkan and intentionally no-op. -OAK_RENDER_BACKEND_EXPORT void oak_renderer_detach_output_texture( - OakRenderBackendHandle handle) +OAK_RENDER_BACKEND_EXPORT void +oak_renderer_detach_output_texture(OakRenderBackendHandle handle) { Q_UNUSED(handle) // Vulkan does not support OFX OpenGL render output attachment. diff --git a/app/render/vulkan/vulkanrenderer.cpp b/app/render/vulkan/vulkanrenderer.cpp index 76594b050..3211e4b51 100644 --- a/app/render/vulkan/vulkanrenderer.cpp +++ b/app/render/vulkan/vulkanrenderer.cpp @@ -63,17 +63,15 @@ struct VulkanRenderer::StagingBuffer { }; static const float kBlitVertices[] = { - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, }; // Constructs the renderer; Vulkan resources are created lazily so unavailable // Vulkan systems can still instantiate the object and report fallback state. -VulkanRenderer::VulkanRenderer(QObject *parent) : Renderer(parent) +VulkanRenderer::VulkanRenderer(QObject *parent) + : Renderer(parent) { } @@ -140,7 +138,8 @@ void VulkanRenderer::DestroyInternal() for (auto it = shaders_.begin(); it != shaders_.end(); ++it) { VulkanShader *sh = it.value(); - for (auto pit = sh->pipeline_cache.begin(); pit != sh->pipeline_cache.end(); ++pit) { + for (auto pit = sh->pipeline_cache.begin(); + pit != sh->pipeline_cache.end(); ++pit) { if (pit.value() != VK_NULL_HANDLE) { vkDestroyPipeline(device_, pit.value(), nullptr); } @@ -150,7 +149,8 @@ void VulkanRenderer::DestroyInternal() vkDestroyPipelineLayout(device_, sh->pipeline_layout, nullptr); } if (sh->descriptor_layout != VK_NULL_HANDLE) { - vkDestroyDescriptorSetLayout(device_, sh->descriptor_layout, nullptr); + vkDestroyDescriptorSetLayout(device_, sh->descriptor_layout, + nullptr); } if (sh->vert_module != VK_NULL_HANDLE) { vkDestroyShaderModule(device_, sh->vert_module, nullptr); @@ -200,7 +200,8 @@ void VulkanRenderer::DestroyInternal() reusable_command_buffer_ = VK_NULL_HANDLE; } - for (auto it = render_pass_cache_.begin(); it != render_pass_cache_.end(); ++it) { + for (auto it = render_pass_cache_.begin(); it != render_pass_cache_.end(); + ++it) { if (it.value() != VK_NULL_HANDLE) { vkDestroyRenderPass(device_, it.value(), nullptr); } @@ -262,10 +263,11 @@ bool VulkanRenderer::CreateInstance() } uint32_t extension_count = 0; - vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr); + vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, + nullptr); QVector extensions(extension_count); vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, - extensions.data()); + extensions.data()); for (const VkExtensionProperties &ext : extensions) { if (strcmp(ext.extensionName, debug_extension) == 0) { has_debug_extension = true; @@ -303,11 +305,10 @@ bool VulkanRenderer::CreateInstance() // Logs validation errors/warnings from the Vulkan validation layers. These are // the first signal of missing barriers or invalid usage that would otherwise // become a GPU hang. -VKAPI_ATTR VkBool32 VKAPI_CALL -VulkanRenderer::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageType, - const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, - void *pUserData) +VKAPI_ATTR VkBool32 VKAPI_CALL VulkanRenderer::DebugCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData) { Q_UNUSED(messageType) Q_UNUSED(pUserData) @@ -320,7 +321,8 @@ VulkanRenderer::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeve // bring-up but flood the log and degrade playback performance. if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { qWarning() << "Vulkan validation error:" << pCallbackData->pMessage; - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { + } else if (messageSeverity & + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { qWarning() << "Vulkan validation warning:" << pCallbackData->pMessage; } @@ -341,12 +343,12 @@ bool VulkanRenderer::CreateDebugMessenger() create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - create_info.messageType = - VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; + create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; create_info.pfnUserCallback = DebugCallback; - VkResult result = create_fn(instance_, &create_info, nullptr, &debug_messenger_); + VkResult result = + create_fn(instance_, &create_info, nullptr, &debug_messenger_); if (result != VK_SUCCESS) { qWarning() << "Failed to create Vulkan debug messenger:" << result; return false; @@ -371,14 +373,16 @@ void VulkanRenderer::DestroyDebugMessenger() // device without swapchain extensions because viewer output is CPU readback. bool VulkanRenderer::CreateDevice() { - VkResult result = vkEnumeratePhysicalDevices(instance_, &physical_device_count_, nullptr); + VkResult result = + vkEnumeratePhysicalDevices(instance_, &physical_device_count_, nullptr); if (result != VK_SUCCESS || physical_device_count_ == 0) { qWarning() << "No Vulkan-capable physical devices found"; return false; } QVector devices(physical_device_count_); - result = vkEnumeratePhysicalDevices(instance_, &physical_device_count_, devices.data()); + result = vkEnumeratePhysicalDevices(instance_, &physical_device_count_, + devices.data()); if (result != VK_SUCCESS) { qWarning() << "Failed to enumerate Vulkan physical devices:" << result; return false; @@ -391,10 +395,11 @@ bool VulkanRenderer::CreateDevice() vkGetPhysicalDeviceMemoryProperties(device, &mem_properties_); uint32_t queue_family_count = 0; - vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, nullptr); + vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, + nullptr); QVector queue_families(queue_family_count); vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, - queue_families.data()); + queue_families.data()); for (uint32_t i = 0; i < queue_family_count; i++) { if (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { @@ -409,7 +414,8 @@ bool VulkanRenderer::CreateDevice() } } - if (physical_device_ == VK_NULL_HANDLE || graphics_queue_family_ == UINT32_MAX) { + if (physical_device_ == VK_NULL_HANDLE || + graphics_queue_family_ == UINT32_MAX) { qWarning() << "No Vulkan physical device with a graphics queue found"; return false; } @@ -433,7 +439,8 @@ bool VulkanRenderer::CreateDevice() device_create_info.enabledExtensionCount = 0; device_create_info.ppEnabledExtensionNames = nullptr; - result = vkCreateDevice(physical_device_, &device_create_info, nullptr, &device_); + result = vkCreateDevice(physical_device_, &device_create_info, nullptr, + &device_); if (result != VK_SUCCESS) { qWarning() << "Failed to create Vulkan logical device:" << result; return false; @@ -454,7 +461,8 @@ bool VulkanRenderer::CreateCommandPool() pool_info.queueFamilyIndex = graphics_queue_family_; pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - VkResult result = vkCreateCommandPool(device_, &pool_info, nullptr, &command_pool_); + VkResult result = + vkCreateCommandPool(device_, &pool_info, nullptr, &command_pool_); if (result != VK_SUCCESS) { qWarning() << "Failed to create Vulkan command pool:" << result; return false; @@ -479,8 +487,8 @@ bool VulkanRenderer::CreateDescriptorPool() pool_info.maxSets = kMaxDescriptorSets; pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; - VkResult result = vkCreateDescriptorPool(device_, &pool_info, nullptr, - &descriptor_pool_); + VkResult result = + vkCreateDescriptorPool(device_, &pool_info, nullptr, &descriptor_pool_); if (result != VK_SUCCESS) { qWarning() << "Failed to create Vulkan descriptor pool:" << result; return false; @@ -491,7 +499,8 @@ bool VulkanRenderer::CreateDescriptorPool() // Returns a cached render pass keyed by color format and load operation. VkRenderPass VulkanRenderer::GetOrCreateRenderPass(VkFormat format, bool clear) { - const quint64 key = (static_cast(format) << 1) | (clear ? 1ULL : 0ULL); + const quint64 key = (static_cast(format) << 1) | + (clear ? 1ULL : 0ULL); auto it = render_pass_cache_.find(key); if (it != render_pass_cache_.end()) { return it.value(); @@ -501,7 +510,7 @@ VkRenderPass VulkanRenderer::GetOrCreateRenderPass(VkFormat format, bool clear) color_attachment.format = format; color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; color_attachment.loadOp = clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : - VK_ATTACHMENT_LOAD_OP_LOAD; + VK_ATTACHMENT_LOAD_OP_LOAD; color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; @@ -538,14 +547,16 @@ VkRenderPass VulkanRenderer::GetOrCreateRenderPass(VkFormat format, bool clear) dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; dependencies[0].dstSubpass = 0; dependencies[0].srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependencies[0].dstStageMask = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dependencies[1].srcSubpass = 0; dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; - dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependencies[1].srcStageMask = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependencies[1].dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | @@ -561,8 +572,8 @@ VkRenderPass VulkanRenderer::GetOrCreateRenderPass(VkFormat format, bool clear) render_pass_info.pDependencies = dependencies; VkRenderPass render_pass = VK_NULL_HANDLE; - VkResult result = vkCreateRenderPass(device_, &render_pass_info, nullptr, - &render_pass); + VkResult result = + vkCreateRenderPass(device_, &render_pass_info, nullptr, &render_pass); if (result != VK_SUCCESS) { qWarning() << "Failed to create Vulkan render pass:" << result; return VK_NULL_HANDLE; @@ -572,7 +583,6 @@ VkRenderPass VulkanRenderer::GetOrCreateRenderPass(VkFormat format, bool clear) return render_pass; } - // Uploads a fullscreen quad to device-local memory through a staging buffer. bool VulkanRenderer::CreateVertexBuffer() { @@ -585,7 +595,8 @@ bool VulkanRenderer::CreateVertexBuffer() buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; VkBuffer staging_buffer; - VkResult result = vkCreateBuffer(device_, &buffer_info, nullptr, &staging_buffer); + VkResult result = + vkCreateBuffer(device_, &buffer_info, nullptr, &staging_buffer); if (result != VK_SUCCESS) { return false; } @@ -597,8 +608,8 @@ bool VulkanRenderer::CreateVertexBuffer() alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.allocationSize = mem_req.size; alloc_info.memoryTypeIndex = FindMemoryType( - mem_req.memoryTypeBits, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + mem_req.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if (alloc_info.memoryTypeIndex == UINT32_MAX) { vkDestroyBuffer(device_, staging_buffer, nullptr); return false; @@ -623,7 +634,8 @@ bool VulkanRenderer::CreateVertexBuffer() memcpy(data, kBlitVertices, (size_t)buffer_size); vkUnmapMemory(device_, staging_memory); - buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; result = vkCreateBuffer(device_, &buffer_info, nullptr, &vertex_buffer_); if (result != VK_SUCCESS) { vkFreeMemory(device_, staging_memory, nullptr); @@ -634,8 +646,8 @@ bool VulkanRenderer::CreateVertexBuffer() vkGetBufferMemoryRequirements(device_, vertex_buffer_, &mem_req); alloc_info.allocationSize = mem_req.size; - alloc_info.memoryTypeIndex = - FindMemoryType(mem_req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + alloc_info.memoryTypeIndex = FindMemoryType( + mem_req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); if (alloc_info.memoryTypeIndex == UINT32_MAX) { vkDestroyBuffer(device_, vertex_buffer_, nullptr); vkFreeMemory(device_, staging_memory, nullptr); @@ -643,7 +655,8 @@ bool VulkanRenderer::CreateVertexBuffer() return false; } - result = vkAllocateMemory(device_, &alloc_info, nullptr, &vertex_buffer_memory_); + result = + vkAllocateMemory(device_, &alloc_info, nullptr, &vertex_buffer_memory_); if (result != VK_SUCCESS) { vkDestroyBuffer(device_, vertex_buffer_, nullptr); vkFreeMemory(device_, staging_memory, nullptr); @@ -651,7 +664,8 @@ bool VulkanRenderer::CreateVertexBuffer() return false; } - result = vkBindBufferMemory(device_, vertex_buffer_, vertex_buffer_memory_, 0); + result = + vkBindBufferMemory(device_, vertex_buffer_, vertex_buffer_memory_, 0); if (result != VK_SUCCESS) { vkFreeMemory(device_, vertex_buffer_memory_, nullptr); vkDestroyBuffer(device_, vertex_buffer_, nullptr); @@ -662,7 +676,9 @@ bool VulkanRenderer::CreateVertexBuffer() // Copy from staging to device local VkCommandBuffer cmd = BeginOneTimeCommands(); - if (cmd == VK_NULL_HANDLE) { return false; } + if (cmd == VK_NULL_HANDLE) { + return false; + } VkBufferCopy copy_region = {}; copy_region.size = buffer_size; vkCmdCopyBuffer(cmd, staging_buffer, vertex_buffer_, 1, ©_region); @@ -693,7 +709,8 @@ bool VulkanRenderer::CreateLinearSampler() sampler_info.minLod = 0.0f; sampler_info.maxLod = 0.0f; - VkResult result = vkCreateSampler(device_, &sampler_info, nullptr, &linear_sampler_); + VkResult result = + vkCreateSampler(device_, &sampler_info, nullptr, &linear_sampler_); if (result != VK_SUCCESS) { qWarning() << "Failed to create Vulkan linear sampler:" << result; return false; @@ -720,7 +737,8 @@ bool VulkanRenderer::CreateNearestSampler() sampler_info.minLod = 0.0f; sampler_info.maxLod = 0.0f; - VkResult result = vkCreateSampler(device_, &sampler_info, nullptr, &nearest_sampler_); + VkResult result = + vkCreateSampler(device_, &sampler_info, nullptr, &nearest_sampler_); if (result != VK_SUCCESS) { qWarning() << "Failed to create Vulkan nearest sampler:" << result; return false; @@ -733,7 +751,8 @@ VkSampler VulkanRenderer::GetSampler(Texture::Interpolation interpolation) const { switch (interpolation) { case Texture::kNearest: - return nearest_sampler_ != VK_NULL_HANDLE ? nearest_sampler_ : linear_sampler_; + return nearest_sampler_ != VK_NULL_HANDLE ? nearest_sampler_ : + linear_sampler_; case Texture::kLinear: case Texture::kMipmappedLinear: default: @@ -745,8 +764,9 @@ VkSampler VulkanRenderer::GetSampler(Texture::Interpolation interpolation) const // Vulkan allocations are expensive and some drivers fragment host-visible heaps // under repeated 4K/F32 readback. Reusing one submit-and-wait staging buffer // keeps peak allocation count low while the renderer mutex serializes callers. -bool VulkanRenderer::CreateStagingBuffer(VkDeviceSize size, VkBuffer *out_buffer, - VkDeviceMemory *out_memory) +bool VulkanRenderer::CreateStagingBuffer(VkDeviceSize size, + VkBuffer *out_buffer, + VkDeviceMemory *out_memory) { if (size == 0) { return false; @@ -793,10 +813,11 @@ bool VulkanRenderer::CreateStagingBuffer(VkDeviceSize size, VkBuffer *out_buffer alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.allocationSize = mem_req.size; alloc_info.memoryTypeIndex = FindMemoryType( - mem_req.memoryTypeBits, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + mem_req.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if (alloc_info.memoryTypeIndex == UINT32_MAX) { - qWarning() << "Failed to find host-visible memory type for Vulkan staging buffer"; + qWarning() + << "Failed to find host-visible memory type for Vulkan staging buffer"; vkDestroyBuffer(device_, buffer, nullptr); return false; } @@ -804,9 +825,10 @@ bool VulkanRenderer::CreateStagingBuffer(VkDeviceSize size, VkBuffer *out_buffer VkDeviceMemory memory = VK_NULL_HANDLE; result = vkAllocateMemory(device_, &alloc_info, nullptr, &memory); if (result != VK_SUCCESS) { - qWarning() << "Failed to allocate Vulkan staging buffer memory:" << result - << "size=" << qulonglong(size) - << "allocation=" << qulonglong(mem_req.size); + qWarning() + << "Failed to allocate Vulkan staging buffer memory:" << result + << "size=" << qulonglong(size) + << "allocation=" << qulonglong(mem_req.size); vkDestroyBuffer(device_, buffer, nullptr); return false; } @@ -830,7 +852,8 @@ bool VulkanRenderer::CreateStagingBuffer(VkDeviceSize size, VkBuffer *out_buffer // Kept for existing call sites; runtime staging buffers are renderer-owned and // released in DestroyInternal() or when a larger staging allocation is required. -void VulkanRenderer::DestroyStagingBuffer(VkBuffer buffer, VkDeviceMemory memory) +void VulkanRenderer::DestroyStagingBuffer(VkBuffer buffer, + VkDeviceMemory memory) { if (staging_buffer_ && buffer == staging_buffer_->buffer && memory == staging_buffer_->memory) { @@ -854,9 +877,10 @@ VkCommandBuffer VulkanRenderer::BeginOneTimeCommands() alloc_info.commandPool = command_pool_; alloc_info.commandBufferCount = 1; - VkResult result = vkAllocateCommandBuffers( - device_, &alloc_info, &reusable_command_buffer_); - if (result != VK_SUCCESS || reusable_command_buffer_ == VK_NULL_HANDLE) { + VkResult result = vkAllocateCommandBuffers(device_, &alloc_info, + &reusable_command_buffer_); + if (result != VK_SUCCESS || + reusable_command_buffer_ == VK_NULL_HANDLE) { qWarning() << "Failed to allocate Vulkan command buffer:" << result; return VK_NULL_HANDLE; } @@ -868,7 +892,8 @@ VkCommandBuffer VulkanRenderer::BeginOneTimeCommands() begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - VkResult result = vkBeginCommandBuffer(reusable_command_buffer_, &begin_info); + VkResult result = + vkBeginCommandBuffer(reusable_command_buffer_, &begin_info); if (result != VK_SUCCESS) { qWarning() << "Failed to begin Vulkan command buffer:" << result; return VK_NULL_HANDLE; @@ -910,14 +935,15 @@ void VulkanRenderer::EndOneTimeCommands(VkCommandBuffer cmd) submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &cmd; - VkResult result = vkQueueSubmit(graphics_queue_, 1, &submit_info, - reusable_fence_); + VkResult result = + vkQueueSubmit(graphics_queue_, 1, &submit_info, reusable_fence_); if (result != VK_SUCCESS) { if (result == VK_ERROR_DEVICE_LOST) { if (!device_lost_) { device_lost_ = true; - qCritical() << "Vulkan device lost during vkQueueSubmit; stopping " - "further GPU submissions"; + qCritical() + << "Vulkan device lost during vkQueueSubmit; stopping " + "further GPU submissions"; } } else { qWarning() << "vkQueueSubmit failed:" << result; @@ -957,7 +983,8 @@ void VulkanRenderer::TransitionImageLayout(VkCommandBuffer cmd, VkImage image, barrier.subresourceRange.layerCount = 1; VkPipelineStageFlags source_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - VkPipelineStageFlags destination_stage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + VkPipelineStageFlags destination_stage = + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; bool handled = false; auto set_transfer = [&]() { @@ -1059,11 +1086,13 @@ void VulkanRenderer::TransitionImageLayout(VkCommandBuffer cmd, VkImage image, } if (!handled) { - qWarning() << "Unhandled Vulkan layout transition from" << old_layout - << "to" << new_layout - << "- using conservative ALL_COMMANDS barrier"; - barrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; + qWarning() + << "Unhandled Vulkan layout transition from" << old_layout << "to" + << new_layout << "- using conservative ALL_COMMANDS barrier"; + barrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | + VK_ACCESS_MEMORY_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | + VK_ACCESS_MEMORY_WRITE_BIT; source_stage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; destination_stage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; } @@ -1072,7 +1101,6 @@ void VulkanRenderer::TransitionImageLayout(VkCommandBuffer cmd, VkImage image, nullptr, 1, &barrier); } - // Records a buffer-to-image copy for tightly packed texture uploads. void VulkanRenderer::CopyBufferToImage(VkCommandBuffer cmd, VkBuffer buffer, VkImage image, uint32_t width, @@ -1089,15 +1117,15 @@ void VulkanRenderer::CopyBufferToImage(VkCommandBuffer cmd, VkBuffer buffer, region.imageOffset = { 0, 0, 0 }; region.imageExtent = { width, height, depth }; - vkCmdCopyBufferToImage(cmd, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ®ion); + vkCmdCopyBufferToImage(cmd, buffer, image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); } // Records an image-to-buffer copy for full texture downloads or one-pixel reads. void VulkanRenderer::CopyImageToBuffer(VkCommandBuffer cmd, VkImage image, VkBuffer buffer, uint32_t width, - uint32_t height, - uint32_t offset_x, uint32_t offset_y) + uint32_t height, uint32_t offset_x, + uint32_t offset_y) { VkBufferImageCopy region = {}; region.bufferOffset = 0; @@ -1107,24 +1135,29 @@ void VulkanRenderer::CopyImageToBuffer(VkCommandBuffer cmd, VkImage image, region.imageSubresource.mipLevel = 0; region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.layerCount = 1; - region.imageOffset = { static_cast(offset_x), static_cast(offset_y), 0 }; + region.imageOffset = { static_cast(offset_x), + static_cast(offset_y), 0 }; region.imageExtent = { width, height, 1 }; - vkCmdCopyImageToBuffer(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, - 1, ®ion); + vkCmdCopyImageToBuffer(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + buffer, 1, ®ion); } // Converts Oak's pixel format/channel count pair to the closest Vulkan format. VkFormat VulkanRenderer::PixelFormatToVkFormat(PixelFormat format, - int channel_count) const + int channel_count) const { switch (format) { case PixelFormat::U8: switch (channel_count) { - case 1: return VK_FORMAT_R8_UNORM; - case 2: return VK_FORMAT_R8G8_UNORM; - case 3: return VK_FORMAT_R8G8B8_UNORM; - case 4: return VK_FORMAT_R8G8B8A8_UNORM; + case 1: + return VK_FORMAT_R8_UNORM; + case 2: + return VK_FORMAT_R8G8_UNORM; + case 3: + return VK_FORMAT_R8G8B8_UNORM; + case 4: + return VK_FORMAT_R8G8B8A8_UNORM; } break; case PixelFormat::U10: @@ -1134,26 +1167,38 @@ VkFormat VulkanRenderer::PixelFormatToVkFormat(PixelFormat format, break; case PixelFormat::U16: switch (channel_count) { - case 1: return VK_FORMAT_R16_UNORM; - case 2: return VK_FORMAT_R16G16_UNORM; - case 3: return VK_FORMAT_R16G16B16_UNORM; - case 4: return VK_FORMAT_R16G16B16A16_UNORM; + case 1: + return VK_FORMAT_R16_UNORM; + case 2: + return VK_FORMAT_R16G16_UNORM; + case 3: + return VK_FORMAT_R16G16B16_UNORM; + case 4: + return VK_FORMAT_R16G16B16A16_UNORM; } break; case PixelFormat::F16: switch (channel_count) { - case 1: return VK_FORMAT_R16_SFLOAT; - case 2: return VK_FORMAT_R16G16_SFLOAT; - case 3: return VK_FORMAT_R16G16B16_SFLOAT; - case 4: return VK_FORMAT_R16G16B16A16_SFLOAT; + case 1: + return VK_FORMAT_R16_SFLOAT; + case 2: + return VK_FORMAT_R16G16_SFLOAT; + case 3: + return VK_FORMAT_R16G16B16_SFLOAT; + case 4: + return VK_FORMAT_R16G16B16A16_SFLOAT; } break; case PixelFormat::F32: switch (channel_count) { - case 1: return VK_FORMAT_R32_SFLOAT; - case 2: return VK_FORMAT_R32G32_SFLOAT; - case 3: return VK_FORMAT_R32G32B32_SFLOAT; - case 4: return VK_FORMAT_R32G32B32A32_SFLOAT; + case 1: + return VK_FORMAT_R32_SFLOAT; + case 2: + return VK_FORMAT_R32G32_SFLOAT; + case 3: + return VK_FORMAT_R32G32B32_SFLOAT; + case 4: + return VK_FORMAT_R32G32B32A32_SFLOAT; } break; case PixelFormat::INVALID: @@ -1175,10 +1220,11 @@ bool VulkanRenderer::IsColorAttachmentSupported(VkFormat format) const // Chooses a renderable Vulkan format and falls back from RGB to RGBA when a // driver does not expose 3-channel color attachment support. VkFormat VulkanRenderer::PickRenderableFormat(PixelFormat format, - int channel_count) const + int channel_count) const { VkFormat candidate = PixelFormatToVkFormat(format, channel_count); - if (candidate != VK_FORMAT_UNDEFINED && IsColorAttachmentSupported(candidate)) { + if (candidate != VK_FORMAT_UNDEFINED && + IsColorAttachmentSupported(candidate)) { return candidate; } @@ -1250,10 +1296,9 @@ float VulkanRenderer::GetFormatMaxAlpha(PixelFormat format) const // Copies tightly-packed pixels while changing channel count. This handles the // common Vulkan fallback where requested RGB data is stored as RGBA on the GPU. -void VulkanRenderer::CopyPixelsWithChannelConversion(const void *src, void *dst, - int width, int height, int depth, - int src_channels, int dst_channels, - PixelFormat format) const +void VulkanRenderer::CopyPixelsWithChannelConversion( + const void *src, void *dst, int width, int height, int depth, + int src_channels, int dst_channels, PixelFormat format) const { int src_bpc = VideoParams::GetBytesPerChannel(format); int dst_bpc = src_bpc; @@ -1269,31 +1314,30 @@ void VulkanRenderer::CopyPixelsWithChannelConversion(const void *src, void *dst, for (int c = 0; c < dst_channels; ++c) { if (c < src_channels) { memcpy(dst_ptr + (i * dst_channels + c) * dst_bpc, - src_ptr + (i * src_channels + c) * src_bpc, - dst_bpc); + src_ptr + (i * src_channels + c) * src_bpc, dst_bpc); } else { // Fill missing channels with 0 (color) or max alpha. if (c == 3) { if (format == PixelFormat::U8) { - *reinterpret_cast(dst_ptr + - (i * dst_channels + c) * dst_bpc) = + *reinterpret_cast( + dst_ptr + (i * dst_channels + c) * dst_bpc) = static_cast(alpha); } else if (format == PixelFormat::U16) { - *reinterpret_cast(dst_ptr + - (i * dst_channels + c) * dst_bpc) = + *reinterpret_cast( + dst_ptr + (i * dst_channels + c) * dst_bpc) = static_cast(alpha); } else if (format == PixelFormat::F16) { // Half-float 1.0: 0x3C00 - *reinterpret_cast(dst_ptr + - (i * dst_channels + c) * dst_bpc) = + *reinterpret_cast( + dst_ptr + (i * dst_channels + c) * dst_bpc) = 0x3C00; } else { - *reinterpret_cast(dst_ptr + - (i * dst_channels + c) * dst_bpc) = - alpha; + *reinterpret_cast( + dst_ptr + (i * dst_channels + c) * dst_bpc) = alpha; } } else { - memset(dst_ptr + (i * dst_channels + c) * dst_bpc, 0, dst_bpc); + memset(dst_ptr + (i * dst_channels + c) * dst_bpc, 0, + dst_bpc); } } } @@ -1323,8 +1367,9 @@ uint32_t VulkanRenderer::FindMemoryType(uint32_t type_filter, // Creates a Vulkan image, memory allocation, and image view for an Oak texture. QVariant VulkanRenderer::CreateNativeTexture(int width, int height, int depth, - PixelFormat format, int channel_count, - const void *data, int linesize) + PixelFormat format, + int channel_count, + const void *data, int linesize) { QMutexLocker lock(&mutex_); @@ -1357,9 +1402,9 @@ QVariant VulkanRenderer::CreateNativeTexture(int width, int height, int depth, image_info.format = vk_format; image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | - VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + image_info.usage = + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.samples = VK_SAMPLE_COUNT_1_BIT; @@ -1375,10 +1420,11 @@ QVariant VulkanRenderer::CreateNativeTexture(int width, int height, int depth, VkMemoryAllocateInfo alloc_info = {}; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.allocationSize = mem_req.size; - alloc_info.memoryTypeIndex = - FindMemoryType(mem_req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + alloc_info.memoryTypeIndex = FindMemoryType( + mem_req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); if (alloc_info.memoryTypeIndex == UINT32_MAX) { - qWarning() << "Failed to find device-local memory type for Vulkan image"; + qWarning() + << "Failed to find device-local memory type for Vulkan image"; vkDestroyImage(device_, tex->image, nullptr); delete tex; return QVariant(); @@ -1386,7 +1432,8 @@ QVariant VulkanRenderer::CreateNativeTexture(int width, int height, int depth, result = vkAllocateMemory(device_, &alloc_info, nullptr, &tex->memory); if (result != VK_SUCCESS) { - qWarning() << "Failed to allocate device memory for Vulkan image:" << result; + qWarning() + << "Failed to allocate device memory for Vulkan image:" << result; vkDestroyImage(device_, tex->image, nullptr); delete tex; return QVariant(); @@ -1404,7 +1451,8 @@ QVariant VulkanRenderer::CreateNativeTexture(int width, int height, int depth, VkImageViewCreateInfo view_info = {}; view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; view_info.image = tex->image; - view_info.viewType = depth > 1 ? VK_IMAGE_VIEW_TYPE_3D : VK_IMAGE_VIEW_TYPE_2D; + view_info.viewType = depth > 1 ? VK_IMAGE_VIEW_TYPE_3D : + VK_IMAGE_VIEW_TYPE_2D; view_info.format = vk_format; view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; view_info.subresourceRange.baseMipLevel = 0; @@ -1431,13 +1479,14 @@ QVariant VulkanRenderer::CreateNativeTexture(int width, int height, int depth, // Upload initial data if provided if (data) { - int cpu_bytes_per_pixel = VideoParams::GetBytesPerPixel(format, channel_count); + int cpu_bytes_per_pixel = + VideoParams::GetBytesPerPixel(format, channel_count); int gpu_bytes_per_pixel = GetVkFormatBytesPerPixel(vk_format); if (gpu_bytes_per_pixel == 0) { gpu_bytes_per_pixel = cpu_bytes_per_pixel; } - VkDeviceSize image_size = static_cast(width) * height * depth * - gpu_bytes_per_pixel; + VkDeviceSize image_size = static_cast(width) * height * + depth * gpu_bytes_per_pixel; if (linesize == 0) { linesize = width; } @@ -1455,9 +1504,10 @@ QVariant VulkanRenderer::CreateNativeTexture(int width, int height, int depth, char *dst = static_cast(mapped); const char *src = static_cast(data); for (int row = 0; row < height * depth; row++) { - memcpy(dst + row * width * cpu_bytes_per_pixel, - src + row * row_stride_bytes, - static_cast(width * cpu_bytes_per_pixel)); + memcpy( + dst + row * width * cpu_bytes_per_pixel, + src + row * row_stride_bytes, + static_cast(width * cpu_bytes_per_pixel)); } } } else { @@ -1472,23 +1522,25 @@ QVariant VulkanRenderer::CreateNativeTexture(int width, int height, int depth, char *dst = tmp.data(); const char *src = static_cast(data); for (int row = 0; row < height * depth; row++) { - memcpy(dst + row * width * cpu_bytes_per_pixel, - src + row * row_stride_bytes, - static_cast(width * cpu_bytes_per_pixel)); + memcpy( + dst + row * width * cpu_bytes_per_pixel, + src + row * row_stride_bytes, + static_cast(width * cpu_bytes_per_pixel)); } } int gpu_channels = gpu_bytes_per_pixel / VideoParams::GetBytesPerChannel(format); - CopyPixelsWithChannelConversion(tmp.constData(), mapped, - width, height, depth, - channel_count, gpu_channels, - format); + CopyPixelsWithChannelConversion(tmp.constData(), mapped, width, + height, depth, channel_count, + gpu_channels, format); } vkUnmapMemory(device_, staging_memory); VkCommandBuffer cmd = BeginOneTimeCommands(); - if (cmd == VK_NULL_HANDLE) { return QVariant(); } + if (cmd == VK_NULL_HANDLE) { + return QVariant(); + } TransitionImageLayout(cmd, tex->image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); CopyBufferToImage(cmd, staging_buffer, tex->image, @@ -1505,7 +1557,9 @@ QVariant VulkanRenderer::CreateNativeTexture(int width, int height, int depth, } } else { VkCommandBuffer cmd = BeginOneTimeCommands(); - if (cmd == VK_NULL_HANDLE) { return QVariant(); } + if (cmd == VK_NULL_HANDLE) { + return QVariant(); + } TransitionImageLayout(cmd, tex->image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); EndOneTimeCommands(cmd); @@ -1543,8 +1597,8 @@ void VulkanRenderer::DestroyNativeTexture(QVariant texture) // Uploads CPU pixels to an existing image. The staging layout is based on the // selected GPU VkFormat, then CPU data is repacked when channel counts differ. void VulkanRenderer::UploadToTexture(const QVariant &handle, - const VideoParams ¶ms, const void *data, - int linesize) + const VideoParams ¶ms, + const void *data, int linesize) { QMutexLocker lock(&mutex_); quint64 id = handle.value(); @@ -1556,8 +1610,8 @@ void VulkanRenderer::UploadToTexture(const QVariant &handle, int width = params.effective_width(); int height = params.effective_height(); int depth = params.effective_depth(); - int cpu_bytes_per_pixel = VideoParams::GetBytesPerPixel(params.format(), - params.channel_count()); + int cpu_bytes_per_pixel = + VideoParams::GetBytesPerPixel(params.format(), params.channel_count()); int gpu_bytes_per_pixel = GetVkFormatBytesPerPixel(tex->vk_format); if (gpu_bytes_per_pixel == 0) { gpu_bytes_per_pixel = cpu_bytes_per_pixel; @@ -1605,16 +1659,17 @@ void VulkanRenderer::UploadToTexture(const QVariant &handle, } int gpu_channels = gpu_bytes_per_pixel / VideoParams::GetBytesPerChannel(params.format()); - CopyPixelsWithChannelConversion(tmp.constData(), mapped, - width, height, depth, - params.channel_count(), gpu_channels, - params.format()); + CopyPixelsWithChannelConversion(tmp.constData(), mapped, width, height, + depth, params.channel_count(), + gpu_channels, params.format()); } vkUnmapMemory(device_, staging_memory); VkCommandBuffer cmd = BeginOneTimeCommands(); - if (cmd == VK_NULL_HANDLE) { return; } + if (cmd == VK_NULL_HANDLE) { + return; + } if (tex->current_layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { TransitionImageLayout(cmd, tex->image, tex->current_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); @@ -1634,8 +1689,8 @@ void VulkanRenderer::UploadToTexture(const QVariant &handle, // Downloads an image to CPU memory. When the GPU format is wider than the // requested CPU format, the staging data is compacted back to the caller layout. void VulkanRenderer::DownloadFromTexture(const QVariant &handle, - const VideoParams ¶ms, void *data, - int linesize) + const VideoParams ¶ms, void *data, + int linesize) { QMutexLocker lock(&mutex_); quint64 id = handle.value(); @@ -1646,8 +1701,8 @@ void VulkanRenderer::DownloadFromTexture(const QVariant &handle, int width = params.effective_width(); int height = params.effective_height(); - int cpu_bytes_per_pixel = VideoParams::GetBytesPerPixel(params.format(), - params.channel_count()); + int cpu_bytes_per_pixel = + VideoParams::GetBytesPerPixel(params.format(), params.channel_count()); int gpu_bytes_per_pixel = GetVkFormatBytesPerPixel(tex->vk_format); if (gpu_bytes_per_pixel == 0) { gpu_bytes_per_pixel = cpu_bytes_per_pixel; @@ -1667,7 +1722,9 @@ void VulkanRenderer::DownloadFromTexture(const QVariant &handle, VkCommandBuffer cmd = BeginOneTimeCommands(); - if (cmd == VK_NULL_HANDLE) { return; } + if (cmd == VK_NULL_HANDLE) { + return; + } if (tex->current_layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) { TransitionImageLayout(cmd, tex->image, tex->current_layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); @@ -1696,10 +1753,9 @@ void VulkanRenderer::DownloadFromTexture(const QVariant &handle, VideoParams::GetBytesPerChannel(params.format()); QByteArray tmp(width * height * gpu_bytes_per_pixel, Qt::Uninitialized); memcpy(tmp.data(), mapped, static_cast(tmp.size())); - CopyPixelsWithChannelConversion(tmp.constData(), data, - width, height, 1, - gpu_channels, params.channel_count(), - params.format()); + CopyPixelsWithChannelConversion(tmp.constData(), data, width, height, 1, + gpu_channels, params.channel_count(), + params.format()); if (linesize != width) { // Repack from tight CPU layout to caller's stride in-place. QByteArray tight(static_cast(data), @@ -1728,14 +1784,16 @@ void VulkanRenderer::Flush() // Clears a texture with vkCmdClearColorImage; null destinations are ignored // because this backend has no implicit swapchain framebuffer. -void VulkanRenderer::ClearDestination(olive::Texture *texture, double r, double g, - double b, double a) +void VulkanRenderer::ClearDestination(olive::Texture *texture, double r, + double g, double b, double a) { QMutexLocker lock(&mutex_); VkCommandBuffer cmd = BeginOneTimeCommands(); - if (cmd == VK_NULL_HANDLE) { return; } + if (cmd == VK_NULL_HANDLE) { + return; + } if (texture) { quint64 id = texture->id().value(); VulkanTexture *tex = textures_.value(id); @@ -1758,9 +1816,11 @@ void VulkanRenderer::ClearDestination(olive::Texture *texture, double r, double range.levelCount = 1; range.baseArrayLayer = 0; range.layerCount = 1; - vkCmdClearColorImage(cmd, tex->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - &clear_color, 1, &range); - TransitionImageLayout(cmd, tex->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + vkCmdClearColorImage(cmd, tex->image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, + 1, &range); + TransitionImageLayout(cmd, tex->image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); tex->current_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } @@ -1769,13 +1829,13 @@ void VulkanRenderer::ClearDestination(olive::Texture *texture, double r, double // Reads one pixel by copying a 1x1 image region into a staging buffer. Color VulkanRenderer::GetPixelFromTexture(olive::Texture *texture, - const QPointF &pt) + const QPointF &pt) { if (!texture) { return Color(); } - int cpu_bytes_per_pixel = VideoParams::GetBytesPerPixel(texture->format(), - texture->channel_count()); + int cpu_bytes_per_pixel = VideoParams::GetBytesPerPixel( + texture->format(), texture->channel_count()); QByteArray data(cpu_bytes_per_pixel, Qt::Uninitialized); quint64 id = texture->id().value(); @@ -1785,8 +1845,10 @@ Color VulkanRenderer::GetPixelFromTexture(olive::Texture *texture, return Color(); } - uint32_t px = static_cast(qBound(0.0, pt.x(), double(tex->width - 1))); - uint32_t py = static_cast(qBound(0.0, pt.y(), double(tex->height - 1))); + uint32_t px = + static_cast(qBound(0.0, pt.x(), double(tex->width - 1))); + uint32_t py = + static_cast(qBound(0.0, pt.y(), double(tex->height - 1))); int gpu_bytes_per_pixel = GetVkFormatBytesPerPixel(tex->vk_format); if (gpu_bytes_per_pixel == 0) { @@ -1795,13 +1857,16 @@ Color VulkanRenderer::GetPixelFromTexture(olive::Texture *texture, VkBuffer staging_buffer; VkDeviceMemory staging_memory; - if (!CreateStagingBuffer(gpu_bytes_per_pixel, &staging_buffer, &staging_memory)) { + if (!CreateStagingBuffer(gpu_bytes_per_pixel, &staging_buffer, + &staging_memory)) { return Color(); } VkCommandBuffer cmd = BeginOneTimeCommands(); - if (cmd == VK_NULL_HANDLE) { return Color(); } + if (cmd == VK_NULL_HANDLE) { + return Color(); + } if (tex->current_layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) { TransitionImageLayout(cmd, tex->image, tex->current_layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); @@ -1817,11 +1882,12 @@ Color VulkanRenderer::GetPixelFromTexture(olive::Texture *texture, int gpu_channels = gpu_bytes_per_pixel / VideoParams::GetBytesPerChannel(texture->format()); QByteArray gpu_pixel(gpu_bytes_per_pixel, Qt::Uninitialized); - memcpy(gpu_pixel.data(), mapped, static_cast(gpu_bytes_per_pixel)); - CopyPixelsWithChannelConversion(gpu_pixel.constData(), data.data(), - 1, 1, 1, - gpu_channels, texture->channel_count(), - texture->format()); + memcpy(gpu_pixel.data(), mapped, + static_cast(gpu_bytes_per_pixel)); + CopyPixelsWithChannelConversion(gpu_pixel.constData(), data.data(), 1, + 1, 1, gpu_channels, + texture->channel_count(), + texture->format()); } vkUnmapMemory(device_, staging_memory); @@ -1861,7 +1927,7 @@ QString VulkanRenderer::EnsureGlslVersion450(const QString &glsl) const // semantics but replaces implicit attributes/varyings and texture sampling with // explicit layouts that Vulkan requires. QString VulkanRenderer::ConvertGlslToVulkan(const QString &glsl, - VkShaderStageFlagBits stage) + VkShaderStageFlagBits stage) { QString result = glsl; @@ -1871,20 +1937,25 @@ QString VulkanRenderer::ConvertGlslToVulkan(const QString &glsl, // Ensure fragment shader output has layout if (stage == VK_SHADER_STAGE_FRAGMENT_BIT) { - result.replace(QStringLiteral("out vec4 frag_color;"), - QStringLiteral("layout(location = 0) out vec4 frag_color;")); - result.replace(QStringLiteral("in vec2 ove_texcoord;"), - QStringLiteral("layout(location = 0) in vec2 ove_texcoord;")); + result.replace( + QStringLiteral("out vec4 frag_color;"), + QStringLiteral("layout(location = 0) out vec4 frag_color;")); + result.replace( + QStringLiteral("in vec2 ove_texcoord;"), + QStringLiteral("layout(location = 0) in vec2 ove_texcoord;")); } // Add layout to vertex attributes and varyings if (stage == VK_SHADER_STAGE_VERTEX_BIT) { - result.replace(QStringLiteral("in vec4 a_position;"), - QStringLiteral("layout(location = 0) in vec4 a_position;")); - result.replace(QStringLiteral("in vec2 a_texcoord;"), - QStringLiteral("layout(location = 1) in vec2 a_texcoord;")); - result.replace(QStringLiteral("out vec2 ove_texcoord;"), - QStringLiteral("layout(location = 0) out vec2 ove_texcoord;")); + result.replace( + QStringLiteral("in vec4 a_position;"), + QStringLiteral("layout(location = 0) in vec4 a_position;")); + result.replace( + QStringLiteral("in vec2 a_texcoord;"), + QStringLiteral("layout(location = 1) in vec2 a_texcoord;")); + result.replace( + QStringLiteral("out vec2 ove_texcoord;"), + QStringLiteral("layout(location = 0) out vec2 ove_texcoord;")); } return result; @@ -1893,32 +1964,44 @@ QString VulkanRenderer::ConvertGlslToVulkan(const QString &glsl, // Returns the std140 storage size for scalar, vector, color, and matrix values. VkDeviceSize VulkanRenderer::GetStd140Size(const QString &type) const { - if (type == QStringLiteral("float")) return 4; - if (type == QStringLiteral("vec2")) return 8; - if (type == QStringLiteral("vec3")) return 12; - if (type == QStringLiteral("vec4")) return 16; - if (type == QStringLiteral("mat4")) return 64; - if (type == QStringLiteral("int") || type == QStringLiteral("bool")) return 4; + if (type == QStringLiteral("float")) + return 4; + if (type == QStringLiteral("vec2")) + return 8; + if (type == QStringLiteral("vec3")) + return 12; + if (type == QStringLiteral("vec4")) + return 16; + if (type == QStringLiteral("mat4")) + return 64; + if (type == QStringLiteral("int") || type == QStringLiteral("bool")) + return 4; return 4; } // Returns std140 base alignment so generated UBO offsets match GPU layout rules. VkDeviceSize VulkanRenderer::GetStd140Alignment(const QString &type) const { - if (type == QStringLiteral("float")) return 4; - if (type == QStringLiteral("vec2")) return 8; - if (type == QStringLiteral("vec3")) return 16; - if (type == QStringLiteral("vec4")) return 16; - if (type == QStringLiteral("mat4")) return 16; - if (type == QStringLiteral("int") || type == QStringLiteral("bool")) return 4; + if (type == QStringLiteral("float")) + return 4; + if (type == QStringLiteral("vec2")) + return 8; + if (type == QStringLiteral("vec3")) + return 16; + if (type == QStringLiteral("vec4")) + return 16; + if (type == QStringLiteral("mat4")) + return 16; + if (type == QStringLiteral("int") || type == QStringLiteral("bool")) + return 4; return 4; } // Scans GLSL uniform declarations and splits them into samplers and values. This // is intentionally narrow and targets the shader style generated by Oak nodes. void VulkanRenderer::ExtractUniforms(const QString &glsl, - QVector *out_uniforms, - QVector *out_samplers) const + QVector *out_uniforms, + QVector *out_samplers) const { static const QRegularExpression re( QStringLiteral(R"(^\s*uniform\s+(\w+)\s+(\w+)\s*;)"), @@ -1968,13 +2051,15 @@ void VulkanRenderer::ComputeUniformLayout(QVector *uniforms) const } // Generates the uniform block source inserted into rewritten shaders. -QString VulkanRenderer::BuildUboBlock(const QVector &uniforms) const +QString +VulkanRenderer::BuildUboBlock(const QVector &uniforms) const { if (uniforms.isEmpty()) { return QString(); } - QString ubo = QStringLiteral("\nlayout(set = 0, binding = 0) uniform UniformBuffer {\n"); + QString ubo = QStringLiteral( + "\nlayout(set = 0, binding = 0) uniform UniformBuffer {\n"); for (const UniformInfo &info : uniforms) { ubo += QStringLiteral(" %1 %2;\n").arg(info.type, info.name); } @@ -1985,8 +2070,7 @@ QString VulkanRenderer::BuildUboBlock(const QVector &uniforms) cons // Rewrites GLSL so non-sampler uniforms live in set=0,binding=0 and sampler // uniforms get deterministic explicit bindings after the UBO. QString VulkanRenderer::RewriteShaderWithUbo( - const QString &glsl, - const QVector &all_uniforms, + const QString &glsl, const QVector &all_uniforms, const QHash &sampler_bindings) const { QString result = glsl; @@ -2010,9 +2094,11 @@ QString VulkanRenderer::RewriteShaderWithUbo( if (IsSamplerType(type)) { int binding = sampler_bindings.value(name, -1); if (binding >= 0) { - QString new_decl = QStringLiteral( - "layout(set = 0, binding = %1) uniform %2 %3;") - .arg(binding).arg(type, name); + QString new_decl = + QStringLiteral( + "layout(set = 0, binding = %1) uniform %2 %3;") + .arg(binding) + .arg(type, name); result.replace(m.capturedStart(), m.capturedLength(), new_decl); } } else { @@ -2042,7 +2128,6 @@ QString VulkanRenderer::RewriteShaderWithUbo( return result; } - // Compiles Vulkan GLSL into SPIR-V using shaderc. Without shaderc this backend // can initialize but cannot create shaders. bool VulkanRenderer::CompileGlslToSpv(const QString &glsl, @@ -2172,18 +2257,24 @@ QVariant VulkanRenderer::CreateNativeShader(olive::ShaderCode code) sampler_bindings[all_samplers[i]] = 1 + i; } - QString converted_vert = RewriteShaderWithUbo(vert_code, all_uniforms, sampler_bindings); - QString converted_frag = RewriteShaderWithUbo(frag_code, all_uniforms, sampler_bindings); + QString converted_vert = + RewriteShaderWithUbo(vert_code, all_uniforms, sampler_bindings); + QString converted_frag = + RewriteShaderWithUbo(frag_code, all_uniforms, sampler_bindings); - converted_vert = ConvertGlslToVulkan(converted_vert, VK_SHADER_STAGE_VERTEX_BIT); - converted_frag = ConvertGlslToVulkan(converted_frag, VK_SHADER_STAGE_FRAGMENT_BIT); + converted_vert = + ConvertGlslToVulkan(converted_vert, VK_SHADER_STAGE_VERTEX_BIT); + converted_frag = + ConvertGlslToVulkan(converted_frag, VK_SHADER_STAGE_FRAGMENT_BIT); - if (!CompileGlslToSpv(converted_vert, VK_SHADER_STAGE_VERTEX_BIT, &vert_spv)) { + if (!CompileGlslToSpv(converted_vert, VK_SHADER_STAGE_VERTEX_BIT, + &vert_spv)) { fprintf(stderr, "Failed to compile Vulkan vertex shader:\n%s\n", converted_vert.toUtf8().constData()); return QVariant(); } - if (!CompileGlslToSpv(converted_frag, VK_SHADER_STAGE_FRAGMENT_BIT, &frag_spv)) { + if (!CompileGlslToSpv(converted_frag, VK_SHADER_STAGE_FRAGMENT_BIT, + &frag_spv)) { fprintf(stderr, "Failed to compile Vulkan fragment shader:\n%s\n", converted_frag.toUtf8().constData()); return QVariant(); @@ -2204,8 +2295,8 @@ QVariant VulkanRenderer::CreateNativeShader(olive::ShaderCode code) vert_info.codeSize = static_cast(vert_spv.size()); vert_info.pCode = reinterpret_cast(vert_spv.constData()); - VkResult result = vkCreateShaderModule(device_, &vert_info, nullptr, - &sh->vert_module); + VkResult result = + vkCreateShaderModule(device_, &vert_info, nullptr, &sh->vert_module); if (result != VK_SUCCESS) { delete sh; return QVariant(); @@ -2216,7 +2307,8 @@ QVariant VulkanRenderer::CreateNativeShader(olive::ShaderCode code) frag_info.codeSize = static_cast(frag_spv.size()); frag_info.pCode = reinterpret_cast(frag_spv.constData()); - result = vkCreateShaderModule(device_, &frag_info, nullptr, &sh->frag_module); + result = + vkCreateShaderModule(device_, &frag_info, nullptr, &sh->frag_module); if (result != VK_SUCCESS) { vkDestroyShaderModule(device_, sh->vert_module, nullptr); delete sh; @@ -2244,7 +2336,7 @@ QVariant VulkanRenderer::CreateNativeShader(olive::ShaderCode code) VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; sampler_binding.descriptorCount = 1; sampler_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | - VK_SHADER_STAGE_FRAGMENT_BIT; + VK_SHADER_STAGE_FRAGMENT_BIT; bindings.append(sampler_binding); } @@ -2254,7 +2346,7 @@ QVariant VulkanRenderer::CreateNativeShader(olive::ShaderCode code) ds_layout_info.pBindings = bindings.constData(); result = vkCreateDescriptorSetLayout(device_, &ds_layout_info, nullptr, - &sh->descriptor_layout); + &sh->descriptor_layout); if (result != VK_SUCCESS) { vkDestroyShaderModule(device_, sh->frag_module, nullptr); vkDestroyShaderModule(device_, sh->vert_module, nullptr); @@ -2268,7 +2360,7 @@ QVariant VulkanRenderer::CreateNativeShader(olive::ShaderCode code) layout_info.pSetLayouts = &sh->descriptor_layout; result = vkCreatePipelineLayout(device_, &layout_info, nullptr, - &sh->pipeline_layout); + &sh->pipeline_layout); if (result != VK_SUCCESS) { vkDestroyDescriptorSetLayout(device_, sh->descriptor_layout, nullptr); vkDestroyShaderModule(device_, sh->frag_module, nullptr); @@ -2281,7 +2373,6 @@ QVariant VulkanRenderer::CreateNativeShader(olive::ShaderCode code) return QVariant::fromValue(sh->id); } - // Releases shader modules, descriptor layout, pipeline layout, and pipelines. void VulkanRenderer::DestroyNativeShader(QVariant shader) { @@ -2291,7 +2382,8 @@ void VulkanRenderer::DestroyNativeShader(QVariant shader) if (!sh) { return; } - for (auto it = sh->pipeline_cache.begin(); it != sh->pipeline_cache.end(); ++it) { + for (auto it = sh->pipeline_cache.begin(); it != sh->pipeline_cache.end(); + ++it) { if (it.value() != VK_NULL_HANDLE) { vkDestroyPipeline(device_, it.value(), nullptr); } @@ -2317,7 +2409,7 @@ void VulkanRenderer::DestroyNativeShader(QVariant shader) bool VulkanRenderer::CreatePipelineForShader(VulkanShader *shader, const VideoParams &dest_params, - VkFormat render_pass_format) + VkFormat render_pass_format) { if (shader->pipeline_cache.contains(render_pass_format)) { return true; @@ -2338,7 +2430,8 @@ bool VulkanRenderer::CreatePipelineForShader(VulkanShader *shader, VkPipelineShaderStageCreateInfo stages[] = { vert_stage, frag_stage }; VkPipelineVertexInputStateCreateInfo vertex_input = {}; - vertex_input.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_input.sType = + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; VkVertexInputBindingDescription binding_desc = {}; binding_desc.binding = 0; @@ -2361,7 +2454,8 @@ bool VulkanRenderer::CreatePipelineForShader(VulkanShader *shader, vertex_input.pVertexAttributeDescriptions = attrs; VkPipelineInputAssemblyStateCreateInfo input_assembly = {}; - input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + input_assembly.sType = + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkViewport viewport = {}; @@ -2372,38 +2466,44 @@ bool VulkanRenderer::CreatePipelineForShader(VulkanShader *shader, VkRect2D scissor = {}; scissor.extent.width = static_cast(dest_params.effective_width()); - scissor.extent.height = static_cast(dest_params.effective_height()); + scissor.extent.height = + static_cast(dest_params.effective_height()); VkPipelineViewportStateCreateInfo viewport_state = {}; - viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_state.sType = + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewport_state.viewportCount = 1; viewport_state.pViewports = &viewport; viewport_state.scissorCount = 1; viewport_state.pScissors = &scissor; VkPipelineRasterizationStateCreateInfo rasterizer = {}; - rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterizer.sType = + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizer.polygonMode = VK_POLYGON_MODE_FILL; rasterizer.cullMode = VK_CULL_MODE_NONE; rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterizer.lineWidth = 1.0f; VkPipelineMultisampleStateCreateInfo multisampling = {}; - multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisampling.sType = + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; VkPipelineColorBlendAttachmentState color_blend = {}; - color_blend.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + color_blend.colorWriteMask = + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; color_blend.blendEnable = VK_FALSE; VkPipelineColorBlendStateCreateInfo color_blending = {}; - color_blending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + color_blending.sType = + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; color_blending.attachmentCount = 1; color_blending.pAttachments = &color_blend; VkDynamicState dynamic_states[] = { VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR }; + VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamic_state = {}; dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamic_state.dynamicStateCount = 2; @@ -2425,9 +2525,8 @@ bool VulkanRenderer::CreatePipelineForShader(VulkanShader *shader, pipeline_info.subpass = 0; VkPipeline new_pipeline = VK_NULL_HANDLE; - VkResult result = vkCreateGraphicsPipelines(device_, VK_NULL_HANDLE, 1, - &pipeline_info, nullptr, - &new_pipeline); + VkResult result = vkCreateGraphicsPipelines( + device_, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &new_pipeline); if (result != VK_SUCCESS) { qWarning() << "Failed to create Vulkan graphics pipeline:" << result; return false; @@ -2452,12 +2551,14 @@ void VulkanRenderer::BlitPass(VulkanShader *shader, VulkanTexture *dest_tex, } VkFormat render_pass_format = dest_tex->vk_format; - VkRenderPass render_pass = GetOrCreateRenderPass(render_pass_format, clear_destination); + VkRenderPass render_pass = + GetOrCreateRenderPass(render_pass_format, clear_destination); if (render_pass == VK_NULL_HANDLE) { return; } - if (!CreatePipelineForShader(shader, destination_params, render_pass_format)) { + if (!CreatePipelineForShader(shader, destination_params, + render_pass_format)) { return; } @@ -2476,7 +2577,7 @@ void VulkanRenderer::BlitPass(VulkanShader *shader, VulkanTexture *dest_tex, fb_info.height = static_cast(dest_tex->height); fb_info.layers = 1; VkResult fb_result = vkCreateFramebuffer(device_, &fb_info, nullptr, - &dest_tex->framebuffer); + &dest_tex->framebuffer); if (fb_result != VK_SUCCESS) { qWarning() << "Failed to create Vulkan framebuffer:" << fb_result; return; @@ -2491,7 +2592,8 @@ void VulkanRenderer::BlitPass(VulkanShader *shader, VulkanTexture *dest_tex, if (CreateStagingBuffer(shader->ubo_size, &ubo_buffer, &ubo_memory)) { void *mapped; vkMapMemory(device_, ubo_memory, 0, shader->ubo_size, 0, &mapped); - memcpy(mapped, ubo_data.constData(), static_cast(shader->ubo_size)); + memcpy(mapped, ubo_data.constData(), + static_cast(shader->ubo_size)); vkUnmapMemory(device_, ubo_memory); } } @@ -2514,7 +2616,8 @@ void VulkanRenderer::BlitPass(VulkanShader *shader, VulkanTexture *dest_tex, ds_alloc.descriptorSetCount = 1; ds_alloc.pSetLayouts = &shader->descriptor_layout; - VkResult result = vkAllocateDescriptorSets(device_, &ds_alloc, &descriptor_set); + VkResult result = + vkAllocateDescriptorSets(device_, &ds_alloc, &descriptor_set); if (result != VK_SUCCESS) { qWarning() << "Failed to allocate Vulkan descriptor set:" << result; if (ubo_buffer != VK_NULL_HANDLE) { @@ -2568,7 +2671,8 @@ void VulkanRenderer::BlitPass(VulkanShader *shader, VulkanTexture *dest_tex, write.dstSet = descriptor_set; write.dstBinding = static_cast(binding); write.dstArrayElement = 0; - write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write.descriptorType = + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; write.descriptorCount = 1; write.pImageInfo = &image_infos.last(); writes.append(write); @@ -2576,14 +2680,16 @@ void VulkanRenderer::BlitPass(VulkanShader *shader, VulkanTexture *dest_tex, } if (!writes.isEmpty()) { - vkUpdateDescriptorSets(device_, writes.size(), writes.constData(), 0, - nullptr); + vkUpdateDescriptorSets(device_, writes.size(), writes.constData(), + 0, nullptr); } } VkCommandBuffer cmd = BeginOneTimeCommands(); - if (cmd == VK_NULL_HANDLE) { return; } + if (cmd == VK_NULL_HANDLE) { + return; + } if (dest_tex->current_layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { TransitionImageLayout(cmd, dest_tex->image, dest_tex->current_layout, @@ -2592,7 +2698,8 @@ void VulkanRenderer::BlitPass(VulkanShader *shader, VulkanTexture *dest_tex, } for (const TextureBinding &tb : bindings) { - if (tb.tex && tb.tex->current_layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + if (tb.tex && tb.tex->current_layout != + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { TransitionImageLayout(cmd, tb.tex->image, tb.tex->current_layout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); tb.tex->current_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -2642,8 +2749,8 @@ void VulkanRenderer::BlitPass(VulkanShader *shader, VulkanTexture *dest_tex, // Bind descriptor set if (descriptor_set != VK_NULL_HANDLE) { vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - shader->pipeline_layout, 0, 1, &descriptor_set, 0, - nullptr); + shader->pipeline_layout, 0, 1, &descriptor_set, + 0, nullptr); } // Draw @@ -2722,7 +2829,8 @@ void VulkanRenderer::Blit(QVariant shader_variant, olive::AcceleratedJob &a_job, quint64 final_id = final_tex.texture->id().value(); final_tex.native = textures_.value(final_id); if (!final_tex.native) { - qWarning() << "VulkanRenderer::Blit failed to resolve temporary destination texture"; + qWarning() + << "VulkanRenderer::Blit failed to resolve temporary destination texture"; return; } dest_tex = final_tex.native; @@ -2745,8 +2853,8 @@ void VulkanRenderer::Blit(QVariant shader_variant, olive::AcceleratedJob &a_job, base_ubo_data.fill(0); } - for (auto it = job.GetValues().constBegin(); it != job.GetValues().constEnd(); - ++it) { + for (auto it = job.GetValues().constBegin(); + it != job.GetValues().constEnd(); ++it) { const NodeValue &value = it.value(); if (value.type() == NodeValue::kTexture) { TexturePtr texture = value.toTexture(); @@ -2755,8 +2863,8 @@ void VulkanRenderer::Blit(QVariant shader_variant, olive::AcceleratedJob &a_job, quint64 tid = texture->id().value(); vtex = textures_.value(tid); } - base_bindings.append({ it.key(), vtex, - job.GetInterpolation(it.key()) }); + base_bindings.append( + { it.key(), vtex, job.GetInterpolation(it.key()) }); } else if (!shader->uniforms.isEmpty() && shader->ubo_size > 0) { // Find matching uniform for (const UniformInfo &u : shader->uniforms) { @@ -2765,10 +2873,12 @@ void VulkanRenderer::Blit(QVariant shader_variant, olive::AcceleratedJob &a_job, char *dst = base_ubo_data.data() + static_cast(u.offset); switch (value.type()) { case NodeValue::kFloat: - *reinterpret_cast(dst) = static_cast(value.toDouble()); + *reinterpret_cast(dst) = + static_cast(value.toDouble()); break; case NodeValue::kInt: - *reinterpret_cast(dst) = static_cast(value.toInt()); + *reinterpret_cast(dst) = + static_cast(value.toInt()); break; case NodeValue::kBoolean: *reinterpret_cast(dst) = value.toBool() ? 1 : 0; @@ -2821,12 +2931,16 @@ void VulkanRenderer::Blit(QVariant shader_variant, olive::AcceleratedJob &a_job, QMatrix4x4 m = job.Get(QStringLiteral("ove_mvpmat")).toMatrix(); memcpy(dst, m.constData(), sizeof(float) * 16); } else if (u.name == QStringLiteral("ove_cropmatrix")) { - QMatrix4x4 m = job.Get(QStringLiteral("ove_cropmatrix")).toMatrix(); + QMatrix4x4 m = + job.Get(QStringLiteral("ove_cropmatrix")).toMatrix(); memcpy(dst, m.constData(), sizeof(float) * 16); } else if (u.name == QStringLiteral("ove_maintex_alpha")) { - *reinterpret_cast(dst) = job.Get(QStringLiteral("ove_maintex_alpha")).toInt(); + *reinterpret_cast(dst) = + job.Get(QStringLiteral("ove_maintex_alpha")).toInt(); } else if (u.name == QStringLiteral("ove_force_opaque")) { - *reinterpret_cast(dst) = job.Get(QStringLiteral("ove_force_opaque")).toBool() ? 1 : 0; + *reinterpret_cast(dst) = + job.Get(QStringLiteral("ove_force_opaque")).toBool() ? 1 : + 0; } } } @@ -2837,7 +2951,8 @@ void VulkanRenderer::Blit(QVariant shader_variant, olive::AcceleratedJob &a_job, QString enabled_name = tb.name + QStringLiteral("_enabled"); for (const UniformInfo &u : shader->uniforms) { if (u.name == enabled_name && u.size == sizeof(int)) { - char *dst = base_ubo_data.data() + static_cast(u.offset); + char *dst = + base_ubo_data.data() + static_cast(u.offset); *reinterpret_cast(dst) = tb.tex ? 1 : 0; break; } @@ -2853,7 +2968,8 @@ void VulkanRenderer::Blit(QVariant shader_variant, olive::AcceleratedJob &a_job, if (shader->ubo_size > 0) { for (const UniformInfo &u : shader->uniforms) { if (u.name == QStringLiteral("ove_iteration")) { - char *dst = pass_ubo_data.data() + static_cast(u.offset); + char *dst = + pass_ubo_data.data() + static_cast(u.offset); *reinterpret_cast(dst) = iteration; break; } @@ -2887,5 +3003,4 @@ void VulkanRenderer::Blit(QVariant shader_variant, olive::AcceleratedJob &a_job, } } - } // namespace olive diff --git a/app/render/vulkan/vulkanrenderer.h b/app/render/vulkan/vulkanrenderer.h index c0d66a17e..48687b8f9 100644 --- a/app/render/vulkan/vulkanrenderer.h +++ b/app/render/vulkan/vulkanrenderer.h @@ -51,8 +51,8 @@ public: // Clears either a texture render target or the currently bound output target. virtual void ClearDestination(olive::Texture *texture = nullptr, - double r = 0.0, double g = 0.0, - double b = 0.0, double a = 0.0) override; + double r = 0.0, double g = 0.0, + double b = 0.0, double a = 0.0) override; // Compiles GLSL to SPIR-V, creates shader modules, and prepares descriptor // metadata for later blits. @@ -63,12 +63,12 @@ public: // Uploads CPU pixel data to a Vulkan image via a staging buffer. virtual void UploadToTexture(const QVariant &handle, - const VideoParams ¶ms, const void *data, - int linesize) override; + const VideoParams ¶ms, const void *data, + int linesize) override; // Downloads a Vulkan image to CPU memory via a staging buffer. virtual void DownloadFromTexture(const QVariant &handle, - const VideoParams ¶ms, void *data, - int linesize) override; + const VideoParams ¶ms, void *data, + int linesize) override; // Waits for outstanding device work to complete. virtual void Flush() override; @@ -80,7 +80,7 @@ public: // Reads a single texture pixel using a one-pixel transfer readback. virtual Color GetPixelFromTexture(olive::Texture *texture, - const QPointF &pt) override; + const QPointF &pt) override; bool IsAvailable() const { @@ -90,14 +90,15 @@ public: protected: // Runs one or more fullscreen shader passes into the destination texture. virtual void Blit(QVariant shader, olive::AcceleratedJob &job, - olive::Texture *destination, VideoParams destination_params, - bool clear_destination) override; + olive::Texture *destination, + VideoParams destination_params, + bool clear_destination) override; // Creates a Vulkan image/view/memory bundle and optionally uploads initial // pixel data. virtual QVariant CreateNativeTexture(int width, int height, int depth, - PixelFormat format, int channel_count, - const void *data = nullptr, - int linesize = 0) override; + PixelFormat format, int channel_count, + const void *data = nullptr, + int linesize = 0) override; // Releases a Vulkan texture bundle. virtual void DestroyNativeTexture(QVariant texture) override; // Releases all Vulkan device resources owned by this renderer. @@ -172,10 +173,10 @@ private: float GetFormatMaxAlpha(PixelFormat format) const; // Repackages tightly packed pixels when the requested CPU channel count // differs from the selected GPU format channel count. - void CopyPixelsWithChannelConversion(const void *src, void *dst, - int width, int height, int depth, - int src_channels, int dst_channels, - PixelFormat format) const; + void CopyPixelsWithChannelConversion(const void *src, void *dst, int width, + int height, int depth, + int src_channels, int dst_channels, + PixelFormat format) const; // Rounds a size up to the requested alignment. VkDeviceSize AlignSize(VkDeviceSize size, VkDeviceSize alignment) const; @@ -187,11 +188,13 @@ private: bool CompileGlslToSpv(const QString &glsl, VkShaderStageFlagBits stage, QByteArray *out_spv); // Rewrites an Oak GLSL shader into Vulkan-compatible GLSL. - QString ConvertGlslToVulkan(const QString &glsl, VkShaderStageFlagBits stage); + QString ConvertGlslToVulkan(const QString &glsl, + VkShaderStageFlagBits stage); // Ensures a shader declares a Vulkan-compatible GLSL version. QString EnsureGlslVersion450(const QString &glsl) const; // Extracts uniforms and sampler names from GLSL declarations. - void ExtractUniforms(const QString &glsl, QVector *out_uniforms, + void ExtractUniforms(const QString &glsl, + QVector *out_uniforms, QVector *out_samplers) const; // Computes std140 offsets and total UBO size for extracted uniforms. void ComputeUniformLayout(QVector *uniforms) const; @@ -199,9 +202,10 @@ private: QString BuildUboBlock(const QVector &uniforms) const; // Rewrites standalone uniforms and samplers into explicit UBO/sampler // bindings accepted by Vulkan GLSL. - QString RewriteShaderWithUbo(const QString &glsl, - const QVector &all_uniforms, - const QHash &sampler_bindings) const; + QString + RewriteShaderWithUbo(const QString &glsl, + const QVector &all_uniforms, + const QHash &sampler_bindings) const; // Returns std140 storage size for a supported GLSL type. VkDeviceSize GetStd140Size(const QString &type) const; // Returns std140 alignment for a supported GLSL type. @@ -225,8 +229,8 @@ private: void BlitPass(VulkanShader *shader, VulkanTexture *dest_tex, const QVector &bindings, const QByteArray &ubo_data, - const VideoParams &destination_params, - bool clear_destination, int iteration); + const VideoParams &destination_params, bool clear_destination, + int iteration); VkInstance instance_ = VK_NULL_HANDLE; VkDebugUtilsMessengerEXT debug_messenger_ = VK_NULL_HANDLE; diff --git a/app/render/worker/workermain.cpp b/app/render/worker/workermain.cpp index 5d7b74bd4..3cc9d78d6 100644 --- a/app/render/worker/workermain.cpp +++ b/app/render/worker/workermain.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -51,6 +52,10 @@ #include "render/colorprocessor.h" #include "render/colortransform.h" +#ifdef Q_OS_MACOS +void HideWorkerDockIcon(); +#endif + namespace { @@ -105,7 +110,6 @@ public: bool InitializeRuntime() { - // Create a minimal Core instance so that code paths calling Core::instance() // (e.g. ViewerOutput::data for timecode display) do not dereference null. // The worker is short-lived; leaking this on exit is harmless. @@ -136,7 +140,8 @@ public: QJsonObject handshake = hs.ToJson(); QOpenGLContext *ctx = nullptr; #ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND - if (auto *dynamic_renderer = dynamic_cast(renderer_)) { + if (auto *dynamic_renderer = + dynamic_cast(renderer_)) { ctx = dynamic_renderer->OpenGLContext(); } else #endif @@ -159,7 +164,8 @@ public: if (type == QLatin1String(olive::ipc::msgtype::kHandshake)) { olive::ipc::HandshakeMsg hs; if (!olive::ipc::HandshakeMsg::FromJson(message, &hs)) { - return Write(ErrorMessage(QStringLiteral("invalid handshake message"))); + return Write( + ErrorMessage(QStringLiteral("invalid handshake message"))); } return AttachOutputPool(hs); } @@ -167,7 +173,8 @@ public: if (type == QLatin1String(olive::ipc::msgtype::kLoadGraph)) { olive::ipc::LoadGraphMsg load; if (!olive::ipc::LoadGraphMsg::FromJson(message, &load)) { - return Write(ErrorMessage(QStringLiteral("invalid load_graph message"))); + return Write( + ErrorMessage(QStringLiteral("invalid load_graph message"))); } return LoadGraph(load.path); } @@ -175,7 +182,8 @@ public: if (type == QLatin1String(olive::ipc::msgtype::kRenderFrame)) { olive::ipc::RenderFrameMsg render; if (!olive::ipc::RenderFrameMsg::FromJson(message, &render)) { - return Write(ErrorMessage(QStringLiteral("invalid render_frame message"))); + return Write(ErrorMessage( + QStringLiteral("invalid render_frame message"))); } return RenderFrame(render); } @@ -190,7 +198,8 @@ public: return true; } - return Write(ErrorMessage(QStringLiteral("unknown message type: %1").arg(type))); + return Write( + ErrorMessage(QStringLiteral("unknown message type: %1").arg(type))); } bool shutdown_requested() const @@ -209,48 +218,58 @@ private: bool AttachOutputPool(const olive::ipc::HandshakeMsg &hs) { if (hs.protocol_version != kProtocolVersion) { - return Write(ErrorMessage(QStringLiteral("unsupported protocol version %1") - .arg(hs.protocol_version))); + return Write( + ErrorMessage(QStringLiteral("unsupported protocol version %1") + .arg(hs.protocol_version))); } - if (hs.shm_key.isEmpty() || hs.output_slots <= 0 || hs.slot_data_bytes <= 0) { - return Write(ErrorMessage(QStringLiteral("handshake missing output shared-memory geometry"))); + if (hs.shm_key.isEmpty() || hs.output_slots <= 0 || + hs.slot_data_bytes <= 0) { + return Write(ErrorMessage(QStringLiteral( + "handshake missing output shared-memory geometry"))); } const size_t bytes = olive::ipc::FrameSlotPool::BytesNeeded( uint32_t(hs.output_slots), size_t(hs.slot_data_bytes)); - if (!output_region_.Open(hs.shm_key, bytes, olive::ipc::SharedMemoryRegion::kAttach)) { - return Write(ErrorMessage(QStringLiteral("failed to attach shared memory: %1") - .arg(output_region_.error()))); + if (!output_region_.Open(hs.shm_key, bytes, + olive::ipc::SharedMemoryRegion::kAttach)) { + return Write(ErrorMessage( + QStringLiteral("failed to attach shared memory: %1") + .arg(output_region_.error()))); } output_pool_ = olive::ipc::FrameSlotPool::Attach(output_region_.data()); if (!output_pool_->IsValid()) { output_region_.Close(); output_pool_.reset(); - return Write(ErrorMessage(QStringLiteral("shared memory does not contain a frame slot pool"))); + return Write(ErrorMessage(QStringLiteral( + "shared memory does not contain a frame slot pool"))); } input_pool_.reset(); input_region_.Close(); if (hs.input_slots > 0) { if (hs.input_shm_key.isEmpty() || hs.input_slot_data_bytes <= 0) { - return Write(ErrorMessage(QStringLiteral("handshake missing input shared-memory geometry"))); + return Write(ErrorMessage(QStringLiteral( + "handshake missing input shared-memory geometry"))); } const size_t input_bytes = olive::ipc::FrameSlotPool::BytesNeeded( uint32_t(hs.input_slots), size_t(hs.input_slot_data_bytes)); if (!input_region_.Open(hs.input_shm_key, input_bytes, olive::ipc::SharedMemoryRegion::kAttach)) { - return Write(ErrorMessage(QStringLiteral("failed to attach input shared memory: %1") - .arg(input_region_.error()))); + return Write(ErrorMessage( + QStringLiteral("failed to attach input shared memory: %1") + .arg(input_region_.error()))); } - input_pool_ = olive::ipc::FrameSlotPool::Attach(input_region_.data()); + input_pool_ = + olive::ipc::FrameSlotPool::Attach(input_region_.data()); if (!input_pool_->IsValid()) { input_region_.Close(); input_pool_.reset(); - return Write(ErrorMessage(QStringLiteral("input shared memory does not contain a frame slot pool"))); + return Write(ErrorMessage(QStringLiteral( + "input shared memory does not contain a frame slot pool"))); } } @@ -259,16 +278,40 @@ private: bool LoadGraph(const QString &path) { + { + QFileInfo fi(path); + if (!fi.exists()) { + LogError( + QStringLiteral("LoadGraph: graph file does not exist: %1") + .arg(path)); + return Write(ErrorMessage( + QStringLiteral("graph file does not exist: %1").arg(path))); + } + if (fi.size() == 0) { + LogError(QStringLiteral("LoadGraph: graph file is empty: %1") + .arg(path)); + return Write(ErrorMessage( + QStringLiteral("graph file is empty: %1").arg(path))); + } + LogError( + QStringLiteral("LoadGraph: loading %1 (%2 bytes, readable=%3)") + .arg(path) + .arg(fi.size()) + .arg(fi.isReadable())); + } + auto loaded = std::make_unique(); // Do not call Initialize() here: project serializers expect a blank // project (root_ == nullptr) and will set root themselves. Calling // Initialize() first triggers Q_ASSERT(!root_) in Project::Load. olive::ProjectSerializer::Result result = - olive::ProjectSerializer::Load(loaded.get(), path, olive::ProjectSerializer::kProject); + olive::ProjectSerializer::Load(loaded.get(), path, + olive::ProjectSerializer::kProject); if (result != olive::ProjectSerializer::kSuccess) { - return Write(ErrorMessage(QStringLiteral("failed to load graph %1: %2") - .arg(path, result.GetDetails()))); + return Write( + ErrorMessage(QStringLiteral("failed to load graph %1: %2") + .arg(path, result.GetDetails()))); } project_ = std::move(loaded); @@ -276,12 +319,15 @@ private: color_processor_cache_.clear(); const auto &data = result.GetLoadData(); - for (auto it = data.node_ptrs.cbegin(); it != data.node_ptrs.cend(); ++it) { + for (auto it = data.node_ptrs.cbegin(); it != data.node_ptrs.cend(); + ++it) { node_by_token_.insert(QString::number(it.key()), it.value()); } - for (auto it = data.node_uuids.cbegin(); it != data.node_uuids.cend(); ++it) { + for (auto it = data.node_uuids.cbegin(); it != data.node_uuids.cend(); + ++it) { node_by_token_.insert(it.value().toString(), it.key()); - node_by_token_.insert(it.value().toString(QUuid::WithoutBraces), it.key()); + node_by_token_.insert(it.value().toString(QUuid::WithoutBraces), + it.key()); } QJsonObject ack; @@ -308,29 +354,36 @@ private: bool RenderFrame(const olive::ipc::RenderFrameMsg &message) { if (!project_) { - return Write(ErrorMessage(QStringLiteral("render_frame received before load_graph"), - message.ticket_id)); + return Write(ErrorMessage( + QStringLiteral("render_frame received before load_graph"), + message.ticket_id)); } if (!output_pool_ || !output_pool_->IsValid()) { - return Write(ErrorMessage(QStringLiteral("render_frame received before output shm handshake"), - message.ticket_id)); + return Write(ErrorMessage( + QStringLiteral( + "render_frame received before output shm handshake"), + message.ticket_id)); } olive::Node *node = FindNode(message.node_uuid); if (!node) { - return Write(ErrorMessage(QStringLiteral("render node not found: %1").arg(message.node_uuid), - message.ticket_id)); + return Write( + ErrorMessage(QStringLiteral("render node not found: %1") + .arg(message.node_uuid), + message.ticket_id)); } QVector input_slots; const QVector requested_input_slots = - message.input_slots.isEmpty() && message.input_slot >= 0 - ? QVector{message.input_slot} - : message.input_slots; + message.input_slots.isEmpty() && message.input_slot >= 0 ? + QVector{ message.input_slot } : + message.input_slots; if (!requested_input_slots.isEmpty()) { if (!input_pool_ || !input_pool_->IsValid()) { - return Write(ErrorMessage(QStringLiteral("render_frame referenced input slot without input pool"), - message.ticket_id)); + return Write(ErrorMessage( + QStringLiteral( + "render_frame referenced input slot without input pool"), + message.ticket_id)); } for (int requested_slot : requested_input_slots) { @@ -339,8 +392,9 @@ private: for (int slot : input_slots) { input_pool_->Release(uint32_t(slot)); } - return Write(ErrorMessage(QStringLiteral("input slot index out of range"), - message.ticket_id)); + return Write(ErrorMessage( + QStringLiteral("input slot index out of range"), + message.ticket_id)); } uint32_t consumed_slot = 0; @@ -348,16 +402,18 @@ private: for (int slot : input_slots) { input_pool_->Release(uint32_t(slot)); } - return Write(ErrorMessage(QStringLiteral("input slot was not ready"), - message.ticket_id)); + return Write( + ErrorMessage(QStringLiteral("input slot was not ready"), + message.ticket_id)); } if (int(consumed_slot) != requested_slot) { input_pool_->Release(consumed_slot); for (int slot : input_slots) { input_pool_->Release(uint32_t(slot)); } - return Write(ErrorMessage(QStringLiteral("input slot order mismatch"), - message.ticket_id)); + return Write(ErrorMessage( + QStringLiteral("input slot order mismatch"), + message.ticket_id)); } input_slots.append(int(consumed_slot)); @@ -368,41 +424,41 @@ private: } } - olive::VideoParams vparams(message.width > 0 ? message.width : kDefaultWidth, - message.height > 0 ? message.height : kDefaultHeight, - olive::rational(1, kDefaultFrameRate), - message.format >= 0 - ? olive::PixelFormat::Format(message.format) - : olive::PixelFormat::F32, - message.channel_count > 0 - ? message.channel_count - : olive::VideoParams::kRGBAChannelCount); + olive::VideoParams vparams( + message.width > 0 ? message.width : kDefaultWidth, + message.height > 0 ? message.height : kDefaultHeight, + olive::rational(1, kDefaultFrameRate), + message.format >= 0 ? olive::PixelFormat::Format(message.format) : + olive::PixelFormat::F32, + message.channel_count > 0 ? message.channel_count : + olive::VideoParams::kRGBAChannelCount); olive::RenderTicketPtr ticket = std::make_shared(); ticket->setProperty("node", olive::QtUtils::PtrToValue(node)); - ticket->setProperty("time", QVariant::fromValue( - olive::rational(int(message.time_num), int(message.time_den)))); + ticket->setProperty("time", + QVariant::fromValue(olive::rational( + int(message.time_num), int(message.time_den)))); ticket->setProperty("size", QSize(message.width, message.height)); ticket->setProperty("matrix", QMatrix4x4()); ticket->setProperty("format", - message.format >= 0 - ? olive::PixelFormat::Format(message.format) - : olive::PixelFormat::INVALID); + message.format >= 0 ? + olive::PixelFormat::Format(message.format) : + olive::PixelFormat::INVALID); ticket->setProperty("usecache", false); ticket->setProperty("channelcount", message.channel_count); ticket->setProperty("mode", olive::RenderMode::Mode(message.mode)); ticket->setProperty("type", olive::RenderManager::kTypeVideo); - ticket->setProperty("colormanager", olive::QtUtils::PtrToValue(project_->color_manager())); + ticket->setProperty("colormanager", olive::QtUtils::PtrToValue( + project_->color_manager())); { olive::ColorProcessorPtr color_output; if (message.has_color_transform) { - QString cache_key = - QStringLiteral("%1|%2|%3|%4") - .arg(message.color_is_display ? 1 : 0) - .arg(message.color_output, - message.color_view, - message.color_look); + QString cache_key = QStringLiteral("%1|%2|%3|%4") + .arg(message.color_is_display ? 1 : 0) + .arg(message.color_output, + message.color_view, + message.color_look); auto it = color_processor_cache_.find(cache_key); if (it != color_processor_cache_.end()) { color_output = it.value(); @@ -410,8 +466,8 @@ private: olive::ColorTransform transform; if (message.color_is_display) { transform = olive::ColorTransform(message.color_output, - message.color_view, - message.color_look); + message.color_view, + message.color_look); } else { transform = olive::ColorTransform(message.color_output); } @@ -425,19 +481,23 @@ private: } } ticket->setProperty("coloroutput", - QVariant::fromValue(color_output)); + QVariant::fromValue(color_output)); } ticket->setProperty("vparam", QVariant::fromValue(vparams)); - ticket->setProperty("aparam", QVariant::fromValue(olive::AudioParams())); + ticket->setProperty("aparam", + QVariant::fromValue(olive::AudioParams())); ticket->setProperty("return", olive::RenderManager::kFrame); ticket->setProperty("cache", QString()); - ticket->setProperty("cachetimebase", QVariant::fromValue(olive::rational(1))); + ticket->setProperty("cachetimebase", + QVariant::fromValue(olive::rational(1))); ticket->setProperty("cacheid", QVariant::fromValue(QUuid())); - ticket->setProperty("multicam", olive::QtUtils::PtrToValue(static_cast(nullptr))); - ticket->setProperty("ipc_input_pool", - olive::QtUtils::PtrToValue( - input_pool_ ? static_cast(&*input_pool_) - : static_cast(nullptr))); + ticket->setProperty("multicam", olive::QtUtils::PtrToValue( + static_cast(nullptr))); + ticket->setProperty( + "ipc_input_pool", + olive::QtUtils::PtrToValue(input_pool_ ? + static_cast(&*input_pool_) : + static_cast(nullptr))); QVariantList input_slot_values; for (int slot : input_slots) { input_slot_values.append(slot); @@ -448,34 +508,42 @@ private: input_slots.isEmpty() ? -1 : input_slots.front()); ticket->Start(); - olive::RenderProcessor::Process(ticket, renderer_, nullptr, &shader_cache_); + olive::RenderProcessor::Process(ticket, renderer_, nullptr, + &shader_cache_); for (int slot : input_slots) { input_pool_->Release(uint32_t(slot)); } if (!ticket->HasResult()) { - return Write(ErrorMessage(QStringLiteral("render produced no frame"), message.ticket_id)); + return Write(ErrorMessage( + QStringLiteral("render produced no frame"), message.ticket_id)); } olive::FramePtr frame = ticket->Get().value(); if (!frame || !frame->is_allocated()) { - return Write(ErrorMessage(QStringLiteral("render result was empty"), message.ticket_id)); + return Write(ErrorMessage(QStringLiteral("render result was empty"), + message.ticket_id)); } uint32_t slot = 0; if (!output_pool_->Acquire(&slot)) { - return Write(ErrorMessage(QStringLiteral("no free output frame slot"), message.ticket_id)); + return Write( + ErrorMessage(QStringLiteral("no free output frame slot"), + message.ticket_id)); } - const int data_size = frame->linesize_bytes()*frame->height(); + const int data_size = frame->linesize_bytes() * frame->height(); if (data_size > int(output_pool_->slot_data_bytes())) { output_pool_->Release(slot); - LogError(QString("Output frame size")+QString::number(data_size)); - LogError(QString("Slot size")+QString::number(output_pool_->slot_data_bytes())); - return Write(ErrorMessage(QStringLiteral("rendered frame does not fit output slot "), - message.ticket_id)); + LogError(QString("Output frame size") + QString::number(data_size)); + LogError(QString("Slot size") + + QString::number(output_pool_->slot_data_bytes())); + return Write(ErrorMessage( + QStringLiteral("rendered frame does not fit output slot "), + message.ticket_id)); } - std::memcpy(output_pool_->SlotData(slot), frame->const_data(), size_t(data_size)); + std::memcpy(output_pool_->SlotData(slot), frame->const_data(), + size_t(data_size)); olive::ipc::FrameSlotMeta *meta = output_pool_->Meta(slot); meta->id = message.ticket_id; meta->time_num = frame->timestamp().numerator(); @@ -489,8 +557,9 @@ private: if (!output_pool_->Publish(slot)) { output_pool_->Release(slot); - return Write(ErrorMessage(QStringLiteral("failed to publish output frame slot"), - message.ticket_id)); + return Write(ErrorMessage( + QStringLiteral("failed to publish output frame slot"), + message.ticket_id)); } olive::ipc::FrameReadyMsg ready; ready.ticket_id = message.ticket_id; @@ -511,7 +580,7 @@ private: QHash color_processor_cache_; }; -} // namespace +} // namespace int main(int argc, char *argv[]) { @@ -520,8 +589,13 @@ int main(int argc, char *argv[]) InstallSurfaceFormat(); QGuiApplication app(argc, argv); + +#ifdef Q_OS_MACOS + HideWorkerDockIcon(); +#endif + QCoreApplication::setOrganizationName(QStringLiteral("oakvideoeditor.org")); - QCoreApplication::setApplicationName(QStringLiteral("olive-render-worker")); + QCoreApplication::setApplicationName(QStringLiteral("oak-render-worker")); QString backend = QStringLiteral("opengl"); const QStringList args = app.arguments(); @@ -574,7 +648,8 @@ int main(int argc, char *argv[]) QOpenGLContext *ctx = nullptr; if (backend == QStringLiteral("opengl")) { #ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND - if (auto *loaded_renderer = dynamic_cast(renderer)) { + if (auto *loaded_renderer = + dynamic_cast(renderer)) { ctx = loaded_renderer->OpenGLContext(); } else #endif @@ -613,7 +688,8 @@ int main(int argc, char *argv[]) if (!olive::ipc::ReadMessage(&buffer, &message, &ok)) { if (!ok) { olive::ipc::WriteMessage( - &out, ErrorMessage(QStringLiteral("malformed control message"))); + &out, ErrorMessage(QStringLiteral( + "malformed control message"))); out.flush(); continue; } diff --git a/app/render/worker/workermain_mac.mm b/app/render/worker/workermain_mac.mm new file mode 100644 index 000000000..31b24547c --- /dev/null +++ b/app/render/worker/workermain_mac.mm @@ -0,0 +1,26 @@ +/*** + + Oak - Non-Linear Video Editor + Copyright (C) 2026 Oak Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#include + +void HideWorkerDockIcon() +{ + [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited]; +} diff --git a/app/shaders/CMakeLists.txt b/app/shaders/CMakeLists.txt index e32b69af3..258def55d 100644 --- a/app/shaders/CMakeLists.txt +++ b/app/shaders/CMakeLists.txt @@ -16,14 +16,14 @@ file(GLOB_RECURSE SHADER_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.frag *.vert) set(QRC_BODY "") -foreach(SHADER_FILE ${SHADER_RESOURCES}) - string(APPEND QRC_BODY "${SHADER_FILE}\n") - configure_file(${SHADER_FILE} ${SHADER_FILE} COPYONLY) -endforeach() +foreach (SHADER_FILE ${SHADER_RESOURCES}) + string(APPEND QRC_BODY "${SHADER_FILE}\n") + configure_file(${SHADER_FILE} ${SHADER_FILE} COPYONLY) +endforeach () configure_file(shaders.qrc.in shaders.qrc @ONLY) set(OLIVE_RESOURCES - ${OLIVE_RESOURCES} - ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc - PARENT_SCOPE + ${OLIVE_RESOURCES} + ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc + PARENT_SCOPE ) diff --git a/app/task/CMakeLists.txt b/app/task/CMakeLists.txt index b8a98e6dd..aa8599fbb 100644 --- a/app/task/CMakeLists.txt +++ b/app/task/CMakeLists.txt @@ -23,9 +23,9 @@ add_subdirectory(proxy) add_subdirectory(render) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/task.h - task/taskmanager.h - task/taskmanager.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/task.h + task/taskmanager.h + task/taskmanager.cpp + PARENT_SCOPE ) diff --git a/app/task/conform/CMakeLists.txt b/app/task/conform/CMakeLists.txt index 6c25e92ce..35d14322d 100644 --- a/app/task/conform/CMakeLists.txt +++ b/app/task/conform/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/conform/conform.h - task/conform/conform.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/conform/conform.h + task/conform/conform.cpp + PARENT_SCOPE ) diff --git a/app/task/customcache/CMakeLists.txt b/app/task/customcache/CMakeLists.txt index c171db697..0c557c04b 100644 --- a/app/task/customcache/CMakeLists.txt +++ b/app/task/customcache/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/customcache/customcachetask.cpp - task/customcache/customcachetask.h - PARENT_SCOPE + ${OLIVE_SOURCES} + task/customcache/customcachetask.cpp + task/customcache/customcachetask.h + PARENT_SCOPE ) diff --git a/app/task/export/CMakeLists.txt b/app/task/export/CMakeLists.txt index 7a7fad1bc..9de1d33bb 100644 --- a/app/task/export/CMakeLists.txt +++ b/app/task/export/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/export/export.h - task/export/export.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/export/export.h + task/export/export.cpp + PARENT_SCOPE ) diff --git a/app/task/precache/CMakeLists.txt b/app/task/precache/CMakeLists.txt index 127475e36..6a63c2648 100644 --- a/app/task/precache/CMakeLists.txt +++ b/app/task/precache/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/precache/precachetask.h - task/precache/precachetask.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/precache/precachetask.h + task/precache/precachetask.cpp + PARENT_SCOPE ) diff --git a/app/task/project/CMakeLists.txt b/app/task/project/CMakeLists.txt index a9761a917..78a92d11b 100644 --- a/app/task/project/CMakeLists.txt +++ b/app/task/project/CMakeLists.txt @@ -14,16 +14,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -if(OpenTimelineIO_FOUND) - add_subdirectory(loadotio) - add_subdirectory(saveotio) -endif() +if (OpenTimelineIO_FOUND) + add_subdirectory(loadotio) + add_subdirectory(saveotio) +endif () add_subdirectory(import) add_subdirectory(load) add_subdirectory(save) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/task/project/import/CMakeLists.txt b/app/task/project/import/CMakeLists.txt index adc4161fc..5042d5b39 100644 --- a/app/task/project/import/CMakeLists.txt +++ b/app/task/project/import/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/project/import/import.h - task/project/import/import.cpp - task/project/import/importerrordialog.h - task/project/import/importerrordialog.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/project/import/import.h + task/project/import/import.cpp + task/project/import/importerrordialog.h + task/project/import/importerrordialog.cpp + PARENT_SCOPE ) diff --git a/app/task/project/import/importerrordialog.cpp b/app/task/project/import/importerrordialog.cpp index 1501d4ab8..315dd3950 100644 --- a/app/task/project/import/importerrordialog.cpp +++ b/app/task/project/import/importerrordialog.cpp @@ -37,9 +37,9 @@ ProjectImportErrorDialog::ProjectImportErrorDialog(const QStringList &filenames, setWindowTitle(tr("Import Error")); - layout->addWidget(new QLabel( - tr("The following files failed to import. Oak Video Editor likely does not " - "support their formats."))); + layout->addWidget(new QLabel(tr( + "The following files failed to import. Oak Video Editor likely does not " + "support their formats."))); QListWidget *list_widget = new QListWidget(); foreach (const QString &s, filenames) { diff --git a/app/task/project/load/CMakeLists.txt b/app/task/project/load/CMakeLists.txt index e2b50ceff..23e7b7af7 100644 --- a/app/task/project/load/CMakeLists.txt +++ b/app/task/project/load/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/project/load/load.h - task/project/load/load.cpp - task/project/load/loadbasetask.h - task/project/load/loadbasetask.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/project/load/load.h + task/project/load/load.cpp + task/project/load/loadbasetask.h + task/project/load/loadbasetask.cpp + PARENT_SCOPE ) diff --git a/app/task/project/loadotio/CMakeLists.txt b/app/task/project/loadotio/CMakeLists.txt index 77752a10e..ce97e1e96 100644 --- a/app/task/project/loadotio/CMakeLists.txt +++ b/app/task/project/loadotio/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/project/loadotio/loadotio.h - task/project/loadotio/loadotio.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/project/loadotio/loadotio.h + task/project/loadotio/loadotio.cpp + PARENT_SCOPE ) diff --git a/app/task/project/save/CMakeLists.txt b/app/task/project/save/CMakeLists.txt index 774f9349e..4c623d5bd 100644 --- a/app/task/project/save/CMakeLists.txt +++ b/app/task/project/save/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/project/save/save.h - task/project/save/save.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/project/save/save.h + task/project/save/save.cpp + PARENT_SCOPE ) diff --git a/app/task/project/saveotio/CMakeLists.txt b/app/task/project/saveotio/CMakeLists.txt index d48b94f43..fb4cb1f8d 100644 --- a/app/task/project/saveotio/CMakeLists.txt +++ b/app/task/project/saveotio/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/project/saveotio/saveotio.h - task/project/saveotio/saveotio.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/project/saveotio/saveotio.h + task/project/saveotio/saveotio.cpp + PARENT_SCOPE ) diff --git a/app/task/proxy/CMakeLists.txt b/app/task/proxy/CMakeLists.txt index 4aa1ea49b..3f51c6644 100644 --- a/app/task/proxy/CMakeLists.txt +++ b/app/task/proxy/CMakeLists.txt @@ -2,8 +2,8 @@ # Copyright (C) 2026 Oak Team set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/proxy/proxy.h - task/proxy/proxy.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/proxy/proxy.h + task/proxy/proxy.cpp + PARENT_SCOPE ) diff --git a/app/task/proxy/proxy.cpp b/app/task/proxy/proxy.cpp index 2bd2f0221..524149802 100644 --- a/app/task/proxy/proxy.cpp +++ b/app/task/proxy/proxy.cpp @@ -29,8 +29,7 @@ namespace olive { -ProxyTask::ProxyTask(const QString &source_filename, - int stream_index, +ProxyTask::ProxyTask(const QString &source_filename, int stream_index, const ProxyManager::ProxyParams ¶ms, const QString &output_filename) : source_filename_(source_filename) @@ -44,9 +43,11 @@ ProxyTask::ProxyTask(const QString &source_filename, bool ProxyTask::Run() { - const QString ffmpeg = QStandardPaths::findExecutable(QStringLiteral("ffmpeg")); + const QString ffmpeg = + QStandardPaths::findExecutable(QStringLiteral("ffmpeg")); if (ffmpeg.isEmpty()) { - SetError(tr("Failed to generate proxy: ffmpeg executable was not found")); + SetError( + tr("Failed to generate proxy: ffmpeg executable was not found")); qWarning() << "ProxyTask: ffmpeg executable not found"; return false; } @@ -55,36 +56,34 @@ bool ProxyTask::Run() if (!output_dir.exists() && !output_dir.mkpath(QStringLiteral("."))) { SetError(tr("Failed to create proxy output directory")); qWarning() << "ProxyTask: failed to create output directory" - << output_dir.absolutePath(); + << output_dir.absolutePath(); return false; } - qDebug() << "ProxyTask: starting ffmpeg proxy generation:" - << source_filename_ << "->" << output_filename_; + qDebug() + << "ProxyTask: starting ffmpeg proxy generation:" << source_filename_ + << "->" << output_filename_; QFile::remove(output_filename_); - const QString scale_filter = QStringLiteral( - "scale=w=%1:h=%2:force_original_aspect_ratio=decrease") - .arg(QString::number(params_.width), - QString::number(params_.height)); + const QString scale_filter = + QStringLiteral("scale=w=%1:h=%2:force_original_aspect_ratio=decrease") + .arg(QString::number(params_.width), + QString::number(params_.height)); const QString container_format = params_.extension.isEmpty() ? QStringLiteral("mp4") : params_.extension; QStringList args; - args << QStringLiteral("-y") - << QStringLiteral("-i") << source_filename_ + args << QStringLiteral("-y") << QStringLiteral("-i") << source_filename_ << QStringLiteral("-map") << QStringLiteral("0:%1").arg(stream_index_) - << QStringLiteral("-an") - << QStringLiteral("-vf") << scale_filter + << QStringLiteral("-an") << QStringLiteral("-vf") << scale_filter << QStringLiteral("-c:v") << QStringLiteral("libx264") << QStringLiteral("-preset") << params_.preset << QStringLiteral("-crf") << QString::number(params_.crf) << QStringLiteral("-pix_fmt") << QStringLiteral("yuv420p") << QStringLiteral("-movflags") << QStringLiteral("+faststart") - << QStringLiteral("-f") << container_format - << output_filename_; + << QStringLiteral("-f") << container_format << output_filename_; QProcess process; process.setProgram(ffmpeg); @@ -94,7 +93,8 @@ bool ProxyTask::Run() if (!process.waitForStarted()) { SetError(tr("Failed to start ffmpeg for proxy generation")); - qWarning() << "ProxyTask: failed to start ffmpeg" << process.errorString(); + qWarning() + << "ProxyTask: failed to start ffmpeg" << process.errorString(); return false; } @@ -108,19 +108,20 @@ bool ProxyTask::Run() } } - if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) { + if (process.exitStatus() != QProcess::NormalExit || + process.exitCode() != 0) { const QString output = QString::fromUtf8(process.readAll()).trimmed(); QFile::remove(output_filename_); SetError(tr("ffmpeg failed to generate proxy: %1").arg(output)); - qWarning() << "ProxyTask: ffmpeg failed with exit code" << process.exitCode() - << "output:" << output; + qWarning() << "ProxyTask: ffmpeg failed with exit code" + << process.exitCode() << "output:" << output; return false; } if (!QFileInfo::exists(output_filename_)) { SetError(tr("ffmpeg finished but proxy file was not created")); qWarning() << "ProxyTask: ffmpeg finished but output file missing" - << output_filename_; + << output_filename_; return false; } diff --git a/app/task/proxy/proxy.h b/app/task/proxy/proxy.h index c763b4a80..e96bb2cb9 100644 --- a/app/task/proxy/proxy.h +++ b/app/task/proxy/proxy.h @@ -28,8 +28,7 @@ namespace olive class ProxyTask : public Task { Q_OBJECT public: - ProxyTask(const QString &source_filename, - int stream_index, + ProxyTask(const QString &source_filename, int stream_index, const ProxyManager::ProxyParams ¶ms, const QString &output_filename); diff --git a/app/task/render/CMakeLists.txt b/app/task/render/CMakeLists.txt index e43581c6e..a430312c9 100644 --- a/app/task/render/CMakeLists.txt +++ b/app/task/render/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - task/render/render.h - task/render/render.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + task/render/render.h + task/render/render.cpp + PARENT_SCOPE ) diff --git a/app/task/render/render.cpp b/app/task/render/render.cpp index 593d1adc9..0642007d8 100644 --- a/app/task/render/render.cpp +++ b/app/task/render/render.cpp @@ -226,7 +226,7 @@ bool RenderTask::Render(ColorManager *manager, const TimeRangeList &video_range, StartTicket(&watcher_thread, manager, next_frame, mode, cache, force_size, force_matrix, force_format, force_channel_count, force_color_output, - force_color_transform); + force_color_transform); } } diff --git a/app/task/render/render.h b/app/task/render/render.h index f943a243b..344937f2a 100644 --- a/app/task/render/render.h +++ b/app/task/render/render.h @@ -125,7 +125,8 @@ private: const rational &time, RenderMode::Mode mode, FrameHashCache *cache, const QSize &force_size, const QMatrix4x4 &force_matrix, PixelFormat force_format, - int force_channel_count, ColorProcessorPtr force_color_output, + int force_channel_count, + ColorProcessorPtr force_color_output, const ColorTransform &force_color_transform); ViewerOutput *viewer_; diff --git a/app/timeline/CMakeLists.txt b/app/timeline/CMakeLists.txt index af2d1070f..1a3e0aacc 100644 --- a/app/timeline/CMakeLists.txt +++ b/app/timeline/CMakeLists.txt @@ -15,24 +15,24 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - timeline/timelinecommon.h - timeline/timelinecoordinate.h - timeline/timelinecoordinate.cpp - timeline/timelinemarker.h - timeline/timelinemarker.cpp - timeline/timelineundocommon.h - timeline/timelineundogeneral.cpp - timeline/timelineundogeneral.h - timeline/timelineundopointer.cpp - timeline/timelineundopointer.h - timeline/timelineundoripple.cpp - timeline/timelineundoripple.h - timeline/timelineundosplit.cpp - timeline/timelineundosplit.h - timeline/timelineundotrack.cpp - timeline/timelineundotrack.h - timeline/timelineworkarea.h - timeline/timelineworkarea.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + timeline/timelinecommon.h + timeline/timelinecoordinate.h + timeline/timelinecoordinate.cpp + timeline/timelinemarker.h + timeline/timelinemarker.cpp + timeline/timelineundocommon.h + timeline/timelineundogeneral.cpp + timeline/timelineundogeneral.h + timeline/timelineundopointer.cpp + timeline/timelineundopointer.h + timeline/timelineundoripple.cpp + timeline/timelineundoripple.h + timeline/timelineundosplit.cpp + timeline/timelineundosplit.h + timeline/timelineundotrack.cpp + timeline/timelineundotrack.h + timeline/timelineworkarea.h + timeline/timelineworkarea.cpp + PARENT_SCOPE ) diff --git a/app/tool/CMakeLists.txt b/app/tool/CMakeLists.txt index 7ae9ff94b..67629be12 100644 --- a/app/tool/CMakeLists.txt +++ b/app/tool/CMakeLists.txt @@ -15,7 +15,7 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - tool/tool.h - PARENT_SCOPE + ${OLIVE_SOURCES} + tool/tool.h + PARENT_SCOPE ) diff --git a/app/ts/CMakeLists.txt b/app/ts/CMakeLists.txt index 8c153a4f9..3c682c5f2 100644 --- a/app/ts/CMakeLists.txt +++ b/app/ts/CMakeLists.txt @@ -15,22 +15,22 @@ # along with this program. If not, see . set(OLIVE_TS_FILES - ts/ar_AR.ts - ts/bs_BA.ts - ts/cs_CZ.ts - ts/de_DE.ts - ts/en_US.ts - ts/es_ES.ts - ts/fr_FR.ts - ts/id_ID.ts - ts/it_IT.ts - ts/pt_BR.ts - ts/ru_RU.ts - ts/sr_RS.ts - ts/tr_TR.ts - ts/uk_UK.ts - ts/zh_CN.ts - ts/zh_TW.ts - ts/ja_JP.ts - PARENT_SCOPE + ts/ar_AR.ts + ts/bs_BA.ts + ts/cs_CZ.ts + ts/de_DE.ts + ts/en_US.ts + ts/es_ES.ts + ts/fr_FR.ts + ts/id_ID.ts + ts/it_IT.ts + ts/pt_BR.ts + ts/ru_RU.ts + ts/sr_RS.ts + ts/tr_TR.ts + ts/uk_UK.ts + ts/zh_CN.ts + ts/zh_TW.ts + ts/ja_JP.ts + PARENT_SCOPE ) diff --git a/app/ui/CMakeLists.txt b/app/ui/CMakeLists.txt index 0cf894b7f..e0f49c2c2 100644 --- a/app/ui/CMakeLists.txt +++ b/app/ui/CMakeLists.txt @@ -20,15 +20,15 @@ add_subdirectory(icons) add_subdirectory(style) set(OLIVE_RESOURCES - ${OLIVE_RESOURCES} - PARENT_SCOPE + ${OLIVE_RESOURCES} + PARENT_SCOPE ) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - ui/colorcoding.cpp - ui/colorcoding.h - ui/humanstrings.cpp - ui/humanstrings.h - PARENT_SCOPE + ${OLIVE_SOURCES} + ui/colorcoding.cpp + ui/colorcoding.h + ui/humanstrings.cpp + ui/humanstrings.h + PARENT_SCOPE ) diff --git a/app/ui/cursors/CMakeLists.txt b/app/ui/cursors/CMakeLists.txt index 2627d8432..37b884072 100644 --- a/app/ui/cursors/CMakeLists.txt +++ b/app/ui/cursors/CMakeLists.txt @@ -15,7 +15,7 @@ # along with this program. If not, see . set(OLIVE_RESOURCES - ${OLIVE_RESOURCES} - ui/cursors/cursors.qrc - PARENT_SCOPE + ${OLIVE_RESOURCES} + ui/cursors/cursors.qrc + PARENT_SCOPE ) diff --git a/app/ui/cursors/razor-a.svg b/app/ui/cursors/razor-a.svg index 17bb4935a..5ee953b3a 100644 --- a/app/ui/cursors/razor-a.svg +++ b/app/ui/cursors/razor-a.svg @@ -20,11047 +20,11047 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="5.svg" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive/cursors/4_16.png" + inkscape:export-xdpi="24" + inkscape:export-ydpi="24"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/cursors/razor-b.svg b/app/ui/cursors/razor-b.svg index db8a4cb64..95c853104 100644 --- a/app/ui/cursors/razor-b.svg +++ b/app/ui/cursors/razor-b.svg @@ -20,11045 +20,11045 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="5b.svg" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive/cursors/4_16.png" + inkscape:export-xdpi="24" + inkscape:export-ydpi="24"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/cursors/razor-c.svg b/app/ui/cursors/razor-c.svg index d557c023e..716f93608 100644 --- a/app/ui/cursors/razor-c.svg +++ b/app/ui/cursors/razor-c.svg @@ -20,11037 +20,11037 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="5c.svg" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive/cursors/4_16.png" + inkscape:export-xdpi="24" + inkscape:export-ydpi="24"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/cursors/ripple-left.svg b/app/ui/cursors/ripple-left.svg index 112e53323..11b54b256 100644 --- a/app/ui/cursors/ripple-left.svg +++ b/app/ui/cursors/ripple-left.svg @@ -20,11058 +20,11058 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="3_left.svg" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive/cursors/1_left_64.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/cursors/ripple-right.svg b/app/ui/cursors/ripple-right.svg index 9f5791cbd..47164d601 100644 --- a/app/ui/cursors/ripple-right.svg +++ b/app/ui/cursors/ripple-right.svg @@ -20,11059 +20,11059 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="3_right.svg" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive/cursors/3_left_16.png" + inkscape:export-xdpi="24" + inkscape:export-ydpi="24"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/cursors/rolling.svg b/app/ui/cursors/rolling.svg index c4a346c59..4b40e03a5 100644 --- a/app/ui/cursors/rolling.svg +++ b/app/ui/cursors/rolling.svg @@ -20,11073 +20,11073 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="2.svg" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive/cursors/2_16.png" + inkscape:export-xdpi="24" + inkscape:export-ydpi="24"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/cursors/slip.svg b/app/ui/cursors/slip.svg index bdefdcf07..8f1f1f3a5 100644 --- a/app/ui/cursors/slip.svg +++ b/app/ui/cursors/slip.svg @@ -20,11059 +20,11059 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="4.svg" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive/cursors/3_right_64.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/cursors/trim-left.svg b/app/ui/cursors/trim-left.svg index d1d4ce94b..f05b10b59 100644 --- a/app/ui/cursors/trim-left.svg +++ b/app/ui/cursors/trim-left.svg @@ -20,11061 +20,11061 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="1_left.svg" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive/cursors/1_right_16.png" + inkscape:export-xdpi="24" + inkscape:export-ydpi="24"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/cursors/trim-right.svg b/app/ui/cursors/trim-right.svg index d6ebb83b8..81f81c1fa 100644 --- a/app/ui/cursors/trim-right.svg +++ b/app/ui/cursors/trim-right.svg @@ -20,11061 +20,11061 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="1_right.svg" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive/cursors/2_64.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/graphics/CMakeLists.txt b/app/ui/graphics/CMakeLists.txt index e32d639f3..6d47c4f20 100644 --- a/app/ui/graphics/CMakeLists.txt +++ b/app/ui/graphics/CMakeLists.txt @@ -15,7 +15,7 @@ # along with this program. If not, see . set(OLIVE_RESOURCES - ${OLIVE_RESOURCES} - ui/graphics/graphics.qrc - PARENT_SCOPE + ${OLIVE_RESOURCES} + ui/graphics/graphics.qrc + PARENT_SCOPE ) diff --git a/app/ui/humanstrings.cpp b/app/ui/humanstrings.cpp index 6b8a19609..e8197acad 100644 --- a/app/ui/humanstrings.cpp +++ b/app/ui/humanstrings.cpp @@ -92,8 +92,8 @@ QString HumanStrings::FormatToString(const SampleFormat &f) break; } - return QCoreApplication::translate("AudioParams", "Unknown (0x%1)") - .arg(static_cast(f), 1, 16); + return QCoreApplication::translate("AudioParams", "Unknown (0x%1)") + .arg(static_cast(f), 1, 16); } } diff --git a/app/ui/icons/CMakeLists.txt b/app/ui/icons/CMakeLists.txt index 41fa1c3b9..b1cae78dc 100644 --- a/app/ui/icons/CMakeLists.txt +++ b/app/ui/icons/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - ui/icons/icons.h - ui/icons/icons.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + ui/icons/icons.h + ui/icons/icons.cpp + PARENT_SCOPE ) diff --git a/app/ui/style/CMakeLists.txt b/app/ui/style/CMakeLists.txt index 62f48f031..9ff51e67c 100644 --- a/app/ui/style/CMakeLists.txt +++ b/app/ui/style/CMakeLists.txt @@ -18,13 +18,13 @@ add_subdirectory(olive-dark) add_subdirectory(olive-light) set(OLIVE_RESOURCES - ${OLIVE_RESOURCES} - PARENT_SCOPE + ${OLIVE_RESOURCES} + PARENT_SCOPE ) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - ui/style/style.h - ui/style/style.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + ui/style/style.h + ui/style/style.cpp + PARENT_SCOPE ) diff --git a/app/ui/style/HOWTO.md b/app/ui/style/HOWTO.md index e92b62d95..cc6d0cfbb 100644 --- a/app/ui/style/HOWTO.md +++ b/app/ui/style/HOWTO.md @@ -5,9 +5,11 @@ Oak Video Editor supports customization of its interface through CSS (Qt CSS) an To create a style, you'll need to create a CSS file called `style.css` and SVG icons. Feel free to duplicate an existing theme for reference. -To save performance, Oak Video Editor doesn't actually use the SVGs directly and will need them to be converted to multiple-size +To save performance, Oak Video Editor doesn't actually use the SVGs directly and will need them to be converted to +multiple-size PNGs. You don't need to worry about this step though, `generate-style.sh` will do this for you automatically. You'll need to re-run this script any time you change an SVG to update the PNG. -For internal use, `generate-style.sh` will also create a QRC so the style can be compiled into Oak Video Editor. You'll need to +For internal use, `generate-style.sh` will also create a QRC so the style can be compiled into Oak Video Editor. You'll +need to manually add the QRC to `ui/style/CMakeLists.txt` though. diff --git a/app/ui/style/olive-dark/CMakeLists.txt b/app/ui/style/olive-dark/CMakeLists.txt index 3a34de164..3cdaf5e6f 100644 --- a/app/ui/style/olive-dark/CMakeLists.txt +++ b/app/ui/style/olive-dark/CMakeLists.txt @@ -19,14 +19,14 @@ set(QRC_BODY "") list(TRANSFORM STYLE_RESOURCES PREPEND "png/") list(APPEND STYLE_RESOURCES "palette.ini") list(APPEND STYLE_RESOURCES "style.css") -foreach(ICON_FILE ${STYLE_RESOURCES}) - string(APPEND QRC_BODY "${ICON_FILE}\n") - configure_file("${ICON_FILE}" "${ICON_FILE}" COPYONLY) -endforeach() +foreach (ICON_FILE ${STYLE_RESOURCES}) + string(APPEND QRC_BODY "${ICON_FILE}\n") + configure_file("${ICON_FILE}" "${ICON_FILE}" COPYONLY) +endforeach () configure_file(res.qrc.in res.qrc @ONLY) set(OLIVE_RESOURCES - ${OLIVE_RESOURCES} - ${CMAKE_CURRENT_BINARY_DIR}/res.qrc - PARENT_SCOPE + ${OLIVE_RESOURCES} + ${CMAKE_CURRENT_BINARY_DIR}/res.qrc + PARENT_SCOPE ) diff --git a/app/ui/style/olive-dark/palette.ini b/app/ui/style/olive-dark/palette.ini index 778c3d8fc..a2822a76e 100644 --- a/app/ui/style/olive-dark/palette.ini +++ b/app/ui/style/olive-dark/palette.ini @@ -1,18 +1,18 @@ [All] -AlternateBase=#353535 -Base=#191919 -BrightText=#FF0000 -Button=#353535 -ButtonText=#FFFFFF -Highlight=#2A82DA -HighlightedText=#FFFFFF -Link=#E0B040 -Text=#FFFFFF -ToolTipBase=#191919 -ToolTipText=#FFFFFF -Window=#353535 -WindowText=#FFFFFF +AlternateBase =#353535 +Base =#191919 +BrightText =#FF0000 +Button =#353535 +ButtonText =#FFFFFF +Highlight =#2A82DA +HighlightedText =#FFFFFF +Link =#E0B040 +Text =#FFFFFF +ToolTipBase =#191919 +ToolTipText =#FFFFFF +Window =#353535 +WindowText =#FFFFFF [Disabled] -ButtonText=#808080 -Text=#A0A0A0 +ButtonText =#808080 +Text =#A0A0A0 diff --git a/app/ui/style/olive-dark/style.css b/app/ui/style/olive-dark/style.css index 1965fc527..eb4319fd3 100644 --- a/app/ui/style/olive-dark/style.css +++ b/app/ui/style/olive-dark/style.css @@ -20,10 +20,37 @@ /* Hack that forces checked QPushButtons to use dark color */ QPushButton:checked { - background: #191919; + background: #191919; } /* Make tab bar a little less chunky */ QTabBar { - font-size: 9pt; + font-size: 9pt; +} + +/* Force KDDockWidgets / QTabBar tabs to use dark palette colors. + On macOS the native tab style can otherwise render light backgrounds + with light text, making inactive tabs unreadable. */ +QTabBar::tab { + background: #353535; + color: #FFFFFF; + border: 1px solid #2a2a2a; + padding: 4px 10px; +} + +QTabBar::tab:selected { + background: #2A82DA; + color: #FFFFFF; +} + +QTabBar::tab:hover { + background: #404040; +} + +QTabBar::tab:!selected { + margin-top: 2px; +} + +QTabBar::close-button { + image: none; } diff --git a/app/ui/style/olive-dark/svg/add-button.svg b/app/ui/style/olive-dark/svg/add-button.svg index 9d282cbc2..cc5985009 100644 --- a/app/ui/style/olive-dark/svg/add-button.svg +++ b/app/ui/style/olive-dark/svg/add-button.svg @@ -18,157 +18,157 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="add-button.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./add-button.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/add-effect.svg b/app/ui/style/olive-dark/svg/add-effect.svg index e2e683a19..4689e5796 100644 --- a/app/ui/style/olive-dark/svg/add-effect.svg +++ b/app/ui/style/olive-dark/svg/add-effect.svg @@ -18,174 +18,174 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - + sodipodi:docname="add-effect.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./add-effect.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/add-transition.svg b/app/ui/style/olive-dark/svg/add-transition.svg index f8e25f146..7e8e8f500 100644 --- a/app/ui/style/olive-dark/svg/add-transition.svg +++ b/app/ui/style/olive-dark/svg/add-transition.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="add-transition.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./add-transition.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-center.svg b/app/ui/style/olive-dark/svg/align-center.svg index aa8add8e1..29609df8d 100644 --- a/app/ui/style/olive-dark/svg/align-center.svg +++ b/app/ui/style/olive-dark/svg/align-center.svg @@ -18,172 +18,172 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-center.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-center.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-justify-all.svg b/app/ui/style/olive-dark/svg/align-justify-all.svg index 79449595f..50129215f 100644 --- a/app/ui/style/olive-dark/svg/align-justify-all.svg +++ b/app/ui/style/olive-dark/svg/align-justify-all.svg @@ -18,170 +18,170 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-justify-all.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-all.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-justify-center.svg b/app/ui/style/olive-dark/svg/align-justify-center.svg index edf269256..a92c6f211 100644 --- a/app/ui/style/olive-dark/svg/align-justify-center.svg +++ b/app/ui/style/olive-dark/svg/align-justify-center.svg @@ -18,171 +18,171 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-justify-center.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-center.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-justify-left.svg b/app/ui/style/olive-dark/svg/align-justify-left.svg index 32b92fb9d..f5dd71857 100644 --- a/app/ui/style/olive-dark/svg/align-justify-left.svg +++ b/app/ui/style/olive-dark/svg/align-justify-left.svg @@ -18,171 +18,171 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-justify-left.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-left.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-justify-right.svg b/app/ui/style/olive-dark/svg/align-justify-right.svg index a9462a530..27d8c0b11 100644 --- a/app/ui/style/olive-dark/svg/align-justify-right.svg +++ b/app/ui/style/olive-dark/svg/align-justify-right.svg @@ -18,171 +18,171 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-justify-right.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-right.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-left.svg b/app/ui/style/olive-dark/svg/align-left.svg index 2ab069535..622312fe8 100644 --- a/app/ui/style/olive-dark/svg/align-left.svg +++ b/app/ui/style/olive-dark/svg/align-left.svg @@ -18,172 +18,172 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-left.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-left.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-right.svg b/app/ui/style/olive-dark/svg/align-right.svg index 3ca1ed7fc..7673a4f3e 100644 --- a/app/ui/style/olive-dark/svg/align-right.svg +++ b/app/ui/style/olive-dark/svg/align-right.svg @@ -18,172 +18,172 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-right.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-right.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-v-bottom.svg b/app/ui/style/olive-dark/svg/align-v-bottom.svg index 8440a5633..a2a561b92 100644 --- a/app/ui/style/olive-dark/svg/align-v-bottom.svg +++ b/app/ui/style/olive-dark/svg/align-v-bottom.svg @@ -18,159 +18,159 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="align-v-bottom.svg" + inkscape:version="1.3-dev (1ca8b206, 2022-07-23)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-all.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-v-middle.svg b/app/ui/style/olive-dark/svg/align-v-middle.svg index 0e57ef75d..24f872a53 100644 --- a/app/ui/style/olive-dark/svg/align-v-middle.svg +++ b/app/ui/style/olive-dark/svg/align-v-middle.svg @@ -18,159 +18,159 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="align-v-middle.svg" + inkscape:version="1.3-dev (1ca8b206, 2022-07-23)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-all.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/align-v-top.svg b/app/ui/style/olive-dark/svg/align-v-top.svg index 4d282e953..daec41cf2 100644 --- a/app/ui/style/olive-dark/svg/align-v-top.svg +++ b/app/ui/style/olive-dark/svg/align-v-top.svg @@ -18,159 +18,159 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="align-v-top.svg" + inkscape:version="1.3-dev (1ca8b206, 2022-07-23)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-all.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/arrow.svg b/app/ui/style/olive-dark/svg/arrow.svg index eef4295a1..91594fc07 100644 --- a/app/ui/style/olive-dark/svg/arrow.svg +++ b/app/ui/style/olive-dark/svg/arrow.svg @@ -18,162 +18,162 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="arrow2.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./arrow.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/audiosource.svg b/app/ui/style/olive-dark/svg/audiosource.svg index 3a6b0b19b..b35bda9fa 100644 --- a/app/ui/style/olive-dark/svg/audiosource.svg +++ b/app/ui/style/olive-dark/svg/audiosource.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="audiosource.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./audiosource.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/beam.svg b/app/ui/style/olive-dark/svg/beam.svg index a698ff405..fefac17cb 100644 --- a/app/ui/style/olive-dark/svg/beam.svg +++ b/app/ui/style/olive-dark/svg/beam.svg @@ -18,873 +18,873 @@ --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="beam2.svg" + inkscape:version="1.1 (c4e8f9e, 2021-05-24)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./beam.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/box.svg b/app/ui/style/olive-dark/svg/box.svg index 599644485..5a377415d 100644 --- a/app/ui/style/olive-dark/svg/box.svg +++ b/app/ui/style/olive-dark/svg/box.svg @@ -18,194 +18,194 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - - - + sodipodi:docname="box.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./box.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/clock.svg b/app/ui/style/olive-dark/svg/clock.svg index bff2ec571..5bffdaf79 100644 --- a/app/ui/style/olive-dark/svg/clock.svg +++ b/app/ui/style/olive-dark/svg/clock.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="clock.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./clock.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/color-picker.svg b/app/ui/style/olive-dark/svg/color-picker.svg index 5edc7af8b..00081b9c7 100644 --- a/app/ui/style/olive-dark/svg/color-picker.svg +++ b/app/ui/style/olive-dark/svg/color-picker.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="color-picker.svg" + inkscape:version="1.3-dev (1ca8b206, 2022-07-23)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./paste.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/copy.svg b/app/ui/style/olive-dark/svg/copy.svg index 4e84a7782..61a18a622 100644 --- a/app/ui/style/olive-dark/svg/copy.svg +++ b/app/ui/style/olive-dark/svg/copy.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="copy.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./copy.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/diamond.svg b/app/ui/style/olive-dark/svg/diamond.svg index 82ecb579d..1272b8b6a 100644 --- a/app/ui/style/olive-dark/svg/diamond.svg +++ b/app/ui/style/olive-dark/svg/diamond.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="diamond.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./diamond.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/dirup.svg b/app/ui/style/olive-dark/svg/dirup.svg index 4d883515e..0d0c4f328 100644 --- a/app/ui/style/olive-dark/svg/dirup.svg +++ b/app/ui/style/olive-dark/svg/dirup.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="dirup.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./dirup.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/error.svg b/app/ui/style/olive-dark/svg/error.svg index 0c7ef277c..b66f9d0ff 100644 --- a/app/ui/style/olive-dark/svg/error.svg +++ b/app/ui/style/olive-dark/svg/error.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="error.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./error.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/export.svg b/app/ui/style/olive-dark/svg/export.svg index 938585f2d..326e74ee4 100644 --- a/app/ui/style/olive-dark/svg/export.svg +++ b/app/ui/style/olive-dark/svg/export.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/eye-closed.svg b/app/ui/style/olive-dark/svg/eye-closed.svg index ce8633c65..9cc35d71c 100644 --- a/app/ui/style/olive-dark/svg/eye-closed.svg +++ b/app/ui/style/olive-dark/svg/eye-closed.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/eye-opened.svg b/app/ui/style/olive-dark/svg/eye-opened.svg index 389a1f7f4..ba945f8e9 100644 --- a/app/ui/style/olive-dark/svg/eye-opened.svg +++ b/app/ui/style/olive-dark/svg/eye-opened.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/ff.svg b/app/ui/style/olive-dark/svg/ff.svg index 426c93fbd..f3bb714a5 100644 --- a/app/ui/style/olive-dark/svg/ff.svg +++ b/app/ui/style/olive-dark/svg/ff.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="ff.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./ff.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/filter.svg b/app/ui/style/olive-dark/svg/filter.svg index 255afc460..eeac50d8b 100644 --- a/app/ui/style/olive-dark/svg/filter.svg +++ b/app/ui/style/olive-dark/svg/filter.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="filter.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./filter.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/folder.svg b/app/ui/style/olive-dark/svg/folder.svg index c72d14d86..363d2e895 100644 --- a/app/ui/style/olive-dark/svg/folder.svg +++ b/app/ui/style/olive-dark/svg/folder.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="folder.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./folder.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/hand.svg b/app/ui/style/olive-dark/svg/hand.svg index 42d6a5663..dc598d809 100644 --- a/app/ui/style/olive-dark/svg/hand.svg +++ b/app/ui/style/olive-dark/svg/hand.svg @@ -18,157 +18,157 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="hand.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./hand.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/iconview.svg b/app/ui/style/olive-dark/svg/iconview.svg index 8e23610dd..3ebda87a5 100644 --- a/app/ui/style/olive-dark/svg/iconview.svg +++ b/app/ui/style/olive-dark/svg/iconview.svg @@ -18,181 +18,181 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="iconview.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./iconview.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/imagesource.svg b/app/ui/style/olive-dark/svg/imagesource.svg index dd626cbb1..b9d8609ac 100644 --- a/app/ui/style/olive-dark/svg/imagesource.svg +++ b/app/ui/style/olive-dark/svg/imagesource.svg @@ -18,164 +18,164 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="imagesource.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./imagesource.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/import.svg b/app/ui/style/olive-dark/svg/import.svg index 2dd4c5097..2dcaf836d 100644 --- a/app/ui/style/olive-dark/svg/import.svg +++ b/app/ui/style/olive-dark/svg/import.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="import.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./import.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/listview.svg b/app/ui/style/olive-dark/svg/listview.svg index 112f5c0c6..d48a5337a 100644 --- a/app/ui/style/olive-dark/svg/listview.svg +++ b/app/ui/style/olive-dark/svg/listview.svg @@ -18,163 +18,163 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="listview.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./listview.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/lock-closed.svg b/app/ui/style/olive-dark/svg/lock-closed.svg index 9728cdbac..71f82b669 100644 --- a/app/ui/style/olive-dark/svg/lock-closed.svg +++ b/app/ui/style/olive-dark/svg/lock-closed.svg @@ -18,161 +18,161 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/lock-opened.svg b/app/ui/style/olive-dark/svg/lock-opened.svg index b0a8c73c3..cd4fd52f0 100644 --- a/app/ui/style/olive-dark/svg/lock-opened.svg +++ b/app/ui/style/olive-dark/svg/lock-opened.svg @@ -18,161 +18,161 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/magnet.svg b/app/ui/style/olive-dark/svg/magnet.svg index bf4097125..a9ff7792d 100644 --- a/app/ui/style/olive-dark/svg/magnet.svg +++ b/app/ui/style/olive-dark/svg/magnet.svg @@ -18,196 +18,196 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - + sodipodi:docname="magnet.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./magnet.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/map.svg b/app/ui/style/olive-dark/svg/map.svg index a857e302a..8a194fd6e 100644 --- a/app/ui/style/olive-dark/svg/map.svg +++ b/app/ui/style/olive-dark/svg/map.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="map5.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive_pablo/icons/iconview.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/minus.svg b/app/ui/style/olive-dark/svg/minus.svg index cf9413c77..c0f05635e 100644 --- a/app/ui/style/olive-dark/svg/minus.svg +++ b/app/ui/style/olive-dark/svg/minus.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="minus.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./minus.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/new.svg b/app/ui/style/olive-dark/svg/new.svg index 1977da1a9..44149968d 100644 --- a/app/ui/style/olive-dark/svg/new.svg +++ b/app/ui/style/olive-dark/svg/new.svg @@ -18,164 +18,164 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="new.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./new.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/next.svg b/app/ui/style/olive-dark/svg/next.svg index cd751974a..dbac1fcb8 100644 --- a/app/ui/style/olive-dark/svg/next.svg +++ b/app/ui/style/olive-dark/svg/next.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="next.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./next.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/nodes_btt.svg b/app/ui/style/olive-dark/svg/nodes_btt.svg index c29d7083c..08cf1c144 100644 --- a/app/ui/style/olive-dark/svg/nodes_btt.svg +++ b/app/ui/style/olive-dark/svg/nodes_btt.svg @@ -18,178 +18,178 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="nodes_btt.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./nodes_btt.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/nodes_ltr.svg b/app/ui/style/olive-dark/svg/nodes_ltr.svg index f190043b6..7f2e812a5 100644 --- a/app/ui/style/olive-dark/svg/nodes_ltr.svg +++ b/app/ui/style/olive-dark/svg/nodes_ltr.svg @@ -18,181 +18,181 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="nodes_ltr.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./nodes_ltr.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - - - - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + + + + - diff --git a/app/ui/style/olive-dark/svg/nodes_rtl.svg b/app/ui/style/olive-dark/svg/nodes_rtl.svg index 681292fb3..3d74654b3 100644 --- a/app/ui/style/olive-dark/svg/nodes_rtl.svg +++ b/app/ui/style/olive-dark/svg/nodes_rtl.svg @@ -18,182 +18,182 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="nodes_rtl.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./nodes_rtl.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - - - - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + + + + - diff --git a/app/ui/style/olive-dark/svg/nodes_ttb.svg b/app/ui/style/olive-dark/svg/nodes_ttb.svg index 40e2d8ac8..c5a669222 100644 --- a/app/ui/style/olive-dark/svg/nodes_ttb.svg +++ b/app/ui/style/olive-dark/svg/nodes_ttb.svg @@ -18,182 +18,182 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="nodes_ttb.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./nodes_ttb.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - - - - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + + + + - diff --git a/app/ui/style/olive-dark/svg/open.svg b/app/ui/style/olive-dark/svg/open.svg index 6c4728533..82a71919f 100644 --- a/app/ui/style/olive-dark/svg/open.svg +++ b/app/ui/style/olive-dark/svg/open.svg @@ -18,172 +18,172 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="open.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./open.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/paste.svg b/app/ui/style/olive-dark/svg/paste.svg index 64d5c65d9..1a1f72efd 100644 --- a/app/ui/style/olive-dark/svg/paste.svg +++ b/app/ui/style/olive-dark/svg/paste.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="paste.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./paste.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/pause.svg b/app/ui/style/olive-dark/svg/pause.svg index ae3e7df68..ef8e93f34 100644 --- a/app/ui/style/olive-dark/svg/pause.svg +++ b/app/ui/style/olive-dark/svg/pause.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="pause.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./pause.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/play.svg b/app/ui/style/olive-dark/svg/play.svg index df89c1130..484ad47db 100644 --- a/app/ui/style/olive-dark/svg/play.svg +++ b/app/ui/style/olive-dark/svg/play.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="play.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./play.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/plus.svg b/app/ui/style/olive-dark/svg/plus.svg index 9f9d05c47..597cfe519 100644 --- a/app/ui/style/olive-dark/svg/plus.svg +++ b/app/ui/style/olive-dark/svg/plus.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="plus.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./plus.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/prev.svg b/app/ui/style/olive-dark/svg/prev.svg index d98e68601..977ae9cf1 100644 --- a/app/ui/style/olive-dark/svg/prev.svg +++ b/app/ui/style/olive-dark/svg/prev.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="prev.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./prev.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/razor.svg b/app/ui/style/olive-dark/svg/razor.svg index 740d68129..76d45d2ea 100644 --- a/app/ui/style/olive-dark/svg/razor.svg +++ b/app/ui/style/olive-dark/svg/razor.svg @@ -18,155 +18,155 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="razor.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./razor.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/record.svg b/app/ui/style/olive-dark/svg/record.svg index 6d3663a41..1563973ea 100644 --- a/app/ui/style/olive-dark/svg/record.svg +++ b/app/ui/style/olive-dark/svg/record.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="record.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./record.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/redo.svg b/app/ui/style/olive-dark/svg/redo.svg index 75b9e88ed..c2e75a2c9 100644 --- a/app/ui/style/olive-dark/svg/redo.svg +++ b/app/ui/style/olive-dark/svg/redo.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="redo.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./redo.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/rew.svg b/app/ui/style/olive-dark/svg/rew.svg index 996cc0eea..e08fa2fd0 100644 --- a/app/ui/style/olive-dark/svg/rew.svg +++ b/app/ui/style/olive-dark/svg/rew.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="rew.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./rew.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/ripple.svg b/app/ui/style/olive-dark/svg/ripple.svg index 5673cc36f..4c7a42827 100644 --- a/app/ui/style/olive-dark/svg/ripple.svg +++ b/app/ui/style/olive-dark/svg/ripple.svg @@ -18,164 +18,164 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="ripple.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./ripple.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/rolling.svg b/app/ui/style/olive-dark/svg/rolling.svg index 0c9a60781..73e2f2600 100644 --- a/app/ui/style/olive-dark/svg/rolling.svg +++ b/app/ui/style/olive-dark/svg/rolling.svg @@ -18,175 +18,175 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - + sodipodi:docname="rolling.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./rolling.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/save.svg b/app/ui/style/olive-dark/svg/save.svg index 997b5711a..4aae58266 100644 --- a/app/ui/style/olive-dark/svg/save.svg +++ b/app/ui/style/olive-dark/svg/save.svg @@ -18,167 +18,167 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="save.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./save.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/sequence.svg b/app/ui/style/olive-dark/svg/sequence.svg index db8f34017..11df956eb 100644 --- a/app/ui/style/olive-dark/svg/sequence.svg +++ b/app/ui/style/olive-dark/svg/sequence.svg @@ -18,167 +18,167 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="sequence.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./sequence.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/slide.svg b/app/ui/style/olive-dark/svg/slide.svg index b2cf8c598..1f4c2f154 100644 --- a/app/ui/style/olive-dark/svg/slide.svg +++ b/app/ui/style/olive-dark/svg/slide.svg @@ -18,171 +18,171 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="slide.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./slide.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/slip.svg b/app/ui/style/olive-dark/svg/slip.svg index aac20ad56..a689f98bc 100644 --- a/app/ui/style/olive-dark/svg/slip.svg +++ b/app/ui/style/olive-dark/svg/slip.svg @@ -18,168 +18,168 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="slip.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./slip.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/smooth_edges.svg b/app/ui/style/olive-dark/svg/smooth_edges.svg index 5a1b166cf..be4af4a6e 100644 --- a/app/ui/style/olive-dark/svg/smooth_edges.svg +++ b/app/ui/style/olive-dark/svg/smooth_edges.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="smooth_edges.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./smooth_edges.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/subtitles.svg b/app/ui/style/olive-dark/svg/subtitles.svg index b3f012cf8..156085726 100644 --- a/app/ui/style/olive-dark/svg/subtitles.svg +++ b/app/ui/style/olive-dark/svg/subtitles.svg @@ -18,316 +18,316 @@ --> - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="subtitles.svg" + inkscape:version="1.3-dev (4e3da4f, 2022-05-14)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-bold.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/text-bold.svg b/app/ui/style/olive-dark/svg/text-bold.svg index 09e53afc6..2dda5ad99 100644 --- a/app/ui/style/olive-dark/svg/text-bold.svg +++ b/app/ui/style/olive-dark/svg/text-bold.svg @@ -18,155 +18,155 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="text-bold.svg" + inkscape:version="1.1 (c4e8f9e, 2021-05-24)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-bold.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + - diff --git a/app/ui/style/olive-dark/svg/text-edit.svg b/app/ui/style/olive-dark/svg/text-edit.svg index e8c12c504..7755dfe33 100644 --- a/app/ui/style/olive-dark/svg/text-edit.svg +++ b/app/ui/style/olive-dark/svg/text-edit.svg @@ -18,277 +18,277 @@ --> - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="text-edit.svg" + inkscape:version="1.3-dev (e659668, 2022-05-03)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-bold.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/text-italic.svg b/app/ui/style/olive-dark/svg/text-italic.svg index ecc36040c..2e6016958 100644 --- a/app/ui/style/olive-dark/svg/text-italic.svg +++ b/app/ui/style/olive-dark/svg/text-italic.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="text-italic.svg" + inkscape:version="1.1 (c4e8f9e, 2021-05-24)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-italic.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/text-small-caps.svg b/app/ui/style/olive-dark/svg/text-small-caps.svg index 73f75d5a8..2b92d0d25 100644 --- a/app/ui/style/olive-dark/svg/text-small-caps.svg +++ b/app/ui/style/olive-dark/svg/text-small-caps.svg @@ -18,177 +18,177 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="text-small-caps.svg" + inkscape:version="1.3-dev (50b0636d, 2022-04-18)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-bold.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/text-strikethrough.svg b/app/ui/style/olive-dark/svg/text-strikethrough.svg index ec81221a9..f3ab328f1 100644 --- a/app/ui/style/olive-dark/svg/text-strikethrough.svg +++ b/app/ui/style/olive-dark/svg/text-strikethrough.svg @@ -18,186 +18,186 @@ --> - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="text-strikethrough.svg" + inkscape:version="1.2-alpha1 (f32a55a0, 2022-04-04)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-underline.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/text-underline.svg b/app/ui/style/olive-dark/svg/text-underline.svg index 971d74bc2..6ef454831 100644 --- a/app/ui/style/olive-dark/svg/text-underline.svg +++ b/app/ui/style/olive-dark/svg/text-underline.svg @@ -18,184 +18,184 @@ --> - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="text-underline.svg" + inkscape:version="1.2-alpha1 (f32a55a0, 2022-04-04)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-underline.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + + - - diff --git a/app/ui/style/olive-dark/svg/track-tool.svg b/app/ui/style/olive-dark/svg/track-tool.svg index 01474f718..f58394589 100644 --- a/app/ui/style/olive-dark/svg/track-tool.svg +++ b/app/ui/style/olive-dark/svg/track-tool.svg @@ -18,209 +18,209 @@ --> - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="track-tool.svg" + inkscape:version="1.3-dev (50b0636d, 2022-04-18)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-underline.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/transition-tool.svg b/app/ui/style/olive-dark/svg/transition-tool.svg index 3290a8bc8..14812b58d 100644 --- a/app/ui/style/olive-dark/svg/transition-tool.svg +++ b/app/ui/style/olive-dark/svg/transition-tool.svg @@ -18,163 +18,163 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="transition-tool.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./transition-tool.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/treeview.svg b/app/ui/style/olive-dark/svg/treeview.svg index 5d5fb4113..0c0edd83b 100644 --- a/app/ui/style/olive-dark/svg/treeview.svg +++ b/app/ui/style/olive-dark/svg/treeview.svg @@ -18,170 +18,170 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="treeview.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./treeview.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/tri-down.svg b/app/ui/style/olive-dark/svg/tri-down.svg index afb8bdda0..38dfde6af 100644 --- a/app/ui/style/olive-dark/svg/tri-down.svg +++ b/app/ui/style/olive-dark/svg/tri-down.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="tri-down.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./tri-down.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/tri-left.svg b/app/ui/style/olive-dark/svg/tri-left.svg index e880a11c0..57f3d73fb 100644 --- a/app/ui/style/olive-dark/svg/tri-left.svg +++ b/app/ui/style/olive-dark/svg/tri-left.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="tri-left.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./tri-left.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/tri-right.svg b/app/ui/style/olive-dark/svg/tri-right.svg index 0f93cbced..f4444eb8a 100644 --- a/app/ui/style/olive-dark/svg/tri-right.svg +++ b/app/ui/style/olive-dark/svg/tri-right.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="tri-right.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./tri-right.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/tri-up.svg b/app/ui/style/olive-dark/svg/tri-up.svg index 29d098230..b0a239922 100644 --- a/app/ui/style/olive-dark/svg/tri-up.svg +++ b/app/ui/style/olive-dark/svg/tri-up.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="tri-up.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./tri-up.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/undo.svg b/app/ui/style/olive-dark/svg/undo.svg index 0b8232af5..2d62cab49 100644 --- a/app/ui/style/olive-dark/svg/undo.svg +++ b/app/ui/style/olive-dark/svg/undo.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="undo.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./undo.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/videosource.svg b/app/ui/style/olive-dark/svg/videosource.svg index 141f1cdb5..5eedf2521 100644 --- a/app/ui/style/olive-dark/svg/videosource.svg +++ b/app/ui/style/olive-dark/svg/videosource.svg @@ -18,153 +18,153 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="videosource.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./videosource.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/zoomin.svg b/app/ui/style/olive-dark/svg/zoomin.svg index b2a14b2af..2515e819f 100644 --- a/app/ui/style/olive-dark/svg/zoomin.svg +++ b/app/ui/style/olive-dark/svg/zoomin.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="zoomin.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./zoomin.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-dark/svg/zoomout.svg b/app/ui/style/olive-dark/svg/zoomout.svg index 4c955e23f..e977ac262 100644 --- a/app/ui/style/olive-dark/svg/zoomout.svg +++ b/app/ui/style/olive-dark/svg/zoomout.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="zoomout.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./zoomout.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/CMakeLists.txt b/app/ui/style/olive-light/CMakeLists.txt index 3a34de164..3cdaf5e6f 100644 --- a/app/ui/style/olive-light/CMakeLists.txt +++ b/app/ui/style/olive-light/CMakeLists.txt @@ -19,14 +19,14 @@ set(QRC_BODY "") list(TRANSFORM STYLE_RESOURCES PREPEND "png/") list(APPEND STYLE_RESOURCES "palette.ini") list(APPEND STYLE_RESOURCES "style.css") -foreach(ICON_FILE ${STYLE_RESOURCES}) - string(APPEND QRC_BODY "${ICON_FILE}\n") - configure_file("${ICON_FILE}" "${ICON_FILE}" COPYONLY) -endforeach() +foreach (ICON_FILE ${STYLE_RESOURCES}) + string(APPEND QRC_BODY "${ICON_FILE}\n") + configure_file("${ICON_FILE}" "${ICON_FILE}" COPYONLY) +endforeach () configure_file(res.qrc.in res.qrc @ONLY) set(OLIVE_RESOURCES - ${OLIVE_RESOURCES} - ${CMAKE_CURRENT_BINARY_DIR}/res.qrc - PARENT_SCOPE + ${OLIVE_RESOURCES} + ${CMAKE_CURRENT_BINARY_DIR}/res.qrc + PARENT_SCOPE ) diff --git a/app/ui/style/olive-light/palette.ini b/app/ui/style/olive-light/palette.ini index 367ee06b3..9fa85bd46 100644 --- a/app/ui/style/olive-light/palette.ini +++ b/app/ui/style/olive-light/palette.ini @@ -1,18 +1,18 @@ [All] -AlternateBase=#D0D0D0 -Base=#F0F0F0 -BrightText=#FF0000 -Button=#D0D0D0 -ButtonText=#000000 -Highlight=#2A82DA -HighlightedText=#FFFFFF -Link=#2A82DA -Text=#000000 -ToolTipBase=#FFFFFF -ToolTipText=#000000 -Window=#D0D0D0 -WindowText=#000000 +AlternateBase =#D0D0D0 +Base =#F0F0F0 +BrightText =#FF0000 +Button =#D0D0D0 +ButtonText =#000000 +Highlight =#2A82DA +HighlightedText =#FFFFFF +Link =#2A82DA +Text =#000000 +ToolTipBase =#FFFFFF +ToolTipText =#000000 +Window =#D0D0D0 +WindowText =#000000 [Disabled] -ButtonText=#808080 -Text=#808080 +ButtonText =#808080 +Text =#808080 diff --git a/app/ui/style/olive-light/style.css b/app/ui/style/olive-light/style.css index ec767f01b..e6579595a 100644 --- a/app/ui/style/olive-light/style.css +++ b/app/ui/style/olive-light/style.css @@ -20,5 +20,5 @@ /* Make tab bar a little less chunky */ QTabBar { - font-size: 9pt; + font-size: 9pt; } diff --git a/app/ui/style/olive-light/svg/add-button.svg b/app/ui/style/olive-light/svg/add-button.svg index 896179044..c9cd96a83 100644 --- a/app/ui/style/olive-light/svg/add-button.svg +++ b/app/ui/style/olive-light/svg/add-button.svg @@ -18,157 +18,157 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="add-button.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./add-button.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/add-effect.svg b/app/ui/style/olive-light/svg/add-effect.svg index edb44a2d5..6f09aa930 100644 --- a/app/ui/style/olive-light/svg/add-effect.svg +++ b/app/ui/style/olive-light/svg/add-effect.svg @@ -18,174 +18,174 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - + sodipodi:docname="add-effect.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./add-effect.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/add-transition.svg b/app/ui/style/olive-light/svg/add-transition.svg index f87ae2415..229a5f33b 100644 --- a/app/ui/style/olive-light/svg/add-transition.svg +++ b/app/ui/style/olive-light/svg/add-transition.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="add-transition.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./add-transition.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-center.svg b/app/ui/style/olive-light/svg/align-center.svg index a16bd4310..8e6ed49b8 100644 --- a/app/ui/style/olive-light/svg/align-center.svg +++ b/app/ui/style/olive-light/svg/align-center.svg @@ -18,172 +18,172 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-center.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-center.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-justify-all.svg b/app/ui/style/olive-light/svg/align-justify-all.svg index 27236e3b0..ff27d1f6f 100644 --- a/app/ui/style/olive-light/svg/align-justify-all.svg +++ b/app/ui/style/olive-light/svg/align-justify-all.svg @@ -18,170 +18,170 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-justify-all.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-all.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-justify-center.svg b/app/ui/style/olive-light/svg/align-justify-center.svg index 2fa19dfca..170619e0a 100644 --- a/app/ui/style/olive-light/svg/align-justify-center.svg +++ b/app/ui/style/olive-light/svg/align-justify-center.svg @@ -18,171 +18,171 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-justify-center.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-center.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-justify-left.svg b/app/ui/style/olive-light/svg/align-justify-left.svg index 3f544b073..b7fe9b3f2 100644 --- a/app/ui/style/olive-light/svg/align-justify-left.svg +++ b/app/ui/style/olive-light/svg/align-justify-left.svg @@ -18,171 +18,171 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-justify-left.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-left.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-justify-right.svg b/app/ui/style/olive-light/svg/align-justify-right.svg index d56e205c1..107f25b16 100644 --- a/app/ui/style/olive-light/svg/align-justify-right.svg +++ b/app/ui/style/olive-light/svg/align-justify-right.svg @@ -18,171 +18,171 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-justify-right.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-right.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-left.svg b/app/ui/style/olive-light/svg/align-left.svg index c96028488..cbfd32534 100644 --- a/app/ui/style/olive-light/svg/align-left.svg +++ b/app/ui/style/olive-light/svg/align-left.svg @@ -18,172 +18,172 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-left.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-left.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-right.svg b/app/ui/style/olive-light/svg/align-right.svg index c1ce64a82..f1ff37829 100644 --- a/app/ui/style/olive-light/svg/align-right.svg +++ b/app/ui/style/olive-light/svg/align-right.svg @@ -18,172 +18,172 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="align-right.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-right.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-v-bottom.svg b/app/ui/style/olive-light/svg/align-v-bottom.svg index b4bddcdba..fe43144b2 100644 --- a/app/ui/style/olive-light/svg/align-v-bottom.svg +++ b/app/ui/style/olive-light/svg/align-v-bottom.svg @@ -18,159 +18,159 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="align-v-bottom.svg" + inkscape:version="1.3-dev (1ca8b206, 2022-07-23)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-all.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-v-middle.svg b/app/ui/style/olive-light/svg/align-v-middle.svg index d71f1e0ba..68c5fd359 100644 --- a/app/ui/style/olive-light/svg/align-v-middle.svg +++ b/app/ui/style/olive-light/svg/align-v-middle.svg @@ -18,159 +18,159 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="align-v-middle.svg" + inkscape:version="1.3-dev (1ca8b206, 2022-07-23)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-all.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/align-v-top.svg b/app/ui/style/olive-light/svg/align-v-top.svg index 97e1274be..59c462ed9 100644 --- a/app/ui/style/olive-light/svg/align-v-top.svg +++ b/app/ui/style/olive-light/svg/align-v-top.svg @@ -18,159 +18,159 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="align-v-top.svg" + inkscape:version="1.3-dev (1ca8b206, 2022-07-23)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./align-justify-all.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/arrow.svg b/app/ui/style/olive-light/svg/arrow.svg index f1b26cb72..4d849f914 100644 --- a/app/ui/style/olive-light/svg/arrow.svg +++ b/app/ui/style/olive-light/svg/arrow.svg @@ -18,162 +18,162 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="arrow2.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./arrow.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/audiosource.svg b/app/ui/style/olive-light/svg/audiosource.svg index 27d45a5d4..776bb844f 100644 --- a/app/ui/style/olive-light/svg/audiosource.svg +++ b/app/ui/style/olive-light/svg/audiosource.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="audiosource.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./audiosource.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/beam.svg b/app/ui/style/olive-light/svg/beam.svg index 4fe6c0a0c..4e5fe8f86 100644 --- a/app/ui/style/olive-light/svg/beam.svg +++ b/app/ui/style/olive-light/svg/beam.svg @@ -18,873 +18,873 @@ --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="beam2.svg" + inkscape:version="1.1 (c4e8f9e, 2021-05-24)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./beam.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/box.svg b/app/ui/style/olive-light/svg/box.svg index a03aebdd8..f3a369258 100644 --- a/app/ui/style/olive-light/svg/box.svg +++ b/app/ui/style/olive-light/svg/box.svg @@ -18,194 +18,194 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - - - + sodipodi:docname="box.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./box.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/clock.svg b/app/ui/style/olive-light/svg/clock.svg index 90f22c99b..3b380a4e8 100644 --- a/app/ui/style/olive-light/svg/clock.svg +++ b/app/ui/style/olive-light/svg/clock.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="clock.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./clock.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/color-picker.svg b/app/ui/style/olive-light/svg/color-picker.svg index 6f9adb082..8d4504cf2 100644 --- a/app/ui/style/olive-light/svg/color-picker.svg +++ b/app/ui/style/olive-light/svg/color-picker.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="color-picker.svg" + inkscape:version="1.3-dev (1ca8b206, 2022-07-23)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./paste.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/copy.svg b/app/ui/style/olive-light/svg/copy.svg index 908770e3c..b6934ca16 100644 --- a/app/ui/style/olive-light/svg/copy.svg +++ b/app/ui/style/olive-light/svg/copy.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="copy.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./copy.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/diamond.svg b/app/ui/style/olive-light/svg/diamond.svg index 8726ae8ea..437b8a796 100644 --- a/app/ui/style/olive-light/svg/diamond.svg +++ b/app/ui/style/olive-light/svg/diamond.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="diamond.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./diamond.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/dirup.svg b/app/ui/style/olive-light/svg/dirup.svg index 347470454..d369cd02d 100644 --- a/app/ui/style/olive-light/svg/dirup.svg +++ b/app/ui/style/olive-light/svg/dirup.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="dirup.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./dirup.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/error.svg b/app/ui/style/olive-light/svg/error.svg index b3d14439d..db0bf57bd 100644 --- a/app/ui/style/olive-light/svg/error.svg +++ b/app/ui/style/olive-light/svg/error.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="error.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./error.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/export.svg b/app/ui/style/olive-light/svg/export.svg index 5e78f6b99..15e82496a 100644 --- a/app/ui/style/olive-light/svg/export.svg +++ b/app/ui/style/olive-light/svg/export.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/eye-closed.svg b/app/ui/style/olive-light/svg/eye-closed.svg index aec936241..b922e8114 100644 --- a/app/ui/style/olive-light/svg/eye-closed.svg +++ b/app/ui/style/olive-light/svg/eye-closed.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/eye-opened.svg b/app/ui/style/olive-light/svg/eye-opened.svg index c4b69c755..418df417e 100644 --- a/app/ui/style/olive-light/svg/eye-opened.svg +++ b/app/ui/style/olive-light/svg/eye-opened.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/ff.svg b/app/ui/style/olive-light/svg/ff.svg index 55f99936d..527cea1aa 100644 --- a/app/ui/style/olive-light/svg/ff.svg +++ b/app/ui/style/olive-light/svg/ff.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="ff.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./ff.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/filter.svg b/app/ui/style/olive-light/svg/filter.svg index 21b5b1404..6c2602938 100644 --- a/app/ui/style/olive-light/svg/filter.svg +++ b/app/ui/style/olive-light/svg/filter.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="filter.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./filter.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/folder.svg b/app/ui/style/olive-light/svg/folder.svg index 5f8cc9a1d..08ffd44c5 100644 --- a/app/ui/style/olive-light/svg/folder.svg +++ b/app/ui/style/olive-light/svg/folder.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="folder.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./folder.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/hand.svg b/app/ui/style/olive-light/svg/hand.svg index 9711a1e87..8186680d3 100644 --- a/app/ui/style/olive-light/svg/hand.svg +++ b/app/ui/style/olive-light/svg/hand.svg @@ -18,157 +18,157 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="hand.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./hand.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/iconview.svg b/app/ui/style/olive-light/svg/iconview.svg index 7670c3c7f..61550e3b7 100644 --- a/app/ui/style/olive-light/svg/iconview.svg +++ b/app/ui/style/olive-light/svg/iconview.svg @@ -18,181 +18,181 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="iconview.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./iconview.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/imagesource.svg b/app/ui/style/olive-light/svg/imagesource.svg index 6dfcbb343..0e2617e19 100644 --- a/app/ui/style/olive-light/svg/imagesource.svg +++ b/app/ui/style/olive-light/svg/imagesource.svg @@ -18,164 +18,164 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="imagesource.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./imagesource.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/import.svg b/app/ui/style/olive-light/svg/import.svg index 3b65f47c2..16e8657fc 100644 --- a/app/ui/style/olive-light/svg/import.svg +++ b/app/ui/style/olive-light/svg/import.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="import.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./import.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/listview.svg b/app/ui/style/olive-light/svg/listview.svg index 0454664c0..291a99a92 100644 --- a/app/ui/style/olive-light/svg/listview.svg +++ b/app/ui/style/olive-light/svg/listview.svg @@ -18,163 +18,163 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="listview.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./listview.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/lock-closed.svg b/app/ui/style/olive-light/svg/lock-closed.svg index 875599821..44686a2bf 100644 --- a/app/ui/style/olive-light/svg/lock-closed.svg +++ b/app/ui/style/olive-light/svg/lock-closed.svg @@ -18,161 +18,161 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/lock-opened.svg b/app/ui/style/olive-light/svg/lock-opened.svg index c94658250..0953522c8 100644 --- a/app/ui/style/olive-light/svg/lock-opened.svg +++ b/app/ui/style/olive-light/svg/lock-opened.svg @@ -18,161 +18,161 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="export.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./export.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/magnet.svg b/app/ui/style/olive-light/svg/magnet.svg index 0cddcc1e4..900915759 100644 --- a/app/ui/style/olive-light/svg/magnet.svg +++ b/app/ui/style/olive-light/svg/magnet.svg @@ -18,196 +18,196 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - - + sodipodi:docname="magnet.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./magnet.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/map.svg b/app/ui/style/olive-light/svg/map.svg index 43e41e465..dd302684b 100644 --- a/app/ui/style/olive-light/svg/map.svg +++ b/app/ui/style/olive-light/svg/map.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="map5.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="/Users/pablo/olive_pablo/icons/iconview.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/minus.svg b/app/ui/style/olive-light/svg/minus.svg index 89a0c36d7..cba520805 100644 --- a/app/ui/style/olive-light/svg/minus.svg +++ b/app/ui/style/olive-light/svg/minus.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="minus.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./minus.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/new.svg b/app/ui/style/olive-light/svg/new.svg index 9a3e4f71b..aff8100e6 100644 --- a/app/ui/style/olive-light/svg/new.svg +++ b/app/ui/style/olive-light/svg/new.svg @@ -18,164 +18,164 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="new.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./new.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/next.svg b/app/ui/style/olive-light/svg/next.svg index 5cea7dc61..9554ff5e1 100644 --- a/app/ui/style/olive-light/svg/next.svg +++ b/app/ui/style/olive-light/svg/next.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="next.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./next.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/nodes_btt.svg b/app/ui/style/olive-light/svg/nodes_btt.svg index d5ae19a8c..9df735777 100644 --- a/app/ui/style/olive-light/svg/nodes_btt.svg +++ b/app/ui/style/olive-light/svg/nodes_btt.svg @@ -18,178 +18,178 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="nodes_btt.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./nodes_btt.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/nodes_ltr.svg b/app/ui/style/olive-light/svg/nodes_ltr.svg index 390e421eb..e0399c688 100644 --- a/app/ui/style/olive-light/svg/nodes_ltr.svg +++ b/app/ui/style/olive-light/svg/nodes_ltr.svg @@ -18,181 +18,181 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="nodes_ltr.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./nodes_ltr.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - - - - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + + + + - diff --git a/app/ui/style/olive-light/svg/nodes_rtl.svg b/app/ui/style/olive-light/svg/nodes_rtl.svg index 932af6eb0..8b7d68ee7 100644 --- a/app/ui/style/olive-light/svg/nodes_rtl.svg +++ b/app/ui/style/olive-light/svg/nodes_rtl.svg @@ -18,182 +18,182 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="nodes_rtl.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./nodes_rtl.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - - - - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + + + + - diff --git a/app/ui/style/olive-light/svg/nodes_ttb.svg b/app/ui/style/olive-light/svg/nodes_ttb.svg index 8f6aa72e4..f8c51421a 100644 --- a/app/ui/style/olive-light/svg/nodes_ttb.svg +++ b/app/ui/style/olive-light/svg/nodes_ttb.svg @@ -18,182 +18,182 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="nodes_ttb.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./nodes_ttb.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - - - - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + + + + - diff --git a/app/ui/style/olive-light/svg/open.svg b/app/ui/style/olive-light/svg/open.svg index 991645aac..8920a9960 100644 --- a/app/ui/style/olive-light/svg/open.svg +++ b/app/ui/style/olive-light/svg/open.svg @@ -18,172 +18,172 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="open.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./open.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/paste.svg b/app/ui/style/olive-light/svg/paste.svg index cfc57ae74..9691bcc60 100644 --- a/app/ui/style/olive-light/svg/paste.svg +++ b/app/ui/style/olive-light/svg/paste.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="paste.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./paste.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/pause.svg b/app/ui/style/olive-light/svg/pause.svg index 9c9524914..822b61f64 100644 --- a/app/ui/style/olive-light/svg/pause.svg +++ b/app/ui/style/olive-light/svg/pause.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="pause.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./pause.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/play.svg b/app/ui/style/olive-light/svg/play.svg index 5b8581305..219340848 100644 --- a/app/ui/style/olive-light/svg/play.svg +++ b/app/ui/style/olive-light/svg/play.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="play.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./play.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/plus.svg b/app/ui/style/olive-light/svg/plus.svg index 26ee76fd7..2c401a4d6 100644 --- a/app/ui/style/olive-light/svg/plus.svg +++ b/app/ui/style/olive-light/svg/plus.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="plus.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./plus.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/prev.svg b/app/ui/style/olive-light/svg/prev.svg index 69740e517..70909b39d 100644 --- a/app/ui/style/olive-light/svg/prev.svg +++ b/app/ui/style/olive-light/svg/prev.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="prev.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./prev.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/razor.svg b/app/ui/style/olive-light/svg/razor.svg index 740098ddb..20532777c 100644 --- a/app/ui/style/olive-light/svg/razor.svg +++ b/app/ui/style/olive-light/svg/razor.svg @@ -18,155 +18,155 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="razor.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./razor.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/record.svg b/app/ui/style/olive-light/svg/record.svg index 6d473dcf8..7c0fa639d 100644 --- a/app/ui/style/olive-light/svg/record.svg +++ b/app/ui/style/olive-light/svg/record.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="record.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./record.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/redo.svg b/app/ui/style/olive-light/svg/redo.svg index 994066105..53794f351 100644 --- a/app/ui/style/olive-light/svg/redo.svg +++ b/app/ui/style/olive-light/svg/redo.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="redo.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./redo.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/rew.svg b/app/ui/style/olive-light/svg/rew.svg index 7ac08624e..c9aebc2ae 100644 --- a/app/ui/style/olive-light/svg/rew.svg +++ b/app/ui/style/olive-light/svg/rew.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="rew.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./rew.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/ripple.svg b/app/ui/style/olive-light/svg/ripple.svg index 57dec756f..1a06ff9a7 100644 --- a/app/ui/style/olive-light/svg/ripple.svg +++ b/app/ui/style/olive-light/svg/ripple.svg @@ -18,164 +18,164 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="ripple.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./ripple.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/rolling.svg b/app/ui/style/olive-light/svg/rolling.svg index 0f5c799e8..fa196589d 100644 --- a/app/ui/style/olive-light/svg/rolling.svg +++ b/app/ui/style/olive-light/svg/rolling.svg @@ -18,175 +18,175 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - - + sodipodi:docname="rolling.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./rolling.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/save.svg b/app/ui/style/olive-light/svg/save.svg index 8d00e9bb3..3c460b34c 100644 --- a/app/ui/style/olive-light/svg/save.svg +++ b/app/ui/style/olive-light/svg/save.svg @@ -18,167 +18,167 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="save.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./save.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/sequence.svg b/app/ui/style/olive-light/svg/sequence.svg index 22cb2aa75..cc300a423 100644 --- a/app/ui/style/olive-light/svg/sequence.svg +++ b/app/ui/style/olive-light/svg/sequence.svg @@ -18,167 +18,167 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="sequence.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./sequence.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/slide.svg b/app/ui/style/olive-light/svg/slide.svg index 7a85f09b8..5fb81f087 100644 --- a/app/ui/style/olive-light/svg/slide.svg +++ b/app/ui/style/olive-light/svg/slide.svg @@ -18,171 +18,171 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="slide.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./slide.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/slip.svg b/app/ui/style/olive-light/svg/slip.svg index 12265b4df..efbc6c3e5 100644 --- a/app/ui/style/olive-light/svg/slip.svg +++ b/app/ui/style/olive-light/svg/slip.svg @@ -18,168 +18,168 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="slip.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./slip.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/smooth_edges.svg b/app/ui/style/olive-light/svg/smooth_edges.svg index d5f638dc8..a7bd44438 100644 --- a/app/ui/style/olive-light/svg/smooth_edges.svg +++ b/app/ui/style/olive-light/svg/smooth_edges.svg @@ -18,151 +18,151 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="smooth_edges.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./smooth_edges.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/subtitles.svg b/app/ui/style/olive-light/svg/subtitles.svg index 78f317df5..43cad742b 100644 --- a/app/ui/style/olive-light/svg/subtitles.svg +++ b/app/ui/style/olive-light/svg/subtitles.svg @@ -18,316 +18,316 @@ --> - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="subtitles.svg" + inkscape:version="1.3-dev (4e3da4f, 2022-05-14)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-bold.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/text-bold.svg b/app/ui/style/olive-light/svg/text-bold.svg index 4c84dc5f0..50de3817d 100644 --- a/app/ui/style/olive-light/svg/text-bold.svg +++ b/app/ui/style/olive-light/svg/text-bold.svg @@ -18,155 +18,155 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="text-bold.svg" + inkscape:version="1.1 (c4e8f9e, 2021-05-24)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-bold.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + - diff --git a/app/ui/style/olive-light/svg/text-edit.svg b/app/ui/style/olive-light/svg/text-edit.svg index 927479eaa..21b56d315 100644 --- a/app/ui/style/olive-light/svg/text-edit.svg +++ b/app/ui/style/olive-light/svg/text-edit.svg @@ -18,277 +18,277 @@ --> - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="text-edit.svg" + inkscape:version="1.3-dev (e659668, 2022-05-03)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-bold.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/text-italic.svg b/app/ui/style/olive-light/svg/text-italic.svg index 4a4ebb287..195163dc9 100644 --- a/app/ui/style/olive-light/svg/text-italic.svg +++ b/app/ui/style/olive-light/svg/text-italic.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="text-italic.svg" + inkscape:version="1.1 (c4e8f9e, 2021-05-24)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-italic.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/text-small-caps.svg b/app/ui/style/olive-light/svg/text-small-caps.svg index f8c2f7758..c7effe296 100644 --- a/app/ui/style/olive-light/svg/text-small-caps.svg +++ b/app/ui/style/olive-light/svg/text-small-caps.svg @@ -18,177 +18,177 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="text-small-caps.svg" + inkscape:version="1.3-dev (50b0636d, 2022-04-18)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-bold.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/text-strikethrough.svg b/app/ui/style/olive-light/svg/text-strikethrough.svg index 99d75c3fd..7785d47ee 100644 --- a/app/ui/style/olive-light/svg/text-strikethrough.svg +++ b/app/ui/style/olive-light/svg/text-strikethrough.svg @@ -18,186 +18,186 @@ --> - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="text-strikethrough.svg" + inkscape:version="1.2-alpha1 (f32a55a0, 2022-04-04)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-underline.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/text-underline.svg b/app/ui/style/olive-light/svg/text-underline.svg index 8f9e57e3b..4c89e12f8 100644 --- a/app/ui/style/olive-light/svg/text-underline.svg +++ b/app/ui/style/olive-light/svg/text-underline.svg @@ -18,184 +18,184 @@ --> - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - + sodipodi:docname="text-underline.svg" + inkscape:version="1.2-alpha1 (f32a55a0, 2022-04-04)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-underline.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + - + inkscape:groupmode="layer" + inkscape:label="Design" + id="layer1" + transform="translate(0,16)"> + + + + - - diff --git a/app/ui/style/olive-light/svg/track-tool.svg b/app/ui/style/olive-light/svg/track-tool.svg index 1da5d7ac3..05edebe6f 100644 --- a/app/ui/style/olive-light/svg/track-tool.svg +++ b/app/ui/style/olive-light/svg/track-tool.svg @@ -18,209 +18,209 @@ --> - - - - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="track-tool.svg" + inkscape:version="1.3-dev (50b0636d, 2022-04-18)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./text-underline.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/transition-tool.svg b/app/ui/style/olive-light/svg/transition-tool.svg index 5aec208e7..e3a3a632d 100644 --- a/app/ui/style/olive-light/svg/transition-tool.svg +++ b/app/ui/style/olive-light/svg/transition-tool.svg @@ -18,163 +18,163 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - + sodipodi:docname="transition-tool.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./transition-tool.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/treeview.svg b/app/ui/style/olive-light/svg/treeview.svg index dbb58fea5..0f3596232 100644 --- a/app/ui/style/olive-light/svg/treeview.svg +++ b/app/ui/style/olive-light/svg/treeview.svg @@ -18,170 +18,170 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - - - + sodipodi:docname="treeview.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./treeview.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/tri-down.svg b/app/ui/style/olive-light/svg/tri-down.svg index 5e50f70b2..a9ba3d2c6 100644 --- a/app/ui/style/olive-light/svg/tri-down.svg +++ b/app/ui/style/olive-light/svg/tri-down.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="tri-down.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./tri-down.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/tri-left.svg b/app/ui/style/olive-light/svg/tri-left.svg index 792f3ca60..d1741cb67 100644 --- a/app/ui/style/olive-light/svg/tri-left.svg +++ b/app/ui/style/olive-light/svg/tri-left.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="tri-left.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./tri-left.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/tri-right.svg b/app/ui/style/olive-light/svg/tri-right.svg index 31839b2e0..2d7630235 100644 --- a/app/ui/style/olive-light/svg/tri-right.svg +++ b/app/ui/style/olive-light/svg/tri-right.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="tri-right.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./tri-right.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/tri-up.svg b/app/ui/style/olive-light/svg/tri-up.svg index be48afe1f..5bacc61e2 100644 --- a/app/ui/style/olive-light/svg/tri-up.svg +++ b/app/ui/style/olive-light/svg/tri-up.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="tri-up.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./tri-up.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/undo.svg b/app/ui/style/olive-light/svg/undo.svg index 8b514b5b4..640f14647 100644 --- a/app/ui/style/olive-light/svg/undo.svg +++ b/app/ui/style/olive-light/svg/undo.svg @@ -18,152 +18,152 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="undo.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./undo.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/videosource.svg b/app/ui/style/olive-light/svg/videosource.svg index ea8941f52..fc240a8b8 100644 --- a/app/ui/style/olive-light/svg/videosource.svg +++ b/app/ui/style/olive-light/svg/videosource.svg @@ -18,153 +18,153 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - + sodipodi:docname="videosource.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./videosource.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/zoomin.svg b/app/ui/style/olive-light/svg/zoomin.svg index 3c2f66f91..a43854ae9 100644 --- a/app/ui/style/olive-light/svg/zoomin.svg +++ b/app/ui/style/olive-light/svg/zoomin.svg @@ -18,156 +18,156 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="zoomin.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./zoomin.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/ui/style/olive-light/svg/zoomout.svg b/app/ui/style/olive-light/svg/zoomout.svg index 3a18254fc..ce06cc87e 100644 --- a/app/ui/style/olive-light/svg/zoomout.svg +++ b/app/ui/style/olive-light/svg/zoomout.svg @@ -18,158 +18,158 @@ --> - - - - - - - - - - - - - - image/svg+xml - - - - Martin Ruskov - - - http://commons.wikimedia.org/wiki/Tango_icon - - - - - - - - - - - - - - - - + sodipodi:docname="zoomout.svg" + inkscape:version="1.2-dev (217ad3d, 2021-07-13)" + sodipodi:version="0.32" + id="svg2" + height="64" + width="64" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + viewBox="0 0 64 64" + inkscape:export-filename="./zoomout.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + diff --git a/app/undo/CMakeLists.txt b/app/undo/CMakeLists.txt index e04e22502..1b82d9b26 100644 --- a/app/undo/CMakeLists.txt +++ b/app/undo/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - undo/undocommand.h - undo/undocommand.cpp - undo/undostack.h - undo/undostack.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + undo/undocommand.h + undo/undocommand.cpp + undo/undostack.h + undo/undostack.cpp + PARENT_SCOPE ) diff --git a/app/widget/CMakeLists.txt b/app/widget/CMakeLists.txt index 26f2b10e8..e260bc4f5 100644 --- a/app/widget/CMakeLists.txt +++ b/app/widget/CMakeLists.txt @@ -56,6 +56,6 @@ add_subdirectory(toolbar) add_subdirectory(viewer) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/widget/audiomonitor/CMakeLists.txt b/app/widget/audiomonitor/CMakeLists.txt index d2e8d2b50..12397bc5b 100644 --- a/app/widget/audiomonitor/CMakeLists.txt +++ b/app/widget/audiomonitor/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/audiomonitor/audiomonitor.h - widget/audiomonitor/audiomonitor.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/audiomonitor/audiomonitor.h + widget/audiomonitor/audiomonitor.cpp + PARENT_SCOPE ) diff --git a/app/widget/bezier/CMakeLists.txt b/app/widget/bezier/CMakeLists.txt index 9c6460353..094488956 100644 --- a/app/widget/bezier/CMakeLists.txt +++ b/app/widget/bezier/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/bezier/bezierwidget.cpp - widget/bezier/bezierwidget.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/bezier/bezierwidget.cpp + widget/bezier/bezierwidget.h + PARENT_SCOPE ) diff --git a/app/widget/clickablelabel/CMakeLists.txt b/app/widget/clickablelabel/CMakeLists.txt index 0268a2a85..c9f055bcd 100644 --- a/app/widget/clickablelabel/CMakeLists.txt +++ b/app/widget/clickablelabel/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/clickablelabel/clickablelabel.h - widget/clickablelabel/clickablelabel.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/clickablelabel/clickablelabel.h + widget/clickablelabel/clickablelabel.cpp + PARENT_SCOPE ) diff --git a/app/widget/collapsebutton/CMakeLists.txt b/app/widget/collapsebutton/CMakeLists.txt index a2ae50765..7e6dadb8d 100644 --- a/app/widget/collapsebutton/CMakeLists.txt +++ b/app/widget/collapsebutton/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/collapsebutton/collapsebutton.h - widget/collapsebutton/collapsebutton.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/collapsebutton/collapsebutton.h + widget/collapsebutton/collapsebutton.cpp + PARENT_SCOPE ) diff --git a/app/widget/colorbutton/CMakeLists.txt b/app/widget/colorbutton/CMakeLists.txt index 6c3c5fee6..6b2e677a1 100644 --- a/app/widget/colorbutton/CMakeLists.txt +++ b/app/widget/colorbutton/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/colorbutton/colorbutton.h - widget/colorbutton/colorbutton.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/colorbutton/colorbutton.h + widget/colorbutton/colorbutton.cpp + PARENT_SCOPE ) diff --git a/app/widget/colorlabelmenu/CMakeLists.txt b/app/widget/colorlabelmenu/CMakeLists.txt index 0879cb270..571ec912d 100644 --- a/app/widget/colorlabelmenu/CMakeLists.txt +++ b/app/widget/colorlabelmenu/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/colorlabelmenu/colorcodingcombobox.cpp - widget/colorlabelmenu/colorcodingcombobox.h - widget/colorlabelmenu/colorlabelmenu.cpp - widget/colorlabelmenu/colorlabelmenu.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/colorlabelmenu/colorcodingcombobox.cpp + widget/colorlabelmenu/colorcodingcombobox.h + widget/colorlabelmenu/colorlabelmenu.cpp + widget/colorlabelmenu/colorlabelmenu.h + PARENT_SCOPE ) diff --git a/app/widget/colorwheel/CMakeLists.txt b/app/widget/colorwheel/CMakeLists.txt index fb1f43082..c39091c1b 100644 --- a/app/widget/colorwheel/CMakeLists.txt +++ b/app/widget/colorwheel/CMakeLists.txt @@ -15,20 +15,20 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/colorwheel/colorgradientwidget.h - widget/colorwheel/colorgradientwidget.cpp - widget/colorwheel/colorpreviewbox.h - widget/colorwheel/colorpreviewbox.cpp - widget/colorwheel/colorspacechooser.h - widget/colorwheel/colorspacechooser.cpp - widget/colorwheel/colorswatchchooser.h - widget/colorwheel/colorswatchchooser.cpp - widget/colorwheel/colorswatchwidget.h - widget/colorwheel/colorswatchwidget.cpp - widget/colorwheel/colorvalueswidget.h - widget/colorwheel/colorvalueswidget.cpp - widget/colorwheel/colorwheelwidget.h - widget/colorwheel/colorwheelwidget.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/colorwheel/colorgradientwidget.h + widget/colorwheel/colorgradientwidget.cpp + widget/colorwheel/colorpreviewbox.h + widget/colorwheel/colorpreviewbox.cpp + widget/colorwheel/colorspacechooser.h + widget/colorwheel/colorspacechooser.cpp + widget/colorwheel/colorswatchchooser.h + widget/colorwheel/colorswatchchooser.cpp + widget/colorwheel/colorswatchwidget.h + widget/colorwheel/colorswatchwidget.cpp + widget/colorwheel/colorvalueswidget.h + widget/colorwheel/colorvalueswidget.cpp + widget/colorwheel/colorwheelwidget.h + widget/colorwheel/colorwheelwidget.cpp + PARENT_SCOPE ) diff --git a/app/widget/columnedgridlayout/CMakeLists.txt b/app/widget/columnedgridlayout/CMakeLists.txt index bd9f28b35..26466f723 100644 --- a/app/widget/columnedgridlayout/CMakeLists.txt +++ b/app/widget/columnedgridlayout/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/columnedgridlayout/columnedgridlayout.h - widget/columnedgridlayout/columnedgridlayout.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/columnedgridlayout/columnedgridlayout.h + widget/columnedgridlayout/columnedgridlayout.cpp + PARENT_SCOPE ) diff --git a/app/widget/curvewidget/CMakeLists.txt b/app/widget/curvewidget/CMakeLists.txt index 23546f74d..56f26da3a 100644 --- a/app/widget/curvewidget/CMakeLists.txt +++ b/app/widget/curvewidget/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/curvewidget/curveview.cpp - widget/curvewidget/curveview.h - widget/curvewidget/curvewidget.cpp - widget/curvewidget/curvewidget.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/curvewidget/curveview.cpp + widget/curvewidget/curveview.h + widget/curvewidget/curvewidget.cpp + widget/curvewidget/curvewidget.h + PARENT_SCOPE ) diff --git a/app/widget/filefield/CMakeLists.txt b/app/widget/filefield/CMakeLists.txt index 075a7aaf4..8561f7cb6 100644 --- a/app/widget/filefield/CMakeLists.txt +++ b/app/widget/filefield/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/filefield/filefield.cpp - widget/filefield/filefield.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/filefield/filefield.cpp + widget/filefield/filefield.h + PARENT_SCOPE ) diff --git a/app/widget/flowlayout/CMakeLists.txt b/app/widget/flowlayout/CMakeLists.txt index 74bf744b9..6e09e6680 100644 --- a/app/widget/flowlayout/CMakeLists.txt +++ b/app/widget/flowlayout/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/flowlayout/flowlayout.h - widget/flowlayout/flowlayout.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/flowlayout/flowlayout.h + widget/flowlayout/flowlayout.cpp + PARENT_SCOPE ) diff --git a/app/widget/focusablelineedit/CMakeLists.txt b/app/widget/focusablelineedit/CMakeLists.txt index e040eb8a0..106f4520b 100644 --- a/app/widget/focusablelineedit/CMakeLists.txt +++ b/app/widget/focusablelineedit/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/focusablelineedit/focusablelineedit.h - widget/focusablelineedit/focusablelineedit.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/focusablelineedit/focusablelineedit.h + widget/focusablelineedit/focusablelineedit.cpp + PARENT_SCOPE ) diff --git a/app/widget/handmovableview/CMakeLists.txt b/app/widget/handmovableview/CMakeLists.txt index d69a10d4d..65158064a 100644 --- a/app/widget/handmovableview/CMakeLists.txt +++ b/app/widget/handmovableview/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/handmovableview/handmovableview.h - widget/handmovableview/handmovableview.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/handmovableview/handmovableview.h + widget/handmovableview/handmovableview.cpp + PARENT_SCOPE ) diff --git a/app/widget/history/CMakeLists.txt b/app/widget/history/CMakeLists.txt index 1ccd89717..d7692fdd8 100644 --- a/app/widget/history/CMakeLists.txt +++ b/app/widget/history/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/history/historywidget.cpp - widget/history/historywidget.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/history/historywidget.cpp + widget/history/historywidget.h + PARENT_SCOPE ) diff --git a/app/widget/keyframeview/CMakeLists.txt b/app/widget/keyframeview/CMakeLists.txt index 3c18f5453..9e982fd60 100644 --- a/app/widget/keyframeview/CMakeLists.txt +++ b/app/widget/keyframeview/CMakeLists.txt @@ -15,12 +15,12 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/keyframeview/keyframeview.cpp - widget/keyframeview/keyframeview.h - widget/keyframeview/keyframeviewinputconnection.cpp - widget/keyframeview/keyframeviewinputconnection.h - widget/keyframeview/keyframeviewundo.cpp - widget/keyframeview/keyframeviewundo.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/keyframeview/keyframeview.cpp + widget/keyframeview/keyframeview.h + widget/keyframeview/keyframeviewinputconnection.cpp + widget/keyframeview/keyframeviewinputconnection.h + widget/keyframeview/keyframeviewundo.cpp + widget/keyframeview/keyframeviewundo.h + PARENT_SCOPE ) diff --git a/app/widget/manageddisplay/CMakeLists.txt b/app/widget/manageddisplay/CMakeLists.txt index 68b0be6e5..dd4e7cf70 100644 --- a/app/widget/manageddisplay/CMakeLists.txt +++ b/app/widget/manageddisplay/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/manageddisplay/manageddisplay.h - widget/manageddisplay/manageddisplay.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/manageddisplay/manageddisplay.h + widget/manageddisplay/manageddisplay.cpp + PARENT_SCOPE ) diff --git a/app/widget/manageddisplay/manageddisplay.cpp b/app/widget/manageddisplay/manageddisplay.cpp index e9cc311db..38c9f98b1 100644 --- a/app/widget/manageddisplay/manageddisplay.cpp +++ b/app/widget/manageddisplay/manageddisplay.cpp @@ -54,7 +54,8 @@ ManagedDisplayWidget::ManagedDisplayWidget(QWidget *parent) RenderManager::instance()->requested_backend()), this); if (!dynamic_renderer->Load()) { - qWarning() << "Failed to load dynamic render backend for viewer, falling back to OpenGL"; + qWarning() + << "Failed to load dynamic render backend for viewer, falling back to OpenGL"; delete dynamic_renderer; attached_renderer_ = new OpenGLRenderer(this); } else { diff --git a/app/widget/menu/CMakeLists.txt b/app/widget/menu/CMakeLists.txt index bf344cef8..4620c05ea 100644 --- a/app/widget/menu/CMakeLists.txt +++ b/app/widget/menu/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/menu/menu.cpp - widget/menu/menu.h - widget/menu/menushared.cpp - widget/menu/menushared.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/menu/menu.cpp + widget/menu/menu.h + widget/menu/menushared.cpp + widget/menu/menushared.h + PARENT_SCOPE ) diff --git a/app/widget/multicam/CMakeLists.txt b/app/widget/multicam/CMakeLists.txt index 2e7df53a7..0a6356ea5 100644 --- a/app/widget/multicam/CMakeLists.txt +++ b/app/widget/multicam/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/multicam/multicamdisplay.cpp - widget/multicam/multicamdisplay.h - widget/multicam/multicamwidget.cpp - widget/multicam/multicamwidget.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/multicam/multicamdisplay.cpp + widget/multicam/multicamdisplay.h + widget/multicam/multicamwidget.cpp + widget/multicam/multicamwidget.h + PARENT_SCOPE ) diff --git a/app/widget/nodecombobox/CMakeLists.txt b/app/widget/nodecombobox/CMakeLists.txt index e26165b77..bee2adce4 100644 --- a/app/widget/nodecombobox/CMakeLists.txt +++ b/app/widget/nodecombobox/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/nodecombobox/nodecombobox.h - widget/nodecombobox/nodecombobox.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/nodecombobox/nodecombobox.h + widget/nodecombobox/nodecombobox.cpp + PARENT_SCOPE ) diff --git a/app/widget/nodeparamview/nodeparambutton.h b/app/widget/nodeparamview/nodeparambutton.h index 1c427b835..840eb0575 100644 --- a/app/widget/nodeparamview/nodeparambutton.h +++ b/app/widget/nodeparamview/nodeparambutton.h @@ -23,25 +23,25 @@ #include -class NodeParamButton : public QPushButton{ -Q_OBJECT +class NodeParamButton : public QPushButton { + Q_OBJECT public: - NodeParamButton(QString name, QWidget *parent = nullptr):QPushButton(parent) + NodeParamButton(QString name, QWidget *parent = nullptr) + : QPushButton(parent) { - this->name_=name; + this->name_ = name; connect(this, &QPushButton::clicked, this, &NodeParamButton::pressed); } signals: void onPressed(QString name); private slots: - void pressed(){ + void pressed() + { emit onPressed(name_); } + private: QString name_; - }; - - #endif //NODEPARAMBUTTON_H diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp index 2a32ee845..526ab169d 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.cpp +++ b/app/widget/nodeparamview/nodeparamviewitem.cpp @@ -254,8 +254,11 @@ NodeParamViewItemBody::NodeParamViewItemBody( { n, input }); if (!(n->GetInputFlags(input) & kInputFlagHidden)) { - QString page_label = n->GetInputProperty(input, QStringLiteral("ui_page")).toString(); - QString group_label = n->GetInputProperty(input, QStringLiteral("ui_group")).toString(); + QString page_label = + n->GetInputProperty(input, QStringLiteral("ui_page")).toString(); + QString group_label = + n->GetInputProperty(input, QStringLiteral("ui_group")) + .toString(); if (!page_label.isEmpty() && page_label != current_page) { QLabel *page_title = new QLabel(page_label, this); QFont f = page_title->font(); diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp index 1ce418054..adb395323 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp @@ -120,8 +120,8 @@ void NodeParamViewWidgetBridge::CreateWidgets() QStringList items = GetInnerInput().GetComboBoxStrings(); QStringList values = GetInnerInput().GetProperty("combo_value_str").toStringList(); - const bool use_value_data = - (t == NodeValue::kStrCombo) && !values.isEmpty(); + const bool use_value_data = (t == NodeValue::kStrCombo) && + !values.isEmpty(); for (int i = 0; i < items.size(); ++i) { const QString &label = items.at(i); if (use_value_data && i < values.size()) { @@ -146,17 +146,15 @@ void NodeParamViewWidgetBridge::CreateWidgets() break; } case NodeValue::kColor: { - if (GetInnerInput().GetProperty("color_semantic") - .toString() == QStringLiteral("scalar")) { + if (GetInnerInput().GetProperty("color_semantic").toString() == + QStringLiteral("scalar")) { CreateSliders(4, parent); } else { ColorButton *color_button = new ColorButton( - GetInnerInput().node()->project()->color_manager(), - parent); + GetInnerInput().node()->project()->color_manager(), parent); widgets_.append(color_button); - connect( - color_button, &ColorButton::ColorChanged, this, - &NodeParamViewWidgetBridge::WidgetCallback); + connect(color_button, &ColorButton::ColorChanged, this, + &NodeParamViewWidgetBridge::WidgetCallback); } break; } @@ -203,11 +201,13 @@ void NodeParamViewWidgetBridge::CreateWidgets() break; } case NodeValue::kPushButton: { - NodeInput input=GetInnerInput(); - NodeParamButton *button=new NodeParamButton(input.name(),parent); + NodeInput input = GetInnerInput(); + NodeParamButton *button = new NodeParamButton(input.name(), parent); widgets_.append(button); - plugin::PluginNode* plugin_node=dynamic_cast(input.node()); - connect(button, &NodeParamButton::onPressed, plugin_node, &plugin::PluginNode::pushButtonClicked); + plugin::PluginNode *plugin_node = + dynamic_cast(input.node()); + connect(button, &NodeParamButton::onPressed, plugin_node, + &plugin::PluginNode::pushButtonClicked); } } @@ -329,15 +329,13 @@ void NodeParamViewWidgetBridge::WidgetCallback() break; } case NodeValue::kColor: { - if (GetInnerInput().GetProperty("color_semantic") - .toString() == QStringLiteral("scalar")) { - FloatSlider *slider = - static_cast(sender()); + if (GetInnerInput().GetProperty("color_semantic").toString() == + QStringLiteral("scalar")) { + FloatSlider *slider = static_cast(sender()); ProcessSlider(slider, slider->GetValue()); } else { // Sender is a ColorButton - ManagedColor c = - static_cast(sender())->GetColor(); + ManagedColor c = static_cast(sender())->GetColor(); MultiUndoCommand *command = new MultiUndoCommand(); @@ -348,22 +346,20 @@ void NodeParamViewWidgetBridge::WidgetCallback() Node *n = GetInnerInput().node(); n->blockSignals(true); - n->SetInputProperty( - GetInnerInput().input(), QStringLiteral("col_input"), - c.color_input()); - n->SetInputProperty( - GetInnerInput().input(), QStringLiteral("col_display"), - c.color_output().display()); - n->SetInputProperty( - GetInnerInput().input(), QStringLiteral("col_view"), - c.color_output().view()); - n->SetInputProperty( - GetInnerInput().input(), QStringLiteral("col_look"), - c.color_output().look()); + n->SetInputProperty(GetInnerInput().input(), + QStringLiteral("col_input"), c.color_input()); + n->SetInputProperty(GetInnerInput().input(), + QStringLiteral("col_display"), + c.color_output().display()); + n->SetInputProperty(GetInnerInput().input(), + QStringLiteral("col_view"), + c.color_output().view()); + n->SetInputProperty(GetInnerInput().input(), + QStringLiteral("col_look"), + c.color_output().look()); n->blockSignals(false); - Core::instance()->undo_stack()->push(command, - GetCommandName()); + Core::instance()->undo_stack()->push(command, GetCommandName()); } break; } @@ -496,7 +492,8 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues() case NodeValue::kBinary: { NodeParamViewTextEdit *e = static_cast(widgets_.first()); - QByteArray bytes = GetInnerInput().GetValueAtTime(node_time).toByteArray(); + QByteArray bytes = + GetInnerInput().GetValueAtTime(node_time).toByteArray(); e->setTextPreservingCursor(QString::fromUtf8(bytes.toBase64())); break; } @@ -558,11 +555,9 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues() break; } case NodeValue::kColor: { - if (GetInnerInput().GetProperty("color_semantic") - .toString() == QStringLiteral("scalar")) { - Color c = GetInnerInput() - .GetValueAtTime(node_time) - .value(); + if (GetInnerInput().GetProperty("color_semantic").toString() == + QStringLiteral("scalar")) { + Color c = GetInnerInput().GetValueAtTime(node_time).value(); static_cast(widgets_.at(0)) ->SetValue(static_cast(c.red())); static_cast(widgets_.at(1)) @@ -572,27 +567,19 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues() static_cast(widgets_.at(3)) ->SetValue(static_cast(c.alpha())); } else { - ManagedColor mc = GetInnerInput() - .GetValueAtTime(node_time) - .value(); + ManagedColor mc = + GetInnerInput().GetValueAtTime(node_time).value(); mc.set_color_input( GetInnerInput().GetProperty("col_input").toString()); - QString d = GetInnerInput() - .GetProperty("col_display") - .toString(); - QString v = GetInnerInput() - .GetProperty("col_view") - .toString(); - QString l = GetInnerInput() - .GetProperty("col_look") - .toString(); + QString d = GetInnerInput().GetProperty("col_display").toString(); + QString v = GetInnerInput().GetProperty("col_view").toString(); + QString l = GetInnerInput().GetProperty("col_look").toString(); mc.set_color_output(ColorTransform(d, v, l)); - static_cast(widgets_.first()) - ->SetColor(mc); + static_cast(widgets_.first())->SetColor(mc); } break; } @@ -868,8 +855,8 @@ void NodeParamViewWidgetBridge::SetProperty(const QString &key, QStringList items = value.toStringList(); QStringList values = GetInnerInput().GetProperty("combo_value_str").toStringList(); - const bool use_value_data = - (data_type == NodeValue::kStrCombo) && !values.isEmpty(); + const bool use_value_data = (data_type == NodeValue::kStrCombo) && + !values.isEmpty(); int index = 0; for (int i = 0; i < items.size(); ++i) { const QString &s = items.at(i); diff --git a/app/widget/nodetableview/CMakeLists.txt b/app/widget/nodetableview/CMakeLists.txt index 2132ccd6a..dc8b3de84 100644 --- a/app/widget/nodetableview/CMakeLists.txt +++ b/app/widget/nodetableview/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/nodetableview/nodetableview.cpp - widget/nodetableview/nodetableview.h - widget/nodetableview/nodetablewidget.cpp - widget/nodetableview/nodetablewidget.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/nodetableview/nodetableview.cpp + widget/nodetableview/nodetableview.h + widget/nodetableview/nodetablewidget.cpp + widget/nodetableview/nodetablewidget.h + PARENT_SCOPE ) diff --git a/app/widget/nodetreeview/CMakeLists.txt b/app/widget/nodetreeview/CMakeLists.txt index a8b5b6dce..2a7cfd6a3 100644 --- a/app/widget/nodetreeview/CMakeLists.txt +++ b/app/widget/nodetreeview/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/nodetreeview/nodetreeview.h - widget/nodetreeview/nodetreeview.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/nodetreeview/nodetreeview.h + widget/nodetreeview/nodetreeview.cpp + PARENT_SCOPE ) diff --git a/app/widget/nodevaluetree/CMakeLists.txt b/app/widget/nodevaluetree/CMakeLists.txt index 44ed10d5b..21dc0b881 100644 --- a/app/widget/nodevaluetree/CMakeLists.txt +++ b/app/widget/nodevaluetree/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/nodevaluetree/nodevaluetree.cpp - widget/nodevaluetree/nodevaluetree.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/nodevaluetree/nodevaluetree.cpp + widget/nodevaluetree/nodevaluetree.h + PARENT_SCOPE ) diff --git a/app/widget/nodeview/CMakeLists.txt b/app/widget/nodeview/CMakeLists.txt index 184ef1190..b36de5cab 100644 --- a/app/widget/nodeview/CMakeLists.txt +++ b/app/widget/nodeview/CMakeLists.txt @@ -15,25 +15,25 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/nodeview/nodeview.cpp - widget/nodeview/nodeview.h - widget/nodeview/nodeviewcommon.h - widget/nodeview/nodeviewcontext.cpp - widget/nodeview/nodeviewcontext.h - widget/nodeview/nodeviewedge.cpp - widget/nodeview/nodeviewedge.h - widget/nodeview/nodeviewitem.cpp - widget/nodeview/nodeviewitem.h - widget/nodeview/nodeviewitemconnector.cpp - widget/nodeview/nodeviewitemconnector.h - widget/nodeview/nodeviewminimap.cpp - widget/nodeview/nodeviewminimap.h - widget/nodeview/nodeviewscene.cpp - widget/nodeview/nodeviewscene.h - widget/nodeview/nodeviewtoolbar.cpp - widget/nodeview/nodeviewtoolbar.h - widget/nodeview/nodewidget.cpp - widget/nodeview/nodewidget.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/nodeview/nodeview.cpp + widget/nodeview/nodeview.h + widget/nodeview/nodeviewcommon.h + widget/nodeview/nodeviewcontext.cpp + widget/nodeview/nodeviewcontext.h + widget/nodeview/nodeviewedge.cpp + widget/nodeview/nodeviewedge.h + widget/nodeview/nodeviewitem.cpp + widget/nodeview/nodeviewitem.h + widget/nodeview/nodeviewitemconnector.cpp + widget/nodeview/nodeviewitemconnector.h + widget/nodeview/nodeviewminimap.cpp + widget/nodeview/nodeviewminimap.h + widget/nodeview/nodeviewscene.cpp + widget/nodeview/nodeviewscene.h + widget/nodeview/nodeviewtoolbar.cpp + widget/nodeview/nodeviewtoolbar.h + widget/nodeview/nodewidget.cpp + widget/nodeview/nodewidget.h + PARENT_SCOPE ) diff --git a/app/widget/nodeview/nodeview.cpp b/app/widget/nodeview/nodeview.cpp index cd7e1a9a6..150eb8329 100644 --- a/app/widget/nodeview/nodeview.cpp +++ b/app/widget/nodeview/nodeview.cpp @@ -74,11 +74,15 @@ NodeView::NodeView(QWidget *parent) SetFlowDirection(NodeViewCommon::kLeftToRight); - show_in_param_editor_action_ = new QAction(tr("Show in Parameter Editor"), this); - Menu::ConformItem(show_in_param_editor_action_, QStringLiteral("shownodeparams"), QKeySequence(tr("Shift+P"))); + show_in_param_editor_action_ = + new QAction(tr("Show in Parameter Editor"), this); + Menu::ConformItem(show_in_param_editor_action_, + QStringLiteral("shownodeparams"), + QKeySequence(tr("Shift+P"))); show_in_param_editor_action_->setShortcutContext(Qt::WindowShortcut); addAction(show_in_param_editor_action_); - connect(show_in_param_editor_action_, &QAction::triggered, this, &NodeView::ShowSelectedNodeInParamEditor); + connect(show_in_param_editor_action_, &QAction::triggered, this, + &NodeView::ShowSelectedNodeInParamEditor); UpdateSceneBoundingRect(); connect(&scene_, &QGraphicsScene::changed, this, @@ -838,8 +842,7 @@ void NodeView::ShowContextMenu(const QPoint &pos) QVector selected = scene_.GetSelectedItems(); - NodeViewItem *item_under_cursor = - dynamic_cast(itemAt(pos)); + NodeViewItem *item_under_cursor = dynamic_cast(itemAt(pos)); if (item_under_cursor && !selected.contains(item_under_cursor)) { // Right-clicked a node that isn't part of the current selection, @@ -879,8 +882,8 @@ void NodeView::ShowContextMenu(const QPoint &pos) m.addSeparator(); // Show in Parameter Editor - QAction *show_in_param_editor_action = m.addAction( - tr("Show in Parameter Editor")); + QAction *show_in_param_editor_action = + m.addAction(tr("Show in Parameter Editor")); show_in_param_editor_action->setShortcut( show_in_param_editor_action_->shortcut()); connect(show_in_param_editor_action, &QAction::triggered, this, @@ -1673,8 +1676,8 @@ void NodeView::ShowSelectedNodeInParamEditor() selection_with_contexts.reserve(selected.size()); foreach (NodeViewItem *item, selected) { if (item && item->GetNode()) { - selection_with_contexts.append(Node::ContextPair{ - item->GetNode(), item->GetContext()}); + selection_with_contexts.append( + Node::ContextPair{ item->GetNode(), item->GetContext() }); } } @@ -1684,7 +1687,7 @@ void NodeView::ShowSelectedNodeInParamEditor() if (PanelManager::instance()) { if (PanelWidget *panel = PanelManager::instance()->GetPanelWithName( - QStringLiteral("ParamPanel"))) { + QStringLiteral("ParamPanel"))) { panel->show(); QMetaObject::invokeMethod(panel, &PanelWidget::raise, Qt::QueuedConnection); diff --git a/app/widget/nodeview/nodeviewitem.cpp b/app/widget/nodeview/nodeviewitem.cpp index 533be911c..d84253b03 100644 --- a/app/widget/nodeview/nodeviewitem.cpp +++ b/app/widget/nodeview/nodeviewitem.cpp @@ -455,10 +455,9 @@ void NodeViewItem::paint(QPainter *painter, int badge_width = qMax(text_width + pad * 2, text_height + pad); int badge_height = text_height + pad; - QRectF badge_rect( - single_unit_rect.right() - badge_width - 4, - single_unit_rect.top() + 4, - badge_width, badge_height); + QRectF badge_rect(single_unit_rect.right() - badge_width - 4, + single_unit_rect.top() + 4, badge_width, + badge_height); painter->setPen(Qt::NoPen); painter->setBrush(QColor(220, 50, 47)); diff --git a/app/widget/path/CMakeLists.txt b/app/widget/path/CMakeLists.txt index 9902d40b5..781daeb91 100644 --- a/app/widget/path/CMakeLists.txt +++ b/app/widget/path/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/path/pathwidget.h - widget/path/pathwidget.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/path/pathwidget.h + widget/path/pathwidget.cpp + PARENT_SCOPE ) diff --git a/app/widget/pixelsampler/CMakeLists.txt b/app/widget/pixelsampler/CMakeLists.txt index 212184c9f..a2f3c4742 100644 --- a/app/widget/pixelsampler/CMakeLists.txt +++ b/app/widget/pixelsampler/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/pixelsampler/pixelsampler.h - widget/pixelsampler/pixelsampler.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/pixelsampler/pixelsampler.h + widget/pixelsampler/pixelsampler.cpp + PARENT_SCOPE ) diff --git a/app/widget/playbackcontrols/CMakeLists.txt b/app/widget/playbackcontrols/CMakeLists.txt index aa10921ee..3786928d2 100644 --- a/app/widget/playbackcontrols/CMakeLists.txt +++ b/app/widget/playbackcontrols/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/playbackcontrols/dragbutton.h - widget/playbackcontrols/dragbutton.cpp - widget/playbackcontrols/playbackcontrols.h - widget/playbackcontrols/playbackcontrols.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/playbackcontrols/dragbutton.h + widget/playbackcontrols/dragbutton.cpp + widget/playbackcontrols/playbackcontrols.h + widget/playbackcontrols/playbackcontrols.cpp + PARENT_SCOPE ) diff --git a/app/widget/projectexplorer/CMakeLists.txt b/app/widget/projectexplorer/CMakeLists.txt index 35445facf..86ee3f61c 100644 --- a/app/widget/projectexplorer/CMakeLists.txt +++ b/app/widget/projectexplorer/CMakeLists.txt @@ -15,25 +15,25 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/projectexplorer/projectexplorer.cpp - widget/projectexplorer/projectexplorer.h - widget/projectexplorer/projectexplorericonview.cpp - widget/projectexplorer/projectexplorericonview.h - widget/projectexplorer/projectexplorericonviewitemdelegate.cpp - widget/projectexplorer/projectexplorericonviewitemdelegate.h - widget/projectexplorer/projectexplorerlistview.cpp - widget/projectexplorer/projectexplorerlistview.h - widget/projectexplorer/projectexplorerlistviewbase.cpp - widget/projectexplorer/projectexplorerlistviewbase.h - widget/projectexplorer/projectexplorerlistviewitemdelegate.cpp - widget/projectexplorer/projectexplorerlistviewitemdelegate.h - widget/projectexplorer/projectexplorernavigation.cpp - widget/projectexplorer/projectexplorernavigation.h - widget/projectexplorer/projectexplorertreeview.cpp - widget/projectexplorer/projectexplorertreeview.h - widget/projectexplorer/projectexplorerundo.h - widget/projectexplorer/projectviewmodel.cpp - widget/projectexplorer/projectviewmodel.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/projectexplorer/projectexplorer.cpp + widget/projectexplorer/projectexplorer.h + widget/projectexplorer/projectexplorericonview.cpp + widget/projectexplorer/projectexplorericonview.h + widget/projectexplorer/projectexplorericonviewitemdelegate.cpp + widget/projectexplorer/projectexplorericonviewitemdelegate.h + widget/projectexplorer/projectexplorerlistview.cpp + widget/projectexplorer/projectexplorerlistview.h + widget/projectexplorer/projectexplorerlistviewbase.cpp + widget/projectexplorer/projectexplorerlistviewbase.h + widget/projectexplorer/projectexplorerlistviewitemdelegate.cpp + widget/projectexplorer/projectexplorerlistviewitemdelegate.h + widget/projectexplorer/projectexplorernavigation.cpp + widget/projectexplorer/projectexplorernavigation.h + widget/projectexplorer/projectexplorertreeview.cpp + widget/projectexplorer/projectexplorertreeview.h + widget/projectexplorer/projectexplorerundo.h + widget/projectexplorer/projectviewmodel.cpp + widget/projectexplorer/projectviewmodel.h + PARENT_SCOPE ) diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index fe3bdd2ba..83a83f3d5 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -47,7 +47,8 @@ namespace olive { -namespace { +namespace +{ QVector GetSelectedProxyFootage(const QVector &items) { QVector footage; @@ -452,23 +453,21 @@ void ProjectExplorer::ShowContextMenu() connect(use_proxy, &QAction::triggered, this, &ProjectExplorer::SetSelectedFootageProxyEnabled); - QAction *reveal_proxy = - proxy_menu->addAction(tr("Reveal Proxy")); - reveal_proxy->setEnabled(std::any_of( - proxy_footage.cbegin(), proxy_footage.cend(), - [](const Footage *footage) { - return !footage->proxy_path().isEmpty(); - })); + QAction *reveal_proxy = proxy_menu->addAction(tr("Reveal Proxy")); + reveal_proxy->setEnabled( + std::any_of(proxy_footage.cbegin(), proxy_footage.cend(), + [](const Footage *footage) { + return !footage->proxy_path().isEmpty(); + })); connect(reveal_proxy, &QAction::triggered, this, &ProjectExplorer::RevealProxyForSelectedFootage); - QAction *delete_proxy = - proxy_menu->addAction(tr("Delete Proxy")); - delete_proxy->setEnabled(std::any_of( - proxy_footage.cbegin(), proxy_footage.cend(), - [](const Footage *footage) { - return !footage->proxy_path().isEmpty(); - })); + QAction *delete_proxy = proxy_menu->addAction(tr("Delete Proxy")); + delete_proxy->setEnabled( + std::any_of(proxy_footage.cbegin(), proxy_footage.cend(), + [](const Footage *footage) { + return !footage->proxy_path().isEmpty(); + })); connect(delete_proxy, &QAction::triggered, this, &ProjectExplorer::DeleteProxiesForSelectedFootage); } @@ -548,9 +547,9 @@ void ProjectExplorer::ReplaceSelectedFootage() { Footage *footage = static_cast(context_menu_items_.first()); - QString file = QFileDialog::getOpenFileName( - this, tr("Replace Footage"), QString(), - Core::FootageFileDialogFilter()); + QString file = + QFileDialog::getOpenFileName(this, tr("Replace Footage"), QString(), + Core::FootageFileDialogFilter()); if (!file.isEmpty()) { if (!Core::IsFootageExtensionAllowed(file)) { QMessageBox::warning( @@ -593,19 +592,22 @@ void ProjectExplorer::OpenContextMenuItemInNewWindow() void ProjectExplorer::GenerateProxiesForSelectedFootage() { if (!ProxyManager::instance() || !project()) { - qWarning() << "GenerateProxiesForSelectedFootage: ProxyManager or project unavailable"; + qWarning() + << "GenerateProxiesForSelectedFootage: ProxyManager or project unavailable"; return; } const QVector footage = GetSelectedProxyFootage(context_menu_items_); - qDebug() << "GenerateProxiesForSelectedFootage: starting proxy generation for" - << footage.size() << "footage item(s)"; + qDebug() + << "GenerateProxiesForSelectedFootage: starting proxy generation for" + << footage.size() << "footage item(s)"; for (Footage *item : footage) { const VideoParams video = item->GetFirstEnabledVideoStream(); if (!video.is_valid()) { - qWarning() << "GenerateProxiesForSelectedFootage: skipping item with no valid video stream" - << item->filename(); + qWarning() + << "GenerateProxiesForSelectedFootage: skipping item with no valid video stream" + << item->filename(); continue; } @@ -619,9 +621,9 @@ void ProjectExplorer::GenerateProxiesForSelectedFootage() item->project()->cache_path(), item->filename(), video.stream_index(), params); qDebug() << "GenerateProxiesForSelectedFootage: proxy state=" - << ProxyManager::ProxyStateToString(proxy.state) - << "file=" << proxy.filename - << "cache=" << item->project()->cache_path(); + << ProxyManager::ProxyStateToString(proxy.state) + << "file=" << proxy.filename + << "cache=" << item->project()->cache_path(); item->SetProxy(proxy.filename, proxy.state, video.stream_index(), params.version, true); item->InvalidateAll(Footage::kFilenameInput); @@ -633,11 +635,11 @@ void ProjectExplorer::SetSelectedFootageProxyEnabled(bool enabled) const QVector footage = GetSelectedProxyFootage(context_menu_items_); qDebug() << "ProjectExplorer::SetSelectedFootageProxyEnabled:" << enabled - << "footage count=" << footage.size(); + << "footage count=" << footage.size(); for (Footage *item : footage) { if (item->proxy_path().isEmpty()) { - qDebug() << " skipping item with empty proxy path" - << item->filename(); + qDebug() + << " skipping item with empty proxy path" << item->filename(); continue; } diff --git a/app/widget/projecttoolbar/CMakeLists.txt b/app/widget/projecttoolbar/CMakeLists.txt index 6c063e6fe..ad5d91a58 100644 --- a/app/widget/projecttoolbar/CMakeLists.txt +++ b/app/widget/projecttoolbar/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/projecttoolbar/projecttoolbar.h - widget/projecttoolbar/projecttoolbar.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/projecttoolbar/projecttoolbar.h + widget/projecttoolbar/projecttoolbar.cpp + PARENT_SCOPE ) diff --git a/app/widget/resizablescrollbar/CMakeLists.txt b/app/widget/resizablescrollbar/CMakeLists.txt index 1e54cff06..17c85792a 100644 --- a/app/widget/resizablescrollbar/CMakeLists.txt +++ b/app/widget/resizablescrollbar/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/resizablescrollbar/resizablescrollbar.cpp - widget/resizablescrollbar/resizablescrollbar.h - widget/resizablescrollbar/resizabletimelinescrollbar.cpp - widget/resizablescrollbar/resizabletimelinescrollbar.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/resizablescrollbar/resizablescrollbar.cpp + widget/resizablescrollbar/resizablescrollbar.h + widget/resizablescrollbar/resizabletimelinescrollbar.cpp + widget/resizablescrollbar/resizabletimelinescrollbar.h + PARENT_SCOPE ) diff --git a/app/widget/scope/CMakeLists.txt b/app/widget/scope/CMakeLists.txt index fd40b03a1..b18faa4ea 100644 --- a/app/widget/scope/CMakeLists.txt +++ b/app/widget/scope/CMakeLists.txt @@ -20,6 +20,6 @@ add_subdirectory(vectorscope) add_subdirectory(waveform) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/widget/scope/histogram/CMakeLists.txt b/app/widget/scope/histogram/CMakeLists.txt index b743df960..91650e393 100644 --- a/app/widget/scope/histogram/CMakeLists.txt +++ b/app/widget/scope/histogram/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/scope/histogram/histogram.h - widget/scope/histogram/histogram.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/scope/histogram/histogram.h + widget/scope/histogram/histogram.cpp + PARENT_SCOPE ) diff --git a/app/widget/scope/histogram/histogram.cpp b/app/widget/scope/histogram/histogram.cpp index 49a966693..898103327 100644 --- a/app/widget/scope/histogram/histogram.cpp +++ b/app/widget/scope/histogram/histogram.cpp @@ -190,7 +190,8 @@ void HistogramScope::DrawScopeSoftware(QPainter &p, const QImage &image) max_count = qMax(max_count, b_counts[i]); } - auto draw_channel = [&](const std::array &counts, const QColor &color) { + auto draw_channel = [&](const std::array &counts, + const QColor &color) { QPen pen(color); pen.setWidth(2); p.setPen(pen); @@ -198,8 +199,8 @@ void HistogramScope::DrawScopeSoftware(QPainter &p, const QImage &image) QVector points; points.reserve(256); for (int i = 0; i < 256; ++i) { - float x = histogram_start_dim_x + - (float(i) / 255.0f) * histogram_dim_x; + float x = + histogram_start_dim_x + (float(i) / 255.0f) * histogram_dim_x; float normalized = float(counts[i]) / float(max_count); float y = histogram_start_dim_y + histogram_dim_y * diff --git a/app/widget/scope/scopebase/CMakeLists.txt b/app/widget/scope/scopebase/CMakeLists.txt index 58263e1b4..0c8dfa0cd 100644 --- a/app/widget/scope/scopebase/CMakeLists.txt +++ b/app/widget/scope/scopebase/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/scope/scopebase/scopebase.h - widget/scope/scopebase/scopebase.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/scope/scopebase/scopebase.h + widget/scope/scopebase/scopebase.cpp + PARENT_SCOPE ) diff --git a/app/widget/scope/scopebase/scopebase.cpp b/app/widget/scope/scopebase/scopebase.cpp index 363835dce..80fd03cbf 100644 --- a/app/widget/scope/scopebase/scopebase.cpp +++ b/app/widget/scope/scopebase/scopebase.cpp @@ -96,16 +96,16 @@ void ScopeBase::UpdateSoftwareImage() const int texture_width = static_cast(width() * devicePixelRatioF()); const int texture_height = static_cast(height() * devicePixelRatioF()); - const VideoParams offscreen_params( - texture_width, texture_height, PixelFormat::U8, - VideoParams::kRGBAChannelCount); + const VideoParams offscreen_params(texture_width, texture_height, + PixelFormat::U8, + VideoParams::kRGBAChannelCount); if (!software_tex_ || software_tex_->params() != offscreen_params) { software_tex_ = renderer()->CreateTexture(offscreen_params); software_buffer_.resize( texture_width * texture_height * VideoParams::GetBytesPerPixel(PixelFormat::U8, - VideoParams::kRGBAChannelCount)); + VideoParams::kRGBAChannelCount)); } if (!software_tex_ || software_tex_->IsDummy()) { @@ -122,15 +122,15 @@ void ScopeBase::UpdateSoftwareImage() job.SetForceOpaque(true); renderer()->BlitColorManaged(job, software_tex_.get()); - renderer()->DownloadFromTexture(software_tex_->id(), software_tex_->params(), - software_buffer_.data(), 0); + renderer()->DownloadFromTexture(software_tex_->id(), + software_tex_->params(), + software_buffer_.data(), 0); software_image_ = QImage( reinterpret_cast(software_buffer_.constData()), texture_width, texture_height, - texture_width * - VideoParams::GetBytesPerPixel(PixelFormat::U8, - VideoParams::kRGBAChannelCount), + texture_width * VideoParams::GetBytesPerPixel( + PixelFormat::U8, VideoParams::kRGBAChannelCount), QImage::Format_RGBA8888_Premultiplied); software_image_.setDevicePixelRatio(devicePixelRatioF()); diff --git a/app/widget/scope/vectorscope/CMakeLists.txt b/app/widget/scope/vectorscope/CMakeLists.txt index d6ee4f89e..7b88c5805 100644 --- a/app/widget/scope/vectorscope/CMakeLists.txt +++ b/app/widget/scope/vectorscope/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/scope/vectorscope/vectorscope.h - widget/scope/vectorscope/vectorscope.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/scope/vectorscope/vectorscope.h + widget/scope/vectorscope/vectorscope.cpp + PARENT_SCOPE ) diff --git a/app/widget/scope/vectorscope/vectorscope.cpp b/app/widget/scope/vectorscope/vectorscope.cpp index a7e7201bb..7553c44e3 100644 --- a/app/widget/scope/vectorscope/vectorscope.cpp +++ b/app/widget/scope/vectorscope/vectorscope.cpp @@ -160,14 +160,13 @@ void VectorscopeScope::DrawScopeSoftware(QPainter &p, const QImage &image) float g = src[1] / 255.0f; float b = src[2] / 255.0f; - float y = r * luma_coeffs[0] + g * luma_coeffs[1] + - b * luma_coeffs[2]; + float y = + r * luma_coeffs[0] + g * luma_coeffs[1] + b * luma_coeffs[2]; float cb = (b - y) / qMax(2.0f * (1.0f - luma_coeffs[2]), 0.0001f); float cr = (r - y) / qMax(2.0f * (1.0f - luma_coeffs[0]), 0.0001f); - QPointF point = center + - QPointF(cr * vectorscope_gain * radius, - -cb * vectorscope_gain * radius); + QPointF point = center + QPointF(cr * vectorscope_gain * radius, + -cb * vectorscope_gain * radius); int px = qRound(point.x()); int py = qRound(point.y()); diff --git a/app/widget/scope/waveform/CMakeLists.txt b/app/widget/scope/waveform/CMakeLists.txt index 28d0b9b7c..ce744cf78 100644 --- a/app/widget/scope/waveform/CMakeLists.txt +++ b/app/widget/scope/waveform/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/scope/waveform/waveform.h - widget/scope/waveform/waveform.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/scope/waveform/waveform.h + widget/scope/waveform/waveform.cpp + PARENT_SCOPE ) diff --git a/app/widget/scope/waveform/waveform.cpp b/app/widget/scope/waveform/waveform.cpp index 058546e9f..7c3439f83 100644 --- a/app/widget/scope/waveform/waveform.cpp +++ b/app/widget/scope/waveform/waveform.cpp @@ -157,13 +157,14 @@ void WaveformScope::DrawScopeSoftware(QPainter &p, const QImage &image) } auto mark = [&](float value, int add_r, int add_g, int add_b) { - int scope_y = waveform_start_dim_y + - int((1.0f - value) * waveform_dim_y); + int scope_y = + waveform_start_dim_y + int((1.0f - value) * waveform_dim_y); if (scope_y < waveform_start_dim_y || scope_y >= waveform_start_dim_y + waveform_dim_y) { return; } - QRgb *dst_line = reinterpret_cast(buf.scanLine(scope_y)); + QRgb *dst_line = + reinterpret_cast(buf.scanLine(scope_y)); QRgb cur = dst_line[scope_x]; int nr = qMin(255, qRed(cur) + add_r); int ng = qMin(255, qGreen(cur) + add_g); diff --git a/app/widget/slider/CMakeLists.txt b/app/widget/slider/CMakeLists.txt index b90c18ab5..1589baa7b 100644 --- a/app/widget/slider/CMakeLists.txt +++ b/app/widget/slider/CMakeLists.txt @@ -17,14 +17,14 @@ add_subdirectory(base) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/slider/floatslider.h - widget/slider/floatslider.cpp - widget/slider/integerslider.h - widget/slider/integerslider.cpp - widget/slider/rationalslider.h - widget/slider/rationalslider.cpp - widget/slider/stringslider.h - widget/slider/stringslider.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/slider/floatslider.h + widget/slider/floatslider.cpp + widget/slider/integerslider.h + widget/slider/integerslider.cpp + widget/slider/rationalslider.h + widget/slider/rationalslider.cpp + widget/slider/stringslider.h + widget/slider/stringslider.cpp + PARENT_SCOPE ) diff --git a/app/widget/slider/base/CMakeLists.txt b/app/widget/slider/base/CMakeLists.txt index 921ec8826..10e843cb6 100644 --- a/app/widget/slider/base/CMakeLists.txt +++ b/app/widget/slider/base/CMakeLists.txt @@ -15,16 +15,16 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/slider/base/decimalsliderbase.h - widget/slider/base/decimalsliderbase.cpp - widget/slider/base/numericsliderbase.h - widget/slider/base/numericsliderbase.cpp - widget/slider/base/sliderbase.h - widget/slider/base/sliderbase.cpp - widget/slider/base/sliderlabel.h - widget/slider/base/sliderlabel.cpp - widget/slider/base/sliderladder.h - widget/slider/base/sliderladder.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/slider/base/decimalsliderbase.h + widget/slider/base/decimalsliderbase.cpp + widget/slider/base/numericsliderbase.h + widget/slider/base/numericsliderbase.cpp + widget/slider/base/sliderbase.h + widget/slider/base/sliderbase.cpp + widget/slider/base/sliderlabel.h + widget/slider/base/sliderlabel.cpp + widget/slider/base/sliderladder.h + widget/slider/base/sliderladder.cpp + PARENT_SCOPE ) diff --git a/app/widget/standardcombos/CMakeLists.txt b/app/widget/standardcombos/CMakeLists.txt index 4cb7164e6..21fa28627 100644 --- a/app/widget/standardcombos/CMakeLists.txt +++ b/app/widget/standardcombos/CMakeLists.txt @@ -15,15 +15,15 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/standardcombos/channellayoutcombobox.h - widget/standardcombos/frameratecombobox.h - widget/standardcombos/interlacedcombobox.h - widget/standardcombos/pixelaspectratiocombobox.h - widget/standardcombos/pixelformatcombobox.h - widget/standardcombos/sampleformatcombobox.h - widget/standardcombos/sampleratecombobox.h - widget/standardcombos/standardcombos.h - widget/standardcombos/videodividercombobox.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/standardcombos/channellayoutcombobox.h + widget/standardcombos/frameratecombobox.h + widget/standardcombos/interlacedcombobox.h + widget/standardcombos/pixelaspectratiocombobox.h + widget/standardcombos/pixelformatcombobox.h + widget/standardcombos/sampleformatcombobox.h + widget/standardcombos/sampleratecombobox.h + widget/standardcombos/standardcombos.h + widget/standardcombos/videodividercombobox.h + PARENT_SCOPE ) diff --git a/app/widget/taskview/CMakeLists.txt b/app/widget/taskview/CMakeLists.txt index 7c380215a..d14e6775a 100644 --- a/app/widget/taskview/CMakeLists.txt +++ b/app/widget/taskview/CMakeLists.txt @@ -15,12 +15,12 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/taskview/elapsedcounterwidget.h - widget/taskview/elapsedcounterwidget.cpp - widget/taskview/taskview.h - widget/taskview/taskview.cpp - widget/taskview/taskviewitem.h - widget/taskview/taskviewitem.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/taskview/elapsedcounterwidget.h + widget/taskview/elapsedcounterwidget.cpp + widget/taskview/taskview.h + widget/taskview/taskview.cpp + widget/taskview/taskviewitem.h + widget/taskview/taskviewitem.cpp + PARENT_SCOPE ) diff --git a/app/widget/timebased/CMakeLists.txt b/app/widget/timebased/CMakeLists.txt index 55609d627..105db8c31 100644 --- a/app/widget/timebased/CMakeLists.txt +++ b/app/widget/timebased/CMakeLists.txt @@ -15,14 +15,14 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/timebased/timebasedview.cpp - widget/timebased/timebasedview.h - widget/timebased/timebasedviewselectionmanager.cpp - widget/timebased/timebasedviewselectionmanager.h - widget/timebased/timebasedwidget.cpp - widget/timebased/timebasedwidget.h - widget/timebased/timescaledobject.cpp - widget/timebased/timescaledobject.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/timebased/timebasedview.cpp + widget/timebased/timebasedview.h + widget/timebased/timebasedviewselectionmanager.cpp + widget/timebased/timebasedviewselectionmanager.h + widget/timebased/timebasedwidget.cpp + widget/timebased/timebasedwidget.h + widget/timebased/timescaledobject.cpp + widget/timebased/timescaledobject.h + PARENT_SCOPE ) diff --git a/app/widget/timelinewidget/CMakeLists.txt b/app/widget/timelinewidget/CMakeLists.txt index d662526ce..1fdbadba4 100644 --- a/app/widget/timelinewidget/CMakeLists.txt +++ b/app/widget/timelinewidget/CMakeLists.txt @@ -19,14 +19,14 @@ add_subdirectory(tool) add_subdirectory(view) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/timelinewidget/timelineandtrackview.cpp - widget/timelinewidget/timelineandtrackview.h - widget/timelinewidget/timelinewidget.cpp - widget/timelinewidget/timelinewidget.h - widget/timelinewidget/timelinewidgetselections.cpp - widget/timelinewidget/timelinewidgetselections.h - widget/timelinewidget/timelinewidgetwaveformsync.cpp - widget/timelinewidget/timelinewidgetwaveformsync.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/timelinewidget/timelineandtrackview.cpp + widget/timelinewidget/timelineandtrackview.h + widget/timelinewidget/timelinewidget.cpp + widget/timelinewidget/timelinewidget.h + widget/timelinewidget/timelinewidgetselections.cpp + widget/timelinewidget/timelinewidgetselections.h + widget/timelinewidget/timelinewidgetwaveformsync.cpp + widget/timelinewidget/timelinewidgetwaveformsync.h + PARENT_SCOPE ) diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 810fcf859..d110dc0a9 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -79,7 +79,8 @@ namespace olive using namespace TimelineWaveformSync; -namespace { +namespace +{ struct SourceSyncClip { ClipBlock *clip = nullptr; @@ -107,8 +108,8 @@ bool GetSourceSyncClip(Block *block, SourceSyncClip *out) return true; } -QVector GetSelectedSourceSyncClips( - const QVector &blocks) +QVector +GetSelectedSourceSyncClips(const QVector &blocks) { QVector clips; for (Block *block : blocks) { @@ -1061,13 +1062,13 @@ void TimelineWidget::SynchronizeSelectedClipsByWaveform() continue; } - const QVector candidate_envelope = - ExtractWaveformCacheEnvelope(sync_clip, sample_rate, - window_samples); + const QVector candidate_envelope = ExtractWaveformCacheEnvelope( + sync_clip, sample_rate, window_samples); const AudioWaveformSync::OffsetResult offset = - AudioWaveformSync::EstimateEnvelopeOffset( - reference_envelope, candidate_envelope, window_samples, - max_offset_windows); + AudioWaveformSync::EstimateEnvelopeOffset(reference_envelope, + candidate_envelope, + window_samples, + max_offset_windows); if (!offset.valid) { continue; } @@ -1105,23 +1106,28 @@ void TimelineWidget::SynchronizeSelectedClipsByWaveform() command->add_child( new SetSelectionsCommand(this, new_selections, GetSelections())); - Core::instance()->undo_stack()->push( - command, tr("Synchronize Clips by Waveform")); + Core::instance()->undo_stack()->push(command, + tr("Synchronize Clips by Waveform")); } void TimelineWidget::GenerateProxiesForSelectedClips() { if (!ProxyManager::instance() || !sequence()) { - qWarning() << "GenerateProxiesForSelectedClips: ProxyManager or sequence unavailable"; + qWarning() + << "GenerateProxiesForSelectedClips: ProxyManager or sequence unavailable"; return; } - const QVector footage = GetSelectedProxyFootage(selected_blocks_); - qDebug() << "GenerateProxiesForSelectedClips: starting proxy generation for" << footage.size() << "footage item(s)"; + const QVector footage = + GetSelectedProxyFootage(selected_blocks_); + qDebug() << "GenerateProxiesForSelectedClips: starting proxy generation for" + << footage.size() << "footage item(s)"; for (Footage *item : footage) { const VideoParams video = item->GetFirstEnabledVideoStream(); if (!video.is_valid()) { - qWarning() << "GenerateProxiesForSelectedClips: skipping item with no valid video stream" << item->filename(); + qWarning() + << "GenerateProxiesForSelectedClips: skipping item with no valid video stream" + << item->filename(); continue; } @@ -1134,7 +1140,8 @@ void TimelineWidget::GenerateProxiesForSelectedClips() ProxyManager::instance()->GetOrStartProxy( item->project()->cache_path(), item->filename(), video.stream_index(), params); - qDebug() << "GenerateProxiesForSelectedClips: proxy state=" << ProxyManager::ProxyStateToString(proxy.state) + qDebug() << "GenerateProxiesForSelectedClips: proxy state=" + << ProxyManager::ProxyStateToString(proxy.state) << "file=" << proxy.filename << "cache=" << item->project()->cache_path(); item->SetProxy(proxy.filename, proxy.state, video.stream_index(), @@ -1145,13 +1152,14 @@ void TimelineWidget::GenerateProxiesForSelectedClips() void TimelineWidget::SetSelectedClipsProxyEnabled(bool enabled) { - const QVector footage = GetSelectedProxyFootage(selected_blocks_); + const QVector footage = + GetSelectedProxyFootage(selected_blocks_); qDebug() << "TimelineWidget::SetSelectedClipsProxyEnabled:" << enabled << "footage count=" << footage.size(); for (Footage *item : footage) { if (item->proxy_path().isEmpty()) { - qDebug() << " skipping item with empty proxy path" - << item->filename(); + qDebug() + << " skipping item with empty proxy path" << item->filename(); continue; } @@ -1162,7 +1170,8 @@ void TimelineWidget::SetSelectedClipsProxyEnabled(bool enabled) void TimelineWidget::RevealProxyForSelectedClips() { - const QVector footage = GetSelectedProxyFootage(selected_blocks_); + const QVector footage = + GetSelectedProxyFootage(selected_blocks_); for (Footage *item : footage) { if (item->proxy_path().isEmpty()) { continue; @@ -1193,15 +1202,16 @@ void TimelineWidget::RevealProxyForSelectedClips() void TimelineWidget::DeleteProxiesForSelectedClips() { - const QVector footage = GetSelectedProxyFootage(selected_blocks_); + const QVector footage = + GetSelectedProxyFootage(selected_blocks_); for (Footage *item : footage) { if (item->proxy_path().isEmpty()) { continue; } QFile::remove(item->proxy_path()); - QFile::remove(ProxyManager::GetWorkingProxyFilename( - item->proxy_path())); + QFile::remove( + ProxyManager::GetWorkingProxyFilename(item->proxy_path())); item->ClearProxy(); item->InvalidateAll(Footage::kFilenameInput); } @@ -1738,21 +1748,21 @@ void TimelineWidget::ShowContextMenu() QAction *reveal_proxy = proxy_menu->addAction(tr("Reveal Proxy")); - reveal_proxy->setEnabled(std::any_of( - proxy_footage.cbegin(), proxy_footage.cend(), - [](const Footage *footage) { - return !footage->proxy_path().isEmpty(); - })); + reveal_proxy->setEnabled( + std::any_of(proxy_footage.cbegin(), proxy_footage.cend(), + [](const Footage *footage) { + return !footage->proxy_path().isEmpty(); + })); connect(reveal_proxy, &QAction::triggered, this, &TimelineWidget::RevealProxyForSelectedClips); QAction *delete_proxy = proxy_menu->addAction(tr("Delete Proxy")); - delete_proxy->setEnabled(std::any_of( - proxy_footage.cbegin(), proxy_footage.cend(), - [](const Footage *footage) { - return !footage->proxy_path().isEmpty(); - })); + delete_proxy->setEnabled( + std::any_of(proxy_footage.cbegin(), proxy_footage.cend(), + [](const Footage *footage) { + return !footage->proxy_path().isEmpty(); + })); connect(delete_proxy, &QAction::triggered, this, &TimelineWidget::DeleteProxiesForSelectedClips); } diff --git a/app/widget/timelinewidget/timelinewidgetwaveformsync.cpp b/app/widget/timelinewidget/timelinewidgetwaveformsync.cpp index 5e3c040f8..f30faa085 100644 --- a/app/widget/timelinewidget/timelinewidgetwaveformsync.cpp +++ b/app/widget/timelinewidget/timelinewidgetwaveformsync.cpp @@ -66,8 +66,8 @@ bool GetWaveformSyncClip(Block *block, WaveformSyncClip *out) return true; } -QVector GetSelectedWaveformSyncClips( - const QVector &blocks) +QVector +GetSelectedWaveformSyncClips(const QVector &blocks) { QVector clips; for (Block *block : blocks) { @@ -108,7 +108,8 @@ QVector ExtractWaveformCacheEnvelope(const WaveformSyncClip &clip, const AudioVisualWaveform::Sample summary = clip.waveform->GetSummaryFromTime(t, length); - for (const AudioVisualWaveform::SamplePerChannel &channel : summary) { + for (const AudioVisualWaveform::SamplePerChannel &channel : + summary) { const double channel_peak = std::max(std::abs(static_cast(channel.min)), std::abs(static_cast(channel.max))); @@ -121,6 +122,6 @@ QVector ExtractWaveformCacheEnvelope(const WaveformSyncClip &clip, return envelope; } -} // namespace TimelineWaveformSync +} // namespace TimelineWaveformSync -} // namespace olive +} // namespace olive diff --git a/app/widget/timelinewidget/timelinewidgetwaveformsync.h b/app/widget/timelinewidget/timelinewidgetwaveformsync.h index 05f3c8d5d..4a77cee61 100644 --- a/app/widget/timelinewidget/timelinewidgetwaveformsync.h +++ b/app/widget/timelinewidget/timelinewidgetwaveformsync.h @@ -38,10 +38,10 @@ class ClipBlock; * @brief Data required to synchronize a clip using its cached audio waveform. */ struct WaveformSyncClip { - ClipBlock *clip = nullptr; - const AudioWaveformCache *waveform = nullptr; - TimeRange media_range; - int sample_rate = 0; + ClipBlock *clip = nullptr; + const AudioWaveformCache *waveform = nullptr; + TimeRange media_range; + int sample_rate = 0; }; /** @@ -64,8 +64,8 @@ bool GetWaveformSyncClip(Block *block, WaveformSyncClip *out); /** * @brief Return all selected blocks that can be synchronized by waveform. */ -QVector GetSelectedWaveformSyncClips( - const QVector &blocks); +QVector +GetSelectedWaveformSyncClips(const QVector &blocks); /** * @brief Extract a peak envelope from the validated regions of a waveform cache. @@ -74,11 +74,11 @@ QVector GetSelectedWaveformSyncClips( * envelope stays aligned to the same absolute timeline. */ QVector ExtractWaveformCacheEnvelope(const WaveformSyncClip &clip, - int sample_rate, - size_t window_samples); + int sample_rate, + size_t window_samples); -} // namespace TimelineWaveformSync +} // namespace TimelineWaveformSync -} // namespace olive +} // namespace olive -#endif // TIMELINEWIDGETWAVEFORMSYNC_H +#endif // TIMELINEWIDGETWAVEFORMSYNC_H diff --git a/app/widget/timelinewidget/tool/CMakeLists.txt b/app/widget/timelinewidget/tool/CMakeLists.txt index 10670d9b0..ec741cbee 100644 --- a/app/widget/timelinewidget/tool/CMakeLists.txt +++ b/app/widget/timelinewidget/tool/CMakeLists.txt @@ -15,36 +15,36 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/timelinewidget/tool/add.cpp - widget/timelinewidget/tool/add.h - widget/timelinewidget/tool/beam.cpp - widget/timelinewidget/tool/beam.h - widget/timelinewidget/tool/edit.cpp - widget/timelinewidget/tool/edit.h - widget/timelinewidget/tool/import.cpp - widget/timelinewidget/tool/import.h - widget/timelinewidget/tool/pointer.cpp - widget/timelinewidget/tool/pointer.h - widget/timelinewidget/tool/razor.cpp - widget/timelinewidget/tool/razor.h - widget/timelinewidget/tool/record.cpp - widget/timelinewidget/tool/record.h - widget/timelinewidget/tool/ripple.cpp - widget/timelinewidget/tool/ripple.h - widget/timelinewidget/tool/rolling.cpp - widget/timelinewidget/tool/rolling.h - widget/timelinewidget/tool/slide.cpp - widget/timelinewidget/tool/slide.h - widget/timelinewidget/tool/slip.cpp - widget/timelinewidget/tool/slip.h - widget/timelinewidget/tool/trackselect.cpp - widget/timelinewidget/tool/trackselect.h - widget/timelinewidget/tool/transition.cpp - widget/timelinewidget/tool/transition.h - widget/timelinewidget/tool/tool.cpp - widget/timelinewidget/tool/tool.h - widget/timelinewidget/tool/zoom.cpp - widget/timelinewidget/tool/zoom.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/timelinewidget/tool/add.cpp + widget/timelinewidget/tool/add.h + widget/timelinewidget/tool/beam.cpp + widget/timelinewidget/tool/beam.h + widget/timelinewidget/tool/edit.cpp + widget/timelinewidget/tool/edit.h + widget/timelinewidget/tool/import.cpp + widget/timelinewidget/tool/import.h + widget/timelinewidget/tool/pointer.cpp + widget/timelinewidget/tool/pointer.h + widget/timelinewidget/tool/razor.cpp + widget/timelinewidget/tool/razor.h + widget/timelinewidget/tool/record.cpp + widget/timelinewidget/tool/record.h + widget/timelinewidget/tool/ripple.cpp + widget/timelinewidget/tool/ripple.h + widget/timelinewidget/tool/rolling.cpp + widget/timelinewidget/tool/rolling.h + widget/timelinewidget/tool/slide.cpp + widget/timelinewidget/tool/slide.h + widget/timelinewidget/tool/slip.cpp + widget/timelinewidget/tool/slip.h + widget/timelinewidget/tool/trackselect.cpp + widget/timelinewidget/tool/trackselect.h + widget/timelinewidget/tool/transition.cpp + widget/timelinewidget/tool/transition.h + widget/timelinewidget/tool/tool.cpp + widget/timelinewidget/tool/tool.h + widget/timelinewidget/tool/zoom.cpp + widget/timelinewidget/tool/zoom.h + PARENT_SCOPE ) diff --git a/app/widget/timelinewidget/trackview/CMakeLists.txt b/app/widget/timelinewidget/trackview/CMakeLists.txt index c0b7845e6..a79cf9578 100644 --- a/app/widget/timelinewidget/trackview/CMakeLists.txt +++ b/app/widget/timelinewidget/trackview/CMakeLists.txt @@ -15,12 +15,12 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/timelinewidget/trackview/trackview.h - widget/timelinewidget/trackview/trackview.cpp - widget/timelinewidget/trackview/trackviewitem.h - widget/timelinewidget/trackview/trackviewitem.cpp - widget/timelinewidget/trackview/trackviewsplitter.h - widget/timelinewidget/trackview/trackviewsplitter.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/timelinewidget/trackview/trackview.h + widget/timelinewidget/trackview/trackview.cpp + widget/timelinewidget/trackview/trackviewitem.h + widget/timelinewidget/trackview/trackviewitem.cpp + widget/timelinewidget/trackview/trackviewsplitter.h + widget/timelinewidget/trackview/trackviewsplitter.cpp + PARENT_SCOPE ) diff --git a/app/widget/timelinewidget/view/CMakeLists.txt b/app/widget/timelinewidget/view/CMakeLists.txt index 4fbe6a280..ae44bb9bd 100644 --- a/app/widget/timelinewidget/view/CMakeLists.txt +++ b/app/widget/timelinewidget/view/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/timelinewidget/view/timelineview.cpp - widget/timelinewidget/view/timelineview.h - widget/timelinewidget/view/timelineviewmouseevent.h - widget/timelinewidget/view/timelineviewghostitem.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/timelinewidget/view/timelineview.cpp + widget/timelinewidget/view/timelineview.h + widget/timelinewidget/view/timelineviewmouseevent.h + widget/timelinewidget/view/timelineviewghostitem.h + PARENT_SCOPE ) diff --git a/app/widget/timeruler/CMakeLists.txt b/app/widget/timeruler/CMakeLists.txt index 895046495..1bd26b6a9 100644 --- a/app/widget/timeruler/CMakeLists.txt +++ b/app/widget/timeruler/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/timeruler/seekablewidget.h - widget/timeruler/seekablewidget.cpp - widget/timeruler/timeruler.h - widget/timeruler/timeruler.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/timeruler/seekablewidget.h + widget/timeruler/seekablewidget.cpp + widget/timeruler/timeruler.h + widget/timeruler/timeruler.cpp + PARENT_SCOPE ) diff --git a/app/widget/timetarget/CMakeLists.txt b/app/widget/timetarget/CMakeLists.txt index 7cca0f27c..3cf9b8804 100644 --- a/app/widget/timetarget/CMakeLists.txt +++ b/app/widget/timetarget/CMakeLists.txt @@ -15,8 +15,8 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/timetarget/timetarget.h - widget/timetarget/timetarget.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/timetarget/timetarget.h + widget/timetarget/timetarget.cpp + PARENT_SCOPE ) diff --git a/app/widget/toolbar/CMakeLists.txt b/app/widget/toolbar/CMakeLists.txt index 6c2b66f66..89a4e7b2f 100644 --- a/app/widget/toolbar/CMakeLists.txt +++ b/app/widget/toolbar/CMakeLists.txt @@ -15,10 +15,10 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/toolbar/toolbar.h - widget/toolbar/toolbar.cpp - widget/toolbar/toolbarbutton.h - widget/toolbar/toolbarbutton.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/toolbar/toolbar.h + widget/toolbar/toolbar.cpp + widget/toolbar/toolbarbutton.h + widget/toolbar/toolbarbutton.cpp + PARENT_SCOPE ) diff --git a/app/widget/viewer/CMakeLists.txt b/app/widget/viewer/CMakeLists.txt index ca6026619..8251b2518 100644 --- a/app/widget/viewer/CMakeLists.txt +++ b/app/widget/viewer/CMakeLists.txt @@ -15,26 +15,26 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/viewer/audiowaveformview.cpp - widget/viewer/audiowaveformview.h - widget/viewer/footageviewer.cpp - widget/viewer/footageviewer.h - widget/viewer/viewer.cpp - widget/viewer/viewer.h - widget/viewer/viewerdisplay.cpp - widget/viewer/viewerdisplay.h - widget/viewer/viewerplaybacktimer.cpp - widget/viewer/viewerplaybacktimer.h - widget/viewer/viewerpreventsleep.cpp - widget/viewer/viewerpreventsleep.h - widget/viewer/viewerqueue.h - widget/viewer/viewersafemargininfo.h - widget/viewer/viewersizer.cpp - widget/viewer/viewersizer.h - widget/viewer/viewertexteditor.cpp - widget/viewer/viewertexteditor.h - widget/viewer/viewerwindow.cpp - widget/viewer/viewerwindow.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/viewer/audiowaveformview.cpp + widget/viewer/audiowaveformview.h + widget/viewer/footageviewer.cpp + widget/viewer/footageviewer.h + widget/viewer/viewer.cpp + widget/viewer/viewer.h + widget/viewer/viewerdisplay.cpp + widget/viewer/viewerdisplay.h + widget/viewer/viewerplaybacktimer.cpp + widget/viewer/viewerplaybacktimer.h + widget/viewer/viewerpreventsleep.cpp + widget/viewer/viewerpreventsleep.h + widget/viewer/viewerqueue.h + widget/viewer/viewersafemargininfo.h + widget/viewer/viewersizer.cpp + widget/viewer/viewersizer.h + widget/viewer/viewertexteditor.cpp + widget/viewer/viewertexteditor.h + widget/viewer/viewerwindow.cpp + widget/viewer/viewerwindow.h + PARENT_SCOPE ) diff --git a/app/widget/viewer/audiowaveformview.cpp b/app/widget/viewer/audiowaveformview.cpp index f3bb2a08a..42f3cdd5a 100644 --- a/app/widget/viewer/audiowaveformview.cpp +++ b/app/widget/viewer/audiowaveformview.cpp @@ -69,7 +69,9 @@ void AudioWaveformView::SetViewer(ViewerOutput *playback) rational tb = playback_->GetVideoParams().frame_rate_as_time_base(); if (tb.isNull()) { - tb = OLIVE_CONFIG("DefaultSequenceFrameRate").value().flipped(); + tb = OLIVE_CONFIG("DefaultSequenceFrameRate") + .value() + .flipped(); } SetTimebase(tb); UpdateSceneRect(); diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 5308c53c8..37ef50491 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -97,11 +97,12 @@ ViewerWidget::ViewerWidget(ViewerDisplayWidget *display, QWidget *parent) &ViewerWidget::CursorColor); connect(display_widget_, &ViewerDisplayWidget::ColorProcessorChanged, this, &ViewerWidget::ColorProcessorChanged); - connect(display_widget_, &ViewerDisplayWidget::ColorProcessorChanged, this, - [](ColorProcessorPtr processor) { - RenderManager::instance()->GetCacher()->SetDisplayColorProcessor( - processor); - }); + connect( + display_widget_, &ViewerDisplayWidget::ColorProcessorChanged, this, + [](ColorProcessorPtr processor) { + RenderManager::instance()->GetCacher()->SetDisplayColorProcessor( + processor); + }); RenderManager::instance()->GetCacher()->SetDisplayColorProcessor( display_widget_->GetCurrentColorProcessor()); connect(display_widget_, &ViewerDisplayWidget::ColorManagerChanged, this, @@ -985,8 +986,7 @@ void ViewerWidget::ForceRequeueFromCurrentTime() // called from paintEvent paths (QueueStarved) where synchronously cancelling // watchers can re-enter the same RenderTicket mutex and deadlock. QMetaObject::invokeMethod( - this, - [this]() { ForceRequeueFromCurrentTimeInternal(); }, + this, [this]() { ForceRequeueFromCurrentTimeInternal(); }, Qt::QueuedConnection); } @@ -1001,7 +1001,7 @@ void ViewerWidget::ForceRequeueFromCurrentTimeInternal() playback_queue_next_frame_ = GetTimestamp() + playback_speed_ * Timecode::time_to_timestamp( - kRequeueWaitTime, timebase(), Timecode::kFloor); + kRequeueWaitTime, timebase(), Timecode::kFloor); ; first_requeue_watcher_ = nullptr; for (int i = 0; i < queue; i++) { @@ -1130,7 +1130,8 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only) // Verify audio processor output params are valid before using them AudioParams output_params = audio_processor_.to(); if (!output_params.is_valid()) { - qWarning() << "Audio processor output params are invalid, skipping audio playback"; + qWarning() + << "Audio processor output params are invalid, skipping audio playback"; } else { AudioManager::instance()->SetOutputNotifyInterval( output_params.time_to_bytes(kAudioPlaybackInterval)); @@ -1138,7 +1139,8 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only) &ViewerWidget::QueueNextAudioBuffer); static const int prequeue_count = 2; - prequeuing_audio_ = prequeue_count; // Queue two buffers ahead of time + prequeuing_audio_ = + prequeue_count; // Queue two buffers ahead of time audio_playback_queue_time_ = GetConnectedNode()->GetPlayhead(); for (int i = 0; i < prequeue_count; i++) { QueueNextAudioBuffer(); @@ -1506,17 +1508,13 @@ void ViewerWidget::RendererGeneratedFrameForQueue() // Ignore this signal if we've paused now if (IsPlaying() || prequeuing_video_) { - const qint64 start_ms = - watcher->property("start").toLongLong(); - const qint64 now_ms = - QDateTime::currentMSecsSinceEpoch(); + const qint64 start_ms = watcher->property("start").toLongLong(); + const qint64 now_ms = QDateTime::currentMSecsSinceEpoch(); const int playback_step = qMax(1, qAbs(playback_speed_)); - const double frame_interval_ms = qMax( - 1.0, - timebase().toDouble() * 1000.0 / - static_cast(playback_step)); - if (start_ms > 0 && - (now_ms - start_ms) > frame_interval_ms) { + const double frame_interval_ms = + qMax(1.0, timebase().toDouble() * 1000.0 / + static_cast(playback_step)); + if (start_ms > 0 && (now_ms - start_ms) > frame_interval_ms) { // If the queue is nearly empty, keep the frame anyway // to prevent the viewer from freezing entirely when // rendering can't keep up with playback speed. @@ -1544,7 +1542,7 @@ void ViewerWidget::RendererGeneratedFrameForQueue() } dw->queue()->AppendTimewise({ ts, push }, - playback_speed_); + playback_speed_); } } diff --git a/app/widget/viewer/viewerdisplay.cpp b/app/widget/viewer/viewerdisplay.cpp index e29fb5d9b..65193cee5 100644 --- a/app/widget/viewer/viewerdisplay.cpp +++ b/app/widget/viewer/viewerdisplay.cpp @@ -385,15 +385,15 @@ void ViewerDisplayWidget::OnPaint() // image itself will be rendered offscreen, downloaded, and painted below. bg_painter.begin(paint_device()); bg_painter_active = true; - bg_painter.fillRect(GetInnerRect(), - show_widget_background_ ? palette().window().color() : - Qt::black); + bg_painter.fillRect(GetInnerRect(), show_widget_background_ ? + palette().window().color() : + Qt::black); } else { // Clear background to empty QColor bg_color = show_widget_background_ ? palette().window().color() : Qt::black; - renderer()->ClearDestination(nullptr, bg_color.redF(), bg_color.greenF(), - bg_color.blueF()); + renderer()->ClearDestination(nullptr, bg_color.redF(), + bg_color.greenF(), bg_color.blueF()); } VideoParams device_params; @@ -412,13 +412,14 @@ void ViewerDisplayWidget::OnPaint() } else if (color_service()) { bool drew_backend_neutral_frame = false; if (FramePtr frame = load_frame_.value()) { - if (!drew_backend_neutral_frame && (!texture_ || - texture_->renderer() != - renderer() // Some implementations don't like it if we upload to a texture created in another (albeit shared) context - || texture_->width() != frame->width() || - texture_->height() != frame->height() || - texture_->format() != frame->format() || - texture_->channel_count() != frame->channel_count())) { + if (!drew_backend_neutral_frame && + (!texture_ || + texture_->renderer() != + renderer() // Some implementations don't like it if we upload to a texture created in another (albeit shared) context + || texture_->width() != frame->width() || + texture_->height() != frame->height() || + texture_->format() != frame->format() || + texture_->channel_count() != frame->channel_count())) { texture_ = renderer()->CreateTexture( frame->video_params(), frame->data(), frame->linesize_pixels()); @@ -427,9 +428,10 @@ void ViewerDisplayWidget::OnPaint() } } else if (TexturePtr texture = load_frame_.value()) { // This is a GPU texture, switch to it directly when possible. - if (!drew_backend_neutral_frame && texture && texture->renderer() && - texture->renderer() != renderer()) { - if (texture->renderer()->IsOpenGL() && renderer()->IsOpenGL()) { + if (!drew_backend_neutral_frame && texture && + texture->renderer() && texture->renderer() != renderer()) { + if (texture->renderer()->IsOpenGL() && + renderer()->IsOpenGL()) { // Shared OpenGL contexts can display the producer texture // directly. Avoid readback here because the producer // renderer may belong to a render thread whose context @@ -441,8 +443,8 @@ void ViewerDisplayWidget::OnPaint() frame->set_video_params(texture->params()); if (frame->allocate()) { texture->renderer()->DownloadFromTexture( - texture->id(), texture->params(), - frame->data(), frame->linesize_pixels()); + texture->id(), texture->params(), frame->data(), + frame->linesize_pixels()); texture_ = renderer()->CreateTexture( frame->video_params(), frame->data(), frame->linesize_pixels()); @@ -475,9 +477,11 @@ void ViewerDisplayWidget::OnPaint() } else { if (deinterlace_) { if (deinterlace_shader_.isNull()) { - deinterlace_shader_ = renderer()->CreateNativeShader( - ShaderCode(FileFunctions::ReadFileAsString( - QStringLiteral(":/shaders/deinterlace.frag")))); + deinterlace_shader_ = + renderer()->CreateNativeShader( + ShaderCode(FileFunctions::ReadFileAsString( + QStringLiteral( + ":/shaders/deinterlace.frag")))); } if (!deinterlace_texture_ || @@ -489,13 +493,15 @@ void ViewerDisplayWidget::OnPaint() } ShaderJob job; - job.Insert(QStringLiteral("resolution_in"), - NodeValue(NodeValue::kVec2, - QVector2D(texture_to_draw->width(), - texture_to_draw->height()))); - job.Insert(QStringLiteral("ove_maintex"), - NodeValue(NodeValue::kTexture, - QVariant::fromValue(texture_to_draw))); + job.Insert( + QStringLiteral("resolution_in"), + NodeValue(NodeValue::kVec2, + QVector2D(texture_to_draw->width(), + texture_to_draw->height()))); + job.Insert( + QStringLiteral("ove_maintex"), + NodeValue(NodeValue::kTexture, + QVariant::fromValue(texture_to_draw))); renderer()->BlitToTexture(deinterlace_shader_, job, deinterlace_texture_.get()); @@ -1453,28 +1459,30 @@ bool ViewerDisplayWidget::DrawBackendNeutralFrame(const FramePtr &frame, if (display_frame->format() == PixelFormat::U8 && display_frame->channel_count() == VideoParams::kRGBAChannelCount) { backend_neutral_cpu_display_frame_ = display_frame; - backend_neutral_cpu_image_ = QImage( - reinterpret_cast(display_frame->const_data()), - display_frame->width(), display_frame->height(), - display_frame->linesize_bytes(), QImage::Format_RGBA8888); + backend_neutral_cpu_image_ = + QImage(reinterpret_cast(display_frame->const_data()), + display_frame->width(), display_frame->height(), + display_frame->linesize_bytes(), QImage::Format_RGBA8888); source_image = backend_neutral_cpu_image_; } else if (display_frame->format() == PixelFormat::U8 && - display_frame->channel_count() == VideoParams::kRGBChannelCount) { + display_frame->channel_count() == + VideoParams::kRGBChannelCount) { backend_neutral_cpu_display_frame_ = display_frame; - backend_neutral_cpu_image_ = QImage( - reinterpret_cast(display_frame->const_data()), - display_frame->width(), display_frame->height(), - display_frame->linesize_bytes(), QImage::Format_RGB888); + backend_neutral_cpu_image_ = + QImage(reinterpret_cast(display_frame->const_data()), + display_frame->width(), display_frame->height(), + display_frame->linesize_bytes(), QImage::Format_RGB888); source_image = backend_neutral_cpu_image_; } else { backend_neutral_cpu_display_frame_.reset(); - const int bytes_per_pixel = display_frame->video_params().GetBytesPerPixel(); + const int bytes_per_pixel = + display_frame->video_params().GetBytesPerPixel(); if (backend_neutral_cpu_image_.size() != - QSize(display_frame->width(), display_frame->height()) || + QSize(display_frame->width(), display_frame->height()) || backend_neutral_cpu_image_.format() != QImage::Format_RGBA8888) { - backend_neutral_cpu_image_ = - QImage(display_frame->width(), display_frame->height(), - QImage::Format_RGBA8888); + backend_neutral_cpu_image_ = QImage(display_frame->width(), + display_frame->height(), + QImage::Format_RGBA8888); } for (int y = 0; y < display_frame->height(); ++y) { @@ -1547,20 +1555,18 @@ bool ViewerDisplayWidget::DrawBackendNeutralTexture(const TexturePtr &texture, // Renders a backend-neutral frame by drawing into an offscreen backend texture, // downloading it to CPU memory, then painting that image with QPainter. void ViewerDisplayWidget::DrawBackendNeutral(const ColorTransformJob &ctj, - QPainter *painter) + QPainter *painter) { if (!painter || !painter->isActive()) { return; } - const int texture_width = - static_cast(width() * devicePixelRatioF()); - const int texture_height = - static_cast(height() * devicePixelRatioF()); + const int texture_width = static_cast(width() * devicePixelRatioF()); + const int texture_height = static_cast(height() * devicePixelRatioF()); - const VideoParams offscreen_params( - texture_width, texture_height, PixelFormat::U8, - VideoParams::kRGBAChannelCount); + const VideoParams offscreen_params(texture_width, texture_height, + PixelFormat::U8, + VideoParams::kRGBAChannelCount); if (!backend_neutral_texture_ || backend_neutral_texture_->params() != offscreen_params) { @@ -1570,7 +1576,7 @@ void ViewerDisplayWidget::DrawBackendNeutral(const ColorTransformJob &ctj, backend_neutral_buffer_.resize( texture_width * texture_height * VideoParams::GetBytesPerPixel(PixelFormat::U8, - VideoParams::kRGBAChannelCount)); + VideoParams::kRGBAChannelCount)); } if (!backend_neutral_texture_ || backend_neutral_texture_->IsDummy()) { @@ -1589,11 +1595,10 @@ void ViewerDisplayWidget::DrawBackendNeutral(const ColorTransformJob &ctj, const int bytes_per_pixel = VideoParams::GetBytesPerPixel( PixelFormat::U8, VideoParams::kRGBAChannelCount); - QImage img(reinterpret_cast( - backend_neutral_buffer_.constData()), - texture_width, texture_height, - texture_width * bytes_per_pixel, - QImage::Format_RGBA8888_Premultiplied); + QImage img( + reinterpret_cast(backend_neutral_buffer_.constData()), + texture_width, texture_height, texture_width * bytes_per_pixel, + QImage::Format_RGBA8888_Premultiplied); img.setDevicePixelRatio(devicePixelRatioF()); // QImage references backend_neutral_buffer_ directly; draw it before the diff --git a/app/widget/viewer/viewerdisplay.h b/app/widget/viewer/viewerdisplay.h index 56aa8c9a6..291d95708 100644 --- a/app/widget/viewer/viewerdisplay.h +++ b/app/widget/viewer/viewerdisplay.h @@ -336,7 +336,8 @@ private: void DrawBackendNeutral(const ColorTransformJob &ctj, QPainter *painter); bool DrawBackendNeutralFrame(const FramePtr &frame, QPainter *painter); - bool DrawBackendNeutralTexture(const TexturePtr &texture, QPainter *painter); + bool DrawBackendNeutralTexture(const TexturePtr &texture, + QPainter *painter); /** * @brief Internal reference to the OpenGL texture to draw. Set in SetTexture() and used in paintGL(). diff --git a/app/widget/viewer/viewerqueue.h b/app/widget/viewer/viewerqueue.h index 0cb9c54d3..33ea2fbe4 100644 --- a/app/widget/viewer/viewerqueue.h +++ b/app/widget/viewer/viewerqueue.h @@ -38,10 +38,19 @@ struct ViewerPlaybackFrame { class ViewerQueue : public std::list { public: - ViewerQueue() : mutex_(new QMutex()) {} + ViewerQueue() + : mutex_(new QMutex()) + { + } ViewerQueue(const ViewerQueue &other) - : std::list(other), mutex_(new QMutex()) {} - ~ViewerQueue() { delete mutex_; } + : std::list(other) + , mutex_(new QMutex()) + { + } + ~ViewerQueue() + { + delete mutex_; + } ViewerQueue &operator=(const ViewerQueue &other) { std::list::operator=(other); diff --git a/app/window/CMakeLists.txt b/app/window/CMakeLists.txt index 5bfd0695e..ce6d5408c 100644 --- a/app/window/CMakeLists.txt +++ b/app/window/CMakeLists.txt @@ -17,7 +17,7 @@ add_subdirectory(mainwindow) set(OLIVE_SOURCES - ${OLIVE_SOURCES} - PARENT_SCOPE + ${OLIVE_SOURCES} + PARENT_SCOPE ) diff --git a/app/window/mainwindow/CMakeLists.txt b/app/window/mainwindow/CMakeLists.txt index f9bade703..a327410b1 100644 --- a/app/window/mainwindow/CMakeLists.txt +++ b/app/window/mainwindow/CMakeLists.txt @@ -15,16 +15,16 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - window/mainwindow/mainmenu.h - window/mainwindow/mainmenu.cpp - window/mainwindow/mainstatusbar.h - window/mainwindow/mainstatusbar.cpp - window/mainwindow/mainwindow.h - window/mainwindow/mainwindow.cpp - window/mainwindow/mainwindowlayoutinfo.h - window/mainwindow/mainwindowlayoutinfo.cpp - window/mainwindow/mainwindowundo.h - window/mainwindow/mainwindowundo.cpp - PARENT_SCOPE + ${OLIVE_SOURCES} + window/mainwindow/mainmenu.h + window/mainwindow/mainmenu.cpp + window/mainwindow/mainstatusbar.h + window/mainwindow/mainstatusbar.cpp + window/mainwindow/mainwindow.h + window/mainwindow/mainwindow.cpp + window/mainwindow/mainwindowlayoutinfo.h + window/mainwindow/mainwindowlayoutinfo.cpp + window/mainwindow/mainwindowundo.h + window/mainwindow/mainwindowundo.cpp + PARENT_SCOPE ) diff --git a/app/window/mainwindow/mainmenu.cpp b/app/window/mainwindow/mainmenu.cpp index 81a26401d..a090d11da 100644 --- a/app/window/mainwindow/mainmenu.cpp +++ b/app/window/mainwindow/mainmenu.cpp @@ -787,8 +787,8 @@ void MainMenu::SequenceCacheClearTriggered() void MainMenu::HelpFeedbackTriggered() { - QDesktopServices::openUrl( - QStringLiteral("https://github.com/olive-editor/olive/issues")); + QDesktopServices::openUrl(QStringLiteral( + "https://github.com/OakVideoEditorCommunity/oak/issues")); } void MainMenu::Retranslate() diff --git a/docker/README.md b/docker/README.md deleted file mode 100644 index fa0c08423..000000000 --- a/docker/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Docker Images - -Olive uses Docker containers for continuous integration on Linux. -No Docker images are involved for the Windows and macOS CI. - -## Overview - -`ci-common` is the shared build image with GCC, Clang and packages that are -needed by most dependent images. It is used to compile Olive's dependencies -in a controlled environment. The final CI image `ci-olive` is assembled from -images maintained by the Olive team as well as from -[aswf-docker](https://github.com/AcademySoftwareFoundation/aswf-docker/). - -Dependency hierarchy: - -1. `ci-common` -2. `ci-otio`, `ci-crashpad`, `ci-ffmpeg`, `ci-ocio` -3. `ci-olive` - -## Usage - -Pull images from [Docker Hub](https://hub.docker.com/u/olivevideoeditor): - -``` -docker pull olivevideoeditor/ci-common:2 -docker pull olivevideoeditor/ci-package-otio:0.14.1 -docker pull olivevideoeditor/ci-package-crashpad -docker pull olivevideoeditor/ci-package-ffmpeg:5.0 -docker pull olivevideoeditor/ci-package-ocio:2022-2.1.1 -docker pull olivevideoeditor/ci-olive:2022.2 -``` - -Use `ci-olive` image as local build container, by mounting working copy at -`~/olive` into guest system at `/opt/olive/olive`: - -```bash -docker run --rm -it -v ~/olive:/opt/olive/olive olivevideoeditor/ci-olive:2022.2 -mkdir build -cd build -cmake .. -G Ninja -cmake --build . -``` - -Rebuild all images locally: - -``` -cd docker -docker build -t olivevideoeditor/ci-common:2 -f ci-common/Dockerfile . -docker build -t olivevideoeditor/ci-package-otio:0.14.1 -f ci-otio/Dockerfile . -docker build -t olivevideoeditor/ci-package-crashpad -f ci-crashpad/Dockerfile . -docker build -t olivevideoeditor/ci-package-ffmpeg:5.0 -f ci-ffmpeg/Dockerfile . -docker build -t olivevideoeditor/ci-package-ocio:2022-2.1.1 -f ci-ocio/Dockerfile . -docker build -t olivevideoeditor/ci-olive:2022.2 -f ci-olive/Dockerfile . -``` - -Note that `2022` in `ci-olive:2022.2` stands for the -[VFX Reference Platform](http://vfxplatform.com/) calendar year and `2` for the -build image revision (should be incremented each time a new image is published). - -Publish images: - -``` -docker push olivevideoeditor/ci-common:2 -docker push olivevideoeditor/ci-package-otio:0.14.1 -docker push olivevideoeditor/ci-package-crashpad -docker push olivevideoeditor/ci-package-ffmpeg:5.0 -docker push olivevideoeditor/ci-package-ocio:2022-2.1.1 -docker push olivevideoeditor/ci-olive:2022.2 -``` diff --git a/docker/ci-common/Dockerfile b/docker/ci-common/Dockerfile deleted file mode 100644 index f7da97214..000000000 --- a/docker/ci-common/Dockerfile +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (C) 2022 Olive Team -# Copyright (c) Contributors to the aswf-docker Project. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later - -# Build image (default): -# docker build -t olivevideoeditor/ci-common:2 -f ci-common/Dockerfile . - -ARG OLIVE_ORG=olivevideoeditor -ARG ASWF_PKG_ORG=aswftesting -ARG CI_COMMON_VERSION=2 -ARG DTS_VERSION=9 -ARG CMAKE_VERSION=3.22.3 - -FROM ${ASWF_PKG_ORG}/ci-package-clang:${CI_COMMON_VERSION} as ci-package-clang -FROM ${ASWF_PKG_ORG}/ci-package-ninja:${CI_COMMON_VERSION} as ci-package-ninja - -FROM centos:7 as ci-common - -ARG OLIVE_ORG -ARG CI_COMMON_VERSION -ARG DTS_VERSION -ARG CMAKE_VERSION - -LABEL maintainer="olivevideoeditor@gmail.com" -LABEL org.opencontainers.image.name="$OLIVE_ORG/ci-common" -LABEL org.opencontainers.image.description="CentOS CI Shared Image" -LABEL org.opencontainers.image.url="http://olivevideoeditor.org" -LABEL org.opencontainers.image.source="https://github.com/olive-editor/olive" -LABEL org.opencontainers.image.vendor="Olive Team" -LABEL org.opencontainers.image.version="1.0" -LABEL org.opencontainers.image.licenses="GPL-3.0-or-later" - -USER root - -COPY scripts/common/install_yumpackages.sh \ - scripts/common/before_build.sh \ - scripts/common/copy_new_files.sh \ - /tmp/ - -ENV DTS_VERSION=${DTS_VERSION} -RUN /tmp/install_yumpackages.sh - -RUN mkdir /opt/olive -WORKDIR /opt/olive - -ENV OLIVE_ORG=${OLIVE_ORG} \ - CI_COMMON_VERSION=${CI_COMMON_VERSION} \ - CMAKE_VERSION=${CMAKE_VERSION} \ - LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/opt/rh/httpd24/root/usr/lib64:/opt/rh/devtoolset-${DTS_VERSION}/root/usr/lib64:/opt/rh/devtoolset-${DTS_VERSION}/root/usr/lib:${LD_LIBRARY_PATH} \ - PATH=/opt/rh/rh-git218/root/usr/bin:/usr/local/bin:/opt/rh/devtoolset-${DTS_VERSION}/root/usr/bin:/opt/app-root/src/bin:/opt/rh/devtoolset-${DTS_VERSION}/root/usr/bin/:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin - -#COPY scripts/common/install_sonar.sh \ -# scripts/common/install_ccache.sh \ -# /tmp/ - -COPY --from=ci-package-clang /. /usr/local/ -COPY --from=ci-package-ninja /. /usr/local/ - -#COPY scripts/common/setup_aswfuser.sh /tmp -#RUN /tmp/setup_aswfuser.sh - -COPY scripts/base/install_cmake.sh \ - /tmp/ - -RUN export DOWNLOADS_DIR=/tmp/downloads && \ - mkdir /tmp/downloads && \ -# source /tmp/versions_base.sh && \ - /tmp/install_cmake.sh && \ -# /tmp/patchup.sh && \ - rm -rf /tmp/downloads -# TODO: Remove scripts from /tmp ? diff --git a/docker/ci-crashpad/Dockerfile b/docker/ci-crashpad/Dockerfile deleted file mode 100644 index 0d2572a86..000000000 --- a/docker/ci-crashpad/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (C) 2022 Olive Team -# SPDX-License-Identifier: GPL-3.0-or-later - -# Build image (default): -# docker build -t olivevideoeditor/ci-package-crashpad -f ci-crashpad/Dockerfile . - -ARG OLIVE_ORG=olivevideoeditor -ARG CI_COMMON_VERSION=2 - -FROM ${OLIVE_ORG}/ci-common:${CI_COMMON_VERSION} as ci-crashpad - -ARG OLIVE_ORG -ARG CI_COMMON_VERSION - -LABEL maintainer="olivevideoeditor@gmail.com" -LABEL org.opencontainers.image.name="$OLIVE_ORG/ci-crashpad" -LABEL org.opencontainers.image.description="CentOS Crashpad Build Image" -LABEL org.opencontainers.image.url="http://olivevideoeditor.org" -LABEL org.opencontainers.image.source="https://github.com/olive-editor/olive" -LABEL org.opencontainers.image.vendor="Olive Team" -LABEL org.opencontainers.image.version="1.0" -LABEL org.opencontainers.image.licenses="GPL-3.0-or-later" - -COPY scripts/build_crashpad.sh \ - /tmp/ - -ENV OLIVE_ORG=${OLIVE_ORG} \ - CI_COMMON_VERSION=${CI_COMMON_VERSION} \ - OLIVE_INSTALL_PREFIX=/usr/local - -RUN /tmp/before_build.sh && \ - /tmp/build_crashpad.sh && \ - /tmp/copy_new_files.sh - -FROM scratch as ci-package-crashpad - -COPY --from=ci-crashpad /package / diff --git a/docker/ci-ffmpeg/Dockerfile b/docker/ci-ffmpeg/Dockerfile deleted file mode 100644 index 1a9a145ff..000000000 --- a/docker/ci-ffmpeg/Dockerfile +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (C) 2022 Olive Team -# SPDX-License-Identifier: GPL-3.0-or-later - -# Build image (default): -# docker build -t olivevideoeditor/ci-package-ffmpeg:5.0 -f ci-ffmpeg/Dockerfile . - -ARG OLIVE_ORG=olivevideoeditor -ARG CI_COMMON_VERSION=2 -ARG FFMPEG_VERSION=5.0 -ARG NASM_VERSION=2.15.05 -ARG YASM_VERSION=1.3.0 -ARG SVTAV1_VERSION=v1.1.0 -ARG X265_VERSION=3.5 -ARG OGG_VERSION=1.3.5 -ARG OPUS_VERSION=1.3.1 -ARG VORBIS_VERSION=1.3.7 -ARG THEORA_VERSION=1.1.1 -ARG VPX_VERSION=1.11.0 -ARG WEBP_VERSION=1.2.2 -ARG LAME_VERSION=3.100 -ARG XVID_VERSION=1.3.7 -ARG OPENJPEG_VERSION=2.4.0 -ARG LIBPNG_VERSION=1.6.37 -# TODO: Make version of x264 selectable? - -FROM ${OLIVE_ORG}/ci-common:${CI_COMMON_VERSION} as ci-ffmpeg - -ARG OLIVE_ORG -ARG CI_COMMON_VERSION -ARG FFMPEG_VERSION -ARG NASM_VERSION -ARG YASM_VERSION -ARG SVTAV1_VERSION -ARG X265_VERSION -ARG OGG_VERSION -ARG OPUS_VERSION -ARG VORBIS_VERSION -ARG THEORA_VERSION -ARG VPX_VERSION -ARG WEBP_VERSION -ARG LAME_VERSION -ARG XVID_VERSION -ARG OPENJPEG_VERSION -ARG LIBPNG_VERSION - -LABEL maintainer="olivevideoeditor@gmail.com" -LABEL org.opencontainers.image.name="$OLIVE_ORG/ci-ffmpeg" -LABEL org.opencontainers.image.description="CentOS FFmpeg Build Image" -LABEL org.opencontainers.image.url="http://olivevideoeditor.org" -LABEL org.opencontainers.image.source="https://github.com/olive-editor/olive" -LABEL org.opencontainers.image.vendor="Olive Team" -LABEL org.opencontainers.image.version="1.0" -LABEL org.opencontainers.image.licenses="GPL-3.0-or-later" - -COPY scripts/build_ffmpeg.sh \ - /tmp/ - -ENV OLIVE_ORG=${OLIVE_ORG} \ - CI_COMMON_VERSION=${CI_COMMON_VERSION} \ - FFMPEG_VERSION=${FFMPEG_VERSION} \ - NASM_VERSION=${NASM_VERSION} \ - YASM_VERSION=${YASM_VERSION} \ - SVTAV1_VERSION=${SVTAV1_VERSION} \ - X265_VERSION=${X265_VERSION} \ - OGG_VERSION=${OGG_VERSION} \ - OPUS_VERSION=${OPUS_VERSION} \ - VORBIS_VERSION=${VORBIS_VERSION} \ - THEORA_VERSION=${THEORA_VERSION} \ - VPX_VERSION=${VPX_VERSION} \ - WEBP_VERSION=${WEBP_VERSION} \ - LAME_VERSION=${LAME_VERSION} \ - XVID_VERSION=${XVID_VERSION} \ - OPENJPEG_VERSION=${OPENJPEG_VERSION} \ - LIBPNG_VERSION=${LIBPNG_VERSION} \ - OLIVE_INSTALL_PREFIX=/usr/local - -RUN /tmp/before_build.sh && \ - /tmp/build_ffmpeg.sh && \ - /tmp/copy_new_files.sh - -FROM scratch as ci-package-ffmpeg - -COPY --from=ci-ffmpeg /package/. / diff --git a/docker/ci-ocio/Dockerfile b/docker/ci-ocio/Dockerfile deleted file mode 100644 index 60e7fd83f..000000000 --- a/docker/ci-ocio/Dockerfile +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (C) 2022 Olive Team -# SPDX-License-Identifier: GPL-3.0-or-later - -# Build image (default): -# docker build -t olivevideoeditor/ci-package-ocio:2022-2.1.1 -f ci-ocio/Dockerfile . - -ARG OLIVE_ORG=olivevideoeditor -ARG ASWF_PKG_ORG=aswftesting -ARG CI_COMMON_VERSION=2 -ARG VFXPLATFORM_VERSION=2022 -# OCIO repo branch or tag name -ARG OCIO_VERSION=v2.1.1 -# Latest configs ~3 GB because of ACES 1.0.x. -# Upstream only copies nuke-default, therefore we also use the older configs. -ARG OCIO_CONFIGS_VERSION=1.0_r2 - -FROM ${OLIVE_ORG}/ci-common:${CI_COMMON_VERSION} as ci-ocio - -ARG OLIVE_ORG -ARG CI_COMMON_VERSION -ARG VFXPLATFORM_VERSION -ARG OCIO_VERSION -ARG OCIO_CONFIGS_VERSION - -LABEL maintainer="olivevideoeditor@gmail.com" -LABEL com.vfxplatform.version=$VFXPLATFORM_VERSION -LABEL org.opencontainers.image.name="$OLIVE_ORG/ci-otio" -LABEL org.opencontainers.image.description="CentOS OpenColorIO Build Image" -LABEL org.opencontainers.image.url="http://olivevideoeditor.org" -LABEL org.opencontainers.image.source="https://github.com/olive-editor/olive" -LABEL org.opencontainers.image.vendor="Olive Team" -LABEL org.opencontainers.image.version="1.0" -LABEL org.opencontainers.image.licenses="GPL-3.0-or-later" - -ENV OLIVE_ORG=${OLIVE_ORG} \ - CI_COMMON_VERSION=${CI_COMMON_VERSION} \ - VFXPLATFORM_VERSION=${VFXPLATFORM_VERSION} \ - OCIO_VERSION=${OCIO_VERSION} \ - OCIO_CONFIGS_VERSION=${OCIO_CONFIGS_VERSION} \ - OLIVE_INSTALL_PREFIX=/usr/local - -COPY scripts/build_ocio.sh \ - /tmp/ - -RUN /tmp/before_build.sh && \ - /tmp/build_ocio.sh && \ - /tmp/copy_new_files.sh - -FROM scratch as ci-package-ocio - -COPY --from=ci-ocio /package/. / diff --git a/docker/ci-oiio/Dockerfile b/docker/ci-oiio/Dockerfile deleted file mode 100644 index 27421beeb..000000000 --- a/docker/ci-oiio/Dockerfile +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (C) 2022 Olive Team -# SPDX-License-Identifier: GPL-3.0-or-later - -# Build image (default): -# docker build -t olivevideoeditor/ci-package-oiio:2.3.13.0 -f ci-oiio/Dockerfile . - -ARG ASWF_PKG_ORG=aswftesting -ARG OLIVE_ORG=olivevideoeditor -ARG CI_COMMON_VERSION=2 -ARG VFXPLATFORM_VERSION=2022 -ARG OIIO_VERSION=v2.3.13.0 -ARG YASM_VERSION=1.3.0 -ARG JPEG_TURBO_VERSION=2.1.3 - -FROM ${ASWF_PKG_ORG}/ci-package-boost:${VFXPLATFORM_VERSION} as ci-package-boost -FROM ${ASWF_PKG_ORG}/ci-package-openexr:${VFXPLATFORM_VERSION} as ci-package-openexr -FROM ${ASWF_PKG_ORG}/ci-package-imath:${VFXPLATFORM_VERSION} as ci-package-imath - -FROM ${OLIVE_ORG}/ci-common:${CI_COMMON_VERSION} as ci-oiio - -ARG OLIVE_ORG -ARG VFXPLATFORM_VERSION -ARG OIIO_VERSION -ARG YASM_VERSION -ARG JPEG_TURBO_VERSION - -LABEL maintainer="olivevideoeditor@gmail.com" -LABEL com.vfxplatform.version=$VFXPLATFORM_VERSION -LABEL org.opencontainers.image.name="$OLIVE_ORG/ci-oiio" -LABEL org.opencontainers.image.description="CentOS OpenImageIO Build Image" -LABEL org.opencontainers.image.url="http://olivevideoeditor.org" -LABEL org.opencontainers.image.source="https://github.com/olive-editor/olive" -LABEL org.opencontainers.image.vendor="Olive Team" -LABEL org.opencontainers.image.version="1.0" -LABEL org.opencontainers.image.licenses="GPL-3.0-or-later" - -ENV OLIVE_ORG=${OLIVE_ORG} \ - VFXPLATFORM_VERSION=${VFXPLATFORM_VERSION} \ - OIIO_VERSION=${OIIO_VERSION} \ - YASM_VERSION=${YASM_VERSION} \ - JPEG_TURBO_VERSION=${JPEG_TURBO_VERSION} \ - OLIVE_INSTALL_PREFIX=/usr/local - -COPY scripts/build_oiio.sh \ - /tmp/ - -COPY --from=ci-package-boost /. /usr/local/ -COPY --from=ci-package-openexr /. /usr/local/ -COPY --from=ci-package-imath /. /usr/local/ - -RUN curl -fLsS -o yasm.tar.gz "http://www.tortall.net/projects/yasm/releases/yasm-${YASM_VERSION}.tar.gz" && \ - tar xf yasm.tar.gz && \ - rm -f yasm.tar.gz && \ - cd yasm* && \ - ./configure --prefix="${OLIVE_INSTALL_PREFIX}" && \ - make -j$(nproc) && \ - make install && \ - cd .. && \ - rm -rf yasm* - -RUN /tmp/before_build.sh && \ - /tmp/build_oiio.sh && \ - /tmp/copy_new_files.sh - -FROM scratch as ci-package-oiio - -COPY --from=ci-oiio /package/. / diff --git a/docker/ci-olive/Dockerfile b/docker/ci-olive/Dockerfile deleted file mode 100644 index fab98dfc0..000000000 --- a/docker/ci-olive/Dockerfile +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (C) 2022 Olive Team -# SPDX-License-Identifier: GPL-3.0-or-later - -# Build image (default): -# docker build -t olivevideoeditor/ci-olive:2022.2 -f ci-olive/Dockerfile . -# -# .n is the build image revision number. It should be incremented each time a -# new image is published (also update the GitHub Actions workflow!). -# This allows to revert to a previous image should something go wrong. - -ARG OLIVE_ORG=olivevideoeditor -ARG ASWF_PKG_ORG=aswftesting -ARG CI_COMMON_VERSION=2 -ARG VFXPLATFORM_VERSION=2022 -ARG OCIO_VERSION=2.1.1 -ARG FFMPEG_VERSION=5.0 -ARG OTIO_VERSION=0.14.1 -ARG OIIO_VERSION=2.3.13.0 - -FROM ${ASWF_PKG_ORG}/ci-package-qt:${VFXPLATFORM_VERSION} as ci-package-qt -FROM ${ASWF_PKG_ORG}/ci-package-python:${VFXPLATFORM_VERSION} as ci-package-python -FROM ${ASWF_PKG_ORG}/ci-package-boost:${VFXPLATFORM_VERSION} as ci-package-boost -FROM ${ASWF_PKG_ORG}/ci-package-imath:${VFXPLATFORM_VERSION} as ci-package-imath -FROM ${ASWF_PKG_ORG}/ci-package-openexr:${VFXPLATFORM_VERSION} as ci-package-openexr -# A custom OIIO package without OpenVDB/Blosc/TBB would be smaller, -# but it currently does not pick up libwebp for some reason. -#FROM ${OLIVE_ORG}/ci-package-oiio:${OIIO_VERSION} as ci-package-oiio -FROM ${ASWF_PKG_ORG}/ci-package-oiio:${VFXPLATFORM_VERSION} as ci-package-oiio -FROM ${ASWF_PKG_ORG}/ci-package-openvdb:${VFXPLATFORM_VERSION} as ci-package-openvdb -FROM ${ASWF_PKG_ORG}/ci-package-blosc:${VFXPLATFORM_VERSION} as ci-package-blosc -FROM ${ASWF_PKG_ORG}/ci-package-tbb:${VFXPLATFORM_VERSION} as ci-package-tbb -#FROM ${ASWF_PKG_ORG}/ci-package-ocio:${VFXPLATFORM_VERSION}-${OCIO_VERSION} as ci-package-ocio -# Our package is compiled as RelWithDebInfo -FROM ${OLIVE_ORG}/ci-package-ocio:${VFXPLATFORM_VERSION}-${OCIO_VERSION} as ci-package-ocio -FROM ${OLIVE_ORG}/ci-package-ffmpeg:${FFMPEG_VERSION} as ci-package-ffmpeg -FROM ${OLIVE_ORG}/ci-package-crashpad:latest as ci-package-crashpad -FROM ${OLIVE_ORG}/ci-package-otio:${OTIO_VERSION} as ci-package-otio - -FROM ${OLIVE_ORG}/ci-common:${CI_COMMON_VERSION} as ci-olive - -ARG OLIVE_ORG -ARG VFXPLATFORM_VERSION -ARG PYTHON_VERSION=3.9 - -LABEL maintainer="olivevideoeditor@gmail.com" -LABEL com.vfxplatform.version=$VFXPLATFORM_VERSION -LABEL org.opencontainers.image.name="olivevideoeditor/ci-olive" -LABEL org.opencontainers.image.description="CentOS CI Olive Build Image" -LABEL org.opencontainers.image.url="http://olivevideoeditor.org" -LABEL org.opencontainers.image.source="https://github.com/olive-editor/olive" -LABEL org.opencontainers.image.vendor="Olive Team" -LABEL org.opencontainers.image.version="1.0" -LABEL org.opencontainers.image.licenses="GPL-3.0-or-later" - -ENV PYTHONPATH=/usr/local/lib/python${PYTHON_VERSION}/site-packages:${PYTHONPATH} \ - CRASHPAD_LOCATION=/usr/local/crashpad \ - VFXPLATFORM_VERSION=${VFXPLATFORM_VERSION} - -COPY --from=ci-package-qt /. /usr/local/ -COPY --from=ci-package-python /. /usr/local/ -COPY --from=ci-package-boost /. /usr/local/ -COPY --from=ci-package-imath /. /usr/local/ -COPY --from=ci-package-openexr /. /usr/local/ -COPY --from=ci-package-oiio /. /usr/local/ -# The ASWF OIIO package requires OpenVDB, Blosc, and TBB -COPY --from=ci-package-openvdb /. /usr/local/ -COPY --from=ci-package-blosc /. /usr/local/ -COPY --from=ci-package-tbb /. /usr/local/ -COPY --from=ci-package-ocio /. /usr/local/ -COPY --from=ci-package-ffmpeg /. /usr/local/ -COPY --from=ci-package-crashpad /. /usr/local/ -COPY --from=ci-package-otio /. /usr/local/ -COPY scripts/build_olive.sh /tmp/ - -RUN curl --location "https://github.com/probonopd/linuxdeployqt/releases/download/7/linuxdeployqt-7-x86_64.AppImage" \ - -o "/usr/local/linuxdeployqt-x86_64.AppImage" && \ - chmod a+x "/usr/local/linuxdeployqt-x86_64.AppImage" diff --git a/docker/ci-otio/Dockerfile b/docker/ci-otio/Dockerfile deleted file mode 100644 index 794b5797d..000000000 --- a/docker/ci-otio/Dockerfile +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (C) 2022 Olive Team -# SPDX-License-Identifier: GPL-3.0-or-later - -# Build image (default): -# docker build -t olivevideoeditor/ci-package-otio:0.14.1 -f ci-otio/Dockerfile . - -ARG OLIVE_ORG=olivevideoeditor -ARG ASWF_PKG_ORG=aswftesting -ARG CI_COMMON_VERSION=2 -ARG VFXPLATFORM_VERSION=2022 -ARG OTIO_VERSION=v0.14.1 -ARG CXX_STANDARD=17 - -# We are currently not interested in the Python implementation and bindings -#FROM ${ASWF_PKG_ORG}/ci-package-python:${VFXPLATFORM_VERSION} as ci-package-python -#FROM ${ASWF_PKG_ORG}/ci-package-qt:${VFXPLATFORM_VERSION} as ci-package-qt -#FROM ${ASWF_PKG_ORG}/ci-package-pyside:${VFXPLATFORM_VERSION} as ci-package-pyside - -FROM ${OLIVE_ORG}/ci-common:${CI_COMMON_VERSION} as ci-otio - -ARG OLIVE_ORG -ARG VFXPLATFORM_VERSION -ARG OTIO_VERSION -ARG CXX_STANDARD -ARG PYTHON_VERSION=3.9 - -LABEL maintainer="olivevideoeditor@gmail.com" -LABEL com.vfxplatform.version=$VFXPLATFORM_VERSION -LABEL org.opencontainers.image.name="$OLIVE_ORG/ci-otio" -LABEL org.opencontainers.image.description="CentOS OpenTimelineIO Build Image" -LABEL org.opencontainers.image.url="http://olivevideoeditor.org" -LABEL org.opencontainers.image.source="https://github.com/olive-editor/olive" -LABEL org.opencontainers.image.vendor="Olive Team" -LABEL org.opencontainers.image.version="1.0" -LABEL org.opencontainers.image.licenses="GPL-3.0-or-later" - -ENV OLIVE_ORG=${OLIVE_ORG} \ - CI_COMMON_VERSION=${CI_COMMON_VERSION} \ - VFXPLATFORM_VERSION=${VFXPLATFORM_VERSION} \ - OTIO_VERSION=${OTIO_VERSION} \ - CXX_STANDARD=${CXX_STANDARD} \ - OLIVE_INSTALL_PREFIX=/usr/local -# PYTHONPATH=/usr/local/lib/python${PYTHON_VERSION}/site-packages:/usr/local/lib/python \ - -COPY scripts/build_otio.sh \ - /tmp/ - -#COPY --from=ci-package-python /. /usr/local/ -#COPY --from=ci-package-qt /. /usr/local/ -#COPY --from=ci-package-pyside /. /usr/local/ - -RUN /tmp/before_build.sh && \ - /tmp/build_otio.sh && \ - /tmp/copy_new_files.sh - -FROM scratch as ci-package-otio - -COPY --from=ci-otio /package/. / diff --git a/docker/scripts/base/install_cmake.sh b/docker/scripts/base/install_cmake.sh deleted file mode 100644 index cab8bc1ff..000000000 --- a/docker/scripts/base/install_cmake.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) Contributors to the aswf-docker Project. All rights reserved. -# Modifications Copyright (C) 2025 mikesolar -# SPDX-License-Identifier: Apache-2.0 - - - - - -set -ex - -if [ ! -f "$DOWNLOADS_DIR/cmake-${CMAKE_VERSION}-Linux-x86_64.sh" ]; then - curl --location "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-Linux-x86_64.sh" -o "$DOWNLOADS_DIR/cmake-${CMAKE_VERSION}-Linux-x86_64.sh" -fi - -sh "$DOWNLOADS_DIR/cmake-${CMAKE_VERSION}-Linux-x86_64.sh" --skip-license --prefix=/usr/local --exclude-subdir diff --git a/docker/scripts/build_crashpad.sh b/docker/scripts/build_crashpad.sh deleted file mode 100644 index 7221ae297..000000000 --- a/docker/scripts/build_crashpad.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env bash -# Copyright (C) 2022 Olive Team -# Modifications Copyright (C) 2025 mikesolar -# SPDX-License-Identifier: GPL-3.0-or-later - - - - - -set -ex - -# Get Google's build tools -git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git - -# HACK: Compile our own gn. The one included in depot_tools requires GLIBC_2.18, -# but CentOS 7 only ships with GLIBC_2.17. -git clone https://gn.googlesource.com/gn -# NOTE: Don't clone with --depth 1, this will make build/gen.py fail! -cd gn -python build/gen.py -ninja -C out -cd .. -# Put the path to our own gn build first -PATH="$(pwd)/gn/out:$(pwd)/depot_tools:$PATH" -export PATH - -# Build Crashpad with Clang (default) -# Toolchain can be controlled with env vars CC, CXX and AR -mkdir crashpad -cd crashpad -git clone --depth 1 https://github.com/olive-editor/crashpad.git -gclient config https://github.com/olive-editor/crashpad.git -gclient sync -cd crashpad -# TODO: Do we want to set any special args here? For example: -# gn gen --args="target_cpu=\"x64\" is_debug=true" out/Default -gn gen out/Default -ninja -C out/Default - -# Include list -echo 'out/Default/crashpad_handler' > /tmp/crashpad_include_list.txt -find . \( -type f -o -type l \) \ - -name "*.h" -o \ - -name "*.o" -o \ - -name "*.a" | cut -c3- >> /tmp/crashpad_include_list.txt - -# Exclude list -echo '**/.git/** -compat/android/** -compat/ios/** -compat/mac/** -compat/non_elf/** -compat/win/** -handler/mac/** -handler/win/** -infra/** -minidump/test/** -out/Default/**_test* -snapshot/fuchsia/** -snapshot/ios/** -snapshot/mac/** -snapshot/win/** -test/** -third_party/fuchsia/** -third_party/gyp/gyp/test/** -third_party/mini_chromium/mini_chromium/base/fuchsia/** -third_party/mini_chromium/mini_chromium/testing/** -tools/mac/** -util/fuchsia/** -util/ios/** -util/mac/** -util/win/**' > /tmp/crashpad_exclude_list.txt - -rsync -av \ - --files-from=/tmp/crashpad_include_list.txt \ - --exclude-from=/tmp/crashpad_exclude_list.txt \ - --prune-empty-dirs \ - . "${OLIVE_INSTALL_PREFIX}/crashpad" - -cd ../.. - -# Build Breakpad for minidump_stackwalk -mkdir breakpad -cd breakpad -fetch breakpad -cd src -./configure --prefix="${OLIVE_INSTALL_PREFIX}" -make -j$(nproc) -make install diff --git a/docker/scripts/build_ffmpeg.sh b/docker/scripts/build_ffmpeg.sh deleted file mode 100644 index 98ad4197f..000000000 --- a/docker/scripts/build_ffmpeg.sh +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env bash -# Copyright (C) 2022 Olive Team -# Modifications Copyright (C) 2025 mikesolar -# SPDX-License-Identifier: GPL-3.0-or-later - - - - - -# Largely based on https://trac.ffmpeg.org/wiki/CompilationGuide/Centos -# -# Uses { command } & pattern for parallelism https://gist.github.com/thenadz/6c0584d42fb007582fbc -# -# TODO: Use advanced options such as LTO? e.g. https://code.videolan.org/videolan/x264/-/blob/master/configure -# TODO: Enable debug symbols? (Or is it opt-out?) -# TODO: Add more ffmpeg libraries? See https://raw.githubusercontent.com/jrottenberg/ffmpeg/master/docker-images/4.2/centos7/Dockerfile - -set -ex - -# Set up recent NASM -{ - curl -fLsS -o nasm.tar.xz "https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}/nasm-${NASM_VERSION}.tar.xz" - tar xf nasm.tar.xz - rm -f nasm.tar.xz - cd nasm* - ./autogen.sh - ./configure \ - --prefix="/usr" - make -j$(nproc) - make install - cd .. - rm -rf nasm* -} & - -# Set up recent YASM -{ - curl -fLsS -o yasm.tar.gz "http://www.tortall.net/projects/yasm/releases/yasm-${YASM_VERSION}.tar.gz" - tar xf yasm.tar.gz - rm -f yasm.tar.gz - cd yasm* - ./configure \ - --prefix="/usr" - make -j$(nproc) - make install - cd .. - rm -rf yasm* -} & - -# join jobs, some libs depend on NASM/YASM -wait - -# Set up libsvtav1 -{ - git clone --depth 1 --branch "${SVTAV1_VERSION}" "https://gitlab.com/AOMediaCodec/SVT-AV1.git" - cd SVT-AV1/Build - cmake .. \ - -G "Unix Makefiles" \ - -DCMAKE_INSTALL_PREFIX="${OLIVE_INSTALL_PREFIX}" \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_APPS=OFF - cmake --build . - cmake --install . - cd ../.. - rm -rf SVT-AV1 -} & - -# Set up libx264 -{ - # TODO: Checkout stable branch instead of master? - git clone --depth 1 "https://code.videolan.org/videolan/x264.git" - cd x264 - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --enable-shared \ - --enable-pic \ - --disable-cli - make - make install - cd .. - rm -rf x264 -} & - -# Set up libx265 -{ - # BitBucket dropped support for Mercurial repos - #hg clone https://bitbucket.org/multicoreware/x265 - # Need to fetch tags (off by default for shallow clones) or checkout a tag to avoid pkg-config error - git clone --depth 1 --branch "${X265_VERSION}" "https://bitbucket.org/multicoreware/x265_git.git" x265 - cd x265/build/linux - cmake \ - -G "Unix Makefiles" \ - -DCMAKE_INSTALL_PREFIX="${OLIVE_INSTALL_PREFIX}" \ - ../../source - make - make install - cd ../../.. - rm -rf x265 -} & - -# Set up libogg -{ - curl -fLsS -o libogg.tar.gz "http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz" - tar xf libogg.tar.gz - rm -f libogg.tar.gz - cd libogg* - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --enable-shared - make - make install - cd .. - rm -rf libogg* -} & - -# Set up libopus -{ - curl -fLsS -o opus.tar.gz "https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz" - tar xf opus.tar.gz - rm -f opus.tar.gz - cd opus* - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --enable-shared - make - make install - cd .. - rm -rf opus* -} & - -# join jobs, libvorbis and libtheora depend on libogg -wait - -# Set up libvorbis -{ - curl -fLsS -o libvorbis.tar.gz "http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERSION}.tar.gz" - tar xf libvorbis.tar.gz - rm -f libvorbis.tar.gz - cd libvorbis* - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --with-ogg="${OLIVE_INSTALL_PREFIX}" \ - --enable-shared - make - make install - cd .. - rm -rf libvorbis* -} & - -# Set up libtheora -{ - curl -fLsS -o libtheora.tar.gz "http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.gz" - tar xf libtheora.tar.gz - rm -f libtheora.tar.gz - cd libtheora* - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --with-ogg="${OLIVE_INSTALL_PREFIX}" \ - --enable-shared - make - make install - cd .. - rm -rf libtheora* -} & - -# Set up libvpx -{ - git clone --depth 1 --branch "v${VPX_VERSION}" "https://chromium.googlesource.com/webm/libvpx.git" - cd libvpx - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --enable-shared \ - --enable-pic \ - --enable-vp8 \ - --enable-vp9 \ - --enable-vp9-highbitdepth \ - --as=yasm \ - --disable-examples \ - --disable-unit-tests \ - --disable-docs \ - --disable-install-bins - make - make install - cd .. - rm -rf libvpx -} & - -### Set up libwebp -{ - curl -fLsS -o libwebp.tar.gz "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz" - tar xf libwebp.tar.gz - rm -f libwebp.tar.gz - cd libwebp* - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --enable-shared - make - make install - cd .. - rm -rf libwebp* -} & - -# Set up libmp3lame -{ - curl -fLsS -o lame.tar.gz "https://downloads.sourceforge.net/project/lame/lame/${LAME_VERSION}/lame-${LAME_VERSION}.tar.gz" - tar xf lame.tar.gz - rm -f lame.tar.gz - cd lame* - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --enable-shared \ - --enable-nasm \ - --disable-frontend - make - make install - cd .. - rm -rf lame* -} & - -### Set up xvid -{ - curl -fLsS -o xvidcore.tar.gz "https://downloads.xvid.com/downloads/xvidcore-${XVID_VERSION}.tar.gz" - tar xf xvidcore.tar.gz - rm -f xvidcore.tar.gz - cd xvidcore/build/generic - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --bindir="${OLIVE_INSTALL_PREFIX}/bin" - make - make install - cd ../../.. - rm -rf xvidcore -} & - -# Set up openjpeg -{ - curl -fLsS -o openjpeg.tar.gz "https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz" - tar xf openjpeg.tar.gz - rm -f openjpeg.tar.gz - cd openjpeg* - cmake \ - -DBUILD_THIRDPARTY:BOOL=ON \ - -DCMAKE_INSTALL_PREFIX="${OLIVE_INSTALL_PREFIX}" \ - . - make - make install - cd .. - rm -rf openjpeg* -} & - -# Set up libpng -{ - git clone --depth 1 "https://git.code.sf.net/p/libpng/code" libpng --branch "v${LIBPNG_VERSION}" - cd libpng - ./autogen.sh - ./configure \ - --prefix="${OLIVE_INSTALL_PREFIX}" - make check - make install - cd .. - rm -rf libpng -} & - -# join all jobs -wait - -curl -fLsS -o ffmpeg.tar.xz "https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.xz" -tar xf ffmpeg.tar.xz -cd ffmpeg* - -# TODO: --enable-debug? -PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:$PKG_CONFIG_PATH" ./configure \ - --disable-doc \ - --disable-ffplay \ - --enable-gpl \ - --enable-version3 \ - --enable-shared \ - --enable-libsvtav1 \ - --enable-libfreetype \ - --enable-libx264 \ - --enable-libx265 \ - --enable-libopus \ - --enable-libvorbis \ - --enable-libtheora \ - --enable-libvpx \ - --enable-libwebp \ - --enable-libmp3lame \ - --enable-libxvid \ - --enable-libopenjpeg \ - --prefix="${OLIVE_INSTALL_PREFIX}" \ - --extra-libs=-lpthread \ - --extra-libs=-lm \ - --extra-cflags="-I${OLIVE_INSTALL_PREFIX}/include" \ - --extra-ldflags="-L${OLIVE_INSTALL_PREFIX}/lib" -make -j$(nproc) -make install -cd .. -rm -rf ffmpeg* diff --git a/docker/scripts/build_ocio.sh b/docker/scripts/build_ocio.sh deleted file mode 100644 index fbddcfa82..000000000 --- a/docker/scripts/build_ocio.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -# Copyright (C) 2022 Olive Team -# Modifications Copyright (C) 2025 mikesolar -# SPDX-License-Identifier: GPL-3.0-or-later - - - - - -set -ex - -mkdir ocio -cd ocio - -git clone --depth 1 --branch "${OCIO_VERSION}" https://github.com/AcademySoftwareFoundation/OpenColorIO.git -cd OpenColorIO - -mkdir build -cd build -cmake \ - -DCMAKE_INSTALL_PREFIX="${OLIVE_INSTALL_PREFIX}" \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DOCIO_BUILD_APPS=OFF \ - -DOCIO_BUILD_NUKE=OFF \ - -DOCIO_BUILD_DOCS=OFF \ - -DOCIO_BUILD_TESTS=OFF \ - -DOCIO_BUILD_GPU_TESTS=OFF \ - -DOCIO_USE_HEADLESS=OFF \ - -DOCIO_BUILD_PYTHON=OFF \ - -DOCIO_BUILD_JAVA=OFF \ - -DOCIO_WARNING_AS_ERROR=OFF \ - -DOCIO_INSTALL_EXT_PACKAGES=ALL \ - .. -make -j$(nproc) -make install - -cd ../.. - -curl --location "https://github.com/imageworks/OpenColorIO-Configs/archive/v${OCIO_CONFIGS_VERSION}.tar.gz" -o "ocio-configs.tar.gz" -tar -zxf ocio-configs.tar.gz -cd "OpenColorIO-Configs-${OCIO_CONFIGS_VERSION}" - -mkdir "${OLIVE_INSTALL_PREFIX}/openColorIO" -cp nuke-default/config.ocio "${OLIVE_INSTALL_PREFIX}/openColorIO/" -cp -r nuke-default/luts "${OLIVE_INSTALL_PREFIX}/openColorIO/" - -cd ../.. -rm -rf ocio diff --git a/docker/scripts/build_oiio.sh b/docker/scripts/build_oiio.sh deleted file mode 100644 index b21bf6dcc..000000000 --- a/docker/scripts/build_oiio.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -# Copyright (C) 2022 Olive Team -# Modifications Copyright (C) 2025 mikesolar -# SPDX-License-Identifier: GPL-3.0-or-later - - - - - -set -ex - -# TODO: Move to install_yumpackages.sh -yum install -y \ - libtiff \ - libtiff-devel \ - libpng \ - libpng-devel - -git clone --depth 1 --branch "$JPEG_TURBO_VERSION" https://github.com/libjpeg-turbo/libjpeg-turbo -cd libjpeg-turbo -mkdir build -cd build -cmake -DCMAKE_INSTALL_PREFIX="${OLIVE_INSTALL_PREFIX}" \ - .. -make -j$(nproc) -make install -cd ../.. -rm -rf libjpeg-turbo - - -# TODO: Make OIIO pick up WebP (missing: WEBPDEMUX_LIBRARY) -git clone --depth 1 --branch "$OIIO_VERSION" https://github.com/OpenImageIO/oiio.git -cd oiio - -mkdir build -cd build -cmake -DCMAKE_INSTALL_PREFIX="${OLIVE_INSTALL_PREFIX}" \ - -DOIIO_BUILD_TOOLS=OFF \ - -DOIIO_BUILD_TESTS=OFF \ - -DVERBOSE=ON \ - -DUSE_PYTHON=0 \ - -DBoost_NO_BOOST_CMAKE=ON \ - .. -make -j$(nproc) -make install - -cd ../.. -rm -rf oiio diff --git a/docker/scripts/build_olive.sh b/docker/scripts/build_olive.sh deleted file mode 100644 index 76cc8ddf5..000000000 --- a/docker/scripts/build_olive.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash - -# -# Oak Video Editor - Non-Linear Video Editor -# Copyright (C) 2025 Olive CE Team -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -git clone --depth 1 https://github.com/olive-editor/olive.git -cd olive -mkdir build -cd build -cmake .. -G "Ninja" -cmake --build . - -cmake --install app --prefix appdir/usr - -# TODO: Can the following libs be excluded? -#libQt5DBus.so,\ -#libQt5MultimediaGstTools.so,\ -#libQt5MultimediaWidgets.so,\ - -/usr/local/linuxdeployqt-x86_64.AppImage \ - appdir/usr/share/applications/org.olivevideoeditor.Olive.desktop \ - -appimage \ - -exclude-libs=\ -libQt5Pdf.so,\ -libQt5Qml.so,\ -libQt5QmlModels.so,\ -libQt5Quick.so,\ -libQt5VirtualKeyboard.so \ - -bundle-non-qt-libs \ - -executable=appdir/usr/bin/crashpad_handler \ - -executable=appdir/usr/bin/minidump_stackwalk \ - -executable=appdir/usr/bin/olive-crashhandler \ - --appimage-extract-and-run - -./Olive*.AppImage --appimage-extract-and-run --version diff --git a/docker/scripts/build_otio.sh b/docker/scripts/build_otio.sh deleted file mode 100644 index 43edb61c1..000000000 --- a/docker/scripts/build_otio.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash -# Copyright (C) 2022 Olive Team -# Modifications Copyright (C) 2025 mikesolar -# SPDX-License-Identifier: GPL-3.0-or-later - - - - - -set -ex - -git clone --depth 1 --branch "$OTIO_VERSION" https://github.com/PixarAnimationStudios/OpenTimelineIO.git -cd OpenTimelineIO - -#pip install --prefix="${OLIVE_INSTALL_PREFIX}" . - -mkdir build -cd build -cmake .. -G "Ninja" \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_CXX_STANDARD="${CXX_STANDARD}" \ - -DCMAKE_INSTALL_PREFIX="${OLIVE_INSTALL_PREFIX}" \ - -DOTIO_PYTHON_INSTALL=OFF -cmake --build . -cmake --install . - -cd ../.. -rm -rf OpenTimelineIO diff --git a/docker/scripts/common/before_build.sh b/docker/scripts/common/before_build.sh deleted file mode 100644 index 277d80fc4..000000000 --- a/docker/scripts/common/before_build.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) Contributors to the aswf-docker Project. All rights reserved. -# Modifications Copyright (C) 2025 mikesolar -# SPDX-License-Identifier: Apache-2.0 - - - - - -set -ex - -rm -rf /package - -cd "${OLIVE_INSTALL_PREFIX}" -find . -type f -o -type l | cut -c3- > /tmp/previous-prefix-files.txt diff --git a/docker/scripts/common/copy_new_files.sh b/docker/scripts/common/copy_new_files.sh deleted file mode 100644 index 78a8340f5..000000000 --- a/docker/scripts/common/copy_new_files.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) Contributors to the aswf-docker Project. All rights reserved. -# Modifications Copyright (C) 2025 mikesolar -# SPDX-License-Identifier: Apache-2.0 - - - - - -set -ex - -mkdir -p /package - -cd "${OLIVE_INSTALL_PREFIX}" -find . -type l -o -type f | cut -c3- > /tmp/new-prefix-files.txt -rsync -av --files-from=/tmp/new-prefix-files.txt --exclude-from=/tmp/previous-prefix-files.txt . /package/ diff --git a/docker/scripts/common/install_yumpackages.sh b/docker/scripts/common/install_yumpackages.sh deleted file mode 100644 index 636909da7..000000000 --- a/docker/scripts/common/install_yumpackages.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env bash -# Copyright (C) 2022 Olive Team -# Modifications Copyright (C) 2025 mikesolar -# Copyright (c) Contributors to the aswf-docker Project. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later - - - - - -set -ex - -# TODO: Check if this causes any problems. ASWF doesn't run a yum update. -yum update -y - -# TODO: Add deps of deps which are explicitly listed in aswf-docker? -yum install --setopt=tsflags=nodocs -y \ - bzip2-devel \ - cups-libs \ - freetype-devel \ - giflib-devel \ - gstreamer1 \ - gstreamer1-devel \ - gstreamer1-plugins-bad-free \ - gstreamer1-plugins-bad-free-devel \ - libcurl-devel \ - libicu-devel \ - libmng-devel \ - LibRaw-devel \ - libwebp-devel \ - libXcomposite \ - libXcomposite-devel \ - libXcursor \ - libXcursor-devel \ - libxkbcommon \ - libxkbcommon-devel \ - libxkbcommon-x11-devel \ - libXScrnSaver \ - libXScrnSaver-devel \ - mesa-libGL-devel \ - numactl-devel \ - openjpeg2-devel \ - pciutils-devel \ - pulseaudio-libs \ - pulseaudio-libs-devel \ - python3-tkinter \ - xcb-util-image \ - xcb-util-image-devel \ - xcb-util-keysyms \ - xcb-util-keysyms-devel \ - xcb-util-renderutil \ - xcb-util-renderutil-devel \ - xcb-util-wm \ - xcb-util-wm-devel \ - zlib-devel - -# This is needed for Xvfb to function properly. -dbus-uuidgen > /etc/machine-id - -yum -y groupinstall "Development Tools" - -# TODO: Below code installs the obsolete devtoolset-6. -# Unclear which devtoolset it will be for VFX platform CY2021: -# https://groups.google.com/forum/#!topic/vfx-platform-discuss/_-_CPw1fD3c - -yum install -y --setopt=tsflags=nodocs centos-release-scl-rh yum-utils - -if [[ $DTS_VERSION == 6 ]]; then - # Use the centos vault as the original devtoolset-6 is not part of CentOS-7 anymore - sed -i 's/7/7.6.1810/g; s|^#\s*\(baseurl=http://\)mirror|\1vault|g; /mirrorlist/d' /etc/yum.repos.d/CentOS-SCLo-*.repo -fi - -yum install -y --setopt=tsflags=nodocs \ - "devtoolset-$DTS_VERSION-toolchain" - -yum install -y epel-release - -# Additional package that are not found initially -yum install -y \ - rh-git218 \ - portaudio-devel -# lame-devel -# libcaca-devel \ -# libdb4-devel \ -# libdc1394-devel \ -# openssl11-devel \ -# p7zip \ -# yasm-devel \ -# zvbi-devel - -# TODO: Does clearing the cache have any negative side effects? -yum clean all - -# HACK: Qt5GuiConfigExtras.cmake expects libGL.so in /usr/local/lib64 but it gets installed to /usr/lib64 -ln -s /usr/lib64/libGL.so /usr/local/lib64/ -# Alternatively, we could edit /usr/local/lib/cmake/Qt5Gui/Qt5GuiConfigExtras.cmake -# - _qt5gui_find_extra_libs(OPENGL "/usr/local/lib64/libGL.so" "" "") -# + _qt5gui_find_extra_libs(OPENGL "/usr/lib64/libGL.so" "" "") diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts deleted file mode 100644 index 9b13b7f50..000000000 --- a/docs/.vuepress/config.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { defineUserConfig } from "vuepress"; -import { hopeTheme } from "vuepress-theme-hope"; - -export default defineUserConfig({ - base: process.env.BASE || "/", - locales: { - "/": { - lang: "en-US", - title: "Oak Video Editor", - description: - "Open-source, non-linear video editor focused on speed and clarity.", - }, - "/zh/": { - lang: "zh-CN", - title: "Oak 视频编辑器", - description: "面向创作者的开源非线性剪辑软件。", - }, - }, - theme: hopeTheme({ - logo: "/images/oak-icon.png", - locales: { - "/": { - selectLanguageName: "English", - navbar: [ - { text: "Home", link: "/" }, - { text: "Build", link: "/build.html" }, - { text: "Project Files", link: "/project-file-reference.html" }, - { text: "Test Plan", link: "/test-plan.html" }, - ], - sidebar: [ - { - text: "Documentation", - children: [ - "/build.md", - "/project-file-reference.md", - "/test-plan.md", - ], - }, - ], - }, - "/zh/": { - selectLanguageName: "简体中文", - navbar: [ - { text: "首页", link: "/zh/" }, - { text: "构建", link: "/zh/build.html" }, - { text: "工程文件", link: "/zh/project-file-reference.html" }, - { text: "测试计划", link: "/zh/test-plan.html" }, - ], - sidebar: [ - { - text: "文档", - children: [ - "/zh/build.md", - "/zh/project-file-reference.md", - "/zh/test-plan.md", - "/zh/structure.md", - ], - }, - ], - }, - }, - }), -}); diff --git a/docs/.vuepress/public/images/oak-icon.png b/docs/.vuepress/public/images/oak-icon.png deleted file mode 100644 index 393dea9fe..000000000 Binary files a/docs/.vuepress/public/images/oak-icon.png and /dev/null differ diff --git a/docs/build.md b/docs/build.md index 713309c34..7f09be15d 100644 --- a/docs/build.md +++ b/docs/build.md @@ -179,6 +179,7 @@ sudo pacman -S --needed \ vulkan-headers \ vulkan-icd-loader \ libxkbcommon \ + fmt \ gcc ``` @@ -199,9 +200,9 @@ ctest --test-dir build --output-on-failure -C Release --- -## macOS (Non-Official Support) +## macOS -Note: macOS support is **non-official**. We only run CI automation on macOS and do not perform manual testing. +macOS is now a fully supported platform. See [`build_macos.md`](build_macos.md) for a dedicated, step-by-step guide. Install dependencies: diff --git a/docs/build_macos.md b/docs/build_macos.md new file mode 100644 index 000000000..72b5ca4dd --- /dev/null +++ b/docs/build_macos.md @@ -0,0 +1,256 @@ +# macOS Build Guide + +This document describes how to build Oak Video Editor from source on macOS. + +For the Chinese version, see [`build-macos-zh.md`](zh/build_macos-zh.md). + +--- + +## Prerequisites + +- macOS 12.0 (Monterey) or later +- [Homebrew](https://brew.sh/) package manager +- Xcode Command Line Tools + +### Install Xcode Command Line Tools + +```bash +xcode-select --install +``` + +--- + +## Install Dependencies + +### 1. Install Homebrew (if not already installed) + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +### 2. Install Build Tools and Libraries + +```bash +brew update +brew install cmake ninja pkg-config +``` + +### 3. Install Qt 6 + +```bash +brew install qt@6 +``` + +Add Qt 6 to your PATH (you may want to add this to your `~/.zshrc`): + +```bash +echo 'export PATH="/opt/homebrew/opt/qt@6/bin:$PATH"' >> ~/.zshrc +source ~/.zshrc +``` + +### 4. Install FFmpeg + +```bash +brew install ffmpeg +``` + +### 5. Install Image/Color Libraries + +```bash +brew install openimageio opencolorio openexr +``` + +### 6. Install Audio and XML Libraries + +```bash +brew install portaudio expat +``` + +### 7. Install Test Framework (Optional) + +Only needed if you plan to build and run tests: + +```bash +brew install googletest +``` + +--- + +## Build OpenTimelineIO (Optional) + +OpenTimelineIO enables importing/exporting timeline data in OTIO format. If you don't need OTIO support, you can skip this step. + +```bash +# Clone the repository +git clone --depth 1 --branch v0.16.0 https://github.com/PixarAnimationStudios/OpenTimelineIO.git +cd OpenTimelineIO + +# Configure and build +cmake -S . -B build -G Ninja \ + -DOTIO_SHARED_LIBS=ON \ + -DOTIO_PYTHON_BINDINGS=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="${PWD}/install" + +cmake --build build +cmake --install build +``` + +Note the installation path (e.g., `${PWD}/install`), you'll need it for the `OTIO_LOCATION` CMake option. + +--- + +## Clone and Build Oak Video Editor + +### 1. Clone the Repository + +```bash +git clone --recursive https://github.com/OakVideoEditorCommunity/oak.git +cd oak +``` + +> **Note:** Make sure to use `--recursive` to clone submodules, as Oak depends on several external libraries included as submodules. + +### 2. Configure with CMake + +Basic configuration (without OTIO): + +```bash +cmake -S . -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DOCIO_LOCATION=$(brew --prefix opencolorio) +``` + +Configuration with OTIO support: + +```bash +cmake -S . -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DOCIO_LOCATION=$(brew --prefix opencolorio) \ + -DOTIO_LOCATION=/path/to/otio/install \ + -DBUILD_TESTS=ON +``` + +### 3. Build + +```bash +cmake --build build --config Release +``` + +The build process may take 10-30 minutes depending on your hardware. + +--- + +## Run the Application + +After successful build, you can run Oak Video Editor: + +```bash +./build/app/oak-editor +``` + +Or open the app bundle (if generated): + +```bash +open ./build/app/Oak.app +``` + +--- + +## Run Tests (Optional) + +If you built with `-DBUILD_TESTS=ON`: + +```bash +ctest --test-dir build --output-on-failure -C Release +``` + +--- + +## Build Options + +| Option | Default | Description | +|--------|---------|-------------| +| `BUILD_TESTS` | `OFF` | Build unit tests | +| `BUILD_DOXYGEN` | `OFF` | Build Doxygen documentation | +| `USE_WERROR` | `OFF` | Treat warnings as errors | +| `OTIO_LOCATION` | - | Path to OpenTimelineIO installation (optional) | +| `OCIO_LOCATION` | - | Path to OpenColorIO installation | + +--- + +## Troubleshooting + +### Qt 6 Not Found + +If CMake cannot find Qt 6, ensure it's in your PATH: + +```bash +export PATH="/opt/homebrew/opt/qt@6/bin:$PATH" +export CMAKE_PREFIX_PATH="/opt/homebrew/opt/qt@6" +``` + +For Intel Macs, the path may be `/usr/local/opt/qt@6` instead. + +### OpenColorIO Not Found + +Make sure to specify the correct `OCIO_LOCATION`: + +```bash +-DOCIO_LOCATION=$(brew --prefix opencolorio) +``` + +### OpenImageIO Not Found + +Try reinstalling OpenImageIO: + +```bash +brew reinstall openimageio +``` + +### PortAudio Issues + +If you encounter audio-related build errors: + +```bash +brew reinstall portaudio +export PKG_CONFIG_PATH="/opt/homebrew/opt/portaudio/lib/pkgconfig:$PKG_CONFIG_PATH" +``` + +### Apple Silicon (M1/M2/M3) Specific Issues + +On Apple Silicon Macs, Homebrew installs to `/opt/homebrew` instead of `/usr/local`. Make sure your environment variables are set correctly: + +```bash +export PATH="/opt/homebrew/bin:$PATH" +export LIBRARY_PATH="/opt/homebrew/lib:$LIBRARY_PATH" +export CPATH="/opt/homebrew/include:$CPATH" +``` + +--- + +## Creating an App Bundle + +To create a distributable `.app` bundle, you may need to use `macdeployqt`: + +```bash +/opt/homebrew/opt/qt@6/bin/macdeployqt build/app/Oak.app +``` + +This will bundle the required Qt libraries into the app. + +--- + +## Uninstall + +To remove the built application: + +```bash +rm -rf build +``` + +To remove Homebrew dependencies (optional): + +```bash +brew uninstall qt@6 ffmpeg openimageio opencolorio openexr portaudio expat googletest +``` diff --git a/docs/test-plan.md b/docs/test-plan.md deleted file mode 100644 index 534c2eee9..000000000 --- a/docs/test-plan.md +++ /dev/null @@ -1,93 +0,0 @@ -# Oak Video Editor Testing Strategy and Plan - -This document describes the automated testing strategy for Oak Video Editor, including unit tests, integration tests, and CI execution. - -## Goals - -- Maximize automation and reduce manual testing. -- Cover all modules with at least one automated test. -- Keep integration tests headless (no GUI interaction). -- Make failures reproducible on Windows/macOS/Linux CI. - -## Test Layers - -### 1) Unit Tests (GoogleTest) -- Focus: small units, deterministic behavior, no GUI. -- Location: `tests/gtest/`. -- Execution: `ctest` target `olive-gtest`. - -### 1.5) Module Smoke Tests (GoogleTest) -- Focus: compile-time and link-time coverage for GUI-heavy modules without instantiating widgets. -- Location: `tests/gtest/module_smoke_test.cpp`. -- Execution: `ctest` target `olive-gtest`. - -### 2) Integration Tests (GoogleTest) -- Focus: cross-module flows without GUI (e.g., serialize → deserialize → resolve). -- Location: `tests/gtest/` (prefixed with `ProjectSerializer`, `TaskManager`, etc.). - -### 3) Legacy Tests (Olive macro tests) -- Existing tests in `tests/general`, `tests/timeline`, `tests/compositing` remain. - -## Module Coverage Map - -Each top-level module has at least one test that exercises its core API or serialization path. - -- `app/common`: `common_current_test.cpp`, `common_xmlutils_test.cpp` -- `app/config`: `config_test.cpp` -- `app/node`: `node_value_test.cpp`, `node_keyframe_test.cpp`, `node_serialization_test.cpp` -- `app/node/project/serializer`: `project_serializer_test.cpp` -- `app/render`: `render_videoparams_test.cpp`, `render_audioparams_test.cpp` -- `app/timeline`: `timeline_marker_test.cpp` -- `app/undo`: `undo_stack_test.cpp` -- `app/task`: `task_taskmanager_test.cpp` -- `app/codec`: `codec_frame_test.cpp` -- `app/pluginSupport`: `plugin_support_test.cpp` -- `app/audio`, `app/cli`, `app/dialog`, `app/panel`, `app/tool`, `app/ui`, `app/widget`, `app/window`: `module_smoke_test.cpp` - -If a module has a GUI dependency (e.g., widgets), tests focus on non-visual data/model components. - -## Integration Test Details - -### Project Serializer Roundtrip -- Creates a minimal project with a built-in node. -- Saves to XML via `ProjectSerializer::Save`. -- Loads with `ProjectSerializer::Load`. -- Verifies that nodes are restored. - -### Task Manager Execution -- Adds a dummy task to `TaskManager`. -- Waits for completion using an event loop. -- Verifies the task ran. - -## Unit Coverage Highlights (Expanded) - -- `app/undo`: `undo_stack_test.cpp` now covers empty stack state, model data, redo list coloring, jump behavior, and ignored empty multi-commands. -- `app/timeline`: `timeline_marker_test.cpp` now covers list ordering, closest-marker lookup, list save/load with unknown elements, and marker add/remove/change commands. -- `app/pluginSupport`: `plugin_support_image_test.cpp` now checks OFX property wiring (bounds/ROD, pixel depth, components, premult) and allocation clearing behavior. -- `app/render`: `render_videoparams_branch_test.cpp` now covers auto divider selection, pixel aspect validation, square-pixel width, and Save/Load roundtrip. - -## Headless Execution - -- Tests avoid QWidget usage. -- CI sets `QT_QPA_PLATFORM=offscreen` to prevent GUI initialization issues. - -## Continuous Integration - -CI runs on Windows, macOS, and Linux: - -1. Install system dependencies (Qt, FFmpeg, OpenImageIO, OpenColorIO, OpenEXR, PortAudio, Expat). -2. Configure with `-DBUILD_TESTS=ON`. -3. Build with CMake + Ninja. -4. Run `ctest` with output on failure. - -### Dependency Installation Notes -- Linux: use distro packages (`apt` on Ubuntu) for Qt6, FFmpeg, OpenImageIO, OpenColorIO, OpenEXR, PortAudio, Expat, OpenGL headers. -- macOS: use Homebrew for Qt6 and media/color/image libraries. -- Windows: use system installers where available (Qt via `install-qt-action`), and vcpkg for the remaining C/C++ libraries. - -## Adding New Tests - -- Place new unit tests in `tests/gtest`. -- Use GoogleTest conventions. -- Prefer deterministic fixtures and local-only resources. -- When adding a new module, add at least one unit test and one integration scenario if applicable. diff --git a/docs/zh/build.md b/docs/zh/build.md index dc051efbe..9dc4366ff 100644 --- a/docs/zh/build.md +++ b/docs/zh/build.md @@ -133,7 +133,7 @@ ctest --test-dir build --output-on-failure -C Release sudo dnf install -y \ cmake ninja-build pkgconf-pkg-config \ qt6-qtbase-devel qt6-qtbase-private-devel qt6-qttools-devel \ - ffmpeg-devel \ + ffmpeg-free-devel \ OpenImageIO-devel \ OpenColorIO-devel \ openexr-devel \ @@ -143,7 +143,8 @@ sudo dnf install -y \ vulkan-headers \ vulkan-loader-devel \ libxkbcommon-devel \ - gcc-c++ + gcc-c++ \ + bzip2-devel ``` 配置并构建: @@ -178,6 +179,7 @@ sudo pacman -S --needed \ vulkan-headers \ vulkan-icd-loader \ libxkbcommon \ + fmt \ gcc ``` @@ -198,9 +200,9 @@ ctest --test-dir build --output-on-failure -C Release --- -## macOS(非官方支持) +## macOS -说明:macOS **非官方支持**,目前只做 CI 自动化测试,不做人工测试。 +macOS 现在是正式支持的平台。更详细的逐步指南请参见 [`build_macos-zh.md`](build_macos-zh.md)。 安装依赖: diff --git a/docs/zh/build_macos-zh.md b/docs/zh/build_macos-zh.md new file mode 100644 index 000000000..4bee93b20 --- /dev/null +++ b/docs/zh/build_macos-zh.md @@ -0,0 +1,256 @@ +# macOS 编译指南 + +本文档介绍如何在 macOS 上从源代码构建 Oak 视频编辑器。 + +英文版本请参见 [`build-macos.md`](../build_macos.md)。 + +--- + +## 前置要求 + +- macOS 12.0 (Monterey) 或更高版本 +- [Homebrew](https://brew.sh/) 包管理器 +- Xcode 命令行工具 + +### 安装 Xcode 命令行工具 + +```bash +xcode-select --install +``` + +--- + +## 安装依赖 + +### 1. 安装 Homebrew(如果尚未安装) + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +### 2. 安装构建工具和库 + +```bash +brew update +brew install cmake ninja pkg-config +``` + +### 3. 安装 Qt 6 + +```bash +brew install qt@6 +``` + +将 Qt 6 添加到你的 PATH(建议添加到 `~/.zshrc`): + +```bash +echo 'export PATH="/opt/homebrew/opt/qt@6/bin:$PATH"' >> ~/.zshrc +source ~/.zshrc +``` + +### 4. 安装 FFmpeg + +```bash +brew install ffmpeg +``` + +### 5. 安装图像/色彩库 + +```bash +brew install openimageio opencolorio openexr +``` + +### 6. 安装音频和 XML 库 + +```bash +brew install portaudio expat +``` + +### 7. 安装测试框架(可选) + +仅在需要构建和运行测试时需要: + +```bash +brew install googletest +``` + +--- + +## 编译 OpenTimelineIO(可选) + +OpenTimelineIO 支持以 OTIO 格式导入/导出时间线数据。如果你不需要 OTIO 支持,可以跳过此步骤。 + +```bash +# 克隆仓库 +git clone --depth 1 --branch v0.16.0 https://github.com/PixarAnimationStudios/OpenTimelineIO.git +cd OpenTimelineIO + +# 配置并编译 +cmake -S . -B build -G Ninja \ + -DOTIO_SHARED_LIBS=ON \ + -DOTIO_PYTHON_BINDINGS=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="${PWD}/install" + +cmake --build build +cmake --install build +``` + +记下安装路径(例如 `${PWD}/install`),稍后在 CMake 配置中需要用到 `OTIO_LOCATION` 选项。 + +--- + +## 克隆并编译 Oak 视频编辑器 + +### 1. 克隆仓库 + +```bash +git clone --recursive https://github.com/OakVideoEditorCommunity/oak.git +cd oak +``` + +> **注意:** 请务必使用 `--recursive` 克隆子模块,因为 Oak 依赖于多个作为子模块包含的外部库。 + +### 2. 使用 CMake 配置 + +基础配置(不包含 OTIO): + +```bash +cmake -S . -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DOCIO_LOCATION=$(brew --prefix opencolorio) +``` + +包含 OTIO 支持的配置: + +```bash +cmake -S . -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DOCIO_LOCATION=$(brew --prefix opencolorio) \ + -DOTIO_LOCATION=/path/to/otio/install \ + -DBUILD_TESTS=ON +``` + +### 3. 编译 + +```bash +cmake --build build --config Release +``` + +编译过程可能需要 10-30 分钟,具体取决于你的硬件配置。 + +--- + +## 运行应用程序 + +编译成功后,你可以运行 Oak 视频编辑器: + +```bash +./build/app/oak-editor +``` + +或者打开应用程序包(如果已生成): + +```bash +open ./build/app/Oak.app +``` + +--- + +## 运行测试(可选) + +如果你使用 `-DBUILD_TESTS=ON` 构建了项目: + +```bash +ctest --test-dir build --output-on-failure -C Release +``` + +--- + +## 编译选项 + +| 选项 | 默认值 | 说明 | +|------|--------|------| +| `BUILD_TESTS` | `OFF` | 构建单元测试 | +| `BUILD_DOXYGEN` | `OFF` | 构建 Doxygen 文档 | +| `USE_WERROR` | `OFF` | 将警告视为错误 | +| `OTIO_LOCATION` | - | OpenTimelineIO 安装路径(可选) | +| `OCIO_LOCATION` | - | OpenColorIO 安装路径 | + +--- + +## 故障排除 + +### 找不到 Qt 6 + +如果 CMake 无法找到 Qt 6,请确保它已在 PATH 中: + +```bash +export PATH="/opt/homebrew/opt/qt@6/bin:$PATH" +export CMAKE_PREFIX_PATH="/opt/homebrew/opt/qt@6" +``` + +对于 Intel Mac,路径可能是 `/usr/local/opt/qt@6`。 + +### 找不到 OpenColorIO + +确保指定了正确的 `OCIO_LOCATION`: + +```bash +-DOCIO_LOCATION=$(brew --prefix opencolorio) +``` + +### 找不到 OpenImageIO + +尝试重新安装 OpenImageIO: + +```bash +brew reinstall openimageio +``` + +### PortAudio 问题 + +如果遇到与音频相关的编译错误: + +```bash +brew reinstall portaudio +export PKG_CONFIG_PATH="/opt/homebrew/opt/portaudio/lib/pkgconfig:$PKG_CONFIG_PATH" +``` + +### Apple Silicon (M1/M2/M3) 特定问题 + +在 Apple Silicon Mac 上,Homebrew 安装到 `/opt/homebrew` 而不是 `/usr/local`。确保环境变量设置正确: + +```bash +export PATH="/opt/homebrew/bin:$PATH" +export LIBRARY_PATH="/opt/homebrew/lib:$LIBRARY_PATH" +export CPATH="/opt/homebrew/include:$CPATH" +``` + +--- + +## 创建应用程序包 + +要创建可分发的 `.app` 包,你可能需要使用 `macdeployqt`: + +```bash +/opt/homebrew/opt/qt@6/bin/macdeployqt build/app/Oak.app +``` + +这会将所需的 Qt 库打包到应用程序中。 + +--- + +## 卸载 + +要删除已构建的应用程序: + +```bash +rm -rf build +``` + +要删除 Homebrew 依赖(可选): + +```bash +brew uninstall qt@6 ffmpeg openimageio opencolorio openexr portaudio expat googletest +``` diff --git a/docs/zh/color-lut-v04-plan.md b/docs/zh/color-lut-v04-plan.md deleted file mode 100644 index 1fe16cb2d..000000000 --- a/docs/zh/color-lut-v04-plan.md +++ /dev/null @@ -1,114 +0,0 @@ -# v0.4 调色与 LUT 实施计划 - -本文档对应 `docs/zh/README.md` 路线图中 v0.4「调色与 LUT」里程碑。 - -## 目标 - -- 支持 `.cube` 与 `.3dl` LUT 文件作为可用调色入口。 -- 完成示波器面板的波形、矢量、直方图三类视图。 -- 提供三向色轮面板,面向阴影、中间调、高光做基础调色控制。 -- 尽量复用现有 OpenColorIO、节点系统、Viewer/Scope 面板和 GPU 渲染管线,不引入独立的调色框架。 - -## 当前状态 - -- 已有 OpenColorIO 基础能力:颜色管理、显示变换、OCIO 调色节点和渲染侧配置。 -- Scope 面板已提供波形、矢量、直方图三类视图。 -- 已有色轮基础控件;当前三向调色先通过节点参数面板暴露 Shadows、Midtones、Highlights 三组颜色与强度参数。 -- LUT 节点已接入节点工厂,并已增加 `.cube`/`.3dl` 相关测试。 - -## 阶段 1:LUT 节点入口 - -状态:已完成首版。 - -交付内容: - -- 新增 OCIO LUT 节点,使用 OpenColorIO `FileTransform` 读取外部 LUT 文件。 -- 明确支持 `.cube` 与 `.3dl` 扩展名,并拒绝未知格式。 -- 在节点工厂中注册 LUT 节点,保证工程加载和节点创建路径一致。 -- 增加 gtest 覆盖 LUT 扩展名支持和简单 LUT 转换结果。 - -验收标准: - -- `olive-gtest` 中 LUT 相关测试通过。 -- `olive-editor` 和 `olive-render-worker` 可正常构建。 -- LUT 文件缺失、格式不支持、OCIO 处理器创建失败时不会导致崩溃。 - -## 阶段 2:示波器补齐 - -状态:已完成首版。 - -交付内容: - -- 保留现有波形和直方图视图。 -- 新增矢量示波器视图,并接入 Scope 面板下拉选择。 -- 矢量示波器应使用当前 Viewer 帧,并经过现有显示/颜色管理路径。 -- 为新增 shader 或资源入口增加资源存在性测试。 - -验收标准: - -- Scope 面板可在 Waveform、Vectorscope、Histogram 间切换。 -- 无当前帧时视图保持空白或安全占位,不崩溃。 -- shader 资源测试和编辑器构建通过。 - -## 阶段 3:三向色轮面板 - -状态:已完成节点参数面板首版;独立三向色轮 dock 面板作为后续体验增强。 - -交付内容: - -- 基于现有参数面板提供 Shadows、Midtones、Highlights 三组控制。 -- 为每组控制提供色彩偏移和强度/亮度相关参数。 -- 将三向色轮参数映射到现有 OCIO 调色节点,或新增可序列化节点承载参数。 -- 保证参数能随工程保存、加载、撤销和重做。 - -验收标准: - -- 用户可以在 UI 中操作三向调色参数并看到 Viewer 结果变化。 -- 参数在工程文件中可序列化并可恢复。 -- 节点参数变更不破坏现有 OCIO 调色节点兼容性。 - -## 阶段 4:集成与体验 - -状态:当前范围已完成;独立三向色轮 dock 面板和更细的交互体验作为后续增强。 - -交付内容: - -- 为 LUT 节点补齐清晰的文件选择过滤器和用户可见名称。已完成。 -- 在调色相关 UI 中保持命名一致:LUT、Waveform、Vectorscope、Histogram、Shadows、Midtones、Highlights。已完成首版。 -- 更新中文文档,说明 LUT、示波器和三向调色的当前入口。已在本文档记录。 - -验收标准: - -- 用户能从现有节点/UI 路径发现 LUT 和调色功能。 -- 文档与实际 UI 命名一致。 -- LUT 文件选择器限制为 `.cube` 与 `.3dl`,并保留 All Files 兜底。 -- 不引入和现有翻译系统冲突的硬编码字符串。 - -## 阶段 5:验证 - -状态:自动化构建和核心测试已通过;手动 Viewer/Scope 观感检查将在真实项目中继续验证。 - -构建命令: - -```sh -ninja -C cmake-build-debug olive-gtest olive-editor olive-render-worker -j2 -``` - -测试命令: - -```sh -QT_QPA_PLATFORM=offscreen cmake-build-debug/tests/gtest/olive-gtest --gtest_filter='ColorLut.*:ColorV04.*:Shaders.*:NodeSerialization.*:NodeValue.*' --gtest_brief=1 -``` - -手动检查: - -- 打开工程并加载一段素材。 -- 在 Scope 面板分别切换 Waveform、Vectorscope、Histogram。 -- 添加 LUT 节点并选择 `.cube` 或 `.3dl` 文件。 -- 调整三向色轮参数,确认 Viewer 输出和工程保存/加载行为。 - -## 风险与待定点 - -- 三向色轮应优先映射到 OCIO 现有调色能力;如果现有节点表达能力不足,再新增独立节点。 -- 矢量示波器 shader 需要兼容当前 OpenGL 版本和已有渲染抽象,避免只在单一驱动上可用。 -- LUT 文件路径序列化需要尊重现有工程文件路径策略,避免绝对路径导致工程不可迁移。 diff --git a/docs/ofx-pluginrenderer-functions-zh.md b/docs/zh/ofx-pluginrenderer-functions-zh.md similarity index 100% rename from docs/ofx-pluginrenderer-functions-zh.md rename to docs/zh/ofx-pluginrenderer-functions-zh.md diff --git a/docs/zh/proxy-media-v04-plan.md b/docs/zh/proxy-media-v04-plan.md deleted file mode 100644 index 943e8493c..000000000 --- a/docs/zh/proxy-media-v04-plan.md +++ /dev/null @@ -1,153 +0,0 @@ -# 代理媒体 v0.4 实施计划 - -## 背景 - -v0.4 已合并“调色、音频与性能”范围,其中代理媒体工作流负责解决 4K/8K 素材在时间线预览、剪辑和调色时的可用性问题。当前代码里已有音频 conform:`ConformManager` 会把音频流转为 PCM cache,但它不适合作为视频代理的直接扩展,因为视频代理需要保留容器、视频编码参数、文件生命周期和解码路由。 - -## 当前状态 - -实施进度: - -- 阶段 1 已完成:已写计划,新增代理状态、稳定文件名函数、`Footage` 代理字段和 XML roundtrip 测试。 -- 阶段 2 已完成:已新增 `ProxyTask` 和 `ProxyManager`,使用 `.working` 临时文件、成功 rename、失败清理,并覆盖状态测试。 -- 阶段 3 已完成:`FootageJob` 携带代理解码信息,预览路径使用 ready 代理,导出/online 路径默认原片,代理缺失自动回退。 -- 阶段 4 已完成:时间线右键已有 `Generate Proxy`、`Use Proxy`、`Reveal Proxy`、`Delete Proxy`。 -- 阶段 5 自动验证已完成;仍需实际 4K/8K 素材做手工播放、重开项目和导出确认。 - -- `app/codec/conformmanager.{h,cpp}` 只处理音频 PCM conform,输出按声道拆分的 `.pcm` 文件。 -- `app/task/conform/conform.{h,cpp}` 只调用 `Decoder::ConformAudio()`。 -- `Decoder::CodecStream` 当前只包含原始 `filename + stream index + block`,解码时会检查该文件存在。 -- `RenderProcessor::ProcessVideoFootage()` 和 `ProcessAudioFootage()` 通过 `FootageJob` 的 filename/decoder/stream index 打开素材。 -- `Footage` 当前保存原始文件名、探测参数、source start time 等项目级元数据,但还没有代理文件状态。 -- timeline 已有 cache/thumbnail/waveform 机制,但这是渲染缓存,不是替代源媒体的代理媒体。 - -## 目标 - -第一阶段交付一个最小但完整的代理工作流: - -- 右键选中项目素材或时间线 clip 可生成代理。 -- 代理文件写入项目 cache/proxy 目录,使用稳定 hash 命名。 -- `Footage` 记录代理状态,项目保存/加载后仍能识别代理。 -- 播放/预览时可选择使用代理,导出默认使用原始素材。 -- 代理缺失、生成中、失败时能安全回退原始素材。 -- 生成任务进入现有 `TaskManager`,支持取消和失败清理。 - -## 非目标 - -- 不在第一版实现复杂代理 preset UI。 -- 不在第一版实现云端/跨机器代理 relink。 -- 不在第一版替代现有 sequence render cache。 -- 不改变音频 conform 的 PCM 路径。 -- 不让导出默认走代理,避免质量风险。 - -## 设计 - -### 1. 新增 ProxyManager - -新增 `app/codec/proxymanager.{h,cpp}`,职责类似但独立于 `ConformManager`: - -- 根据源文件、stream index、代理参数生成目标文件名。 -- 判断代理状态:missing、generating、ready、failed。 -- 避免同一素材重复生成任务。 -- 使用 `.working` 临时文件,成功后原子 rename。 -- 发出 `ProxyReady` 信号通知 UI/缓存失效。 - -### 2. 新增 ProxyTask - -新增 `app/task/proxy/proxy.{h,cpp}`: - -- 输入原始文件、decoder id、视频 stream、代理参数、输出路径。 -- 第一版优先使用 FFmpeg CLI 或内部 FFmpeg 编码路径生成 H.264/MP4 代理。 -- 目标默认参数:较短边不超过 720p,保持宽高比,8-bit 4:2:0,CRF 23 左右。 -- 失败时写清晰 error,删除 `.working`。 - -如果当前构建环境不适合直接调用外部 `ffmpeg`,则优先使用项目内部编码接口;否则在任务内检测 `ffmpeg` 可执行文件并给出失败信息。 - -### 3. 扩展 Footage 代理元数据 - -在 `Footage` 中增加: - -- `proxy_enabled` -- `proxy_path` -- `proxy_state` -- `proxy_video_stream_index` -- `proxy_generation_preset/version` - -项目 XML 写入 `path`。 - -`Clear()` 不能无条件清掉已保存代理路径,只有换源文件或重新探测时才重置不兼容代理。 - -### 4. 解码路由 - -提供统一方法选择实际解码源: - -- 在线预览/时间线播放:如果项目/素材启用代理且代理 ready,则使用代理文件。 -- 离线渲染/导出:默认使用原文件。 -- 用户以后可加“导出使用代理”选项,但默认关闭。 - -优先在 `FootageJob` 构造或 `RenderProcessor::ProcessVideoFootage()` 前完成选择,避免把代理逻辑散落到 decoder 内部。 - -### 5. UI 入口 - -第一版入口: - -- 时间线 clip 右键:`Generate Proxy`、`Use Proxy`、`Reveal Proxy`、`Delete Proxy`。 -- 项目素材右键若已有菜单结构可复用,也增加同样入口;如果项目素材菜单结构分散,先实现时间线入口。 -- 菜单启用规则:仅视频素材可生成代理;代理生成中禁用重复生成;代理缺失时 `Use Proxy` 可显示但禁用。 - -### 6. 缓存和失效 - -代理 ready 后: - -- 触发相关 footage/clip 的 video frame cache、thumbnail cache invalidation。 -- 不触碰 audio conform cache。 -- 不删除已有原始媒体 render cache,避免用户切换代理/原片时状态不可恢复。 - -## 实施阶段 - -### 阶段 1:计划和基础数据结构 - -- 写本计划。 -- 添加 proxy 状态枚举和 filename 生成函数。 -- 添加 `Footage` 代理字段和 XML 保存/加载测试。 - -### 阶段 2:代理生成任务 - -- 添加 `ProxyTask`。 -- 添加 `ProxyManager`。 -- 生成 `.working` 文件,成功 rename。 -- 增加单元测试覆盖文件名稳定性和状态转换。 - -### 阶段 3:解码路由 - -- 扩展 `FootageJob` 或其创建点,携带“实际解码文件”。 -- 在线模式优先代理,离线/导出默认原片。 -- 代理缺失自动回退原片。 - -### 阶段 4:时间线 UI - -- 时间线右键增加生成/启用/删除代理动作。 -- 动作进入 undo 或直接项目状态变更;代理生成任务本身不进 undo。 -- 代理 ready 后刷新 timeline/viewer。 - -### 阶段 5:验证 - -- `ninja -C cmake-build-debug olive-gtest olive-editor -j22` -- 代理字段 XML roundtrip 测试。 -- ProxyManager 状态测试。 -- 手工测试:导入 4K 素材、生成代理、启用代理、播放、关闭重开项目、删除代理、导出确认默认原片。 - -## 风险 - -- 外部 `ffmpeg` 依赖不可用会让代理生成失败;需要清晰错误并不影响原片播放。 -- 代理视频 stream index 可能不同于原片,需要解码路由在代理文件里使用正确 stream。 -- 代理分辨率改变会影响 thumbnails/cache,需要切换后明确 invalidation。 -- 项目保存相对/绝对代理路径策略要谨慎;第一版使用 cache 目录内路径并可重建。 - -## 完成标准 - -- 用户能从时间线对视频 clip 生成代理。 -- 代理生成结束后,启用代理的在线预览路径实际读取代理文件。 -- 项目重开后代理状态保留。 -- 代理缺失或生成失败时不影响原始素材播放。 -- 相关构建和 gtest 通过。 diff --git a/docs/zh/render-backend-dynamic-plan.md b/docs/zh/render-backend-dynamic-plan.md deleted file mode 100644 index 96bc3b80c..000000000 --- a/docs/zh/render-backend-dynamic-plan.md +++ /dev/null @@ -1,161 +0,0 @@ -# 动态渲染后端拆分计划 - -## 目标 - -将当前强绑定 OpenGL 的渲染实现拆成可动态加载的后端库,使主程序只依赖一个轻量适配器: - -- OpenGL 后端封装到私有动态库。 -- Vulkan 后端封装到独立动态库。 -- 后端库内部继续使用 C++ 实现。 -- 后端库对外只导出 C ABI。 -- C ABI 使用不透明 handle 表示 C++ 对象。 -- 每个 C 函数对应一个后端类成员函数。 -- 构造函数导出为特殊 create 函数,析构函数导出为特殊 destroy 函数。 -- 主程序适配器构造时按配置显式加载后端库并调用 create/init,析构时调用 destroy 并卸载库。 - -## 命名约束 - -用户期望后端名为 `libgl.so` 和 `libvulkan.so`。Linux 系统上 `libGL.so`/`libgl.so` 容易和系统 OpenGL loader 混淆,因此工程实现应优先使用私有库名或私有目录,例如: - -- `liboakgl.so` -- `liboakvulkan.so` -- 或 `render_backends/libgl.so`、`render_backends/libvulkan.so` - -适配器只从 Oak 私有后端目录查找,避免加载到系统图形库。 - -## 阶段 1:OpenGL 动态后端骨架 - -- 新增稳定 C ABI 头:`app/render/backend/renderbackend_c.h`。 -- 新增 `DynamicRenderer` 适配器,继承现有 `Renderer`,内部用 `QLibrary` 加载后端。 -- 将现有 `OpenGLRenderer` 包装成 OpenGL 后端导出函数。 -- `RenderManager` 按 `GraphicsBackend` 选择加载 OpenGL 或 Vulkan 后端。 -- 在 Vulkan 后端未实现前,请求 Vulkan 时加载占位后端或回退 OpenGL,并记录明确 warning。 - -## 阶段 2:两层适配器 ABI - -本计划不是把 OpenGL 代码用 C 重写。动态库一侧继续保留现有 C++ `OpenGLRenderer`/未来 `VulkanRenderer` 实现,只在导出边界增加一层 C wrapper;主程序和渲染进程一侧再用 `DynamicRenderer` 把 C 函数封回 C++ `Renderer` 接口。 - -第一阶段 C ABI 可以用 `void *` 承载现有 C++ 对象指针,例如 `QVariant`、`VideoParams`、`ShaderCode`、`Texture`、`AcceleratedJob`。C 函数内部只做类型转换并调用对应 C++ 成员函数。这样两侧代码都不用大改,但有一个前提:后端库和主程序必须用同一套头文件、编译器 ABI 和 Qt/FFmpeg/OpenFX 依赖构建。 - -长期要把 ABI 稳定下来时,再逐步引入更明确的 C 结构,避免跨库暴露 Qt/C++ 类型: - -- texture handle:`OakBackendTextureHandle` -- shader handle:`OakBackendShaderHandle` -- video params C struct:宽、高、depth、pixel format、channel count、linesize -- shader code C struct:vertex/fragment 字符串 -- blit job C struct:输入 texture handle、uniform 数组、输出 texture handle -- readback/upload 使用裸指针和 stride - -这一步是 ABI 稳定化,不是把后端内部实现改成 C。 - -## 阶段 2.5:最小化 OpenGL/Vulkan 后端链接边界(已完成) - -此前 `oakgl`/`oakvulkan` 通过 `$` 把整个 editor 对象库链进动态库,导致后端库包含项目、节点、任务、cache、UI 等大量 editor 代码和全局状态。 - -本次已完成链接边界收敛: - -- 新增静态库 `libolive-rendercore`,仅包含渲染核心代码: - - 渲染器基类与数据类型:`Renderer`、`Texture`、`VideoParams`、`ShaderCode`、`AcceleratedJob`、`ShaderJob`。 - - 动态适配器:`DynamicRenderer`、`renderbackend_c.h`。 - - 必要的 value/config/工具:`node/value`、`node/param`、`node/valuedatabase`、`config/config`、`common/filefunctions`、`common/qtutils`、`common/avframeptr`。 -- `oakgl`/`oakvulkan` 现在只链接 `libolive-rendercore`,不再链接完整 `libolive-editor`。 -- `liboakgl.so` / `liboakvulkan.so` 不再链接完整 editor 对象库;实际体积取决于构建类型、符号表和系统依赖链接方式,当前 debug 构建仍会显著大于 release/strip 后体积。 -- 为隔离依赖做的头文件清理: - - `renderer.h` 移除 `node/node.h`、`render/colorprocessor.h`、`render/job/colortransformjob.h`、`job/pluginjob.h`,改为前向声明。 - - `videoparams.h` 移除 `ofxImageEffect.h`,OFX 字符串 setter 实现下移到 `videoparams.cpp`。 - - `texture.h` 用新增的 `common/avframeptr.h` 替代 `common/ffmpegutils.h`,避免后端拉入大量 FFmpeg 工具代码。 - - `renderer.cpp` 的颜色管理(`GetColorContext` / `BlitColorManaged`)和隔行(`InterlaceTexture`)实现分别拆到 `render/colormanagement.cpp` 和 `render/interlacetexture.cpp`,这两个文件仍由 editor/worker 链接,但不进入后端库。 -- 修复了拆分过程中暴露的 `StyleManager::kDefaultStyle` 跨库符号问题:改为 header 内 `inline static` 定义,使 `config.cpp` 在后端库中自包含。 - -剩余优化空间: -- 长远可将 `libolive-editor` 也改为依赖 `libolive-rendercore`,彻底消除渲染核心代码在主程序与后端库之间的重复编译/重复链接。当前阶段先保证后端边界干净、主程序保持兼容。 - -## 阶段 3:Vulkan 后端(offscreen 核心已实现,运行时依赖可用 Vulkan ICD) - -- 新增 Vulkan 后端库 `liboakvulkan.so`(当系统安装了 Vulkan 头文件/库时构建;无 Vulkan 环境时 CMake 自动跳过)。 -- 新增 `VulkanRenderer` 类,继承 `Renderer`,使用原生 Vulkan API 实现 offscreen 渲染管线;代码已合入,并在本机 NVIDIA Vulkan 驱动上通过了基础端到端渲染测试。 -- CMake 集成:根目录查找 `Vulkan` 和 `shaderc`(可选);`oakvulkan` 目标链接 `Vulkan::Vulkan` 与 `shaderc_shared`;若 `Vulkan` 未找到则不构建该库,避免无 Vulkan 头文件时编译失败。 -- 实现 Vulkan instance/device/queue/command pool 管理(代码层完成)。 -- 实现 offscreen image/texture 管理(`CreateNativeTexture` / `DestroyNativeTexture`),支持 2D/3D、多种 pixel format(U8/U16/F16/F32 × 1/2/3/4 channel);3-channel 格式会探测 `COLOR_ATTACHMENT` 支持并自动回退到 4-channel 等价格式。 -- 实现 staging buffer 上传/下载(`UploadToTexture` / `DownloadFromTexture`)。 -- 实现 `ClearDestination`(`vkCmdClearColorImage`)。 -- 实现 `Flush`(`vkDeviceWaitIdle`)。 -- 实现 GLSL → SPIR-V 运行时编译(通过 `shaderc`),支持顶点/片段共享 UBO、显式 sampler binding、顶点 uniform(如 `ove_mvpmat`)和常用 varyings。 -- 实现基础 graphics pipeline 用于 `Blit`(全屏 quad、顶点缓冲、按格式缓存的 render pass、combined image sampler descriptor set、persistent linear/nearest sampler、per-texture framebuffer cache)。 -- 提供 `GetPixelFromTexture`(基于 `DownloadFromTexture` 的简化实现)。 -- `oak_renderer_is_available` 现在会在首次检查时尝试 `Init()`,成功后报告 Vulkan 可用。 -- 测试更新: - - `LoadsExperimentalVulkanBackendWhenAvailable`:验证 Vulkan 后端可加载、初始化、报告能力位。 - - `FallsBackWhenExperimentalVulkanUnavailable`:在 Vulkan 不可用的系统上验证回退 OpenGL;在 Vulkan 可用的系统上自动 SKIP。 - - `VulkanUploadBlitDownload`:创建 Vulkan backend,上传 U8 RGBA 纹理,经默认 pass-through shader Blit 到目标纹理,再下载并验证像素一致;该测试在当前开发环境的真实 Vulkan 驱动上通过。 -- **已修复的明显问题(代码层)**: - - 初始化幂等性:`Init()` / `PostInit()` 可安全重复调用。 - - `Blit` 中的 descriptor/sampler 生命周期:sampler 与 descriptor set 在 `EndOneTimeCommands` 后统一释放。 - - sampler binding:从数组绑定改为显式 `layout(set=0, binding=N)`,避免跨驱动 array-of-samplers 行为不一致。 - - image layout 跟踪:输入纹理在绘制前被过渡到 `SHADER_READ_ONLY_OPTIMAL`。 - - viewport/scissor:改为 dynamic state,避免 pipeline 缓存 key 遗漏视口尺寸。 - - render pass clear:`clear_destination` 为 true 时 `loadOp` 设为 `CLEAR`。 - - 格式支持探测:通过 `vkGetPhysicalDeviceFormatProperties` 检查 `COLOR_ATTACHMENT` 能力,3-channel 不支持时回退到 4-channel(上传/下载的 CPU 侧通道对齐仍待完善)。 - - framebuffer / sampler 缓存:每张纹理延迟创建并复用 framebuffer;按插值模式复用 linear/nearest sampler。 - - 单通道纹理 swizzle:image view 组件映射为 R→RGB、A=1,匹配 OpenGL 灰度行为。 - - 纹理启用标志:为声明 `NAME_enabled` 的 shader 自动设置 0/1。 -- **已修复 / 已实现**: - - 链接边界已最小化,`liboakvulkan.so` 现在只依赖 `libolive-rendercore`。 - - 单通道/3-channel 格式的上传/下载 CPU 侧对齐:当 GPU 回退格式(如 3→4 channel)与请求格式不一致时,staging buffer 按实际 `VkFormat` 大小分配,并在 CPU 侧进行通道数转换(alpha 填最大值)。 - - `Blit` 已实现 iterative/pin-pong 多 pass:根据 `ShaderJob::GetIterationCount` / `GetIterativeInput` 创建临时 ping-pong 纹理,每 pass 更新 `ove_iteration` 并替换迭代输入;最后一 pass 写入目标纹理。 - - null-destination Blit 实现为渲染到临时 offscreen texture,保证调用不崩溃。 - - 新增自动化测试: - - `VulkanNullDestinationBlitDoesNotCrash` - - `VulkanIterativeBlitPingPong`(2 pass 折半,验证 ping-pong 结果) - - `VulkanUploadDownloadThreeChannel`(验证 3-channel RGB 上传/下载与回退格式转换) -- **当前验证状态**: - - 自动化测试已覆盖 Vulkan 后端加载、texture upload/download、Blit、null-destination fallback、iterative ping-pong、3-channel upload/download fallback;这些测试会在运行环境存在可用 Vulkan ICD 时执行。 - - 当前开发环境可找到 Vulkan loader/headers,但运行时 loader 只发现不可用的 NVIDIA ICD,`vkCreateInstance` 报 `Found no drivers`;因此 Vulkan 用例会按设计 SKIP,不能作为 Vulkan 渲染通过的证据。 - - Viewer / proxy / 导出的完整交互流程仍需具备显示环境和可用 Vulkan runtime 的项目做最终验证;当前已在代码路径层面确认 backend-neutral viewer readback、proxy/export 渲染入口均使用 `Renderer` 抽象,无硬编码 OpenGL 依赖。 - -## 阶段 4:Viewer 双后端(backend-neutral 路径已落地,Vulkan viewer 为原型) - -- 当前 viewer display 基于 OpenGL widget 和 GL texture id。 -- 默认构建下 Viewer 的 managed display 现在使用 `DynamicRenderer` 创建 renderer,并把现有 `QOpenGLContext` 传入动态后端;若动态后端加载失败则回退到 `OpenGLRenderer`。 -- `OAK_ENABLE_DYNAMIC_RENDER_BACKEND` 默认改为 `ON`,保留 `OFF` 作为应急开关。 -- 新增 backend-neutral viewer path 框架: - - `ManagedDisplayWidget` 支持非 OpenGL inner widget(普通 `QWidget`),通过 `Renderer::IsOpenGL()` 判断。 - - `RenderManager` 不再在 `requested_backend_ == kVulkan` 时强制 fallback。 - - `ViewerDisplayWidget` 已移除 `glIsTexture()` 的直接 OpenGL 依赖,改为通用的跨 renderer texture 拷贝。 - - `ScopeBase` 在 backend-neutral 时安全跳过(TODO:完整 scope display 路径)。 -- OpenGL 使用现有 `QOpenGLWidget/QOpenGLWindow`。 -- Vulkan / backend-neutral viewer readback display 路径(offscreen texture → download → QImage → QPainter)已搭建: - - 新增 `ManagedDisplayWidgetBackendNeutral`,在普通 `QWidget` 的 `paintEvent` 中转发到 `ManagedDisplayWidget::OnPaint`。 - - `ViewerDisplayWidget::OnPaint` 在 backend-neutral 模式下改用 `QPainter` 填充背景,将颜色管理后的画面渲染到 U8 RGBA offscreen texture,再 `Download` 到 CPU buffer,最后用 `QImage::Format_RGBA8888_Premultiplied` + `setDevicePixelRatio` 绘制到 inner widget。 - - OpenGL 路径保持原有 `BlitColorManaged` 直接到 widget 不变。 -- Viewer 只消费后端 texture handle 或 readback frame,不直接假设 GL texture id。 -- **状态说明**:backend-neutral 代码已合并;VulkanRenderer 现在可完成单 pass Blit,Viewer 的 backend-neutral readback 路径在代码层面可工作,但尚未在完整 UI 播放/导出流程中验证。 - -## 阶段 5:OpenFX 处理边界(边界框架已完成,Vulkan 路径待验证) - -- OpenFX 插件 OpenGL 渲染路径保留 OpenGL 依赖,不强行改写。 -- `PluginRenderer` 不再继承 `OpenGLRenderer`,改为持有通用的 `Renderer *`: - - OpenGL 渲染路径仅在 `renderer_->IsOpenGL()` 为 true 时启用,并正确调用 `OlivePluginInstance::setOpenGLEnabled(use_opengl)`。 - - 非 OpenGL 渲染器(Vulkan、DynamicRenderer 加载的任意后端)自动回退到 CPU readback/upload 路径,不再因缺少 OpenGL context 而直接跳过插件渲染。 -- 将 OFX 输出纹理绑定/解绑抽象为 `Renderer::AttachOutputTexture` / `DetachOutputTexture`: - - `OpenGLRenderer` 实现为 `AttachTextureAsDestination` / `DetachTextureAsDestination`。 - - C ABI 新增 `oak_renderer_attach_output_texture` / `oak_renderer_detach_output_texture`。 - - `DynamicRenderer` 通过 C ABI 转发,使动态 OpenGL 后端也能支持 OFX OpenGL 渲染。 - - `VulkanRenderer` 默认 no-op,Vulkan 项目中的 OFX 插件回退到 CPU 路径。 -- 格式转换(`ConvertFrameIfNeeded`、`ConvertTextureForParams`)、readback(`ReadbackTextureToFrame`)、upload 等辅助函数保持后端无关,通过 `Renderer` 接口调用,无需移入后端库。 -- `RenderProcessor::ProcessPluginJob` 不再要求 `render_ctx_` 实现 `OpenGLContextProvider`,任何 `Renderer` 都能驱动插件渲染。 -- 更新相关 gtest:`PluginRenderer` 构造函数现在需要传入 renderer 指针,测试传入 `nullptr` 验证纯 CPU 路径。 -- **状态说明**:后端无关的边界框架和 OpenGL 动态路径已可编译并通过现有测试;Vulkan 下的 OFX CPU 回退路径代码已就位,并在 Vulkan 可完成基础 Blit 的当前版本上具备验证条件。 - -## 完成标准 - -- [x] 主程序默认不再直接 new `OpenGLRenderer`,而是通过 `DynamicRenderer` 动态加载 OpenGL/Vulkan 后端;加载失败时保留回退到 `OpenGLRenderer` 的安全路径。 -- [x] `OAK_ENABLE_DYNAMIC_RENDER_BACKEND` 默认 `ON`,`liboakgl.so` 默认构建并安装;`liboakvulkan.so` 在检测到 Vulkan 开发库时构建并安装。 -- [x] OpenGL 后端库可单独构建、加载、初始化、销毁。 -- [x] 用户能在配置中选择 OpenGL/Vulkan。 -- [x] Vulkan 不可用时自动回退到 OpenGL,不崩溃;`RenderManager::backend()` 会在 `DynamicRenderer` 内部回退后同步为实际运行后端。 -- [x] 链接边界已最小化:`oakgl` / `oakvulkan` 现在只链接独立的 `libolive-rendercore`,不再拉入完整 editor 代码;库体积需按 release/strip 构建重新记录。 -- [ ] Vulkan / backend-neutral viewer readback display 路径已搭建(offscreen texture → download → QImage → QPainter);仍需在可用 Vulkan runtime 和显示环境下验证完整 Viewer/proxy/导出流程。 -- [x] OpenFX 插件渲染边界已处理:`PluginRenderer` 后端无关化,非 OpenGL 渲染器自动回退 CPU 路径,动态 OpenGL 后端通过 C ABI 支持 OFX OpenGL 输出绑定。 -- [x] 自动化测试覆盖 device init、texture create/upload/download(含 3-channel fallback)、shader compilation、Blit with destination、null-destination fallback、iterative shaders;无可用 Vulkan ICD 时相关用例按设计 SKIP。 -- [ ] 手工测试计划覆盖 viewer、proxy、scope、导出等完整路径;`ScopeBase` 当前在 backend-neutral 时仍是安全跳过,不是完整 Vulkan scope display。 diff --git a/docs/zh/render-process-isolation-plan.md b/docs/zh/render-process-isolation-plan.md deleted file mode 100644 index 6eddf634b..000000000 --- a/docs/zh/render-process-isolation-plan.md +++ /dev/null @@ -1,280 +0,0 @@ -# 渲染独立进程化 — 实现计划 - -> **状态**:实施中(阶段 0–5 已完成,阶段 6 可选优化未做) -> **分支**:`feat/render-process-isolation` -> **范围**:把视频帧渲染拆到独立进程,主进程通过共享内存 + stdio 调度多个渲染 worker,全程无锁。 - ---- - -## 1. 背景(为什么做) - -Oak(Olive 分叉,Qt6/C++17 视频编辑器)当前是**单进程**架构:所有渲染在主进程的后台 -`QThread` 里完成(`app/render/rendermanager.cpp` 的 `video_thread_` / `audio_thread_` / -`waveform_threads_` 等),通过 `RenderManager::RenderFrame()` → `RenderThread` 队列 → -`RenderProcessor::Process()` 的 ticket 异步管线工作。 - -把渲染留在主进程有三个问题: - -1. **崩溃传染** —— OFX 第三方插件(0.3 里程碑的核心目标“任意 OFX 插件加载不崩溃”)一旦崩溃,会带走整个编辑器,丢失未保存的工作。 -2. **难以横向扩展** —— GPU 上下文、解码器缓存都绑在一个进程里,无法利用多核/多 GPU 并行。 -3. **预渲染受限** —— 预渲染窗口(见 `TODO.md` 的 LRU 预渲染计划)受单进程资源约束。 - -**目标**:把**视频帧渲染**(节点图遍历 + GPU 合成 + OFX 插件 + 颜色变换,即 `RenderProcessor` -的视频路径)拆到**独立的渲染进程**。主进程作为调度器,通过**共享内存 + stdio** 与**多个**渲染 -worker 通信。硬性要求**无锁**:跨进程数据交换走预分配的共享内存 slot 池 + SPSC 环形索引队列, -控制平面走 stdio 上的换行分隔消息。 - -### 1.1 已确认的范围决策 - -| 维度 | 决策 | -|---|---| -| **拆分范围** | 仅**视频帧渲染**。音频/波形/dry-run 暂留主进程。→ worker 链接 OpenGL / OCIO / OpenImageIO / OFX,**不**链接 UI(Widgets)。 | -| **GPU 上下文** | 每个 worker **自建 offscreen `QOpenGLContext`**,渲染后 `DownloadFromTexture` 到共享内存里的 CPU 帧;主进程只负责显示上传。 | -| **素材输入** | **主进程解码**(复用现有 `DecoderCache`),把解码后的原始帧经共享内存喂给 worker。→ worker **不**链接 FFmpeg。 | -| **图同步** | **全量序列化**整个节点图(复用 `ProjectSerializer`),架构预留增量通道。 | -| **帧回传** | **固定 slot 池 + 无锁环形队列**(按最大分辨率预分配)。 | -| **控制协议** | **纯文本 NDJSON**(每行一条 JSON),便于 `cat`/`tee` 调试、手工注入测试。大块图数据走临时文件传路径。 | -| **落地策略** | **分阶段**,每步可编译可验证,旧的进程内渲染保留为默认,用开关切换。 | - ---- - -## 2. 现有架构锚点(复用,不重写) - -| 关注点 | 文件 / 符号 | -|---|---| -| 渲染调度/线程池 | `app/render/rendermanager.{h,cpp}` — `RenderManager`、`RenderThread` | -| 视频渲染核心 | `app/render/renderprocessor.{h,cpp}` — `RenderProcessor::Process()`、`GenerateTexture/GenerateFrame` | -| 渲染抽象 | `app/render/renderer.h`、`app/render/opengl/openglrenderer.{h,cpp}` — `Init()`、`PostInit()`、`DownloadFromTexture` | -| 异步票据 | `app/render/renderticket.{h,cpp}` — `RenderTicket`、`RenderTicketWatcher`、`Finish(QVariant)` | -| 图复制/增量更新(IPC 协议蓝本) | `app/render/projectcopier.{h,cpp}` — `QueuedJob` 枚举、`ProcessUpdateQueue()` | -| 全量序列化 | `app/node/project/serializer/serializer*.{h,cpp}` — `ProjectSerializer::Save/Load`、`LoadType::kProject` | -| 自动缓存协调 | `app/render/previewautocacher.{h,cpp}` — 票据的实际消费者 | -| 帧内存(单段连续 buffer) | `app/codec/frame.{h,cpp}` + `app/render/framemanager.h` — `data_`/`linesize_`/`allocated_size()` | -| 帧消费/显示 | `app/widget/viewer/viewer.cpp` — `SetDisplayImage()`、`ticket->Get()` | -| 进程入口 | `app/main.cpp` — `QSurfaceFormat` 设置(OpenGL 3.2 core)、`AA_ShareOpenGLContexts` | -| 构建 | 根 `CMakeLists.txt`、`app/CMakeLists.txt` — `add_executable(olive-editor ...)` + `libolive-editor` OBJECT 库 | - -**关键观察**: - -- `RenderProcessor::Process()` 已是无状态静态入口,参数全在 `ticket->property(...)` 里。这是进程边界的天然切割点。 -- `Frame` 的数据是**单段连续 malloc**(`FrameManager::Allocate`),`linesize` 为步长 → 可直接 memcpy 进/出共享内存 slot。 -- `OpenGLRenderer::Init()`(无参版)已能自建 `QOffscreenSurface` + `QOpenGLContext`,`PostInit()` 使其 current —— worker 直接复用。 -- 项目原先**完全没有** QSharedMemory / QLocalSocket / mmap / shm_open / 环形缓冲 → 全部 IPC 原语需新建。 -- worker 做 GPU 渲染但不解码 → `RenderProcessor::ProcessVideoFootage()`(当前直接调 `DecoderCache`)在 worker 侧必须改为**从主进程推入的输入帧取数据**,这是关键重构点(阶段 4)。 - ---- - -## 3. 目标架构 - -``` -┌─────────────────── 主进程 (olive-editor) ───────────────────┐ -│ Viewer / PreviewAutoCacher │ -│ │ GetSingleFrame() │ -│ ▼ │ -│ RenderManager (调度器) │ -│ ├─ DecoderCache ← 解码原始素材帧 │ -│ ├─ RenderWorkerPool ← 新增 │ -│ │ ├─ WorkerProcess #0 (QProcess + stdio + SHM) │ -│ │ ├─ WorkerProcess #1 │ -│ │ └─ ... │ -│ └─ ProjectSerializer ← 全量图快照 │ -└─────────────────────────────────────────────────────────────┘ - stdio (控制平面: NDJSON, 每行一条 JSON 消息) - SHM (数据平面: 输入素材帧 slot 池 + 输出帧 slot 池, 无锁环形索引) - │ -┌──────────────── 渲染进程 (olive-render-worker) ×N ───────────┐ -│ workermain: 读 stdin NDJSON 控制循环 │ -│ ├─ 反序列化节点图 (ProjectSerializer::Load) │ -│ ├─ offscreen QOpenGLContext + OpenGLRenderer │ -│ ├─ RenderProcessor (视频路径; ProcessVideoFootage 改为 │ -│ │ 从输入 SHM slot 取帧, 不再直接解码) │ -│ └─ DownloadFromTexture → 写输出 SHM slot → 发 frame_ready │ -└─────────────────────────────────────────────────────────────┘ -``` - -### 3.1 无锁 IPC 设计 - -**控制平面(stdio)**:worker 的 stdin/stdout,**纯文本 NDJSON**——每条消息一行 -compact `QJsonObject`,`\n` 结尾。仅承载低频控制流量(握手、提交任务、取消、关闭)。 -纯文本便于 `cat`/`tee` 抓管道调试、手工注入测试;单读单写天然无锁。诊断信息走 stderr, -绝不污染 stdout 控制通道。**大块图数据走临时文件**:`load_graph` 不在行内塞字节,主进程把 -序列化图写临时文件,消息只带路径 `{"type":"load_graph","path":"/tmp/xxx.ove"}`。 - -**数据平面(共享内存)**:每个 worker 一段共享内存,封装在 `SharedMemoryRegion` -(POSIX `shm_open`+`mmap` / Windows `CreateFileMapping`+`MapViewOfFile`)。布局由 -`FrameSlotPool` 管理: - -- **两个 SPSC 环形队列**(`SpscRingBuffer`)的原子游标(`std::atomic` head/tail, - `memory_order_acquire/release`):`free_ring`(空闲 slot 索引)和 `ready_ring`(已填充 slot - 索引)。每个环单生产者单消费者 → 无需互斥锁。 -- **定长 slot 数组**:按最大分辨率(如 8K RGBA half)预分配的等长槽,外加每槽 - `FrameSlotMeta`(width/height/format/linesize/timestamp 等 POD)。 -- **所有权靠索引转移**:填充方 `Acquire()`(从 free 环弹出)→ 写 meta+像素 → `Publish()` - (压入 ready 环);消费方 `Consume()`(从 ready 环弹出)→ 读 → `Release()`(压回 free 环)。 - 环满即天然背压,无需额外锁。 - -一个 pool 建模单向帧流。输出方向(worker→主)放渲染结果;输入方向(主→worker)放解码素材。 - ---- - -## 4. 分阶段实现计划 - -> 每个阶段都能独立编译、独立验证。前期阶段不改变现有行为(进程内渲染仍是默认), -> 用开关切到多进程路径,最后再切默认。 - -### ✅ 阶段 0:IPC 基础设施(已完成) - -新增 `app/render/ipc/` 模块: - -- `spscringbuffer.h` —— header-only,`std::atomic` 游标的单生产者单消费者环形索引队列,POD,可直接放共享内存。 -- `sharedmemoryregion.{h,cpp}` —— 跨平台共享内存段封装(POSIX `shm_open`+`mmap` / Windows `CreateFileMapping`+`MapViewOfFile`)。直接用原生 API 而非 `QSharedMemory`(后者带隐式信号量与引用计数,不适合大帧)。 -- `frameslotpool.{h,cpp}` —— 在共享内存段上布局两个环 + 定长 slot 池;提供 `Acquire/Publish/Consume/Release` 与 `FrameSlotMeta`。 -- `ipcmessage.{h,cpp}` —— NDJSON 控制消息编解码(`WriteMessage`/`ReadMessage` + 各类型的 `ToJson/FromJson`)。 - -**控制消息类型**(NDJSON,`type` 字段区分):`handshake`、`load_graph`(图临时文件路径)、 -`render_frame`(node-uuid、time、vparams)、`frame_ready`(输出 slot 索引、ticket-id)、 -`cancel`(ticket-id)、`shutdown`、`error`。预留 `graph_update` 增量类型(阶段 6 实现)。 - -**测试**(`tests/gtest/render_ipc_test.cpp`,Google Test): -- 环形队列:基础语义 + 回绕 + **并发 200 万值** FIFO 无丢失无重复。 -- slot 池:单线程握手 + 耗尽/回填 + **并发 20 万帧**数据完整性。 -- NDJSON:类型往返 + 逐字节半包 + 畸形行跳过 + 错误类型拒绝。 - -> 注意:`SpscRingBuffer` 内部数组访问器命名为 `slot_array()` 而非 `slots()`,以规避 Qt 的 `slots` 宏。 - -### ✅ 阶段 1:worker 可执行目标(已完成) - -- `app/CMakeLists.txt` 新增 `add_executable(olive-render-worker ...)`,复用 `libolive-editor` OBJECT 库 + `olive-version-obj`,与 `olive-gtest` 同款链接方式。 -- 新增 `app/render/worker/workermain.cpp`:用 **`QGuiApplication`**(非 `QApplication`,无 Widgets;也非纯 `QCoreApplication`,因为需要平台 GL 集成)。 -- 安装与主进程一致的 `QSurfaceFormat`(OpenGL 3.2 core,24 位深度),设置 `AA_UseDesktopOpenGL` / `AA_ShareOpenGLContexts`。 -- 当前行为:`OpenGLRenderer::Init()` + `PostInit()` 建 offscreen GL 上下文 → 校验 `context()->isValid()` → 在 stdout 打一行 NDJSON 握手(含实际 GL 版本)→ 干净退出。 -- **链接说明**:当前用全量 `OLIVE_LIBRARIES`(含 Widgets/FFmpeg),裁剪 UI-only 依赖留到后续阶段。 - -**验证结果**:worker 在默认平台与 `-platform offscreen` 下均成功输出 -`{"gl_major":3,"gl_minor":2,...,"type":"handshake"}`,stdout 仅一行合法 JSON,退出码 0。 - -### 阶段 2:worker 主循环 + 单帧渲染回路(基础回路已接入) - -- ✅ `workermain.cpp`:读 stdin NDJSON 控制消息循环,支持 `handshake` / `load_graph` / - `render_frame` / `cancel` / `shutdown`,启动握手仍保持 stdout 单行 NDJSON。 -- ✅ `load_graph` → `ProjectSerializer::Load(LoadType::kProject)` 反序列化出 `Project` + 节点图; - `ProjectSerializer::LoadData` 现在暴露旧 ptr token → 新 `Node*` 映射,worker 用它解析 - `render_frame.node`。旧版 serializer 已有的 node UUID 映射也保留兼容。 -- ✅ `render_frame` → 构造本地 `RenderTicket`(参数从消息填 property,复刻 - `RenderManager::RenderFrame` 的关键 `setProperty`)→ - `RenderProcessor::Process(ticket, renderer, decoder_cache=nullptr, shader_cache)`。 -- ✅ 先**不**接输入素材:渲染结果为 `FramePtr` 后写入输出 `FrameSlotPool` slot, - 填 `FrameSlotMeta`,发布 slot 并回 `frame_ready`。 -- ✅ 临时测试驱动启动 1 个 worker,加载最小 SolidGenerator 项目,主进程从输出 slot - 读回 64x64 F32 RGBA 帧并校验元数据与像素非零。待固化为自动化测试。 - -**验证结果**: -- `cmake --build build --target olive-render-worker olive-gtest -j2` 通过。 -- `QT_QPA_PLATFORM=offscreen build/tests/gtest/olive-gtest --gtest_filter='SpscRingBuffer*:*FrameSlotPool*:*IpcMessage*:*ProjectSerializer*' --gtest_brief=1` - 通过,11 个测试全部通过。 -- 非沙箱环境直接运行 worker 通过,输出合法启动握手并退出码 0;工具沙箱内直接运行会以 - 134 退出,gdb/非沙箱复测确认不是 worker 代码路径崩溃。 -- 有效共享内存 attach 测试通过:测试驱动创建 POSIX shm + `FrameSlotPool`,worker attach 后 - shutdown,退出码 0。 -- 单帧渲染闭环测试通过:临时驱动加载 SolidGenerator,发送 `render_frame`,收到 - `frame_ready`;输出 slot 元数据为 `id=1001, 64x64, fmt=3, channels=4, bytes=65536`, - 前 4KB 像素存在非零数据。 - -### 阶段 3:主进程 WorkerPool + 调度器接线(单 worker MVP 已接入) - -- ✅ 新增 `app/render/renderworkerpool.{h,cpp}`: - - 当前 MVP 用后台 `QThread` 持有任务队列,每个任务启动 1 个 `olive-render-worker`, - 建立输出 SHM 段 + stdio 管道。 - - `SubmitFrame(RenderTicketPtr, RenderVideoParams)`:写全量图快照临时文件 → - 发送 `handshake` / `load_graph` / `render_frame` → worker 回 `frame_ready` 后从输出 slot - 拷出 `FramePtr` → `ticket->Finish(...)`。对上层 `RenderTicketWatcher`/`Viewer` 保持透明。 - - 当前仅支持普通视频 `ReturnType::kFrame`;素材输入仍按阶段 4 处理,失败或不支持时回退旧路径。 -- ✅ `RenderManager` 增加 `kMultiProcess` backend 分支(与 `kOpenGL` 并存),开关开启且 - WorkerPool 接受任务时 `RenderFrame()` 走 `RenderWorkerPool`。 -- ✅ 多进程渲染已设为唯一视频渲染路径,`RenderProcessIsolationEnabled` 配置项已移除。 -- 待补:常驻 N worker、忙闲/负载派发、崩溃重启与重派、Viewer 开关实测。 - -**验证结果**: -- `cmake --build build --target olive-render-worker olive-editor -j22` 通过。 -- `QT_QPA_PLATFORM=offscreen build/tests/gtest/olive-gtest --gtest_filter='SpscRingBuffer*:*FrameSlotPool*:*IpcMessage*:*ProjectSerializer*' --gtest_brief=1` - 通过,11 个测试全部通过。 -- 非沙箱环境 `printf '{"type":"shutdown"}\n' | build/app/olive-render-worker` 通过,输出合法 - handshake。 - -### 阶段 4:素材输入解耦(关键重构) - -- ✅ `Decoder` 增加 CPU 帧接口 `RetrieveVideoFrame()`;FFmpeg 路径输出 packed RGBA CPU frame,OIIO 路径返回 still frame CPU buffer。 -- ✅ `RenderWorkerPool` 派发前 dry-run 遍历当前帧素材输入,使用主进程 `DecoderCache` 预解码,成功后写入 main→worker 输入 `FrameSlotPool`。 -- ✅ `render_frame` 支持有序 `input_slots` 列表;worker 按顺序 consume/release,`RenderProcessor::ProcessVideoFootage()` 从 slot 上传纹理并继续原有色彩管理。 -- ✅ 没有输入 slot 且 worker 无 `DecoderCache` 时,素材节点安全跳过,不再空指针崩溃。 -- ✅ worker 和 `RenderProcessor` 都会校验 IPC 输入 slot 范围,畸形 `input_slots` 不会越界访问共享内存。 -- ✅ 真实素材 CPU 预解码已由 `CodecDecoder.RetrieveVideoFrameFromDemoMp4` 覆盖;IPC slot 顺序由 - `IpcMessage.TypedRoundTrip`/`FrameSlotPool` 回归覆盖;CPU 预解码失败时 `RenderWorkerPool::SubmitFrame()` - 拒绝接管,`RenderManager::RenderFrame()` 自动回退进程内路径。 - -### 阶段 5:多 worker、取消、健壮性 - -- ✅ `RenderManager::RemoveTicket()` 已转发到 `RenderWorkerPool`,多进程渲染 ticket 可被统一取消。 -- ✅ `RenderWorkerPool::RemoveTicket()` 支持移除尚未开始的排队任务,并同步清理对应图快照临时文件。 -- ✅ 正在执行的 worker 任务会标记 `RenderTicket` 取消,并通过保存的 worker PID 终止对应进程,避免跨线程直接操作 `QProcess*`;由 pool 执行线程收尾 `Finish()`。 -- ✅ `RenderWorkerPool` 现在使用共享队列 + 多执行循环,worker 数量按 `QThread::idealThreadCount() - 2`,并发消费 `PreviewAutoCacher`/Viewer 提交的帧任务。 -- ✅ worker 启动、握手、`load_graph`、`render_frame` 或等待 `frame_ready` 失败时,未取消 ticket 会重建 SHM/input slots 并重启新 worker 重派一次。 -- ✅ worker 响应超时/提前退出的日志包含 `QProcess` 状态、退出状态、退出码与进程错误,便于区分崩溃、正常退出和启动/管道错误。 -- ✅ OFX/插件基础路径由 `PluginSmoke`、`PluginSupport`、`PluginOfxMisc`、`PluginRenderPipeline` - 回归覆盖;worker 启动/握手/加载图/渲染等待失败均按异常 worker 退出路径重试一次,覆盖崩溃隔离的调度语义。 -- 背压:slot 池/环满时调度器暂缓派发(环满即天然背压)。 - -### 阶段 6:图增量同步(可选优化) - -- 把 `ProjectCopier` 的 `QueuedJob`(kNodeAdded/kEdgeAdded/kValueChanged…)编码成 `graph_update` 消息,worker 侧等价 `ProcessUpdateQueue`,省去每次全量序列化。 -- 阶段 0 已预留消息类型,此处填实现。 - ---- - -## 5. 文件清单 - -**新增** - -| 文件 | 阶段 | 状态 | -|---|---|---| -| `app/render/ipc/spscringbuffer.h` | 0 | ✅ | -| `app/render/ipc/sharedmemoryregion.{h,cpp}` | 0 | ✅ | -| `app/render/ipc/frameslotpool.{h,cpp}` | 0 | ✅ | -| `app/render/ipc/ipcmessage.{h,cpp}` | 0 | ✅ | -| `app/render/ipc/CMakeLists.txt` | 0 | ✅ | -| `tests/gtest/render_ipc_test.cpp` | 0 | ✅ | -| `app/render/worker/workermain.cpp` | 1/2 | ✅ 基础主循环 | -| `app/render/renderworkerpool.{h,cpp}` | 3 | ✅ 单 worker MVP | - -**修改** - -| 文件 | 阶段 | 状态 | -|---|---|---| -| `app/render/CMakeLists.txt`(加 `add_subdirectory(ipc)`) | 0 | ✅ | -| `tests/gtest/CMakeLists.txt`(注册 ipc 测试) | 0 | ✅ | -| `app/CMakeLists.txt`(新增 `olive-render-worker` target) | 1 | ✅ | -| `app/node/project/serializer/serializer*.{h,cpp}`(暴露加载映射供 worker 查节点) | 2 | ✅ | -| `app/render/rendermanager.{h,cpp}`(`kMultiProcess` 分支 + WorkerPool 接线) | 3 | ✅ 单 worker MVP | -| `app/codec/decoder.{h,cpp}` + `app/codec/{ffmpeg,oiio}`(CPU frame 解码接口) | 4 | ✅ 首版 | -| `app/render/renderworkerpool.{h,cpp}`(主进程预解码并填 input slot) | 4 | ✅ 首版 | -| `app/render/renderprocessor.cpp`(`ProcessVideoFootage` 改取输入 slot) | 4 | ✅ 首版 | -| `app/config/config.cpp`(多进程开关默认值) | 3 | ✅ 默认关闭 | - ---- - -## 6. 验证方式(端到端) - -1. **IPC 单元测试**:多线程压测 SPSC 环形队列 + slot 池,确认无锁正确性(无丢失/重复/数据竞争,可配 TSan)。— 阶段 0 已覆盖。 -2. **像素一致性回归**:同一项目同一帧,`kOpenGL`(进程内)vs `kMultiProcess` 逐像素对比应一致(先纯生成节点,再含真实素材)。 -3. **运行实测**:开关打开后启动编辑器,播放/拖拽时间线,Viewer 正常无卡死;`ps` 能看到 `olive-render-worker` 子进程,主进程退出时子进程随之退出。 -4. **崩溃隔离**:人为让 worker 段错误(或加载会崩的 OFX 插件),确认主进程存活、WorkerPool 自动重启并恢复渲染。 -5. **性能**:多 worker 预渲染窗口吞吐 vs 单进程基线对比。 - ---- - -## 7. 开放问题(实现时定) - -- SHM slot 尺寸/数量的默认值(按硬件分档,参考 `TODO.md` 同款问题)。 -- worker 数默认值(CPU/GPU 数推导)。 -- OFX 插件在多 worker 下的句柄/许可证并发是否有限制。 -- worker 链接集裁剪时机:何时安全移除 Widgets/FFmpeg 依赖(依赖阶段 4 素材解耦完成)。 diff --git a/docs/zh/rgbaf32-global-plan.md b/docs/zh/rgbaf32-global-plan.md deleted file mode 100644 index e68a26390..000000000 --- a/docs/zh/rgbaf32-global-plan.md +++ /dev/null @@ -1,122 +0,0 @@ -# 素材读入强制转换为 RGBAF32 并内部全链路使用 F32 处理 — 实施计划 - -## 1. 现状分析 - -### 1.1 视频读入位置 - -视频/图像素材在以下位置被读入并解码为 GPU Texture: - -| 层级 | 文件 | 职责 | -|------|------|------| -| 解码接口 | `app/codec/decoder.h` / `.cpp` | 基类 `Decoder`,定义 `RetrieveVideo(RetrieveVideoParams)` 公共接口 | -| FFmpeg 解码 | `app/codec/ffmpeg/ffmpegdecoder.cpp` | `FFmpegDecoder::RetrieveVideoInternal()` —— 核心视频解码路径 | -| OIIO 解码 | `app/codec/oiio/oiiodecoder.cpp` | `OIIODecoder::RetrieveVideoInternal()` —— 静态图片解码路径 | -| 渲染触发 | `app/render/renderprocessor.cpp` | `ProcessVideoFootage()` —— 在节点图遍历中触发解码,并做颜色管理转换 | -| 遍历调度 | `app/node/traverser.cpp` | `ResolveJobs()` —— 将 `FootageJob` 分发给 `ProcessVideoFootage()` | - -**数据流:** -``` -文件 → FFmpegDecoder::RetrieveVideoInternal() - → RetrieveFrame() 解码出 AVFrame - → PreProcessFrame() CPU 缩放/格式转换 (sws_scale_frame) - → ProcessFrameIntoTexture() 上传为 GPU Texture - → YUV 格式:上传为 3 个 plane texture + YUV→RGB shader - → RGBA/RGBA64LE:直接 glTexSubImage2D 上传 - → RenderProcessor::ProcessVideoFootage() - → BlitColorManaged() OCIO 颜色空间转换 shader - → 进入节点图后续处理 -``` - -### 1.2 像素格式体系 - -- **核心枚举:** `ext/core/include/olive/core/render/pixelformat.h` 定义 `PixelFormat::U8 / U16 / F16 / F32` -- **GPU 格式映射:** `app/render/opengl/openglrenderer.cpp` 已将 `F32 + 4ch` 映射到 `GL_RGBA32F / GL_FLOAT` -- **内部工作格式:** `NodeTraverser::GetCacheVideoParams().format()` 决定节点图内部缓存格式 -- **项目默认配置:** `app/config/config.cpp` 中 `OnlinePixelFormat = F32`,`OfflinePixelFormat = F16`,说明设计意图就是在线编辑使用 F32 - -### 1.3 当前 F32 支持的关键缺失 - -1. **`FFmpegDecoder::GetNativePixelFormat()` 不识别 F32 FFmpeg 格式** - - 仅映射 `RGBA → U8`、`RGBA64 → U16` - - `AV_PIX_FMT_RGBAF32`、`AV_PIX_FMT_RGBF32` 等落入 `default: INVALID` - -2. **`IsPixelFormatGLSLCompatible()` 未将 RGBAF32 列为 GLSL 兼容** - - 这会导致即使解码器输出 RGBAF32,也会强制走 `sws_scale_frame` CPU 转换路径 - -3. **`ProcessFrameIntoTexture()` 直接上传路径缺少 RGBAF32 分支** - - 当前只有 `YUV...` 和 `RGBA / RGBA64LE` 两个直接上传分支,没有 `RGBAF32` 等直接上传路径 - -4. **`PreProcessFrame()` 的 `sws_scale_frame` 目标格式选择需验证 F32 支持** - - `FFmpegUtils::GetCompatiblePixelFormat(..., maximum=F32)` 理论上应返回 `AV_PIX_FMT_RGBAF32`,但需实测验证 - -5. **OIIO 解码器已原生支持 F32(FLOAT → F32),无需修改** - -## 2. 目标 - -- **读入时转换:** 无论源素材格式(YUV、U8、U16、F16 等),在解码器层面统一转换为 **RGBAF32** 后上传 GPU -- **内部全链路 F32:** 节点图遍历、效果处理、合成、缓存等内部环节全部使用 `PixelFormat::F32`(4 通道) -- **导出保持灵活:** 导出/编码时从 F32 转换为目标格式,保持现有编码逻辑 - -## 3. 实施方案:全局强制 F32 - -**思路:** 将 F32 作为唯一的内部工作格式,在解码器出口强制转换。 - -**改动点:** - -1. **解码器层强制 F32 输出** - - `FFmpegDecoder::RetrieveVideoInternal()`: - - 修改 `RetrieveVideoParams` 或内部逻辑,令 `maximum_format` 固定为 `F32` - - 在 `PreProcessFrame()` 中,若源格式非 RGBAF32,通过 `sws_scale_frame` 转换到 `AV_PIX_FMT_RGBAF32` - - 在 `ProcessFrameIntoTexture()` 中增加 `AV_PIX_FMT_RGBAF32` 直接上传分支(`GL_RGBA32F / GL_FLOAT`) - - `OIIODecoder::RetrieveVideoInternal()`: - - OIIO 读入后,若格式非 F32,通过 `Frame::convert(PixelFormat::F32)` 转换,再上传 - -2. **修复 F32 格式映射** - - `FFmpegDecoder::GetNativePixelFormat()` 增加 `AV_PIX_FMT_RGBAF32 → PixelFormat::F32`、`AV_PIX_FMT_RGBF32 → PixelFormat::F32` - - `FFmpegDecoder::GetNativeChannelCount()` 增加对应分支 - - `IsPixelFormatGLSLCompatible()` 增加 `AV_PIX_FMT_RGBAF32`(可选,因为强制转换后解码器输出就是 RGBAF32) - -3. **内部工作格式锁定 F32** - - 在 `NodeTraverser` 初始化或 `RenderProcessor` 创建时,`SetCacheVideoParams()` 强制 `format = PixelFormat::F32` - - 移除用户层对工作格式的可选配置(或保留配置但忽略/默认 F32) - - `traverser.cpp` 中 `FootageJob`、`GenerateJob`、`ColorTransformJob` 的格式设置已经使用 `GetCacheVideoParams().format()`,因此只需确保基类参数是 F32 即可 - -4. **导出层适配** - - `FFmpegEncoder` 的输入当前通过 `avfilter` 图做格式转换,源为 F32 时: - - `FFmpegUtils::GetFFmpegPixelFormat(F32, 4)` 已返回 `AV_PIX_FMT_RGBAF32` - - 验证 filter graph 的 `buffer` source 和 `format` filter 能否正确处理 `RGBAF32` - - `RenderProcessor::GenerateFrame()` 下载 GPU texture 到 `FramePtr` 时,`DownloadFromTexture()` 已支持 `GL_FLOAT`,直接得到 F32 CPU buffer - -## 4. 关键文件与修改清单 - -| 文件 | 修改内容 | -|------|----------| -| `app/codec/ffmpeg/ffmpegdecoder.cpp` | ① `GetNativePixelFormat()` 增加 RGBAF32/RGBF32 → F32 映射
② `GetNativeChannelCount()` 增加对应分支
③ `IsPixelFormatGLSLCompatible()` 增加 RGBAF32
④ `ProcessFrameIntoTexture()` 增加 RGBAF32 直接上传分支
⑤ `PreProcessFrame()` 确保 divider=1 且格式为 RGBAF32 时跳过 CPU 转换 | -| `app/codec/oiio/oiiodecoder.cpp` | `RetrieveVideoInternal()` 上传前若 `frame.format() != F32` 则调用 `convert(F32)` | -| `app/node/traverser.cpp` 或 `app/render/renderprocessor.cpp` | 初始化时强制 `SetCacheVideoParams().format = F32` | -| `app/codec/ffmpeg/ffmpegencoder.cpp` | 验证 filter graph 对 RGBAF32 source 的处理,必要时调整 | -| `app/render/opengl/openglrenderer.cpp` | 确认 `GL_RGBA32F / GL_FLOAT` 路径完整,补充必要错误检查 | -| `app/codec/ffmpeg/ffmpegutils.cpp` | 验证 `GetCompatiblePixelFormat(maximum=F32)` 的行为 | - -## 5. 风险评估 - -| 风险 | 说明 | 缓解措施 | -|------|------|----------| -| 内存带宽 ×4 | F32 是 U8 的 4 倍、U16/F16 的 2 倍,显存和内存占用显著增加 | 这是预期代价;`OfflinePixelFormat` 机制可继续用于代理预览,降低分辨率同时用 F16 减少带宽 | -| FFmpeg swscale 对 RGBAF32 支持 | `sws_scale_frame` 是否能正确处理 `AV_PIX_FMT_RGBAF32` 作为目标格式需验证 | 先写单元测试验证;若不支持,可用 OIIO `Frame::convert()` 作为 fallback,或在 GPU 上通过 shader 做格式转换 | -| OFX 插件兼容性 | 大部分 OFX 插件支持 `kOfxBitDepthFloat`,但仍有少数可能只支持 U8/U16 | `PluginRenderer` 已有格式转换路径,F32 的支持比 F16 更成熟 | -| 性能回归 | YUV→RGB 原来在 GPU 走 shader,若强制先转 RGBAF32 再上传,可能需要调整流程 | YUV 素材仍保留 GPU shader 转换路径,只是 shader 输出目标 texture 格式改为 F32(OpenGL 已支持 `GL_RGBA32F` 作为 render target) | -| 缓存文件体积翻倍 | 帧缓存从 U8/U16 改为 F32 后,磁盘缓存体积增大 | 可接受;必要时调整缓存策略或压缩 | - -## 6. 建议的实施顺序 - -1. **第一阶段:** 修复 `FFmpegDecoder` F32 映射 + 增加 RGBAF32 直接上传分支,编写解码器单元测试 -2. **第二阶段:** 在 `OIIODecoder` 添加强制 F32 转换 -3. **第三阶段:** 锁定内部工作格式为 F32,验证节点图全链路 -4. **第四阶段:** 验证导出编码路径,确认 filter graph 对 RGBAF32 的处理 -5. **第五阶段:** 性能测试与回归测试 - -## 7. 决策点 - -- 是否保留 `OfflinePixelFormat = F16` 的代理降级机制?还是连 proxy 也强制 F32? -- 若保留代理降级,是否需要在解码器层根据 online/offline 模式选择输出格式? diff --git a/docs/zh/structure.md b/docs/zh/structure.md deleted file mode 100644 index 8b029fd8d..000000000 --- a/docs/zh/structure.md +++ /dev/null @@ -1,168 +0,0 @@ -Oak Video Editor 项目结构概览(中文) -========================== - -这份文档是基于当前仓库目录组织的快速导航,便于后续查找代码位置。 - -顶层目录 --------- -- app: 主应用源码入口,涵盖核心、渲染、UI、插件、节点系统等。 -- cmake: CMake 相关脚本与模块。 -- docker: 构建/运行相关的容器配置。 -- docs: 项目文档(你现在正在看的位置)。 -- ext: 可能包含外部依赖或子模块(按需查看)。 -- tests: 测试代码与用例。 -- third_party: 第三方库及其源码(如 OpenFX HostSupport)。 -- build、cmake-build-debug、test_compile: 构建产物或构建目录(通常不需要手动改)。 - -app 目录(核心模块) -------------------- -- app/core.*: 应用核心入口、初始化流程。 -- app/main.cpp: 程序入口点。 -- app/version.*: 版本信息与构建元数据。 -- app/common: 通用基础设施与工具类(日志、路径、字符串等)。 -- app/config: 配置加载与项目设置。 -- app/render: 渲染子系统(帧缓存、渲染管线、插件渲染桥接等)。 -- app/node: 节点系统,节点类型与图结构的核心逻辑。 -- app/widget: UI 控件与节点视图(节点图、参数面板等)。 -- app/panel: UI 面板组织与管理。 -- app/window: 窗口与主界面。 -- app/timeline: 时间线与剪辑管理。 -- app/tool: 交互工具(选择、裁剪等)。 -- app/undo: 撤销/重做系统。 -- app/task: 异步任务与后台作业。 -- app/audio: 音频处理与播放。 -- app/codec: 编解码相关支持。 -- app/shaders: 渲染着色器资源。 -- app/ts: 时间/时间轴相关通用类型。 -- app/dialog: 对话框与提示类 UI。 -- app/cli: 命令行工具入口或相关实现。 -- app/pluginSupport: OpenFX 插件 Host 侧实现(Clip/Image/Param/Host/PluginInstance 等)。 -- app/packaging: 打包或发布相关逻辑。 - -重点文件索引(按模块) ----------------------- -下面列的是“常用/核心入口”文件,不是完整清单,但足够定位主要流程。 - -核心入口与全局 -------------- -- app/main.cpp: 程序入口。 -- app/core.h、app/core.cpp: 应用生命周期与初始化总控。 -- app/version.h、app/version.cpp: 版本与构建信息。 - -渲染系统 --------- -- app/render/renderer.h、app/render/renderer.cpp: 渲染主调度。 -- app/render/rendermanager.h、app/render/rendermanager.cpp: 渲染队列与任务管理。 -- app/render/renderticket.h、app/render/renderticket.cpp: 单次渲染请求。 -- app/render/renderprocessor.h、app/render/renderprocessor.cpp: 渲染处理管线。 -- app/render/texture.h、app/render/texture.cpp: 纹理/帧数据容器。 -- app/render/videoparams.h、app/render/videoparams.cpp: 视频格式参数。 -- app/render/job/pluginjob.h、app/render/job/pluginjob.cpp: 插件渲染作业。 -- app/render/plugin/pluginrenderer.h、app/render/plugin/pluginrenderer.cpp: OpenFX 插件渲染桥接。 - -节点系统 --------- -- app/node/node.h、app/node/node.cpp: 节点基类与生命周期。 -- app/node/param.h、app/node/param.cpp: 节点参数与动画/关键帧。 -- app/node/value.h、app/node/value.cpp: 节点值与运行时数据。 -- app/node/factory.h、app/node/factory.cpp: 节点注册与创建。 -- app/node/traverser.h、app/node/traverser.cpp: 图遍历与求值。 -- app/node/plugins/Plugin.h、app/node/plugins/Plugin.cpp: OpenFX 插件节点。 - -OpenFX Host 侧实现 ------------------- -- app/pluginSupport/OliveHost.h、app/pluginSupport/OliveHost.cpp: OpenFX Host 入口与消息接口。 -- app/pluginSupport/OlivePluginInstance.h、app/pluginSupport/OlivePluginInstance.cpp: 插件实例生命周期与参数管理。 -- app/pluginSupport/OliveClip.h、app/pluginSupport/OliveClip.cpp: Clip 实例与图像读写桥接。 -- app/pluginSupport/image.h、app/pluginSupport/image.cpp: OpenFX Image 封装与数据映射。 -- app/pluginSupport/paraminstance.h、app/pluginSupport/paraminstance.cpp: 参数实例实现。 -- third_party/openfx/HostSupport/include/ofxhImageEffect.h: HostSupport 核心接口。 - -节点 UI(Node View) -------------------- -- app/widget/nodeview/nodeview.h、app/widget/nodeview/nodeview.cpp: 节点视图主控。 -- app/widget/nodeview/nodeviewitem.h、app/widget/nodeview/nodeviewitem.cpp: 节点渲染与交互。 -- app/widget/nodeview/nodeviewscene.h、app/widget/nodeview/nodeviewscene.cpp: QGraphicsScene 逻辑。 -- app/widget/nodeview/nodeviewedge.h、app/widget/nodeview/nodeviewedge.cpp: 连线显示。 - -参数 UI(Param View) --------------------- -- app/widget/nodeparamview/nodeparamview.h、app/widget/nodeparamview/nodeparamview.cpp: 参数面板主控。 -- app/widget/nodeparamview/nodeparamviewitem.h、app/widget/nodeparamview/nodeparamviewitem.cpp: 参数项容器与布局。 -- app/widget/nodeparamview/nodeparamviewwidgetbridge.h、app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp: 参数类型到控件的桥接。 -- app/widget/nodeparamview/nodeparamviewtextedit.h、app/widget/nodeparamview/nodeparamviewtextedit.cpp: 多行文本参数控件。 - -面板与窗口 ----------- -- app/panel/panelmanager.h、app/panel/panelmanager.cpp: 面板管理器与切换逻辑。 -- app/panel/timebased/timebased.h、app/panel/timebased/timebased.cpp: 时间基面板基类(时间轴/视图共享逻辑)。 -- app/panel/node/node.h、app/panel/node/node.cpp: 节点面板入口。 -- app/panel/param/param.h、app/panel/param/param.cpp: 参数面板入口。 -- app/window: 主窗口与窗口级 UI 结构。 - -时间线/播放核心 --------------- -- app/node/output/viewer/viewer.h、app/node/output/viewer/viewer.cpp: Viewer 输出节点(播放头/长度/渲染请求)。 -- app/widget/viewer/viewer.h、app/widget/viewer/viewer.cpp: Viewer 面板与播放控制。 -- app/widget/timelinewidget/timelinewidget.h、app/widget/timelinewidget/timelinewidget.cpp: 时间线 UI 与交互主控。 - -进度与任务 UI ------------- -- app/dialog/progress/progress.h、app/dialog/progress/progress.cpp: 通用进度对话框。 -- app/widget/taskview/taskviewitem.h、app/widget/taskview/taskviewitem.cpp: 任务进度条展示。 - -撤销/编辑分组 ------------- -- app/undo/undocommand.h、app/undo/undocommand.cpp: UndoCommand 与 MultiUndoCommand 的基础实现。 -- app/undo/undostack.h、app/undo/undostack.cpp: 撤销栈(无原生“批量编辑”接口)。 -- app/pluginSupport/OlivePluginInstance.h、app/pluginSupport/OlivePluginInstance.cpp: OpenFX editBegin/editEnd 触发时创建批量撤销分组。 -- app/pluginSupport/OlivePluginInstance.cpp: DeferredRedoCommand 包装已应用的命令,避免批量 push 时重复执行。 -- app/pluginSupport/paraminstance.h、app/pluginSupport/paraminstance.cpp: 参数 Set 走统一的 SubmitUndoCommand 接口,支持批量合并。 - -与 OpenFX 相关的主要位置 ------------------------ -- app/pluginSupport: OpenFX HostSupport 的封装与 Olive 侧实现。 -- app/render/plugin: 插件渲染调度与帧处理逻辑。 -- app/node/plugins: 插件节点定义与 UI 参数桥接。 -- third_party/openfx: OpenFX HostSupport 源码与接口头文件。 - -构建与配置 ----------- -- CMakeLists.txt: 根构建配置入口。 -- cmake/: 自定义 CMake 模块与工具链脚本。 - -其他说明 --------- -- README.md: 项目整体说明与开发入口。 -- TODO-zh.md: OpenFX 支持的中文 TODO 说明。 - -流程图/调用关系(ASCII) ------------------------ -OpenFX 插件渲染主流程(逻辑简化): -``` -Node(Graph) - -> app/node/plugins/Plugin.cpp - -> app/render/plugin/pluginrenderer.cpp - -> app/pluginSupport/OlivePluginInstance.cpp - -> app/pluginSupport/OliveClip.cpp - -> app/pluginSupport/image.cpp - -> app/render/texture.cpp / AVFrame 映射 -``` - -OpenFX 参数 UI 生成流程(逻辑简化): -``` -OFX Param Descriptor - -> app/pluginSupport/OlivePluginInstance.cpp (newParam) - -> app/node/plugins/Plugin.cpp (Node Input 生成) - -> app/widget/nodeparamview/nodeparamview.cpp - -> app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp (控件桥接) -``` - -插件消息展示流程(逻辑简化): -``` -OFX Host Message - -> app/pluginSupport/OliveHost.cpp (保存消息) - -> app/pluginSupport/OlivePluginInstance.cpp (发出消息数量变化) - -> app/widget/nodeview/nodeviewitem.cpp (节点右上角徽标) - -> app/widget/nodeparamview/nodeparamviewitem.cpp (面板顶部消息) -``` diff --git a/docs/zh/test-plan.md b/docs/zh/test-plan.md deleted file mode 100644 index 09f96873b..000000000 --- a/docs/zh/test-plan.md +++ /dev/null @@ -1,93 +0,0 @@ -# Oak Video Editor 测试策略与计划 - -本文档描述 Oak Video Editor 的自动化测试策略,包括单元测试、集成测试以及 CI 执行方式。 - -## 目标 - -- 尽量自动化,减少人工测试。 -- 覆盖所有模块(至少一个自动化测试)。 -- 集成测试保持无 GUI(头less)。 -- 在 Windows/macOS/Linux 上可重复运行。 - -## 测试层级 - -### 1) 单元测试(GoogleTest) -- 目标:小范围、确定性、无 GUI。 -- 目录:`tests/gtest/`。 -- 执行:`ctest` 里的 `olive-gtest`。 - -### 1.5) 模块冒烟测试(GoogleTest) -- 目标:对 GUI 相关模块做编译期/链接期覆盖,不实例化控件。 -- 目录:`tests/gtest/module_smoke_test.cpp`。 -- 执行:`ctest` 里的 `olive-gtest`。 - -### 2) 集成测试(GoogleTest) -- 目标:跨模块流程但不依赖 GUI(例如序列化→反序列化)。 -- 目录:`tests/gtest/`(如 `ProjectSerializer`、`TaskManager`)。 - -### 3) 现有测试(Olive 宏测试) -- 目录:`tests/general`、`tests/timeline`、`tests/compositing` 保持不变。 - -## 模块覆盖映射 - -每个顶层模块至少有一个测试用例。 - -- `app/common`:`common_current_test.cpp`、`common_xmlutils_test.cpp` -- `app/config`:`config_test.cpp` -- `app/node`:`node_value_test.cpp`、`node_keyframe_test.cpp`、`node_serialization_test.cpp` -- `app/node/project/serializer`:`project_serializer_test.cpp` -- `app/render`:`render_videoparams_test.cpp`、`render_audioparams_test.cpp` -- `app/timeline`:`timeline_marker_test.cpp` -- `app/undo`:`undo_stack_test.cpp` -- `app/task`:`task_taskmanager_test.cpp` -- `app/codec`:`codec_frame_test.cpp` -- `app/pluginSupport`:`plugin_support_test.cpp` -- `app/audio`、`app/cli`、`app/dialog`、`app/panel`、`app/tool`、`app/ui`、`app/widget`、`app/window`:`module_smoke_test.cpp` - -若模块包含 GUI 依赖,则测试聚焦于其非可视逻辑/数据结构。 - -## 集成测试说明 - -### 项目序列化回归 -- 创建最小项目并添加内置节点。 -- 使用 `ProjectSerializer::Save` 写出 XML。 -- 再用 `ProjectSerializer::Load` 读回。 -- 验证节点恢复。 - -### 任务管理器执行 -- 向 `TaskManager` 添加一个 DummyTask。 -- 使用事件循环等待完成。 -- 验证任务确实执行。 - -## 单元覆盖重点(已扩展) - -- `app/undo`:`undo_stack_test.cpp` 覆盖空栈状态、模型数据、redo 区域颜色、jump 行为、空 MultiUndoCommand 忽略逻辑。 -- `app/timeline`:`timeline_marker_test.cpp` 覆盖列表排序、最近 marker 查询、含未知元素的保存/加载、marker 增删改命令。 -- `app/pluginSupport`:`plugin_support_image_test.cpp` 覆盖 OFX 属性映射(bounds/ROD、像素深度、通道、预乘)及分配/清理行为。 -- `app/render`:`render_videoparams_branch_test.cpp` 覆盖自动 divider、像素宽高比校验、方形像素宽度、Save/Load 回归。 - -## 无 GUI 运行 - -- 测试避免使用 QWidget。 -- CI 中设置 `QT_QPA_PLATFORM=offscreen` 防止 GUI 初始化问题。 - -## 持续集成 - -CI 在 Windows/macOS/Linux 上执行: - -1. 安装依赖(Qt、FFmpeg、OpenImageIO、OpenColorIO、OpenEXR、PortAudio、Expat)。 -2. `-DBUILD_TESTS=ON` 配置。 -3. 使用 CMake + Ninja 构建。 -4. 运行 `ctest` 输出失败信息。 - -### 依赖安装说明 -- Linux:优先使用发行版系统包(Ubuntu 上用 `apt`)安装 Qt6、FFmpeg、OpenImageIO、OpenColorIO、OpenEXR、PortAudio、Expat、OpenGL 头文件。 -- macOS:使用 Homebrew 安装 Qt6 和图像/色彩/多媒体相关库。 -- Windows:尽量使用系统安装器(Qt 通过 `install-qt-action`),其余 C/C++ 库通过 vcpkg 安装。 - -## 新增测试规范 - -- 新测试放在 `tests/gtest`。 -- 使用 GoogleTest 规范。 -- 尽量保持确定性与无外部依赖。 -- 新模块至少增加 1 个单元测试 + 1 个集成场景(可合并)。 diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index 135d557c3..448a97685 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -18,4 +18,7 @@ add_subdirectory(core EXCLUDE_FROM_ALL) set(KDDockWidgets_STATIC ON CACHE INTERNAL "Force KDDockWidgets to build statically") set(KDDockWidgets_QT6 ${BUILD_QT6} CACHE INTERNAL "Conform KDDockWidgets' Qt 6 setting to ours") +# Oak only uses the QtWidgets frontend; building the QtQuick frontend causes +# duplicate QML module registration on macOS and pulls in unused dependencies. +set(KDDockWidgets_FRONTENDS "qtwidgets" CACHE INTERNAL "Only build the QtWidgets frontend for Oak") add_subdirectory(KDDockWidgets EXCLUDE_FROM_ALL) diff --git a/ofxTestLog.txt b/ofxTestLog.txt deleted file mode 100644 index d399dc6f2..000000000 --- a/ofxTestLog.txt +++ /dev/null @@ -1,1887 +0,0 @@ -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Failed on getting int property OfxPropAPIVersion[0], host returned status kOfxStatErrBadIndex; - Retrieved int property OfxPropAPIVersion[0], was given 0. - ERROR : Failed on getting int property OfxPropAPIVersion[1], host returned status kOfxStatErrBadIndex; - Retrieved int property OfxPropAPIVersion[1], was given 0. - Retrieved string property OfxPropName[0], was given UNKNOWN. - Retrieved string property OfxPropLabel[0], was given UNKNOWN. - ERROR : Failed on getting int property OfxPropVersion[0], host returned status kOfxStatErrBadIndex; - Retrieved int property OfxPropVersion[0], was given 0. - ERROR : Failed on getting int property OfxPropVersion[1], host returned status kOfxStatErrBadIndex; - Retrieved int property OfxPropVersion[1], was given 0. - ERROR : Failed on getting int property OfxPropVersion[2], host returned status kOfxStatErrBadIndex; - Retrieved int property OfxPropVersion[2], was given 0. - Retrieved string property OfxPropVersionLabel[0], was given . - Retrieved int property OfxImageEffectHostPropIsBackground[0], was given 0. - Retrieved int property OfxImageEffectPropSupportsOverlays[0], was given 1. - Retrieved int property OfxImageEffectPropSupportsMultiResolution[0], was given 1. - Retrieved int property OfxImageEffectPropSupportsTiles[0], was given 1. - Retrieved int property OfxImageEffectPropTemporalClipAccess[0], was given 1. - Retrieved int property OfxImageEffectPropMultipleClipDepths[0], was given 1. - Retrieved int property OfxImageEffectPropSupportsMultipleClipPARs[0], was given 0. - Retrieved int property OfxImageEffectPropSetableFrameRate[0], was given 0. - Retrieved int property OfxImageEffectPropSetableFielding[0], was given 0. - Retrieved int property OfxImageEffectInstancePropSequentialRender[0], was given 0. - Retrieved int property OfxParamHostPropSupportsStringAnimation[0], was given 0. - Retrieved int property OfxParamHostPropSupportsCustomInteract[0], was given 0. - Retrieved int property OfxParamHostPropSupportsChoiceAnimation[0], was given 0. - Retrieved int property OfxParamHostPropSupportsBooleanAnimation[0], was given 0. - Retrieved int property OfxParamHostPropSupportsCustomAnimation[0], was given 0. - Retrieved pointer property OfxPropHostOSHandle[0], was given 0x0. - ERROR : Failed on getting int property OfxParamHostPropSupportsParametricAnimation[0], host returned status kOfxStatErrUnknown; - Retrieved int property OfxParamHostPropSupportsParametricAnimation[0], was given 0. - Retrieved int property OfxImageEffectPropRenderQualityDraft[0], was given 0. - ERROR : Failed on getting string property OfxImageEffectHostPropNativeOrigin[0], host returned status kOfxStatErrBadIndex; - Retrieved string property OfxImageEffectHostPropNativeOrigin[0], was given (null). - Retrieved string property OfxImageEffectPropOpenGLRenderSupported[0], was given false. - ERROR : Failed on getting int property FnOfxImageEffectCanTransform[0], host returned status kOfxStatErrUnknown; - Retrieved int property FnOfxImageEffectCanTransform[0], was given 0. - ERROR : Failed on getting int property uk.co.thefoundry.OfxImageEffectPropMultiPlanar[0], host returned status kOfxStatErrUnknown; - Retrieved int property uk.co.thefoundry.OfxImageEffectPropMultiPlanar[0], was given 0. - Retrieved int property OfxParamHostPropMaxParameters[0], was given -1. - Retrieved int property OfxParamHostPropMaxPages[0], was given 0. - Retrieved int property OfxParamHostPropPageRowColumnCount[0], was given 0. - Retrieved int property OfxParamHostPropPageRowColumnCount[1], was given 0. - ERROR : Failed on getting int property NatronOfxHostIsNatron[0], host returned status kOfxStatErrUnknown; - Retrieved int property NatronOfxHostIsNatron[0], was given 0. - ERROR : Failed on getting int property NatronOfxParamHostPropSupportsDynamicChoices[0], host returned status kOfxStatErrUnknown; - Retrieved int property NatronOfxParamHostPropSupportsDynamicChoices[0], was given 0. - ERROR : Failed on getting int property NatronOfxParamPropChoiceCascading[0], host returned status kOfxStatErrUnknown; - Retrieved int property NatronOfxParamPropChoiceCascading[0], was given 0. - ERROR : Failed on getting string property NatronOfxImageEffectPropChannelSelector[0], host returned status kOfxStatErrUnknown; - Retrieved string property NatronOfxImageEffectPropChannelSelector[0], was given (null). - ERROR : Failed on getting int property OfxImageEffectPropCanDistort[0], host returned status kOfxStatErrUnknown; - Retrieved int property OfxImageEffectPropCanDistort[0], was given 0. - ERROR : Failed on fetching dimension for property NatronOfxPropNativeOverlays, host returned status kOfxStatErrUnknown. - Fetched dimension of property NatronOfxPropNativeOverlays, returned 0. - Fetched dimension of property OfxImageEffectPropSupportedComponents, returned 0. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SmoothBilateralCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Blur input stream by bilateral filtering. -Uses the 'blur_bilateral' function from the CImg library. -See also: http://opticalenquiry.com/nuke/index.php?title=Bilateral - -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SmoothBilateralGuidedCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Apply joint/cross bilateral filtering on image A, guided by the intensity differences of image B. Uses the 'blur_bilateral' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - ERROR : Failed on setting int property NatronOfxImageEffectPropDeprecated[0] to 1, host returned status kOfxStatErrUnknown (3); - Set int property NatronOfxImageEffectPropDeprecated[0] to be 1. - Set string property OfxPropLabel[0] to be BlurCImg. - Set string property OfxPropPluginDescription[0] to be Blur input stream or compute derivatives. -The blur filter can be a quasi-Gaussian, a Gaussian, a box, a triangle or a quadratic filter. - -Note that the Gaussian filter [1] is implemented as an IIR (infinite impulse response) filter [2][3], whereas most compositing software implement the Gaussian as a FIR (finite impulse response) filter by cropping the Gaussian impulse response. Consequently, when blurring a white dot on black background, it produces very small values very far away from the dot. The quasi-Gaussian filter is also IIR. - -A very common process in compositing to expand colors on the edge of a matte is to use the premult-blur-unpremult combination [4][5]. The very small values produced by the IIR Gaussian filter produce undesirable artifacts after unpremult. For this process, the FIR quadratic filter (or the faster triangle or box filters) should be preferred over the IIR Gaussian filter. - -References: -[1] https://en.wikipedia.org/wiki/Gaussian_filter -[2] I.T. Young, L.J. van Vliet, M. van Ginkel, Recursive Gabor filtering. IEEE Trans. Sig. Proc., vol. 50, pp. 2799-2805, 2002. (this is an improvement over Young-Van Vliet, Sig. Proc. 44, 1995) -[3] B. Triggs and M. Sdika. Boundary conditions for Young-van Vliet recursive filtering. IEEE Trans. Signal Processing, vol. 54, pp. 2365-2367, 2006. -[4] Nuke Expand Edges or how to get rid of outlines. http://franzbrandstaetter.com/?p=452 -[5] Colour Smear for Nuke. http://richardfrazer.com/tools-tutorials/colour-smear-for-nuke/ - -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu). - -This plugin was compiled with debug, with assertions, without inlines, without OpenMP, using Clang version 21.0.0 (clang-2100.1.1.101).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - ERROR : Failed on setting int property NatronOfxImageEffectPropDeprecated[0] to 1, host returned status kOfxStatErrUnknown (3); - Set int property NatronOfxImageEffectPropDeprecated[0] to be 1. - Set string property OfxPropLabel[0] to be LaplacianCImg. - Set string property OfxPropPluginDescription[0] to be Blur input stream, and subtract the result from the input image. This is not a mathematically correct Laplacian (which would be the sum of second derivatives over X and Y). -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - ERROR : Failed on setting int property NatronOfxImageEffectPropDeprecated[0] to 1, host returned status kOfxStatErrUnknown (3); - Set int property NatronOfxImageEffectPropDeprecated[0] to be 1. - Set string property OfxPropLabel[0] to be ChromaBlurCImg. - Set string property OfxPropPluginDescription[0] to be Blur the chrominance of an input stream. Smoothing is done on the x and y components in the CIE xyY color space. Used to prep strongly compressed and chroma subsampled footage for keying. -The blur filter can be a quasi-Gaussian, a Gaussian, a box, a triangle or a quadratic filter. -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - ERROR : Failed on setting int property NatronOfxImageEffectPropDeprecated[0] to 1, host returned status kOfxStatErrUnknown (3); - Set int property NatronOfxImageEffectPropDeprecated[0] to be 1. - Set string property OfxPropLabel[0] to be BloomCImg. - Set string property OfxPropPluginDescription[0] to be Apply a Bloom filter (Kawase 2004) that sums multiple blur filters of different radii, -resulting in a larger but sharper glare than a simple blur. -It is similar to applying 'Count' separate Blur filters to the same input image with sizes 'Size', 'Size'*'Ratio', 'Size'*'Ratio'^2, etc., and averaging the results. -The blur radii follow a geometric progression (of common ratio 2 in the original implementation, bloomRatio in this implementation), and a total of bloomCount blur kernels are summed up (bloomCount=5 in the original implementation, and the kernels are Gaussian). -The blur filter can be a quasi-Gaussian, a Gaussian, a box, a triangle or a quadratic filter. -Ref.: Masaki Kawase, "Practical Implementation of High Dynamic Range Rendering", GDC 2004. -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be BlurCImg. - Set string property OfxPropPluginDescription[0] to be Blur input stream or compute derivatives. -The blur filter can be a quasi-Gaussian, a Gaussian, a box, a triangle or a quadratic filter. - -Note that the Gaussian filter [1] is implemented as an IIR (infinite impulse response) filter [2][3], whereas most compositing software implement the Gaussian as a FIR (finite impulse response) filter by cropping the Gaussian impulse response. Consequently, when blurring a white dot on black background, it produces very small values very far away from the dot. The quasi-Gaussian filter is also IIR. - -A very common process in compositing to expand colors on the edge of a matte is to use the premult-blur-unpremult combination [4][5]. The very small values produced by the IIR Gaussian filter produce undesirable artifacts after unpremult. For this process, the FIR quadratic filter (or the faster triangle or box filters) should be preferred over the IIR Gaussian filter. - -References: -[1] https://en.wikipedia.org/wiki/Gaussian_filter -[2] I.T. Young, L.J. van Vliet, M. van Ginkel, Recursive Gabor filtering. IEEE Trans. Sig. Proc., vol. 50, pp. 2799-2805, 2002. (this is an improvement over Young-Van Vliet, Sig. Proc. 44, 1995) -[3] B. Triggs and M. Sdika. Boundary conditions for Young-van Vliet recursive filtering. IEEE Trans. Signal Processing, vol. 54, pp. 2365-2367, 2006. -[4] Nuke Expand Edges or how to get rid of outlines. http://franzbrandstaetter.com/?p=452 -[5] Colour Smear for Nuke. http://richardfrazer.com/tools-tutorials/colour-smear-for-nuke/ - -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu). - -This plugin was compiled with debug, with assertions, without inlines, without OpenMP, using Clang version 21.0.0 (clang-2100.1.1.101).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be LaplacianCImg. - Set string property OfxPropPluginDescription[0] to be Blur input stream, and subtract the result from the input image. This is not a mathematically correct Laplacian (which would be the sum of second derivatives over X and Y). -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be ChromaBlurCImg. - Set string property OfxPropPluginDescription[0] to be Blur the chrominance of an input stream. Smoothing is done on the x and y components in the CIE xyY color space. Used to prep strongly compressed and chroma subsampled footage for keying. -The blur filter can be a quasi-Gaussian, a Gaussian, a box, a triangle or a quadratic filter. -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be BloomCImg. - Set string property OfxPropPluginDescription[0] to be Apply a Bloom filter (Kawase 2004) that sums multiple blur filters of different radii, -resulting in a larger but sharper glare than a simple blur. -It is similar to applying 'Count' separate Blur filters to the same input image with sizes 'Size', 'Size'*'Ratio', 'Size'*'Ratio'^2, etc., and averaging the results. -The blur radii follow a geometric progression (of common ratio 2 in the original implementation, bloomRatio in this implementation), and a total of bloomCount blur kernels are summed up (bloomCount=5 in the original implementation, and the kernels are Gaussian). -The blur filter can be a quasi-Gaussian, a Gaussian, a box, a triangle or a quadratic filter. -Ref.: Masaki Kawase, "Practical Implementation of High Dynamic Range Rendering", GDC 2004. -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be ErodeBlurCImg. - Set string property OfxPropPluginDescription[0] to be Performs an operation that looks like an erosion or a dilation by smoothing the image and then remapping the values of the result. -The image is first smoothed by a triangle filter of width 2*abs(size). -Now suppose the image is a 0-1 step edge (I=0 for x less than 0, I=1 for x greater than 0). The intensities are linearly remapped so that the value at x=size-0.5 is mapped to 0 and the value at x=size+0.5 is mapped to 1. -This process usually works well for mask images (i.e. images which are either 0 or 1), but may give strange results on images with real intensities, where another Erode filter has to be used. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SharpenCImg. - Set string property OfxPropPluginDescription[0] to be Sharpen the input stream by enhancing its Laplacian. -The effects adds the Laplacian (as computed by the Laplacian plugin) times the 'Amount' parameter to the input stream. -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SoftenCImg. - Set string property OfxPropPluginDescription[0] to be Soften the input stream by reducing its Laplacian. -The effects subtracts the Laplacian (as computed by the Laplacian plugin) times the 'Amount' parameter from the input stream. -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be EdgeExtendCImg. - Set string property OfxPropPluginDescription[0] to be Fill a matte (i.e. a non-opaque color image with an alpha channel) by extending the edges of the matte. This effect does nothing an an opaque image. -If the input matte comes from a keyer, the alpha channel of the matte should be first eroded by a small amount to remove pixels containing mixed foreground/background colors. If not, these mixed colors may be extended instead of the pure foreground colors. -The filling process works by iteratively blurring the image, and merging the non-blurred image over the image to get to the next iteration. There are exactly 'Slices' such operations. The blur size at each iteration is linearly increasing. -'Size' is thus the total size of the edge extension, and 'Slices' is an indicator of the precision: the more slices there are, the sharper is the final image near the original edges. -Optionally, the image can be multiplied by the alpha channel on input (premultiplied), and divided by the alpha channel on output (unpremultiplied), so that if RGB contain an image and Alpha contains a mask, the output is an image where the RGB is smeared from the non-zero areas of the mask to the zero areas of the same mask. -The 'Size' parameter gives the size of the largest blur kernel, 'Count' gives the number of blur kernels, and 'Ratio' gives the ratio between consecutive blur kernel sizes. The size of the smallest blur kernel is thus 'Size'/'Ratio'^('Count'-1) -To get the classical single unpremult-blur-premult, use 'Count'=1 and set the size to the size of the blur kernel. However, near the mask borders, a frontier can be seen between the non-blurred area (this inside of the mask) and the blurred area. Using more blur sizes will give a much smoother transition. -The idea for the builtup blurs to expand RGB comes from the EdgeExtend effect for Nuke by Frank Rueter (except the blurs were merged from the smallest to the largest, and here it is done the other way round), with suggestions by Lucas Pfaff. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be EdgeDetectCImg. - Set string property OfxPropPluginDescription[0] to be Perform edge detection by computing the image gradient magnitude. Optionally, edge detection can be preceded by blurring, and followed by erosion and thresholding. In most cases, EdgeDetect is followed a Grade node to extract the proper edges and generate a mask from these. - -For color or multi-channel images, several edge detection algorithms are proposed to combine the gradients computed in each channel: -- Separate: the gradient magnitude is computed in each channel separately, and the output is a color edge image. -- RMS: the RMS of per-channel gradients magnitudes is computed. -- Max: the maximum per-channel gradient magnitude is computed. -- Tensor: the tensor gradient norm [1]. - -References: -- [1] Silvano Di Zenzo, A note on the gradient of a multi-image, CVGIP 33, 116-125 (1986). http://people.csail.mit.edu/tieu/notebook/imageproc/dizenzo86.pdf - -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SmoothPatchBasedCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Denoise selected images by non-local patch averaging. -This uses the method described in: Non-Local Image Smoothing by Applying Anisotropic Diffusion PDE's in the Space of Patches (D. Tschumperlé, L. Brun), ICIP'09 (https://tschumperle.users.greyc.fr/publications/tschumperle_icip09.pdf). -Uses the 'blur_patch' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be DilateCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Dilate (or erode) input stream by a rectangular structuring element of specified size and Neumann boundary conditions (pixels out of the image get the value of the nearest pixel). -A negative size will perform an erosion instead of a dilation. -Different sizes can be given for the x and y axis. -Uses the 'dilate' and 'erode' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 17, when there is only 17 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be DistanceCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Compute at each pixel the distance to pixels that have a value of zero. -The distance is normalized with respect to the largest image dimension, so that it is between 0 and 1. -Optionally, a signed distance to the frontier between zero and nonzero values can be computed. -The distance transform can then be thresholded using the Threshold effect, or transformed using the ColorLookup effect, in order to generate a mask for another effect. -See alse https://en.wikipedia.org/wiki/Distance_transform -Uses the 'distance' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 0. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 18, when there is only 16 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be EqualizeCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Color. - Set string property OfxPropPluginDescription[0] to be Equalize histogram of pixel values. -To equalize image brightness only, use the HistEQCImg plugin. -Uses the 'equalize' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 0. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 19, when there is only 15 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be ErodeCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Erode (or dilate) input stream by a rectangular structuring element of specified size and Neumann boundary conditions (pixels out of the image get the value of the nearest pixel). -A negative size will perform a dilation instead of an erosion. -Different sizes can be given for the x and y axis. -Uses the 'erode' and 'dilate' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 20, when there is only 14 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be ErodeSmoothCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Erode or dilate input stream using a normalized power-weighted filter. -This gives a smoother result than the Erode or Dilate node. -See "Robust local max-min filters by normalized power-weighted filtering" by L.J. van Vliet, http://dx.doi.org/10.1109/ICPR.2004.1334273 -Uses the 'vanvliet' and 'deriche' functions from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 21, when there is only 13 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be GMICExpr. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - ERROR : Failed on fetching dimension for property NatronOfxPropDescriptionIsMarkdown, host returned status kOfxStatErrUnknown. - Fetched dimension of property NatronOfxPropDescriptionIsMarkdown, returned 0. - Set string property OfxPropPluginDescription[0] to be Quickly generate or process image from mathematical formula evaluated for each pixel. -Full documentation for G'MIC/CImg expressions can be found at http://gmic.eu/reference.shtml#section9 -The only difference is the predefined variables 'T' (current time) and 'K' (render scale). - -Sample expressions: - -'j(sin(y/100/k+t/10)*20*k,sin(x/100/k+t/10)*20*k)' distorts the image with time-varying waves. - -'0.5*(j(1)-j(-1))' will estimate the X-derivative of an image with a classical finite difference scheme. - -'if(x%10==0,1,i)' will draw blank vertical lines on every 10th column of an image. - -Press the 'Help' button for more documentation or read the expression documentation at http://gmic.eu/reference.shtml#section9 - -Uses the 'fill' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 0. - Set int property OfxImageEffectPropSupportsTiles[0] to be 0. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 22, when there is only 12 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SmoothGuidedCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Blur image, with the Guided Image filter. -The algorithm is described in: He et al., "Guided Image Filtering," http://research.microsoft.com/en-us/um/people/kahe/publications/pami12guidedfilter.pdf -Uses the 'blur_guided' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 23, when there is only 11 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be HistEQCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Color. - Set string property OfxPropPluginDescription[0] to be Equalize histogram of brightness values. -Uses the 'equalize' function from the CImg library on the 'V' channel of the HSV decomposition of the image. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 0. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 24, when there is only 10 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be InpaintCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Inpaint (a.k.a. content-aware fill) the areas indicated by the Mask input using patch-based inpainting. -Be aware that this filter may produce different results on each frame of a video, even if there is little change in the video content. To inpaint areas with lots of details, it may be better to inpaint on a single frame and paste the inpainted area on other frames (if a transform is also required to match the other frames, it may be computed by tracking). - -A tutorial on using this filter can be found at http://blog.patdavid.net/2014/02/getting-around-in-gimp-gmic-inpainting.html -The algorithm is described in the two following publications: -"A Smarter Examplar-based Inpainting Algorithm using Local and Global Heuristics for more Geometric Coherence." (M. Daisy, P. Buyssens, D. Tschumperlé, O. Lezoray). IEEE International Conference on Image Processing (ICIP'14), Paris/France, Oct. 2014 -and -"A Fast Spatial Patch Blending Algorithm for Artefact Reduction in Pattern-based Image Inpainting." (M. Daisy, D. Tschumperlé, O. Lezoray). SIGGRAPH Asia 2013 Technical Briefs, Hong-Kong, November 2013. - -Uses the 'inpaint' plugin from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu). The 'inpaint' CImg plugin is distributed under the CeCILL (compatible with the GNU GPL) license.. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 0. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 25, when there is only 9 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be Matrix3x3CImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter/Matrix. - Set string property OfxPropPluginDescription[0] to be Compute the convolution of the input image with the specified matrix. -This works by multiplying each surrounding pixel of the input image with the corresponding matrix coefficient (the current pixel is at the center of the matrix), and summing up the results. -For example [-1 -1 -1] [-1 8 -1] [-1 -1 -1] produces an edge detection filter (which is an approximation of the Laplacian filter) by multiplying the center pixel by 8 and the surrounding pixels by -1, and then adding the nine values together to calculate the new value of the center pixel. -Uses the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 26, when there is only 8 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be Matrix5x5CImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter/Matrix. - Set string property OfxPropPluginDescription[0] to be Compute the convolution of the input image with the specified matrix. -This works by multiplying each surrounding pixel of the input image with the corresponding matrix coefficient (the current pixel is at the center of the matrix), and summing up the results. -For example [-1 -1 -1] [-1 8 -1] [-1 -1 -1] produces an edge detection filter (which is an approximation of the Laplacian filter) by multiplying the center pixel by 8 and the surrounding pixels by -1, and then adding the nine values together to calculate the new value of the center pixel. -Uses the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 27, when there is only 7 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be MedianCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Apply a median filter to input images. Pixel values within a square box of the given size around the current pixel are sorted, and the median value is output if it does not differ from the current value by more than the given. Median filtering is performed per-channel. -Uses the 'blur_median' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 28, when there is only 6 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be NoiseCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Draw. - Set string property OfxPropPluginDescription[0] to be Add random noise to input stream. - -Uses the 'noise' function from the CImg library, modified so that noise is reproductible at each render. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 29, when there is only 5 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be PlasmaCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Draw. - Set string property OfxPropPluginDescription[0] to be Draw a random plasma texture (using the mid-point algorithm). - -Uses the 'draw_plasma' function from the CImg library, modified so that noise is reproductible at each render.. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGenerator. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 2. - Set string property OfxImageEffectPropSupportedContexts[2] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 0. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 30, when there is only 4 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SmoothRollingGuidanceCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Filter out details under a given scale using the Rolling Guidance filter. -Rolling Guidance is described fully in http://www.cse.cuhk.edu.hk/~leojia/projects/rollguidance/ -Iterates the 'blur_bilateral' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 0. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 31, when there is only 3 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SharpenInvDiffCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Sharpen selected images by inverse diffusion. -Uses 'sharpen' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 0. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 32, when there is only 2 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SharpenShockCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Sharpen selected images by shock filters. -Uses 'sharpen' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 0. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - -ERROR : Host attempted to get plugin 33, when there is only 1 plugin(s), so it should have asked for 0. -******************************************************************************** -START mainEntry (OfxActionLoad) - WARNING : Could not fetch the optional suite 'OfxParametricParameterSuite' version 1. - WARNING : Could not fetch the optional suite 'NukeOfxCameraSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 1. - WARNING : Could not fetch the optional suite 'uk.co.thefoundry.FnOfxImageEffectPlaneSuite' version 2. - WARNING : Could not fetch the optional suite 'OfxVegasProgressSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasStereoscopicImageEffectSuite' version 1. - WARNING : Could not fetch the optional suite 'OfxVegasKeyframeSuite' version 1. - ERROR : Tried to create host description when we already have one. - START validating properties of Host Property. - STOP property validation of Host Property. -STOP mainEntry (OfxActionLoad) - -******************************************************************************** -START mainEntry (OfxActionDescribe) - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - START validating properties of Plugin Descriptor. - ERROR : Default value of OfxImageEffectPluginRenderThreadSafety[0] = 'OfxImageEffectRenderInstanceSafe', it should be 'OfxImageEffectRenderFullySafe'; - ERROR : Default value of OfxImageEffectPluginPropHostFrameThreading[0] = 1, it should be 0; - STOP property validation of Plugin Descriptor. - Set string property OfxPropLabel[0] to be SmoothAnisotropicCImg. - Set string property OfxImageEffectPluginPropGrouping[0] to be Filter. - Set string property OfxPropPluginDescription[0] to be Smooth/Denoise input stream using anisotropic PDE-based smoothing. -Uses the 'blur_anisotropic' function from the CImg library. -CImg is a free, open-source library distributed under the CeCILL-C (close to the GNU LGPL) or CeCILL (compatible with the GNU GPL) licenses. It can be used in commercial applications (see http://cimg.eu).. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 0. - Set string property OfxImageEffectPropSupportedContexts[0] to be OfxImageEffectContextFilter. - Fetched dimension of property OfxImageEffectPropSupportedContexts, returned 1. - Set string property OfxImageEffectPropSupportedContexts[1] to be OfxImageEffectContextGeneral. - Fetched dimension of property OfxImageEffectPropSupportedPixelDepths, returned 0. - Set string property OfxImageEffectPropSupportedPixelDepths[0] to be OfxBitDepthFloat. - Set int property OfxImageEffectPluginPropSingleInstance[0] to be 0. - Set int property OfxImageEffectPluginPropHostFrameThreading[0] to be 1. - Set int property OfxImageEffectPropSupportsMultiResolution[0] to be 1. - Set int property OfxImageEffectPropSupportsTiles[0] to be 1. - Set int property OfxImageEffectPropTemporalClipAccess[0] to be 0. - Set int property OfxImageEffectPluginPropFieldRenderTwiceAlways[0] to be 1. - Set int property OfxImageEffectPropSupportsMultipleClipPARs[0] to be 0. - Set int property OfxImageEffectPropMultipleClipDepths[0] to be 0. - Set string property OfxImageEffectPluginRenderThreadSafety[0] to be OfxImageEffectRenderFullySafe. -STOP mainEntry (OfxActionDescribe) - -******************************************************************************** -START mainEntry (OfxActionUnload) -STOP mainEntry (OfxActionUnload) - diff --git a/tests/gtest/audio_level_meter_test.cpp b/tests/gtest/audio_level_meter_test.cpp index 052c1b7a7..740f7cd6b 100644 --- a/tests/gtest/audio_level_meter_test.cpp +++ b/tests/gtest/audio_level_meter_test.cpp @@ -11,7 +11,8 @@ extern "C" { #include } -namespace { +namespace +{ olive::core::AudioParams MakeStereoParams() { diff --git a/tests/gtest/audio_smoke_test.cpp b/tests/gtest/audio_smoke_test.cpp index ca57906e9..13206635c 100644 --- a/tests/gtest/audio_smoke_test.cpp +++ b/tests/gtest/audio_smoke_test.cpp @@ -33,28 +33,31 @@ extern "C" { using namespace olive; using namespace olive::core; -namespace olive { -namespace audio { -namespace test { +namespace olive +{ +namespace audio +{ +namespace test +{ // ============================================================================ // Helper Functions // ============================================================================ static AudioParams MakeAudioParams(int sample_rate, uint64_t channel_layout, - SampleFormat format) + SampleFormat format) { - return AudioParams(sample_rate, channel_layout, format); + return AudioParams(sample_rate, channel_layout, format); } static void FillSampleBuffer(SampleBuffer &buffer, float value) { - for (int ch = 0; ch < buffer.channel_count(); ++ch) { - float *data = buffer.data(ch); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - data[i] = value; - } - } + for (int ch = 0; ch < buffer.channel_count(); ++ch) { + float *data = buffer.data(ch); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + data[i] = value; + } + } } // ============================================================================ @@ -63,114 +66,115 @@ static void FillSampleBuffer(SampleBuffer &buffer, float value) TEST(AudioSmokeParams, DefaultConstruction) { - AudioParams params; - EXPECT_FALSE(params.is_valid()); - EXPECT_EQ(params.sample_rate(), 0); - EXPECT_EQ(params.channel_count(), 0); - EXPECT_EQ(params.format(), SampleFormat::INVALID); + AudioParams params; + EXPECT_FALSE(params.is_valid()); + EXPECT_EQ(params.sample_rate(), 0); + EXPECT_EQ(params.channel_count(), 0); + EXPECT_EQ(params.format(), SampleFormat::INVALID); } TEST(AudioSmokeParams, ValidConstruction) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - - EXPECT_TRUE(params.is_valid()); - EXPECT_EQ(params.sample_rate(), 48000); - EXPECT_EQ(params.channel_count(), 2); - EXPECT_EQ(params.format(), SampleFormat::F32P); - EXPECT_EQ(params.bytes_per_sample_per_channel(), 4); - EXPECT_EQ(params.bits_per_sample(), 32); + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + + EXPECT_TRUE(params.is_valid()); + EXPECT_EQ(params.sample_rate(), 48000); + EXPECT_EQ(params.channel_count(), 2); + EXPECT_EQ(params.format(), SampleFormat::F32P); + EXPECT_EQ(params.bytes_per_sample_per_channel(), 4); + EXPECT_EQ(params.bits_per_sample(), 32); } TEST(AudioSmokeParams, MonoChannelLayout) { - AudioParams params(44100, AV_CH_LAYOUT_MONO, SampleFormat::S16); - - EXPECT_TRUE(params.is_valid()); - EXPECT_EQ(params.sample_rate(), 44100); - EXPECT_EQ(params.channel_count(), 1); + AudioParams params(44100, AV_CH_LAYOUT_MONO, SampleFormat::S16); + + EXPECT_TRUE(params.is_valid()); + EXPECT_EQ(params.sample_rate(), 44100); + EXPECT_EQ(params.channel_count(), 1); } TEST(AudioSmokeParams, SurroundChannelLayout) { - AudioParams params(48000, AV_CH_LAYOUT_5POINT1, SampleFormat::F32P); - - EXPECT_TRUE(params.is_valid()); - EXPECT_EQ(params.channel_count(), 6); + AudioParams params(48000, AV_CH_LAYOUT_5POINT1, SampleFormat::F32P); + + EXPECT_TRUE(params.is_valid()); + EXPECT_EQ(params.channel_count(), 6); } TEST(AudioSmokeParams, TimeConversions) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - - // Time to samples - EXPECT_EQ(params.time_to_samples(1.0), 48000); - EXPECT_EQ(params.time_to_samples(0.5), 24000); - EXPECT_EQ(params.time_to_samples(2.0), 96000); - - // Samples to bytes - EXPECT_EQ(params.samples_to_bytes(48000), 48000 * 2 * 4); // samples * channels * bytes_per_sample - - // Time to bytes - EXPECT_EQ(params.time_to_bytes(1.0), 48000 * 2 * 4); + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + + // Time to samples + EXPECT_EQ(params.time_to_samples(1.0), 48000); + EXPECT_EQ(params.time_to_samples(0.5), 24000); + EXPECT_EQ(params.time_to_samples(2.0), 96000); + + // Samples to bytes + EXPECT_EQ(params.samples_to_bytes(48000), + 48000 * 2 * 4); // samples * channels * bytes_per_sample + + // Time to bytes + EXPECT_EQ(params.time_to_bytes(1.0), 48000 * 2 * 4); } TEST(AudioSmokeParams, EqualityOperators) { - AudioParams params1(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams params2(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams params3(44100, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams params4(48000, AV_CH_LAYOUT_MONO, SampleFormat::F32P); - AudioParams params5(48000, AV_CH_LAYOUT_STEREO, SampleFormat::S16); - - EXPECT_TRUE(params1 == params2); - EXPECT_FALSE(params1 != params2); - - EXPECT_FALSE(params1 == params3); // Different sample rate - EXPECT_FALSE(params1 == params4); // Different channel layout - EXPECT_FALSE(params1 == params5); // Different format + AudioParams params1(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams params2(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams params3(44100, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams params4(48000, AV_CH_LAYOUT_MONO, SampleFormat::F32P); + AudioParams params5(48000, AV_CH_LAYOUT_STEREO, SampleFormat::S16); + + EXPECT_TRUE(params1 == params2); + EXPECT_FALSE(params1 != params2); + + EXPECT_FALSE(params1 == params3); // Different sample rate + EXPECT_FALSE(params1 == params4); // Different channel layout + EXPECT_FALSE(params1 == params5); // Different format } TEST(AudioSmokeParams, CopyConstruction) { - AudioParams original(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams copy(original); - - EXPECT_TRUE(copy.is_valid()); - EXPECT_EQ(copy.sample_rate(), original.sample_rate()); - EXPECT_EQ(copy.channel_count(), original.channel_count()); - EXPECT_EQ(copy.format(), original.format()); - - // Modifying copy should not affect original - copy.set_sample_rate(44100); - EXPECT_EQ(original.sample_rate(), 48000); - EXPECT_EQ(copy.sample_rate(), 44100); + AudioParams original(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams copy(original); + + EXPECT_TRUE(copy.is_valid()); + EXPECT_EQ(copy.sample_rate(), original.sample_rate()); + EXPECT_EQ(copy.channel_count(), original.channel_count()); + EXPECT_EQ(copy.format(), original.format()); + + // Modifying copy should not affect original + copy.set_sample_rate(44100); + EXPECT_EQ(original.sample_rate(), 48000); + EXPECT_EQ(copy.sample_rate(), 44100); } TEST(AudioSmokeParams, CopyAssignment) { - AudioParams original(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams copy; - copy = original; - - EXPECT_TRUE(copy.is_valid()); - EXPECT_EQ(copy.sample_rate(), original.sample_rate()); - EXPECT_EQ(copy.channel_count(), original.channel_count()); - EXPECT_EQ(copy.format(), original.format()); + AudioParams original(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams copy; + copy = original; + + EXPECT_TRUE(copy.is_valid()); + EXPECT_EQ(copy.sample_rate(), original.sample_rate()); + EXPECT_EQ(copy.channel_count(), original.channel_count()); + EXPECT_EQ(copy.format(), original.format()); } TEST(AudioSmokeParams, ChannelLayoutModification) { - AudioParams params(48000, AV_CH_LAYOUT_MONO, SampleFormat::F32P); - EXPECT_EQ(params.channel_count(), 1); - - // Change to stereo - params.set_channel_layout(AV_CH_LAYOUT_STEREO); - EXPECT_EQ(params.channel_count(), 2); - - // Change to 5.1 - params.set_channel_layout(AV_CH_LAYOUT_5POINT1); - EXPECT_EQ(params.channel_count(), 6); + AudioParams params(48000, AV_CH_LAYOUT_MONO, SampleFormat::F32P); + EXPECT_EQ(params.channel_count(), 1); + + // Change to stereo + params.set_channel_layout(AV_CH_LAYOUT_STEREO); + EXPECT_EQ(params.channel_count(), 2); + + // Change to 5.1 + params.set_channel_layout(AV_CH_LAYOUT_5POINT1); + EXPECT_EQ(params.channel_count(), 6); } // ============================================================================ @@ -179,147 +183,147 @@ TEST(AudioSmokeParams, ChannelLayoutModification) TEST(AudioSmokeBuffer, DefaultConstruction) { - SampleBuffer buffer; - EXPECT_FALSE(buffer.is_allocated()); - EXPECT_EQ(buffer.channel_count(), 0); - EXPECT_EQ(buffer.sample_count(), 0); + SampleBuffer buffer; + EXPECT_FALSE(buffer.is_allocated()); + EXPECT_EQ(buffer.channel_count(), 0); + EXPECT_EQ(buffer.sample_count(), 0); } TEST(AudioSmokeBuffer, Allocation) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(48000)); // 1 second of samples - - EXPECT_TRUE(buffer.is_allocated()); - EXPECT_EQ(buffer.channel_count(), 2); - EXPECT_EQ(buffer.sample_count(), 48000); + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(48000)); // 1 second of samples + + EXPECT_TRUE(buffer.is_allocated()); + EXPECT_EQ(buffer.channel_count(), 2); + EXPECT_EQ(buffer.sample_count(), 48000); } TEST(AudioSmokeBuffer, DataAccess) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(100)); - - // Fill with test data - FillSampleBuffer(buffer, 0.5f); - - // Verify data - for (int ch = 0; ch < buffer.channel_count(); ++ch) { - const float *data = buffer.data(ch); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - EXPECT_FLOAT_EQ(data[i], 0.5f); - } - } + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(100)); + + // Fill with test data + FillSampleBuffer(buffer, 0.5f); + + // Verify data + for (int ch = 0; ch < buffer.channel_count(); ++ch) { + const float *data = buffer.data(ch); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + EXPECT_FLOAT_EQ(data[i], 0.5f); + } + } } TEST(AudioSmokeBuffer, Silence) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(100)); - - // Fill with non-zero values - FillSampleBuffer(buffer, 0.5f); - - // Apply silence - buffer.silence(); - - // Verify silence - for (int ch = 0; ch < buffer.channel_count(); ++ch) { - const float *data = buffer.data(ch); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - EXPECT_FLOAT_EQ(data[i], 0.0f); - } - } + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(100)); + + // Fill with non-zero values + FillSampleBuffer(buffer, 0.5f); + + // Apply silence + buffer.silence(); + + // Verify silence + for (int ch = 0; ch < buffer.channel_count(); ++ch) { + const float *data = buffer.data(ch); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + EXPECT_FLOAT_EQ(data[i], 0.0f); + } + } } TEST(AudioSmokeBuffer, VolumeTransform) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(100)); - - // Fill with 1.0 - FillSampleBuffer(buffer, 1.0f); - - // Apply volume transform (50%) - buffer.transform_volume(0.5f); - - // Verify volume change - for (int ch = 0; ch < buffer.channel_count(); ++ch) { - const float *data = buffer.data(ch); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - EXPECT_FLOAT_EQ(data[i], 0.5f); - } - } + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(100)); + + // Fill with 1.0 + FillSampleBuffer(buffer, 1.0f); + + // Apply volume transform (50%) + buffer.transform_volume(0.5f); + + // Verify volume change + for (int ch = 0; ch < buffer.channel_count(); ++ch) { + const float *data = buffer.data(ch); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + EXPECT_FLOAT_EQ(data[i], 0.5f); + } + } } TEST(AudioSmokeBuffer, Clamp) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(100)); - - // Fill with values outside [-1, 1] - for (int ch = 0; ch < buffer.channel_count(); ++ch) { - float *data = buffer.data(ch); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - data[i] = (i % 2 == 0) ? 2.0f : -2.0f; - } - } - - // Apply clamp - buffer.clamp(); - - // Verify clamping - for (int ch = 0; ch < buffer.channel_count(); ++ch) { - const float *data = buffer.data(ch); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - EXPECT_GE(data[i], -1.0f); - EXPECT_LE(data[i], 1.0f); - } - } + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(100)); + + // Fill with values outside [-1, 1] + for (int ch = 0; ch < buffer.channel_count(); ++ch) { + float *data = buffer.data(ch); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + data[i] = (i % 2 == 0) ? 2.0f : -2.0f; + } + } + + // Apply clamp + buffer.clamp(); + + // Verify clamping + for (int ch = 0; ch < buffer.channel_count(); ++ch) { + const float *data = buffer.data(ch); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + EXPECT_GE(data[i], -1.0f); + EXPECT_LE(data[i], 1.0f); + } + } } TEST(AudioSmokeBuffer, FastSet) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer source(params, size_t(100)); - SampleBuffer dest(params, size_t(100)); - - FillSampleBuffer(source, 0.75f); - dest.silence(); - - // Fast copy from source to dest - dest.fast_set(source, 0); // Copy to channel 0 - - // Verify channel 0 copied - const float *dest_data = dest.data(0); - for (size_t i = 0; i < dest.sample_count(); ++i) { - EXPECT_FLOAT_EQ(dest_data[i], 0.75f); - } + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer source(params, size_t(100)); + SampleBuffer dest(params, size_t(100)); + + FillSampleBuffer(source, 0.75f); + dest.silence(); + + // Fast copy from source to dest + dest.fast_set(source, 0); // Copy to channel 0 + + // Verify channel 0 copied + const float *dest_data = dest.data(0); + for (size_t i = 0; i < dest.sample_count(); ++i) { + EXPECT_FLOAT_EQ(dest_data[i], 0.75f); + } } TEST(AudioSmokeBuffer, RipChannel) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(100)); - - // Fill channel 0 with 0.5, channel 1 with 0.25 - float *ch0 = buffer.data(0); - float *ch1 = buffer.data(1); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - ch0[i] = 0.5f; - ch1[i] = 0.25f; - } - - // Rip channel 0 - SampleBuffer ripped = buffer.rip_channel(0); - - EXPECT_EQ(ripped.channel_count(), 1); - EXPECT_EQ(ripped.sample_count(), buffer.sample_count()); - - const float *ripped_data = ripped.data(0); - for (size_t i = 0; i < ripped.sample_count(); ++i) { - EXPECT_FLOAT_EQ(ripped_data[i], 0.5f); - } + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(100)); + + // Fill channel 0 with 0.5, channel 1 with 0.25 + float *ch0 = buffer.data(0); + float *ch1 = buffer.data(1); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + ch0[i] = 0.5f; + ch1[i] = 0.25f; + } + + // Rip channel 0 + SampleBuffer ripped = buffer.rip_channel(0); + + EXPECT_EQ(ripped.channel_count(), 1); + EXPECT_EQ(ripped.sample_count(), buffer.sample_count()); + + const float *ripped_data = ripped.data(0); + for (size_t i = 0; i < ripped.sample_count(); ++i) { + EXPECT_FLOAT_EQ(ripped_data[i], 0.5f); + } } // ============================================================================ @@ -328,201 +332,201 @@ TEST(AudioSmokeBuffer, RipChannel) TEST(AudioSmokeWaveform, DefaultConstruction) { - AudioVisualWaveform waveform; - EXPECT_EQ(waveform.channel_count(), 0); - EXPECT_EQ(waveform.length(), rational(0)); + AudioVisualWaveform waveform; + EXPECT_EQ(waveform.channel_count(), 0); + EXPECT_EQ(waveform.length(), rational(0)); } TEST(AudioSmokeWaveform, ChannelCount) { - AudioVisualWaveform waveform; - waveform.set_channel_count(2); - EXPECT_EQ(waveform.channel_count(), 2); - - waveform.set_channel_count(6); - EXPECT_EQ(waveform.channel_count(), 6); + AudioVisualWaveform waveform; + waveform.set_channel_count(2); + EXPECT_EQ(waveform.channel_count(), 2); + + waveform.set_channel_count(6); + EXPECT_EQ(waveform.channel_count(), 6); } TEST(AudioSmokeWaveform, OverwriteSamples) { - AudioVisualWaveform waveform; - waveform.set_channel_count(2); - - // Create sample buffer with sine wave-like data - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(4800)); // 0.1 seconds - - for (int ch = 0; ch < buffer.channel_count(); ++ch) { - float *data = buffer.data(ch); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - data[i] = std::sin(float(i) * 0.1f); - } - } - - // Write samples to waveform - waveform.OverwriteSamples(buffer, 48000, rational(0)); - - EXPECT_GT(waveform.length(), rational(0)); + AudioVisualWaveform waveform; + waveform.set_channel_count(2); + + // Create sample buffer with sine wave-like data + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(4800)); // 0.1 seconds + + for (int ch = 0; ch < buffer.channel_count(); ++ch) { + float *data = buffer.data(ch); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + data[i] = std::sin(float(i) * 0.1f); + } + } + + // Write samples to waveform + waveform.OverwriteSamples(buffer, 48000, rational(0)); + + EXPECT_GT(waveform.length(), rational(0)); } TEST(AudioSmokeWaveform, OverwriteSilence) { - AudioVisualWaveform waveform; - waveform.set_channel_count(2); - - // First add some samples - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(4800)); - FillSampleBuffer(buffer, 0.5f); - waveform.OverwriteSamples(buffer, 48000, rational(0)); - - rational original_length = waveform.length(); - - // Overwrite with silence - waveform.OverwriteSilence(rational(0), rational(1, 10)); // 0.1 seconds - - // Length should be at least as long as original - EXPECT_GE(waveform.length(), original_length); + AudioVisualWaveform waveform; + waveform.set_channel_count(2); + + // First add some samples + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(4800)); + FillSampleBuffer(buffer, 0.5f); + waveform.OverwriteSamples(buffer, 48000, rational(0)); + + rational original_length = waveform.length(); + + // Overwrite with silence + waveform.OverwriteSilence(rational(0), rational(1, 10)); // 0.1 seconds + + // Length should be at least as long as original + EXPECT_GE(waveform.length(), original_length); } TEST(AudioSmokeWaveform, TrimIn) { - AudioVisualWaveform waveform; - waveform.set_channel_count(2); - - // Add samples - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(48000)); // 1 second - FillSampleBuffer(buffer, 0.5f); - waveform.OverwriteSamples(buffer, 48000, rational(0)); - - EXPECT_EQ(waveform.length(), rational(1)); - - // Trim 0.25 seconds from start - waveform.TrimIn(rational(1, 4)); - - EXPECT_EQ(waveform.length(), rational(3, 4)); + AudioVisualWaveform waveform; + waveform.set_channel_count(2); + + // Add samples + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(48000)); // 1 second + FillSampleBuffer(buffer, 0.5f); + waveform.OverwriteSamples(buffer, 48000, rational(0)); + + EXPECT_EQ(waveform.length(), rational(1)); + + // Trim 0.25 seconds from start + waveform.TrimIn(rational(1, 4)); + + EXPECT_EQ(waveform.length(), rational(3, 4)); } TEST(AudioSmokeWaveform, Resize) { - AudioVisualWaveform waveform; - waveform.set_channel_count(2); - - // Add samples - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(48000)); - FillSampleBuffer(buffer, 0.5f); - waveform.OverwriteSamples(buffer, 48000, rational(0)); - - EXPECT_EQ(waveform.length(), rational(1)); - - // Resize to 0.5 seconds - waveform.Resize(rational(1, 2)); - - EXPECT_EQ(waveform.length(), rational(1, 2)); + AudioVisualWaveform waveform; + waveform.set_channel_count(2); + + // Add samples + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(48000)); + FillSampleBuffer(buffer, 0.5f); + waveform.OverwriteSamples(buffer, 48000, rational(0)); + + EXPECT_EQ(waveform.length(), rational(1)); + + // Resize to 0.5 seconds + waveform.Resize(rational(1, 2)); + + EXPECT_EQ(waveform.length(), rational(1, 2)); } TEST(AudioSmokeWaveform, TrimRange) { - AudioVisualWaveform waveform; - waveform.set_channel_count(2); - - // Add 2 seconds of samples - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(96000)); - FillSampleBuffer(buffer, 0.5f); - waveform.OverwriteSamples(buffer, 48000, rational(0)); - - EXPECT_EQ(waveform.length(), rational(2)); - - // Trim to range [0.5, 1.0] (0.5 seconds duration starting at 0.5) - waveform.TrimRange(rational(1, 2), rational(1, 2)); - - EXPECT_EQ(waveform.length(), rational(1, 2)); + AudioVisualWaveform waveform; + waveform.set_channel_count(2); + + // Add 2 seconds of samples + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(96000)); + FillSampleBuffer(buffer, 0.5f); + waveform.OverwriteSamples(buffer, 48000, rational(0)); + + EXPECT_EQ(waveform.length(), rational(2)); + + // Trim to range [0.5, 1.0] (0.5 seconds duration starting at 0.5) + waveform.TrimRange(rational(1, 2), rational(1, 2)); + + EXPECT_EQ(waveform.length(), rational(1, 2)); } TEST(AudioSmokeWaveform, Mid) { - AudioVisualWaveform waveform; - waveform.set_channel_count(2); - - // Add 2 seconds of samples - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(96000)); - FillSampleBuffer(buffer, 0.5f); - waveform.OverwriteSamples(buffer, 48000, rational(0)); - - // Get mid section [0.5, 1.5] - AudioVisualWaveform mid = waveform.Mid(rational(1, 2), rational(1)); - - EXPECT_EQ(mid.length(), rational(1)); - EXPECT_EQ(mid.channel_count(), 2); + AudioVisualWaveform waveform; + waveform.set_channel_count(2); + + // Add 2 seconds of samples + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(96000)); + FillSampleBuffer(buffer, 0.5f); + waveform.OverwriteSamples(buffer, 48000, rational(0)); + + // Get mid section [0.5, 1.5] + AudioVisualWaveform mid = waveform.Mid(rational(1, 2), rational(1)); + + EXPECT_EQ(mid.length(), rational(1)); + EXPECT_EQ(mid.channel_count(), 2); } TEST(AudioSmokeWaveform, GetSummaryFromTime) { - AudioVisualWaveform waveform; - waveform.set_channel_count(2); - - // Add samples with varying values - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(4800)); - for (int ch = 0; ch < buffer.channel_count(); ++ch) { - float *data = buffer.data(ch); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - data[i] = (i % 2 == 0) ? 0.8f : -0.8f; - } - } - waveform.OverwriteSamples(buffer, 48000, rational(0)); - - // Get summary for first half - auto summary = waveform.GetSummaryFromTime(rational(0), rational(1, 20)); - - EXPECT_EQ(summary.size(), 2); // 2 channels - // Summary should reflect the min/max of the samples - EXPECT_LE(summary[0].min, 0.0f); - EXPECT_GE(summary[0].max, 0.0f); + AudioVisualWaveform waveform; + waveform.set_channel_count(2); + + // Add samples with varying values + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(4800)); + for (int ch = 0; ch < buffer.channel_count(); ++ch) { + float *data = buffer.data(ch); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + data[i] = (i % 2 == 0) ? 0.8f : -0.8f; + } + } + waveform.OverwriteSamples(buffer, 48000, rational(0)); + + // Get summary for first half + auto summary = waveform.GetSummaryFromTime(rational(0), rational(1, 20)); + + EXPECT_EQ(summary.size(), 2); // 2 channels + // Summary should reflect the min/max of the samples + EXPECT_LE(summary[0].min, 0.0f); + EXPECT_GE(summary[0].max, 0.0f); } TEST(AudioSmokeWaveform, SumSamples) { - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(100)); - - // Fill with known pattern - for (int ch = 0; ch < buffer.channel_count(); ++ch) { - float *data = buffer.data(ch); - for (size_t i = 0; i < buffer.sample_count(); ++i) { - data[i] = float(i) / 100.0f; - } - } - - auto summary = AudioVisualWaveform::SumSamples(buffer, 0, 100); - - EXPECT_EQ(summary.size(), 2); - EXPECT_FLOAT_EQ(summary[0].min, 0.0f); - EXPECT_FLOAT_EQ(summary[0].max, 0.99f); + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(100)); + + // Fill with known pattern + for (int ch = 0; ch < buffer.channel_count(); ++ch) { + float *data = buffer.data(ch); + for (size_t i = 0; i < buffer.sample_count(); ++i) { + data[i] = float(i) / 100.0f; + } + } + + auto summary = AudioVisualWaveform::SumSamples(buffer, 0, 100); + + EXPECT_EQ(summary.size(), 2); + EXPECT_FLOAT_EQ(summary[0].min, 0.0f); + EXPECT_FLOAT_EQ(summary[0].max, 0.99f); } TEST(AudioSmokeWaveform, ReSumSamples) { - // Create sample data - std::vector samples(200); - for (size_t i = 0; i < 100; ++i) { - samples[i * 2].min = -0.5f; - samples[i * 2].max = 0.5f; - samples[i * 2 + 1].min = -0.3f; - samples[i * 2 + 1].max = 0.3f; - } - - auto summary = AudioVisualWaveform::ReSumSamples(samples.data(), 200, 2); - - EXPECT_EQ(summary.size(), 2); - EXPECT_FLOAT_EQ(summary[0].min, -0.5f); - EXPECT_FLOAT_EQ(summary[0].max, 0.5f); - EXPECT_FLOAT_EQ(summary[1].min, -0.3f); - EXPECT_FLOAT_EQ(summary[1].max, 0.3f); + // Create sample data + std::vector samples(200); + for (size_t i = 0; i < 100; ++i) { + samples[i * 2].min = -0.5f; + samples[i * 2].max = 0.5f; + samples[i * 2 + 1].min = -0.3f; + samples[i * 2 + 1].max = 0.3f; + } + + auto summary = AudioVisualWaveform::ReSumSamples(samples.data(), 200, 2); + + EXPECT_EQ(summary.size(), 2); + EXPECT_FLOAT_EQ(summary[0].min, -0.5f); + EXPECT_FLOAT_EQ(summary[0].max, 0.5f); + EXPECT_FLOAT_EQ(summary[1].min, -0.3f); + EXPECT_FLOAT_EQ(summary[1].max, 0.3f); } // ============================================================================ @@ -531,101 +535,101 @@ TEST(AudioSmokeWaveform, ReSumSamples) TEST(AudioSmokeProcessor, DefaultConstruction) { - AudioProcessor processor; - EXPECT_FALSE(processor.IsOpen()); + AudioProcessor processor; + EXPECT_FALSE(processor.IsOpen()); } TEST(AudioSmokeProcessor, OpenClose) { - AudioProcessor processor; - - AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams to(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - - EXPECT_TRUE(processor.Open(from, to, 1.0)); - EXPECT_TRUE(processor.IsOpen()); - - processor.Close(); - EXPECT_FALSE(processor.IsOpen()); + AudioProcessor processor; + + AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams to(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + + EXPECT_TRUE(processor.Open(from, to, 1.0)); + EXPECT_TRUE(processor.IsOpen()); + + processor.Close(); + EXPECT_FALSE(processor.IsOpen()); } TEST(AudioSmokeProcessor, SampleRateConversion) { - AudioProcessor processor; - - AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams to(44100, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - - EXPECT_TRUE(processor.Open(from, to, 1.0)); - EXPECT_TRUE(processor.IsOpen()); - EXPECT_EQ(processor.from().sample_rate(), 48000); - EXPECT_EQ(processor.to().sample_rate(), 44100); + AudioProcessor processor; + + AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams to(44100, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + + EXPECT_TRUE(processor.Open(from, to, 1.0)); + EXPECT_TRUE(processor.IsOpen()); + EXPECT_EQ(processor.from().sample_rate(), 48000); + EXPECT_EQ(processor.to().sample_rate(), 44100); } TEST(AudioSmokeProcessor, ChannelLayoutConversion) { - AudioProcessor processor; - - AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams to(48000, AV_CH_LAYOUT_MONO, SampleFormat::F32P); - - EXPECT_TRUE(processor.Open(from, to, 1.0)); - EXPECT_TRUE(processor.IsOpen()); - EXPECT_EQ(processor.from().channel_count(), 2); - EXPECT_EQ(processor.to().channel_count(), 1); + AudioProcessor processor; + + AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams to(48000, AV_CH_LAYOUT_MONO, SampleFormat::F32P); + + EXPECT_TRUE(processor.Open(from, to, 1.0)); + EXPECT_TRUE(processor.IsOpen()); + EXPECT_EQ(processor.from().channel_count(), 2); + EXPECT_EQ(processor.to().channel_count(), 1); } TEST(AudioSmokeProcessor, FormatConversion) { - AudioProcessor processor; - - AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams to(48000, AV_CH_LAYOUT_STEREO, SampleFormat::S16P); - - EXPECT_TRUE(processor.Open(from, to, 1.0)); - EXPECT_TRUE(processor.IsOpen()); + AudioProcessor processor; + + AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams to(48000, AV_CH_LAYOUT_STEREO, SampleFormat::S16P); + + EXPECT_TRUE(processor.Open(from, to, 1.0)); + EXPECT_TRUE(processor.IsOpen()); } TEST(AudioSmokeProcessor, TempoChange) { - AudioProcessor processor; - - AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams to(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - - // Open with 2x tempo - EXPECT_TRUE(processor.Open(from, to, 2.0)); - EXPECT_TRUE(processor.IsOpen()); + AudioProcessor processor; + + AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams to(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + + // Open with 2x tempo + EXPECT_TRUE(processor.Open(from, to, 2.0)); + EXPECT_TRUE(processor.IsOpen()); } TEST(AudioSmokeProcessor, InvalidOpen) { - AudioProcessor processor; - - // Open with valid params - AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - AudioParams to(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - EXPECT_TRUE(processor.Open(from, to, 1.0)); - - // Try to open again while already open (should fail) - EXPECT_FALSE(processor.Open(from, to, 1.0)); + AudioProcessor processor; + + // Open with valid params + AudioParams from(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + AudioParams to(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + EXPECT_TRUE(processor.Open(from, to, 1.0)); + + // Try to open again while already open (should fail) + EXPECT_FALSE(processor.Open(from, to, 1.0)); } TEST(AudioSmokeProcessor, ConvertWithoutOpen) { - AudioProcessor processor; - - // Create input data - float *input[2] = {nullptr, nullptr}; - std::vector ch0(100, 0.5f); - std::vector ch1(100, 0.5f); - input[0] = ch0.data(); - input[1] = ch1.data(); - - AudioProcessor::Buffer output; - - // Should fail since processor is not open - EXPECT_EQ(processor.Convert(input, 100, &output), -1); + AudioProcessor processor; + + // Create input data + float *input[2] = { nullptr, nullptr }; + std::vector ch0(100, 0.5f); + std::vector ch1(100, 0.5f); + input[0] = ch0.data(); + input[1] = ch1.data(); + + AudioProcessor::Buffer output; + + // Should fail since processor is not open + EXPECT_EQ(processor.Convert(input, 100, &output), -1); } // ============================================================================ @@ -634,47 +638,48 @@ TEST(AudioSmokeProcessor, ConvertWithoutOpen) TEST(AudioSmokePreviewDevice, Construction) { - PreviewAudioDevice device; - EXPECT_TRUE(device.isSequential()); - EXPECT_EQ(device.bytes_per_frame(), 0); // BUG: Should be initialized properly + PreviewAudioDevice device; + EXPECT_TRUE(device.isSequential()); + EXPECT_EQ(device.bytes_per_frame(), + 0); // BUG: Should be initialized properly } TEST(AudioSmokePreviewDevice, BytesPerFrame) { - PreviewAudioDevice device; - - device.set_bytes_per_frame(8); // 2 channels * 4 bytes (F32) - EXPECT_EQ(device.bytes_per_frame(), 8); - - device.set_bytes_per_frame(4); // 2 channels * 2 bytes (S16) - EXPECT_EQ(device.bytes_per_frame(), 4); + PreviewAudioDevice device; + + device.set_bytes_per_frame(8); // 2 channels * 4 bytes (F32) + EXPECT_EQ(device.bytes_per_frame(), 8); + + device.set_bytes_per_frame(4); // 2 channels * 2 bytes (S16) + EXPECT_EQ(device.bytes_per_frame(), 4); } TEST(AudioSmokePreviewDevice, NotifyInterval) { - PreviewAudioDevice device; - - device.set_notify_interval(100); // 100 frames - // Cannot directly verify, but should not crash + PreviewAudioDevice device; + + device.set_notify_interval(100); // 100 frames + // Cannot directly verify, but should not crash } TEST(AudioSmokePreviewDevice, Clear) { - PreviewAudioDevice device; - device.open(QIODevice::ReadWrite); - - // Write some data - QByteArray data(1000, 0xAB); - device.write(data); - - // Clear - device.clear(); - - // Device should be empty now (next read should return 0 or silence) - char buf[100]; - qint64 read = device.readData(buf, sizeof(buf)); - // After clear, read should return 0 or the buffer should be zeroed - EXPECT_TRUE(read >= 0); + PreviewAudioDevice device; + device.open(QIODevice::ReadWrite); + + // Write some data + QByteArray data(1000, 0xAB); + device.write(data); + + // Clear + device.clear(); + + // Device should be empty now (next read should return 0 or silence) + char buf[100]; + qint64 read = device.readData(buf, sizeof(buf)); + // After clear, read should return 0 or the buffer should be zeroed + EXPECT_TRUE(read >= 0); } // ============================================================================ @@ -683,59 +688,59 @@ TEST(AudioSmokePreviewDevice, Clear) TEST(AudioSmokeSampleFormat, ByteCount) { - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::INVALID), 0); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::U8), 1); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::U8P), 1); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S16), 2); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S16P), 2); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S32), 4); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S32P), 4); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F32), 4); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F32P), 4); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S64), 8); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S64P), 8); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F64), 8); - EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F64P), 8); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::INVALID), 0); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::U8), 1); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::U8P), 1); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S16), 2); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S16P), 2); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S32), 4); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S32P), 4); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F32), 4); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F32P), 4); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S64), 8); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S64P), 8); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F64), 8); + EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F64P), 8); } TEST(AudioSmokeSampleFormat, PackedVsPlanar) { - // Packed formats - EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::U8)); - EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::S16)); - EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::S32)); - EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::F32)); - EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::S64)); - EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::F64)); - - // Planar formats - EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::U8P)); - EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::S16P)); - EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::S32P)); - EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::F32P)); - EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::S64P)); - EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::F64P)); + // Packed formats + EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::U8)); + EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::S16)); + EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::S32)); + EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::F32)); + EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::S64)); + EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::F64)); + + // Planar formats + EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::U8P)); + EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::S16P)); + EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::S32P)); + EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::F32P)); + EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::S64P)); + EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::F64P)); } TEST(AudioSmokeSampleFormat, StringConversion) { - // Test to_string (values may vary based on FFmpeg version) - EXPECT_EQ(SampleFormat::to_string(SampleFormat::U8), "u8"); - EXPECT_EQ(SampleFormat::to_string(SampleFormat::S16), "s16"); - EXPECT_EQ(SampleFormat::to_string(SampleFormat::S32), "s32"); - // F32 can be "flt" or "f32" depending on FFmpeg version - std::string f32_str = SampleFormat::to_string(SampleFormat::F32); - EXPECT_TRUE(f32_str == "flt" || f32_str == "f32"); - // F64 can be "dbl" or "f64" depending on FFmpeg version - std::string f64_str = SampleFormat::to_string(SampleFormat::F64); - EXPECT_TRUE(f64_str == "dbl" || f64_str == "f64"); - - // Test from_string - EXPECT_EQ(SampleFormat::from_string("u8"), SampleFormat::U8); - EXPECT_EQ(SampleFormat::from_string("s16"), SampleFormat::S16); - // from_string may not support all format names - EXPECT_EQ(SampleFormat::from_string(""), SampleFormat::INVALID); - EXPECT_EQ(SampleFormat::from_string("unknown"), SampleFormat::INVALID); + // Test to_string (values may vary based on FFmpeg version) + EXPECT_EQ(SampleFormat::to_string(SampleFormat::U8), "u8"); + EXPECT_EQ(SampleFormat::to_string(SampleFormat::S16), "s16"); + EXPECT_EQ(SampleFormat::to_string(SampleFormat::S32), "s32"); + // F32 can be "flt" or "f32" depending on FFmpeg version + std::string f32_str = SampleFormat::to_string(SampleFormat::F32); + EXPECT_TRUE(f32_str == "flt" || f32_str == "f32"); + // F64 can be "dbl" or "f64" depending on FFmpeg version + std::string f64_str = SampleFormat::to_string(SampleFormat::F64); + EXPECT_TRUE(f64_str == "dbl" || f64_str == "f64"); + + // Test from_string + EXPECT_EQ(SampleFormat::from_string("u8"), SampleFormat::U8); + EXPECT_EQ(SampleFormat::from_string("s16"), SampleFormat::S16); + // from_string may not support all format names + EXPECT_EQ(SampleFormat::from_string(""), SampleFormat::INVALID); + EXPECT_EQ(SampleFormat::from_string("unknown"), SampleFormat::INVALID); } // ============================================================================ @@ -744,86 +749,88 @@ TEST(AudioSmokeSampleFormat, StringConversion) TEST(AudioSmokeThread, ConcurrentWaveformAccess) { - const int num_threads = 4; - const int num_ops_per_thread = 50; - - AudioVisualWaveform waveform; - waveform.set_channel_count(2); - - // Pre-populate with data - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(4800)); - FillSampleBuffer(buffer, 0.5f); - waveform.OverwriteSamples(buffer, 48000, rational(0)); - - std::vector threads; - std::atomic success_count{0}; - - for (int t = 0; t < num_threads; ++t) { - threads.emplace_back([&waveform, &success_count, num_ops_per_thread]() { - for (int i = 0; i < num_ops_per_thread; ++i) { - // Read summary from different times - auto summary = waveform.GetSummaryFromTime( - rational(i % 10, 100), // 0.00 to 0.09 seconds - rational(1, 100) // 0.01 second duration - ); - - if (summary.size() == 2) { - success_count++; - } - } - }); - } - - for (auto &t : threads) { - t.join(); - } - - EXPECT_EQ(success_count.load(), num_threads * num_ops_per_thread); + const int num_threads = 4; + const int num_ops_per_thread = 50; + + AudioVisualWaveform waveform; + waveform.set_channel_count(2); + + // Pre-populate with data + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(4800)); + FillSampleBuffer(buffer, 0.5f); + waveform.OverwriteSamples(buffer, 48000, rational(0)); + + std::vector threads; + std::atomic success_count{ 0 }; + + for (int t = 0; t < num_threads; ++t) { + threads.emplace_back([&waveform, &success_count, num_ops_per_thread]() { + for (int i = 0; i < num_ops_per_thread; ++i) { + // Read summary from different times + auto summary = waveform.GetSummaryFromTime( + rational(i % 10, 100), // 0.00 to 0.09 seconds + rational(1, 100) // 0.01 second duration + ); + + if (summary.size() == 2) { + success_count++; + } + } + }); + } + + for (auto &t : threads) { + t.join(); + } + + EXPECT_EQ(success_count.load(), num_threads * num_ops_per_thread); } TEST(AudioSmokeThread, ConcurrentSampleBufferOperations) { - const int num_threads = 4; - - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - SampleBuffer buffer(params, size_t(1000)); - FillSampleBuffer(buffer, 0.5f); - - std::vector threads; - std::atomic success_count{0}; - - for (int t = 0; t < num_threads; ++t) { - threads.emplace_back([&buffer, &success_count, t]() { - // Each thread applies different operations - switch (t % 4) { - case 0: - buffer.transform_volume(0.8f); - success_count++; - break; - case 1: - buffer.clamp(); - success_count++; - break; - case 2: { - auto ripped = buffer.rip_channel(0); - if (ripped.channel_count() == 1) success_count++; - break; - } - case 3: { - auto ptrs = buffer.to_raw_ptrs(); - if (!ptrs.empty()) success_count++; - break; - } - } - }); - } - - for (auto &t : threads) { - t.join(); - } - - EXPECT_EQ(success_count.load(), num_threads); + const int num_threads = 4; + + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + SampleBuffer buffer(params, size_t(1000)); + FillSampleBuffer(buffer, 0.5f); + + std::vector threads; + std::atomic success_count{ 0 }; + + for (int t = 0; t < num_threads; ++t) { + threads.emplace_back([&buffer, &success_count, t]() { + // Each thread applies different operations + switch (t % 4) { + case 0: + buffer.transform_volume(0.8f); + success_count++; + break; + case 1: + buffer.clamp(); + success_count++; + break; + case 2: { + auto ripped = buffer.rip_channel(0); + if (ripped.channel_count() == 1) + success_count++; + break; + } + case 3: { + auto ptrs = buffer.to_raw_ptrs(); + if (!ptrs.empty()) + success_count++; + break; + } + } + }); + } + + for (auto &t : threads) { + t.join(); + } + + EXPECT_EQ(success_count.load(), num_threads); } } // namespace test diff --git a/tests/gtest/audio_synchronizer_test.cpp b/tests/gtest/audio_synchronizer_test.cpp index 5d3edce04..6e9cabd0e 100644 --- a/tests/gtest/audio_synchronizer_test.cpp +++ b/tests/gtest/audio_synchronizer_test.cpp @@ -13,8 +13,8 @@ TEST(AudioSynchronizer, PlacesCandidateBySourceStartTime) candidate.has_source_start_time = true; const olive::AudioSynchronizer::Placement placement = - olive::AudioSynchronizer::PlaceBySourceTime( - reference, candidate, olive::core::rational(10)); + olive::AudioSynchronizer::PlaceBySourceTime(reference, candidate, + olive::core::rational(10)); ASSERT_TRUE(placement.valid); EXPECT_EQ(placement.timeline_in, olive::core::rational(22)); @@ -33,8 +33,8 @@ TEST(AudioSynchronizer, AccountsForMediaInWhenPlacingBySourceTime) candidate.has_source_start_time = true; const olive::AudioSynchronizer::Placement placement = - olive::AudioSynchronizer::PlaceBySourceTime( - reference, candidate, olive::core::rational(20)); + olive::AudioSynchronizer::PlaceBySourceTime(reference, candidate, + olive::core::rational(20)); ASSERT_TRUE(placement.valid); EXPECT_EQ(placement.timeline_in, olive::core::rational(23)); @@ -49,8 +49,8 @@ TEST(AudioSynchronizer, RejectsMissingSourceStartTime) olive::AudioSynchronizer::SourceClip candidate; const olive::AudioSynchronizer::Placement placement = - olive::AudioSynchronizer::PlaceBySourceTime( - reference, candidate, olive::core::rational(10)); + olive::AudioSynchronizer::PlaceBySourceTime(reference, candidate, + olive::core::rational(10)); EXPECT_FALSE(placement.valid); } diff --git a/tests/gtest/audio_waveform_sync_test.cpp b/tests/gtest/audio_waveform_sync_test.cpp index 3fe816590..e6ebb4c98 100644 --- a/tests/gtest/audio_waveform_sync_test.cpp +++ b/tests/gtest/audio_waveform_sync_test.cpp @@ -9,7 +9,8 @@ extern "C" { #include } -namespace { +namespace +{ olive::core::AudioParams MakeMonoParams() { @@ -46,13 +47,11 @@ TEST(AudioWaveformSync, ExtractsRmsEnvelope) TEST(AudioWaveformSync, EstimatesCandidateLag) { - const QVector reference_values = { - 0.0f, 0.0f, 0.8f, 0.8f, 0.1f, 0.1f, 0.6f, 0.6f, 0.0f, 0.0f - }; - const QVector candidate_values = { - 0.0f, 0.0f, 0.0f, 0.0f, 0.8f, 0.8f, 0.1f, - 0.1f, 0.6f, 0.6f, 0.0f, 0.0f - }; + const QVector reference_values = { 0.0f, 0.0f, 0.8f, 0.8f, 0.1f, + 0.1f, 0.6f, 0.6f, 0.0f, 0.0f }; + const QVector candidate_values = { 0.0f, 0.0f, 0.0f, 0.0f, + 0.8f, 0.8f, 0.1f, 0.1f, + 0.6f, 0.6f, 0.0f, 0.0f }; const olive::AudioWaveformSync::OffsetResult result = olive::AudioWaveformSync::EstimateOffset( @@ -65,13 +64,11 @@ TEST(AudioWaveformSync, EstimatesCandidateLag) TEST(AudioWaveformSync, EstimatesCandidateLead) { - const QVector reference_values = { - 0.0f, 0.0f, 0.0f, 0.0f, 0.9f, 0.9f, 0.3f, - 0.3f, 0.7f, 0.7f, 0.0f, 0.0f - }; - const QVector candidate_values = { - 0.9f, 0.9f, 0.3f, 0.3f, 0.7f, 0.7f, 0.0f, 0.0f - }; + const QVector reference_values = { 0.0f, 0.0f, 0.0f, 0.0f, + 0.9f, 0.9f, 0.3f, 0.3f, + 0.7f, 0.7f, 0.0f, 0.0f }; + const QVector candidate_values = { 0.9f, 0.9f, 0.3f, 0.3f, + 0.7f, 0.7f, 0.0f, 0.0f }; const olive::AudioWaveformSync::OffsetResult result = olive::AudioWaveformSync::EstimateOffset( diff --git a/tests/gtest/codec_decoder_test.cpp b/tests/gtest/codec_decoder_test.cpp index 5ea752567..4b876333e 100644 --- a/tests/gtest/codec_decoder_test.cpp +++ b/tests/gtest/codec_decoder_test.cpp @@ -11,7 +11,8 @@ TEST(CodecDecoder, RetrieveVideoFrameFromDemoMp4) .filePath(QStringLiteral("tests/demo.mp4")); ASSERT_TRUE(QFileInfo::exists(path)); - olive::DecoderPtr decoder = olive::Decoder::CreateFromID(QStringLiteral("ffmpeg")); + olive::DecoderPtr decoder = + olive::Decoder::CreateFromID(QStringLiteral("ffmpeg")); ASSERT_TRUE(decoder); ASSERT_TRUE(decoder->Open(olive::Decoder::CodecStream(path, 0, nullptr))); diff --git a/tests/gtest/codec_encoder_test.cpp b/tests/gtest/codec_encoder_test.cpp index 05d7bc1f2..c8731f9dd 100644 --- a/tests/gtest/codec_encoder_test.cpp +++ b/tests/gtest/codec_encoder_test.cpp @@ -2,7 +2,8 @@ #include "codec/encoder.h" -namespace { +namespace +{ class TestEncoder final : public olive::Encoder { public: explicit TestEncoder(const olive::EncodingParams ¶ms) @@ -57,8 +58,8 @@ TEST(CodecEncoder, ImageSequenceFilenames) QStringLiteral("frame_[####].png")), QStringLiteral("frame.png")); - const QString filename = encoder.GetFilenameForFrame( - olive::core::rational(1, 24)); + const QString filename = + encoder.GetFilenameForFrame(olive::core::rational(1, 24)); EXPECT_EQ(filename, QStringLiteral("frame_0001.png")); } @@ -66,21 +67,18 @@ TEST(CodecEncoder, MatrixGeneration) { using Method = olive::EncodingParams::VideoScalingMethod; - QMatrix4x4 stretch = - olive::EncodingParams::GenerateMatrix(Method::kStretch, 1920, 1080, - 1280, 720); + QMatrix4x4 stretch = olive::EncodingParams::GenerateMatrix( + Method::kStretch, 1920, 1080, 1280, 720); EXPECT_TRUE(qFuzzyCompare(stretch(0, 0), 1.0f)); EXPECT_TRUE(qFuzzyCompare(stretch(1, 1), 1.0f)); - QMatrix4x4 fit = - olive::EncodingParams::GenerateMatrix(Method::kFit, 1920, 1080, - 1024, 1024); + QMatrix4x4 fit = olive::EncodingParams::GenerateMatrix(Method::kFit, 1920, + 1080, 1024, 1024); EXPECT_TRUE(qFuzzyCompare(fit(0, 0), 1.0f)); EXPECT_FALSE(qFuzzyCompare(fit(1, 1), 1.0f)); - QMatrix4x4 crop = - olive::EncodingParams::GenerateMatrix(Method::kCrop, 1920, 1080, - 1024, 1024); + QMatrix4x4 crop = olive::EncodingParams::GenerateMatrix(Method::kCrop, 1920, + 1080, 1024, 1024); EXPECT_FALSE(qFuzzyCompare(crop(0, 0), 1.0f)); EXPECT_TRUE(qFuzzyCompare(crop(1, 1), 1.0f)); } diff --git a/tests/gtest/codec_exportformat_test.cpp b/tests/gtest/codec_exportformat_test.cpp index 4e005a5ff..3fdea8357 100644 --- a/tests/gtest/codec_exportformat_test.cpp +++ b/tests/gtest/codec_exportformat_test.cpp @@ -12,7 +12,8 @@ TEST(CodecExportFormat, NamesAndExtensions) QStringLiteral("mxf")); EXPECT_EQ(ExportFormat::GetName(ExportFormat::kFormatCount), QStringLiteral("Unknown")); - EXPECT_TRUE(ExportFormat::GetExtension(ExportFormat::kFormatCount).isEmpty()); + EXPECT_TRUE( + ExportFormat::GetExtension(ExportFormat::kFormatCount).isEmpty()); } TEST(CodecExportFormat, AllFormatsHaveNames) diff --git a/tests/gtest/codec_frame_test.cpp b/tests/gtest/codec_frame_test.cpp index 2c5551d50..3e1938616 100644 --- a/tests/gtest/codec_frame_test.cpp +++ b/tests/gtest/codec_frame_test.cpp @@ -44,9 +44,9 @@ TEST(CodecFrame, AllocateMatchesLineSize) TEST(CodecFrame, DestroyDeallocatesData) { olive::FramePtr frame = olive::Frame::Create(); - frame->set_video_params(olive::VideoParams( - 8, 8, olive::core::PixelFormat::U8, - olive::VideoParams::kRGBAChannelCount)); + frame->set_video_params( + olive::VideoParams(8, 8, olive::core::PixelFormat::U8, + olive::VideoParams::kRGBAChannelCount)); frame->allocate(); EXPECT_TRUE(frame->is_allocated()); @@ -55,7 +55,6 @@ TEST(CodecFrame, DestroyDeallocatesData) EXPECT_EQ(frame->data(), nullptr); } - TEST(CodecFrame, AllocateInvalidParamsFails) { olive::Frame frame; @@ -157,13 +156,15 @@ TEST(CodecFrame, InterlaceFrames) TEST(CodecFrame, InterlaceIncompatibleReturnsNull) { olive::FramePtr top = olive::Frame::Create(); - top->set_video_params(olive::VideoParams( - 4, 4, olive::core::PixelFormat::U8, olive::VideoParams::kRGBAChannelCount)); + top->set_video_params( + olive::VideoParams(4, 4, olive::core::PixelFormat::U8, + olive::VideoParams::kRGBAChannelCount)); top->allocate(); olive::FramePtr bottom = olive::Frame::Create(); - bottom->set_video_params(olive::VideoParams( - 8, 8, olive::core::PixelFormat::U8, olive::VideoParams::kRGBAChannelCount)); + bottom->set_video_params( + olive::VideoParams(8, 8, olive::core::PixelFormat::U8, + olive::VideoParams::kRGBAChannelCount)); bottom->allocate(); EXPECT_EQ(olive::Frame::Interlace(top, bottom), nullptr); @@ -177,8 +178,7 @@ TEST(CodecFrame, ConvertU8ToU16) frame->set_video_params(params); frame->allocate(); - olive::FramePtr converted = - frame->convert(olive::core::PixelFormat::U16); + olive::FramePtr converted = frame->convert(olive::core::PixelFormat::U16); ASSERT_NE(converted, nullptr); EXPECT_EQ(converted->format(), olive::core::PixelFormat::U16); EXPECT_EQ(converted->width(), 4); diff --git a/tests/gtest/color_lut_test.cpp b/tests/gtest/color_lut_test.cpp index ef67a5b2f..d086f6e77 100644 --- a/tests/gtest/color_lut_test.cpp +++ b/tests/gtest/color_lut_test.cpp @@ -18,7 +18,8 @@ namespace OCIO = OCIO_NAMESPACE; -namespace { +namespace +{ bool IsOakSupportedLutExtension(QString suffix) { @@ -31,19 +32,19 @@ bool IsOakSupportedLutExtension(QString suffix) QString WriteTestCube(QTemporaryDir *dir) { - const QString path = QDir(dir->path()).filePath(QStringLiteral("invert.cube")); + const QString path = + QDir(dir->path()).filePath(QStringLiteral("invert.cube")); QFile file(path); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { return QString(); } - const QByteArray data = - "TITLE \"Oak test invert\"\n" - "LUT_1D_SIZE 2\n" - "DOMAIN_MIN 0.0 0.0 0.0\n" - "DOMAIN_MAX 1.0 1.0 1.0\n" - "1.0 1.0 1.0\n" - "0.0 0.0 0.0\n"; + const QByteArray data = "TITLE \"Oak test invert\"\n" + "LUT_1D_SIZE 2\n" + "DOMAIN_MIN 0.0 0.0 0.0\n" + "DOMAIN_MAX 1.0 1.0 1.0\n" + "1.0 1.0 1.0\n" + "0.0 0.0 0.0\n"; file.write(data); file.close(); return path; @@ -87,9 +88,10 @@ protected: } } - virtual void ProcessColorTransform(olive::TexturePtr destination, - const olive::Node *node, - const olive::ColorTransformJob *job) override + virtual void + ProcessColorTransform(olive::TexturePtr destination, + const olive::Node *node, + const olive::ColorTransformJob *job) override { Q_UNUSED(destination) Q_UNUSED(node) @@ -110,11 +112,12 @@ protected: } }; -QString WriteTestCubeLut(QTemporaryDir *dir, const char *title, - float low, float high) +QString WriteTestCubeLut(QTemporaryDir *dir, const char *title, float low, + float high) { - const QString path = QDir(dir->path()).filePath( - QStringLiteral("%1.cube").arg(QString::fromUtf8(title))); + const QString path = + QDir(dir->path()) + .filePath(QStringLiteral("%1.cube").arg(QString::fromUtf8(title))); QFile file(path); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { return QString(); @@ -147,14 +150,13 @@ QString WriteAsymmetricCube(QTemporaryDir *dir) return QString(); } - const QByteArray data = - "TITLE \"Oak test asymmetric\"\n" - "LUT_1D_SIZE 3\n" - "DOMAIN_MIN 0.0 0.0 0.0\n" - "DOMAIN_MAX 1.0 1.0 1.0\n" - "0.00 0.00 0.00\n" - "0.75 0.75 0.75\n" - "1.00 1.00 1.00\n"; + const QByteArray data = "TITLE \"Oak test asymmetric\"\n" + "LUT_1D_SIZE 3\n" + "DOMAIN_MIN 0.0 0.0 0.0\n" + "DOMAIN_MAX 1.0 1.0 1.0\n" + "0.00 0.00 0.00\n" + "0.75 0.75 0.75\n" + "1.00 1.00 1.00\n"; file.write(data); file.close(); return path; @@ -231,7 +233,8 @@ TEST(ColorLut, CubeFileTransformConvertsColor) olive::ColorProcessor::Create(config->getProcessor(transform)); ASSERT_TRUE(processor); - const olive::Color out = processor->ConvertColor(olive::Color(0.25f, 0.50f, 0.75f, 1.0f)); + const olive::Color out = + processor->ConvertColor(olive::Color(0.25f, 0.50f, 0.75f, 1.0f)); EXPECT_NEAR(out.red(), 0.75f, 0.02f); EXPECT_NEAR(out.green(), 0.50f, 0.02f); EXPECT_NEAR(out.blue(), 0.25f, 0.02f); @@ -240,9 +243,8 @@ TEST(ColorLut, CubeFileTransformConvertsColor) TEST(ColorV04, FactoryCreatesColorNodes) { - std::unique_ptr lut( - olive::NodeFactory::CreateFromFactoryIndex( - olive::NodeFactory::kOCIOLut)); + std::unique_ptr lut(olive::NodeFactory::CreateFromFactoryIndex( + olive::NodeFactory::kOCIOLut)); ASSERT_NE(lut, nullptr); EXPECT_EQ(lut->id(), QStringLiteral("org.olivevideoeditor.Olive.ociolut")); @@ -260,8 +262,8 @@ TEST(ColorV04, FactoryCreatesColorNodes) olive::ThreeWayColorNode::kHighlightsColorInput)); const olive::Color neutral = - three_way->GetStandardValue( - olive::ThreeWayColorNode::kMidtonesColorInput) + three_way + ->GetStandardValue(olive::ThreeWayColorNode::kMidtonesColorInput) .value(); EXPECT_FLOAT_EQ(neutral.red(), 0.5f); EXPECT_FLOAT_EQ(neutral.green(), 0.5f); @@ -306,9 +308,8 @@ TEST(ColorLutNode, ForwardDirectionInvertsPixels) olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); PixelColorTransformTraverser traverser; traverser.SetCacheVideoParams(params); @@ -354,9 +355,8 @@ TEST(ColorLutNode, InverseDirectionReversesForwardTransform) olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); PixelColorTransformTraverser traverser; traverser.SetCacheVideoParams(params); @@ -402,9 +402,8 @@ TEST(ColorLutNode, SwitchingDirectionUpdatesProcessorAndPixels) olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); // First render: forward direction. PixelColorTransformTraverser forward_traverser; @@ -471,9 +470,8 @@ TEST(ColorLutNode, EmptyFilePathLeavesProcessorNull) olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); PixelColorTransformTraverser traverser; traverser.SetCacheVideoParams(params); @@ -503,14 +501,13 @@ TEST(ColorLutNode, MissingFilePathLeavesProcessorNull) auto *lut = new olive::OCIOLutNode(); lut->setParent(&project); lut->SetStandardValue(olive::OCIOLutNode::kFileInput, - QStringLiteral("/nonexistent/path/lut.cube")); + QStringLiteral("/nonexistent/path/lut.cube")); olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); PixelColorTransformTraverser traverser; traverser.SetCacheVideoParams(params); @@ -538,14 +535,13 @@ TEST(ColorLutNode, UnsupportedExtensionLeavesProcessorNull) auto *lut = new olive::OCIOLutNode(); lut->setParent(&project); lut->SetStandardValue(olive::OCIOLutNode::kFileInput, - QStringLiteral("/tmp/lut.txt")); + QStringLiteral("/tmp/lut.txt")); olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); PixelColorTransformTraverser traverser; traverser.SetCacheVideoParams(params); @@ -579,14 +575,13 @@ TEST(ColorLutNode, DirectionStringValuesAreAccepted) lut->setParent(&project); lut->SetStandardValue(olive::OCIOLutNode::kFileInput, path); lut->SetStandardValue(olive::OCIOLutNode::kDirectionInput, - QStringLiteral("forward")); + QStringLiteral("forward")); olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); PixelColorTransformTraverser traverser; traverser.SetCacheVideoParams(params); @@ -626,14 +621,13 @@ TEST(ColorLutNode, DirectionStringInverseIsAccepted) lut->setParent(&project); lut->SetStandardValue(olive::OCIOLutNode::kFileInput, path); lut->SetStandardValue(olive::OCIOLutNode::kDirectionInput, - QStringLiteral("inverse")); + QStringLiteral("inverse")); olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); PixelColorTransformTraverser traverser; traverser.SetCacheVideoParams(params); @@ -676,9 +670,8 @@ TEST(ColorLutNode, ReusingSameFileDoesNotCrash) olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); // Render twice; the second render should reuse the cached processor. for (int i = 0; i < 2; ++i) { @@ -708,10 +701,8 @@ TEST(ColorLutNode, SwitchingBackToOriginalFileRestoresOriginalPixels) QTemporaryDir dir; ASSERT_TRUE(dir.isValid()); - const QString invert_path = WriteTestCubeLut( - &dir, "invert", 0.0f, 1.0f); - const QString boost_path = WriteTestCubeLut( - &dir, "boost", 0.5f, 1.0f); + const QString invert_path = WriteTestCubeLut(&dir, "invert", 0.0f, 1.0f); + const QString boost_path = WriteTestCubeLut(&dir, "boost", 0.5f, 1.0f); ASSERT_FALSE(invert_path.isEmpty()); ASSERT_FALSE(boost_path.isEmpty()); @@ -728,9 +719,8 @@ TEST(ColorLutNode, SwitchingBackToOriginalFileRestoresOriginalPixels) olive::Node::ConnectEdge( solid, olive::NodeInput(lut, olive::OCIOLutNode::kTextureInput)); - const olive::VideoParams params( - 16, 16, olive::core::PixelFormat::F32, - olive::VideoParams::kRGBAChannelCount); + const olive::VideoParams params(16, 16, olive::core::PixelFormat::F32, + olive::VideoParams::kRGBAChannelCount); auto render = [&]() { PixelColorTransformTraverser traverser; diff --git a/tests/gtest/common_commandlineparser_test.cpp b/tests/gtest/common_commandlineparser_test.cpp index 6dc879180..ba81d83cb 100644 --- a/tests/gtest/common_commandlineparser_test.cpp +++ b/tests/gtest/common_commandlineparser_test.cpp @@ -4,80 +4,80 @@ TEST(CommonCommandLineParser, OptionWithoutArgument) { - CommandLineParser parser; - const CommandLineParser::Option *opt = parser.AddOption( - {QStringLiteral("help"), QStringLiteral("h")}, - QStringLiteral("Show help"), false); + CommandLineParser parser; + const CommandLineParser::Option *opt = + parser.AddOption({ QStringLiteral("help"), QStringLiteral("h") }, + QStringLiteral("Show help"), false); - parser.Process({QStringLiteral("app"), QStringLiteral("-help")}); + parser.Process({ QStringLiteral("app"), QStringLiteral("-help") }); - EXPECT_TRUE(opt->IsSet()); + EXPECT_TRUE(opt->IsSet()); } TEST(CommonCommandLineParser, ShortOption) { - CommandLineParser parser; - const CommandLineParser::Option *opt = parser.AddOption( - {QStringLiteral("help"), QStringLiteral("h")}, - QStringLiteral("Show help"), false); + CommandLineParser parser; + const CommandLineParser::Option *opt = + parser.AddOption({ QStringLiteral("help"), QStringLiteral("h") }, + QStringLiteral("Show help"), false); - parser.Process({QStringLiteral("app"), QStringLiteral("-h")}); + parser.Process({ QStringLiteral("app"), QStringLiteral("-h") }); - EXPECT_TRUE(opt->IsSet()); + EXPECT_TRUE(opt->IsSet()); } TEST(CommonCommandLineParser, OptionWithArgument) { - CommandLineParser parser; - const CommandLineParser::Option *opt = parser.AddOption( - {QStringLiteral("project")}, QStringLiteral("Project file"), true, - QStringLiteral("file")); + CommandLineParser parser; + const CommandLineParser::Option *opt = parser.AddOption( + { QStringLiteral("project") }, QStringLiteral("Project file"), true, + QStringLiteral("file")); - parser.Process({QStringLiteral("app"), QStringLiteral("-project"), - QStringLiteral("test.ove")}); + parser.Process({ QStringLiteral("app"), QStringLiteral("-project"), + QStringLiteral("test.ove") }); - EXPECT_TRUE(opt->IsSet()); - EXPECT_EQ(opt->GetSetting(), QStringLiteral("test.ove")); + EXPECT_TRUE(opt->IsSet()); + EXPECT_EQ(opt->GetSetting(), QStringLiteral("test.ove")); } TEST(CommonCommandLineParser, PositionalArgument) { - CommandLineParser parser; - const CommandLineParser::PositionalArgument *arg = - parser.AddPositionalArgument(QStringLiteral("filename"), - QStringLiteral("Project file"), true); + CommandLineParser parser; + const CommandLineParser::PositionalArgument *arg = + parser.AddPositionalArgument(QStringLiteral("filename"), + QStringLiteral("Project file"), true); - parser.Process({QStringLiteral("app"), QStringLiteral("test.ove")}); + parser.Process({ QStringLiteral("app"), QStringLiteral("test.ove") }); - EXPECT_EQ(arg->GetSetting(), QStringLiteral("test.ove")); + EXPECT_EQ(arg->GetSetting(), QStringLiteral("test.ove")); } TEST(CommonCommandLineParser, UnknownOptionWarning) { - CommandLineParser parser; - parser.AddOption({QStringLiteral("known")}, QStringLiteral("Known")); + CommandLineParser parser; + parser.AddOption({ QStringLiteral("known") }, QStringLiteral("Known")); - // Should not crash; unknown option is logged - parser.Process({QStringLiteral("app"), QStringLiteral("-unknown")}); + // Should not crash; unknown option is logged + parser.Process({ QStringLiteral("app"), QStringLiteral("-unknown") }); } TEST(CommonCommandLineParser, UnknownPositionalWarning) { - CommandLineParser parser; + CommandLineParser parser; - // Should not crash; unknown positional is logged - parser.Process({QStringLiteral("app"), QStringLiteral("extra")}); + // Should not crash; unknown positional is logged + parser.Process({ QStringLiteral("app"), QStringLiteral("extra") }); } TEST(CommonCommandLineParser, HiddenOptionExcludedFromHelp) { - CommandLineParser parser; - parser.AddOption({QStringLiteral("visible")}, QStringLiteral("Visible")); - parser.AddOption({QStringLiteral("hidden")}, QStringLiteral("Hidden"), - false, QString(), true); - parser.AddPositionalArgument(QStringLiteral("file"), - QStringLiteral("Input file")); + CommandLineParser parser; + parser.AddOption({ QStringLiteral("visible") }, QStringLiteral("Visible")); + parser.AddOption({ QStringLiteral("hidden") }, QStringLiteral("Hidden"), + false, QString(), true); + parser.AddPositionalArgument(QStringLiteral("file"), + QStringLiteral("Input file")); - // Should not crash; hidden option should be skipped during help output - parser.PrintHelp("/usr/bin/app"); + // Should not crash; hidden option should be skipped during help output + parser.PrintHelp("/usr/bin/app"); } diff --git a/tests/gtest/common_current_test.cpp b/tests/gtest/common_current_test.cpp index bff3a4c0e..b505b5033 100644 --- a/tests/gtest/common_current_test.cpp +++ b/tests/gtest/common_current_test.cpp @@ -11,7 +11,8 @@ TEST(CommonCurrent, SetAndGetVideoParams) params.set_height(1080); Current::getInstance().setCurrentVideoParams(params); - const olive::VideoParams &stored = Current::getInstance().currentVideoParams(); + const olive::VideoParams &stored = + Current::getInstance().currentVideoParams(); EXPECT_EQ(stored.width(), 1920); EXPECT_EQ(stored.height(), 1080); } @@ -22,6 +23,7 @@ TEST(CommonCurrent, SetAndGetAudioParams) params.set_sample_rate(48000); Current::getInstance().setCurrentAudioParams(params); - const olive::AudioParams &stored = Current::getInstance().currentAudioParams(); + const olive::AudioParams &stored = + Current::getInstance().currentAudioParams(); EXPECT_EQ(stored.sample_rate(), 48000); } diff --git a/tests/gtest/common_debug_test.cpp b/tests/gtest/common_debug_test.cpp index 617f8469f..5d5107955 100644 --- a/tests/gtest/common_debug_test.cpp +++ b/tests/gtest/common_debug_test.cpp @@ -4,13 +4,13 @@ TEST(CommonDebug, DebugHandlerFormatsAllLevels) { - // Install handler and restore after test - QtMessageHandler old = qInstallMessageHandler(olive::DebugHandler); + // Install handler and restore after test + QtMessageHandler old = qInstallMessageHandler(olive::DebugHandler); - qDebug() << "debug message"; - qInfo() << "info message"; - qWarning() << "warning message"; - qCritical() << "critical message"; + qDebug() << "debug message"; + qInfo() << "info message"; + qWarning() << "warning message"; + qCritical() << "critical message"; - qInstallMessageHandler(old); + qInstallMessageHandler(old); } diff --git a/tests/gtest/common_decibel_test.cpp b/tests/gtest/common_decibel_test.cpp index ba545811b..236944e7b 100644 --- a/tests/gtest/common_decibel_test.cpp +++ b/tests/gtest/common_decibel_test.cpp @@ -4,49 +4,49 @@ TEST(CommonDecibel, FromLinearZeroReturnsMinimum) { - EXPECT_DOUBLE_EQ(olive::Decibel::fromLinear(0.0), olive::Decibel::MINIMUM); + EXPECT_DOUBLE_EQ(olive::Decibel::fromLinear(0.0), olive::Decibel::MINIMUM); } TEST(CommonDecibel, FromLinearOneReturnsZero) { - EXPECT_DOUBLE_EQ(olive::Decibel::fromLinear(1.0), 0.0); + EXPECT_DOUBLE_EQ(olive::Decibel::fromLinear(1.0), 0.0); } TEST(CommonDecibel, FromLinearTenReturnsTwenty) { - EXPECT_DOUBLE_EQ(olive::Decibel::fromLinear(10.0), 20.0); + EXPECT_DOUBLE_EQ(olive::Decibel::fromLinear(10.0), 20.0); } TEST(CommonDecibel, ToLinearZeroReturnsOne) { - EXPECT_DOUBLE_EQ(olive::Decibel::toLinear(0.0), 1.0); + EXPECT_DOUBLE_EQ(olive::Decibel::toLinear(0.0), 1.0); } TEST(CommonDecibel, ToLinearMinimumReturnsZero) { - EXPECT_DOUBLE_EQ(olive::Decibel::toLinear(olive::Decibel::MINIMUM), 0.0); + EXPECT_DOUBLE_EQ(olive::Decibel::toLinear(olive::Decibel::MINIMUM), 0.0); } TEST(CommonDecibel, ToLinearTwentyReturnsTen) { - EXPECT_DOUBLE_EQ(olive::Decibel::toLinear(20.0), 10.0); + EXPECT_DOUBLE_EQ(olive::Decibel::toLinear(20.0), 10.0); } TEST(CommonDecibel, FromLogarithmicAtEdges) { - EXPECT_DOUBLE_EQ(olive::Decibel::fromLogarithmic(0.0), - olive::Decibel::MINIMUM); - EXPECT_DOUBLE_EQ(olive::Decibel::fromLogarithmic(1.0), 0.0); + EXPECT_DOUBLE_EQ(olive::Decibel::fromLogarithmic(0.0), + olive::Decibel::MINIMUM); + EXPECT_DOUBLE_EQ(olive::Decibel::fromLogarithmic(1.0), 0.0); } TEST(CommonDecibel, ToLogarithmicAtEdges) { - EXPECT_DOUBLE_EQ(olive::Decibel::toLogarithmic(0.0), 1.0); + EXPECT_DOUBLE_EQ(olive::Decibel::toLogarithmic(0.0), 1.0); } TEST(CommonDecibel, LinearLogarithmicRoundTrip) { - EXPECT_NEAR(olive::Decibel::LogarithmicToLinear( - olive::Decibel::LinearToLogarithmic(0.5)), - 0.5, 1e-6); + EXPECT_NEAR(olive::Decibel::LogarithmicToLinear( + olive::Decibel::LinearToLogarithmic(0.5)), + 0.5, 1e-6); } diff --git a/tests/gtest/common_digit_test.cpp b/tests/gtest/common_digit_test.cpp index e22943525..cf1ce24c2 100644 --- a/tests/gtest/common_digit_test.cpp +++ b/tests/gtest/common_digit_test.cpp @@ -4,20 +4,20 @@ TEST(CommonDigit, SingleDigit) { - EXPECT_EQ(olive::GetDigitCount(0), 1); - EXPECT_EQ(olive::GetDigitCount(5), 1); - EXPECT_EQ(olive::GetDigitCount(-5), 1); + EXPECT_EQ(olive::GetDigitCount(0), 1); + EXPECT_EQ(olive::GetDigitCount(5), 1); + EXPECT_EQ(olive::GetDigitCount(-5), 1); } TEST(CommonDigit, MultipleDigits) { - EXPECT_EQ(olive::GetDigitCount(10), 2); - EXPECT_EQ(olive::GetDigitCount(999), 3); - EXPECT_EQ(olive::GetDigitCount(1000), 4); - EXPECT_EQ(olive::GetDigitCount(-12345), 5); + EXPECT_EQ(olive::GetDigitCount(10), 2); + EXPECT_EQ(olive::GetDigitCount(999), 3); + EXPECT_EQ(olive::GetDigitCount(1000), 4); + EXPECT_EQ(olive::GetDigitCount(-12345), 5); } TEST(CommonDigit, LargeValue) { - EXPECT_EQ(olive::GetDigitCount(123456789012345LL), 15); + EXPECT_EQ(olive::GetDigitCount(123456789012345LL), 15); } diff --git a/tests/gtest/common_ffmpegutils_test.cpp b/tests/gtest/common_ffmpegutils_test.cpp index d3906d12f..5eb4c67d9 100644 --- a/tests/gtest/common_ffmpegutils_test.cpp +++ b/tests/gtest/common_ffmpegutils_test.cpp @@ -6,144 +6,149 @@ using namespace olive; TEST(CommonFFmpegUtils, GetNativeSampleFormatMapsCorrectly) { - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_U8), - SampleFormat::U8); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S16), - SampleFormat::S16); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S32), - SampleFormat::S32); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S64), - SampleFormat::S64); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_FLT), - SampleFormat::F32); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_DBL), - SampleFormat::F64); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_U8P), - SampleFormat::U8P); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S16P), - SampleFormat::S16P); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S32P), - SampleFormat::S32P); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S64P), - SampleFormat::S64P); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_FLTP), - SampleFormat::F32P); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_DBLP), - SampleFormat::F64P); - EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_NONE), - SampleFormat::INVALID); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_U8), + SampleFormat::U8); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S16), + SampleFormat::S16); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S32), + SampleFormat::S32); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S64), + SampleFormat::S64); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_FLT), + SampleFormat::F32); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_DBL), + SampleFormat::F64); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_U8P), + SampleFormat::U8P); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S16P), + SampleFormat::S16P); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S32P), + SampleFormat::S32P); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_S64P), + SampleFormat::S64P); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_FLTP), + SampleFormat::F32P); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_DBLP), + SampleFormat::F64P); + EXPECT_EQ(FFmpegUtils::GetNativeSampleFormat(AV_SAMPLE_FMT_NONE), + SampleFormat::INVALID); } TEST(CommonFFmpegUtils, GetFFmpegSampleFormatMapsCorrectly) { - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::U8), - AV_SAMPLE_FMT_U8); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S16), - AV_SAMPLE_FMT_S16); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S32), - AV_SAMPLE_FMT_S32); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S64), - AV_SAMPLE_FMT_S64); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::F32), - AV_SAMPLE_FMT_FLT); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::F64), - AV_SAMPLE_FMT_DBL); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::U8P), - AV_SAMPLE_FMT_U8P); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S16P), - AV_SAMPLE_FMT_S16P); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S32P), - AV_SAMPLE_FMT_S32P); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S64P), - AV_SAMPLE_FMT_S64P); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::F32P), - AV_SAMPLE_FMT_FLTP); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::F64P), - AV_SAMPLE_FMT_DBLP); - EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::INVALID), - AV_SAMPLE_FMT_NONE); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::U8), + AV_SAMPLE_FMT_U8); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S16), + AV_SAMPLE_FMT_S16); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S32), + AV_SAMPLE_FMT_S32); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S64), + AV_SAMPLE_FMT_S64); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::F32), + AV_SAMPLE_FMT_FLT); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::F64), + AV_SAMPLE_FMT_DBL); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::U8P), + AV_SAMPLE_FMT_U8P); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S16P), + AV_SAMPLE_FMT_S16P); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S32P), + AV_SAMPLE_FMT_S32P); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::S64P), + AV_SAMPLE_FMT_S64P); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::F32P), + AV_SAMPLE_FMT_FLTP); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::F64P), + AV_SAMPLE_FMT_DBLP); + EXPECT_EQ(FFmpegUtils::GetFFmpegSampleFormat(SampleFormat::INVALID), + AV_SAMPLE_FMT_NONE); } TEST(CommonFFmpegUtils, GetSwsColorspaceFromAVColorSpace) { - EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_BT709), - SWS_CS_ITU709); - EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_FCC), - SWS_CS_FCC); - EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_BT470BG), - SWS_CS_ITU624); - EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_SMPTE170M), - SWS_CS_SMPTE170M); - EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_SMPTE240M), - SWS_CS_SMPTE240M); - EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_BT2020_NCL), - SWS_CS_BT2020); - EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_UNSPECIFIED), - SWS_CS_DEFAULT); + EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_BT709), + SWS_CS_ITU709); + EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_FCC), + SWS_CS_FCC); + EXPECT_EQ(FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_BT470BG), + SWS_CS_ITU624); + EXPECT_EQ( + FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_SMPTE170M), + SWS_CS_SMPTE170M); + EXPECT_EQ( + FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_SMPTE240M), + SWS_CS_SMPTE240M); + EXPECT_EQ( + FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_BT2020_NCL), + SWS_CS_BT2020); + EXPECT_EQ( + FFmpegUtils::GetSwsColorspaceFromAVColorSpace(AVCOL_SPC_UNSPECIFIED), + SWS_CS_DEFAULT); } TEST(CommonFFmpegUtils, ConvertJPEGSpaceToRegularSpace) { - EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ420P), - AV_PIX_FMT_YUV420P); - EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ422P), - AV_PIX_FMT_YUV422P); - EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ444P), - AV_PIX_FMT_YUV444P); - EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ440P), - AV_PIX_FMT_YUV440P); - EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ411P), - AV_PIX_FMT_YUV411P); - EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUV420P), - AV_PIX_FMT_YUV420P); + EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ420P), + AV_PIX_FMT_YUV420P); + EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ422P), + AV_PIX_FMT_YUV422P); + EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ444P), + AV_PIX_FMT_YUV444P); + EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ440P), + AV_PIX_FMT_YUV440P); + EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUVJ411P), + AV_PIX_FMT_YUV411P); + EXPECT_EQ(FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AV_PIX_FMT_YUV420P), + AV_PIX_FMT_YUV420P); } TEST(CommonFFmpegUtils, GetCompatiblePixelFormatNative) { - EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::U8), - PixelFormat::U8); - EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::U10), - PixelFormat::U8); - EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::U16), - PixelFormat::U16); - EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::F16), - PixelFormat::U16); - EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::F32), - PixelFormat::U16); - EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::INVALID), - PixelFormat::INVALID); + EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::U8), + PixelFormat::U8); + EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::U10), + PixelFormat::U8); + EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::U16), + PixelFormat::U16); + EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::F16), + PixelFormat::U16); + EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::F32), + PixelFormat::U16); + EXPECT_EQ(FFmpegUtils::GetCompatiblePixelFormat(PixelFormat::INVALID), + PixelFormat::INVALID); } TEST(CommonFFmpegUtils, GetFFmpegPixelFormat) { - EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::U8, - VideoParams::kRGBChannelCount), - AV_PIX_FMT_RGB24); - EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::U16, - VideoParams::kRGBChannelCount), - AV_PIX_FMT_RGB48); - EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::F32, - VideoParams::kRGBChannelCount), - AV_PIX_FMT_RGBF32); - EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::U8, - VideoParams::kRGBAChannelCount), - AV_PIX_FMT_RGBA); - EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::U16, - VideoParams::kRGBAChannelCount), - AV_PIX_FMT_RGBA64); - EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::F32, - VideoParams::kRGBAChannelCount), - AV_PIX_FMT_RGBAF32); - EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::INVALID, 0), - AV_PIX_FMT_NONE); + EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::U8, + VideoParams::kRGBChannelCount), + AV_PIX_FMT_RGB24); + EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::U16, + VideoParams::kRGBChannelCount), + AV_PIX_FMT_RGB48); + EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::F32, + VideoParams::kRGBChannelCount), + AV_PIX_FMT_RGBF32); + EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::U8, + VideoParams::kRGBAChannelCount), + AV_PIX_FMT_RGBA); + EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::U16, + VideoParams::kRGBAChannelCount), + AV_PIX_FMT_RGBA64); + EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::F32, + VideoParams::kRGBAChannelCount), + AV_PIX_FMT_RGBAF32); + EXPECT_EQ(FFmpegUtils::GetFFmpegPixelFormat(PixelFormat::INVALID, 0), + AV_PIX_FMT_NONE); } TEST(CommonFFmpegUtils, GetCompatiblePixelFormatAV) { - AVPixelFormat fmt = FFmpegUtils::GetCompatiblePixelFormat(AV_PIX_FMT_YUV420P); - EXPECT_NE(fmt, AV_PIX_FMT_NONE); + AVPixelFormat fmt = + FFmpegUtils::GetCompatiblePixelFormat(AV_PIX_FMT_YUV420P); + EXPECT_NE(fmt, AV_PIX_FMT_NONE); - fmt = FFmpegUtils::GetCompatiblePixelFormat(AV_PIX_FMT_YUV420P, - PixelFormat::U8); - EXPECT_EQ(fmt, AV_PIX_FMT_RGBA); + fmt = FFmpegUtils::GetCompatiblePixelFormat(AV_PIX_FMT_YUV420P, + PixelFormat::U8); + EXPECT_EQ(fmt, AV_PIX_FMT_RGBA); } diff --git a/tests/gtest/common_filefunctions_test.cpp b/tests/gtest/common_filefunctions_test.cpp index defff8088..43b0aec89 100644 --- a/tests/gtest/common_filefunctions_test.cpp +++ b/tests/gtest/common_filefunctions_test.cpp @@ -16,7 +16,9 @@ TEST(CommonFileFunctions, EnsureFilenameExtension) EXPECT_EQ(olive::FileFunctions::EnsureFilenameExtension( QStringLiteral("PROJECT"), QStringLiteral("ove")), QStringLiteral("PROJECT.ove")); - EXPECT_TRUE(olive::FileFunctions::EnsureFilenameExtension(QString(), QStringLiteral("ove")).isEmpty()); + EXPECT_TRUE(olive::FileFunctions::EnsureFilenameExtension( + QString(), QStringLiteral("ove")) + .isEmpty()); EXPECT_EQ(olive::FileFunctions::EnsureFilenameExtension( QStringLiteral("project"), QString()), QStringLiteral("project")); @@ -46,7 +48,8 @@ TEST(CommonFileFunctions, DirectoryIsValid) QTemporaryDir dir; ASSERT_TRUE(dir.isValid()); - EXPECT_TRUE(olive::FileFunctions::DirectoryIsValid(QDir(dir.path()), false)); + EXPECT_TRUE( + olive::FileFunctions::DirectoryIsValid(QDir(dir.path()), false)); QDir nonexistent(dir.filePath(QStringLiteral("subdir/nested"))); EXPECT_TRUE(olive::FileFunctions::DirectoryIsValid(nonexistent, true)); @@ -133,7 +136,8 @@ TEST(CommonFileFunctions, ReadFileAsString) EXPECT_EQ(olive::FileFunctions::ReadFileAsString(f.fileName()), QStringLiteral("hello world")); EXPECT_TRUE(olive::FileFunctions::ReadFileAsString( - QStringLiteral("/nonexistent/path")).isEmpty()); + QStringLiteral("/nonexistent/path")) + .isEmpty()); } TEST(CommonFileFunctions, GetUniqueFileIdentifier) @@ -148,10 +152,10 @@ TEST(CommonFileFunctions, GetUniqueFileIdentifier) EXPECT_EQ(id1, id2); EXPECT_TRUE(olive::FileFunctions::GetUniqueFileIdentifier( - QStringLiteral("/nonexistent")).isEmpty()); + QStringLiteral("/nonexistent")) + .isEmpty()); } - TEST(CommonFileFunctions, GetConfigurationLocation) { QString loc = olive::FileFunctions::GetConfigurationLocation(); @@ -176,7 +180,8 @@ TEST(CommonFileFunctions, DirectoryIsValidExisting) { QTemporaryDir dir; ASSERT_TRUE(dir.isValid()); - EXPECT_TRUE(olive::FileFunctions::DirectoryIsValid(QDir(dir.path()), false)); + EXPECT_TRUE( + olive::FileFunctions::DirectoryIsValid(QDir(dir.path()), false)); } TEST(CommonFileFunctions, CopyDirectoryWithOverwrite) @@ -212,5 +217,5 @@ TEST(CommonFileFunctions, CopyDirectorySourceMissing) // Should not crash even if source doesn't exist olive::FileFunctions::CopyDirectory(QStringLiteral("/nonexistent/path"), - dst.path(), false); + dst.path(), false); } diff --git a/tests/gtest/common_jobtime_test.cpp b/tests/gtest/common_jobtime_test.cpp index 4eb38f5d0..955c6dfcc 100644 --- a/tests/gtest/common_jobtime_test.cpp +++ b/tests/gtest/common_jobtime_test.cpp @@ -4,39 +4,39 @@ TEST(CommonJobTime, ConstructorAcquiresValue) { - olive::JobTime a; - olive::JobTime b; + olive::JobTime a; + olive::JobTime b; - EXPECT_NE(a.value(), b.value()); - EXPECT_LT(a.value(), b.value()); + EXPECT_NE(a.value(), b.value()); + EXPECT_LT(a.value(), b.value()); } TEST(CommonJobTime, AcquireUpdatesValue) { - olive::JobTime a; - uint64_t first = a.value(); - a.Acquire(); - uint64_t second = a.value(); + olive::JobTime a; + uint64_t first = a.value(); + a.Acquire(); + uint64_t second = a.value(); - EXPECT_GT(second, first); + EXPECT_GT(second, first); } TEST(CommonJobTime, ComparisonOperators) { - olive::JobTime a; - olive::JobTime b; + olive::JobTime a; + olive::JobTime b; - EXPECT_LT(a, b); - EXPECT_GT(b, a); - EXPECT_LE(a, a); - EXPECT_GE(b, b); - EXPECT_EQ(a, a); - EXPECT_NE(a, b); + EXPECT_LT(a, b); + EXPECT_GT(b, a); + EXPECT_LE(a, a); + EXPECT_GE(b, b); + EXPECT_EQ(a, a); + EXPECT_NE(a, b); } TEST(CommonJobTime, DebugStream) { - olive::JobTime a; - QDebug debug(QtDebugMsg); - debug << a; + olive::JobTime a; + QDebug debug(QtDebugMsg); + debug << a; } diff --git a/tests/gtest/common_qtutils_test.cpp b/tests/gtest/common_qtutils_test.cpp index f1edbb9b3..4a672026b 100644 --- a/tests/gtest/common_qtutils_test.cpp +++ b/tests/gtest/common_qtutils_test.cpp @@ -30,7 +30,8 @@ TEST(CommonQtUtils, FlipControlAndShiftModifiers) // (Qt::ControlModifier & Qt::ShiftModifier is always zero), so the function // always swaps Control and Shift. This test documents current behavior. Qt::KeyboardModifiers both = Qt::ControlModifier | Qt::ShiftModifier; - Qt::KeyboardModifiers flipped = olive::QtUtils::FlipControlAndShiftModifiers(both); + Qt::KeyboardModifiers flipped = + olive::QtUtils::FlipControlAndShiftModifiers(both); EXPECT_TRUE(flipped & Qt::ControlModifier); EXPECT_FALSE(flipped & Qt::ShiftModifier); @@ -112,11 +113,10 @@ TEST(CommonQtUtils, ToQColor) EXPECT_NEAR(qc.alphaF(), 0.4, 0.001); } - TEST(CommonQtUtils, GetFormattedDateTime) { QDateTime dt = QDateTime::fromString(QStringLiteral("2025-01-15T10:30:00"), - Qt::ISODate); + Qt::ISODate); QString s = olive::QtUtils::GetFormattedDateTime(dt); EXPECT_FALSE(s.isEmpty()); } @@ -132,8 +132,8 @@ TEST(CommonQtUtils, WordWrapString) EXPECT_GE(wrapped.size(), 1u); // Should preserve manual newlines - wrapped = olive::QtUtils::WordWrapString( - QStringLiteral("line1\nline2"), fm, 1000); + wrapped = olive::QtUtils::WordWrapString(QStringLiteral("line1\nline2"), fm, + 1000); EXPECT_EQ(wrapped.size(), 2); } diff --git a/tests/gtest/common_xmlutils_test.cpp b/tests/gtest/common_xmlutils_test.cpp index e0ad0ada5..40c58be5a 100644 --- a/tests/gtest/common_xmlutils_test.cpp +++ b/tests/gtest/common_xmlutils_test.cpp @@ -59,7 +59,6 @@ TEST(CommonXmlUtils, ReadNextStartElementSkipsUnknown) EXPECT_EQ(reader.name().toString(), QStringLiteral("known")); } - TEST(CommonXmlUtils, ReadNextStartElementWithCancel) { QByteArray xml = ""; diff --git a/tests/gtest/config_test.cpp b/tests/gtest/config_test.cpp index 7292dd761..3c0893442 100644 --- a/tests/gtest/config_test.cpp +++ b/tests/gtest/config_test.cpp @@ -46,18 +46,18 @@ TEST(Config, GraphicsBackendStringConversion) olive::RenderManager::kVulkan); EXPECT_EQ(olive::RenderManager::BackendFromString(QStringLiteral("dummy")), olive::RenderManager::kDummy); - EXPECT_EQ(olive::RenderManager::BackendFromString( - QStringLiteral("multiprocess")), - olive::RenderManager::kMultiProcess); - EXPECT_EQ(olive::RenderManager::BackendToString( - olive::RenderManager::kOpenGL), - QStringLiteral("opengl")); - EXPECT_EQ(olive::RenderManager::BackendToString( - olive::RenderManager::kVulkan), - QStringLiteral("vulkan")); - EXPECT_EQ(olive::RenderManager::BackendToString( - olive::RenderManager::kDummy), - QStringLiteral("dummy")); + EXPECT_EQ( + olive::RenderManager::BackendFromString(QStringLiteral("multiprocess")), + olive::RenderManager::kMultiProcess); + EXPECT_EQ( + olive::RenderManager::BackendToString(olive::RenderManager::kOpenGL), + QStringLiteral("opengl")); + EXPECT_EQ( + olive::RenderManager::BackendToString(olive::RenderManager::kVulkan), + QStringLiteral("vulkan")); + EXPECT_EQ( + olive::RenderManager::BackendToString(olive::RenderManager::kDummy), + QStringLiteral("dummy")); EXPECT_EQ(olive::RenderManager::BackendToString( olive::RenderManager::kMultiProcess), QStringLiteral("multiprocess")); diff --git a/tests/gtest/core_bezier_test.cpp b/tests/gtest/core_bezier_test.cpp index 5c1c4cf0b..c43304755 100644 --- a/tests/gtest/core_bezier_test.cpp +++ b/tests/gtest/core_bezier_test.cpp @@ -6,115 +6,115 @@ using namespace olive::core; TEST(CoreBezier, DefaultConstruction) { - Bezier b; - EXPECT_DOUBLE_EQ(b.x(), 0.0); - EXPECT_DOUBLE_EQ(b.y(), 0.0); - EXPECT_DOUBLE_EQ(b.cp1_x(), 0.0); - EXPECT_DOUBLE_EQ(b.cp1_y(), 0.0); - EXPECT_DOUBLE_EQ(b.cp2_x(), 0.0); - EXPECT_DOUBLE_EQ(b.cp2_y(), 0.0); + Bezier b; + EXPECT_DOUBLE_EQ(b.x(), 0.0); + EXPECT_DOUBLE_EQ(b.y(), 0.0); + EXPECT_DOUBLE_EQ(b.cp1_x(), 0.0); + EXPECT_DOUBLE_EQ(b.cp1_y(), 0.0); + EXPECT_DOUBLE_EQ(b.cp2_x(), 0.0); + EXPECT_DOUBLE_EQ(b.cp2_y(), 0.0); } TEST(CoreBezier, ValueConstruction) { - Bezier b(1.0, 2.0); - EXPECT_DOUBLE_EQ(b.x(), 1.0); - EXPECT_DOUBLE_EQ(b.y(), 2.0); + Bezier b(1.0, 2.0); + EXPECT_DOUBLE_EQ(b.x(), 1.0); + EXPECT_DOUBLE_EQ(b.y(), 2.0); } TEST(CoreBezier, FullConstruction) { - Bezier b(1.0, 2.0, 3.0, 4.0, 5.0, 6.0); - EXPECT_DOUBLE_EQ(b.x(), 1.0); - EXPECT_DOUBLE_EQ(b.y(), 2.0); - EXPECT_DOUBLE_EQ(b.cp1_x(), 3.0); - EXPECT_DOUBLE_EQ(b.cp1_y(), 4.0); - EXPECT_DOUBLE_EQ(b.cp2_x(), 5.0); - EXPECT_DOUBLE_EQ(b.cp2_y(), 6.0); + Bezier b(1.0, 2.0, 3.0, 4.0, 5.0, 6.0); + EXPECT_DOUBLE_EQ(b.x(), 1.0); + EXPECT_DOUBLE_EQ(b.y(), 2.0); + EXPECT_DOUBLE_EQ(b.cp1_x(), 3.0); + EXPECT_DOUBLE_EQ(b.cp1_y(), 4.0); + EXPECT_DOUBLE_EQ(b.cp2_x(), 5.0); + EXPECT_DOUBLE_EQ(b.cp2_y(), 6.0); } TEST(CoreBezier, Setters) { - Bezier b; - b.set_x(10.0); - b.set_y(20.0); - b.set_cp1_x(30.0); - b.set_cp1_y(40.0); - b.set_cp2_x(50.0); - b.set_cp2_y(60.0); + Bezier b; + b.set_x(10.0); + b.set_y(20.0); + b.set_cp1_x(30.0); + b.set_cp1_y(40.0); + b.set_cp2_x(50.0); + b.set_cp2_y(60.0); - EXPECT_DOUBLE_EQ(b.x(), 10.0); - EXPECT_DOUBLE_EQ(b.y(), 20.0); - EXPECT_DOUBLE_EQ(b.cp1_x(), 30.0); - EXPECT_DOUBLE_EQ(b.cp1_y(), 40.0); - EXPECT_DOUBLE_EQ(b.cp2_x(), 50.0); - EXPECT_DOUBLE_EQ(b.cp2_y(), 60.0); + EXPECT_DOUBLE_EQ(b.x(), 10.0); + EXPECT_DOUBLE_EQ(b.y(), 20.0); + EXPECT_DOUBLE_EQ(b.cp1_x(), 30.0); + EXPECT_DOUBLE_EQ(b.cp1_y(), 40.0); + EXPECT_DOUBLE_EQ(b.cp2_x(), 50.0); + EXPECT_DOUBLE_EQ(b.cp2_y(), 60.0); } TEST(CoreBezier, QuadraticXtoT) { - double t = Bezier::QuadraticXtoT(0.5, 0.0, 0.5, 1.0); - EXPECT_NEAR(t, 0.5, 0.00001); + double t = Bezier::QuadraticXtoT(0.5, 0.0, 0.5, 1.0); + EXPECT_NEAR(t, 0.5, 0.00001); - t = Bezier::QuadraticXtoT(0.0, 0.0, 0.5, 1.0); - EXPECT_NEAR(t, 0.0, 0.00001); + t = Bezier::QuadraticXtoT(0.0, 0.0, 0.5, 1.0); + EXPECT_NEAR(t, 0.0, 0.00001); - t = Bezier::QuadraticXtoT(1.0, 0.0, 0.5, 1.0); - EXPECT_NEAR(t, 1.0, 0.00001); + t = Bezier::QuadraticXtoT(1.0, 0.0, 0.5, 1.0); + EXPECT_NEAR(t, 1.0, 0.00001); } TEST(CoreBezier, QuadraticTtoY) { - EXPECT_NEAR(Bezier::QuadraticTtoY(0.0, 0.5, 1.0, 0.0), 0.0, 0.00001); - EXPECT_NEAR(Bezier::QuadraticTtoY(0.0, 0.5, 1.0, 0.5), 0.5, 0.00001); - EXPECT_NEAR(Bezier::QuadraticTtoY(0.0, 0.5, 1.0, 1.0), 1.0, 0.00001); + EXPECT_NEAR(Bezier::QuadraticTtoY(0.0, 0.5, 1.0, 0.0), 0.0, 0.00001); + EXPECT_NEAR(Bezier::QuadraticTtoY(0.0, 0.5, 1.0, 0.5), 0.5, 0.00001); + EXPECT_NEAR(Bezier::QuadraticTtoY(0.0, 0.5, 1.0, 1.0), 1.0, 0.00001); } TEST(CoreBezier, QuadraticXtoY) { - Imath::V2d a(0.0, 0.0); - Imath::V2d b(0.5, 0.5); - Imath::V2d c(1.0, 1.0); + Imath::V2d a(0.0, 0.0); + Imath::V2d b(0.5, 0.5); + Imath::V2d c(1.0, 1.0); - EXPECT_NEAR(Bezier::QuadraticXtoY(0.5, a, b, c), 0.5, 0.00001); + EXPECT_NEAR(Bezier::QuadraticXtoY(0.5, a, b, c), 0.5, 0.00001); } TEST(CoreBezier, CubicXtoT) { - double t = Bezier::CubicXtoT(0.5, 0.0, 0.33, 0.66, 1.0); - EXPECT_NEAR(t, 0.5, 0.01); + double t = Bezier::CubicXtoT(0.5, 0.0, 0.33, 0.66, 1.0); + EXPECT_NEAR(t, 0.5, 0.01); } TEST(CoreBezier, CubicTtoY) { - EXPECT_NEAR(Bezier::CubicTtoY(0.0, 0.33, 0.66, 1.0, 0.0), 0.0, 0.00001); - EXPECT_NEAR(Bezier::CubicTtoY(0.0, 0.33, 0.66, 1.0, 1.0), 1.0, 0.00001); + EXPECT_NEAR(Bezier::CubicTtoY(0.0, 0.33, 0.66, 1.0, 0.0), 0.0, 0.00001); + EXPECT_NEAR(Bezier::CubicTtoY(0.0, 0.33, 0.66, 1.0, 1.0), 1.0, 0.00001); } TEST(CoreBezier, CubicXtoY) { - Imath::V2d a(0.0, 0.0); - Imath::V2d b(0.33, 0.0); - Imath::V2d c(0.66, 1.0); - Imath::V2d d(1.0, 1.0); + Imath::V2d a(0.0, 0.0); + Imath::V2d b(0.33, 0.0); + Imath::V2d c(0.66, 1.0); + Imath::V2d d(1.0, 1.0); - double y = Bezier::CubicXtoY(0.5, a, b, c, d); - EXPECT_GE(y, 0.0); - EXPECT_LE(y, 1.0); + double y = Bezier::CubicXtoY(0.5, a, b, c, d); + EXPECT_GE(y, 0.0); + EXPECT_LE(y, 1.0); } TEST(CoreBezier, VectorConverters) { - Bezier b(1.0, 2.0, 3.0, 4.0, 5.0, 6.0); - Imath::V2d v = b.to_vec(); - EXPECT_DOUBLE_EQ(v.x, 1.0); - EXPECT_DOUBLE_EQ(v.y, 2.0); + Bezier b(1.0, 2.0, 3.0, 4.0, 5.0, 6.0); + Imath::V2d v = b.to_vec(); + EXPECT_DOUBLE_EQ(v.x, 1.0); + EXPECT_DOUBLE_EQ(v.y, 2.0); - Imath::V2d cp1 = b.control_point_1_to_vec(); - EXPECT_DOUBLE_EQ(cp1.x, 3.0); - EXPECT_DOUBLE_EQ(cp1.y, 4.0); + Imath::V2d cp1 = b.control_point_1_to_vec(); + EXPECT_DOUBLE_EQ(cp1.x, 3.0); + EXPECT_DOUBLE_EQ(cp1.y, 4.0); - Imath::V2d cp2 = b.control_point_2_to_vec(); - EXPECT_DOUBLE_EQ(cp2.x, 5.0); - EXPECT_DOUBLE_EQ(cp2.y, 6.0); + Imath::V2d cp2 = b.control_point_2_to_vec(); + EXPECT_DOUBLE_EQ(cp2.x, 5.0); + EXPECT_DOUBLE_EQ(cp2.y, 6.0); } diff --git a/tests/gtest/core_color_test.cpp b/tests/gtest/core_color_test.cpp index a2ae98b13..6d7217642 100644 --- a/tests/gtest/core_color_test.cpp +++ b/tests/gtest/core_color_test.cpp @@ -6,164 +6,164 @@ using namespace olive::core; TEST(CoreColor, DefaultConstruction) { - Color c; - EXPECT_FLOAT_EQ(c.red(), 0.0f); - EXPECT_FLOAT_EQ(c.green(), 0.0f); - EXPECT_FLOAT_EQ(c.blue(), 0.0f); - EXPECT_FLOAT_EQ(c.alpha(), 0.0f); + Color c; + EXPECT_FLOAT_EQ(c.red(), 0.0f); + EXPECT_FLOAT_EQ(c.green(), 0.0f); + EXPECT_FLOAT_EQ(c.blue(), 0.0f); + EXPECT_FLOAT_EQ(c.alpha(), 0.0f); } TEST(CoreColor, ValueConstruction) { - Color c(0.1f, 0.2f, 0.3f, 0.4f); - EXPECT_FLOAT_EQ(c.red(), 0.1f); - EXPECT_FLOAT_EQ(c.green(), 0.2f); - EXPECT_FLOAT_EQ(c.blue(), 0.3f); - EXPECT_FLOAT_EQ(c.alpha(), 0.4f); + Color c(0.1f, 0.2f, 0.3f, 0.4f); + EXPECT_FLOAT_EQ(c.red(), 0.1f); + EXPECT_FLOAT_EQ(c.green(), 0.2f); + EXPECT_FLOAT_EQ(c.blue(), 0.3f); + EXPECT_FLOAT_EQ(c.alpha(), 0.4f); } TEST(CoreColor, SettersAndDataAccess) { - Color c; - c.set_red(0.5f); - c.set_green(0.6f); - c.set_blue(0.7f); - c.set_alpha(0.8f); + Color c; + c.set_red(0.5f); + c.set_green(0.6f); + c.set_blue(0.7f); + c.set_alpha(0.8f); - EXPECT_FLOAT_EQ(c.data()[0], 0.5f); - EXPECT_FLOAT_EQ(c.data()[1], 0.6f); - EXPECT_FLOAT_EQ(c.data()[2], 0.7f); - EXPECT_FLOAT_EQ(c.data()[3], 0.8f); + EXPECT_FLOAT_EQ(c.data()[0], 0.5f); + EXPECT_FLOAT_EQ(c.data()[1], 0.6f); + EXPECT_FLOAT_EQ(c.data()[2], 0.7f); + EXPECT_FLOAT_EQ(c.data()[3], 0.8f); } TEST(CoreColor, FromHsvRed) { - Color c = Color::fromHsv(0.0f, 1.0f, 1.0f); - EXPECT_NEAR(c.red(), 1.0f, 0.001f); - EXPECT_NEAR(c.green(), 0.0f, 0.001f); - EXPECT_NEAR(c.blue(), 0.0f, 0.001f); + Color c = Color::fromHsv(0.0f, 1.0f, 1.0f); + EXPECT_NEAR(c.red(), 1.0f, 0.001f); + EXPECT_NEAR(c.green(), 0.0f, 0.001f); + EXPECT_NEAR(c.blue(), 0.0f, 0.001f); } TEST(CoreColor, FromHsvGreen) { - Color c = Color::fromHsv(120.0f, 1.0f, 1.0f); - EXPECT_NEAR(c.red(), 0.0f, 0.001f); - EXPECT_NEAR(c.green(), 1.0f, 0.001f); - EXPECT_NEAR(c.blue(), 0.0f, 0.001f); + Color c = Color::fromHsv(120.0f, 1.0f, 1.0f); + EXPECT_NEAR(c.red(), 0.0f, 0.001f); + EXPECT_NEAR(c.green(), 1.0f, 0.001f); + EXPECT_NEAR(c.blue(), 0.0f, 0.001f); } TEST(CoreColor, FromHsvBlue) { - Color c = Color::fromHsv(240.0f, 1.0f, 1.0f); - EXPECT_NEAR(c.red(), 0.0f, 0.001f); - EXPECT_NEAR(c.green(), 0.0f, 0.001f); - EXPECT_NEAR(c.blue(), 1.0f, 0.001f); + Color c = Color::fromHsv(240.0f, 1.0f, 1.0f); + EXPECT_NEAR(c.red(), 0.0f, 0.001f); + EXPECT_NEAR(c.green(), 0.0f, 0.001f); + EXPECT_NEAR(c.blue(), 1.0f, 0.001f); } TEST(CoreColor, HsvRoundTrip) { - Color original(0.8f, 0.4f, 0.2f); - float h, s, v; - original.toHsv(&h, &s, &v); + Color original(0.8f, 0.4f, 0.2f); + float h, s, v; + original.toHsv(&h, &s, &v); - EXPECT_NEAR(original.hsv_hue(), h, 0.001f); - EXPECT_NEAR(original.hsv_saturation(), s, 0.001f); - EXPECT_NEAR(original.value(), v, 0.001f); + EXPECT_NEAR(original.hsv_hue(), h, 0.001f); + EXPECT_NEAR(original.hsv_saturation(), s, 0.001f); + EXPECT_NEAR(original.value(), v, 0.001f); } TEST(CoreColor, HslRoundTrip) { - Color original(0.2f, 0.5f, 0.8f); - float h, s, l; - original.toHsl(&h, &s, &l); + Color original(0.2f, 0.5f, 0.8f); + float h, s, l; + original.toHsl(&h, &s, &l); - EXPECT_NEAR(original.hsl_hue(), h, 0.001f); - EXPECT_NEAR(original.hsl_saturation(), s, 0.001f); - EXPECT_NEAR(original.lightness(), l, 0.001f); + EXPECT_NEAR(original.hsl_hue(), h, 0.001f); + EXPECT_NEAR(original.hsl_saturation(), s, 0.001f); + EXPECT_NEAR(original.lightness(), l, 0.001f); } TEST(CoreColor, ArithmeticOperators) { - Color a(1.0f, 2.0f, 3.0f, 4.0f); - Color b(0.5f, 0.5f, 0.5f, 0.5f); + Color a(1.0f, 2.0f, 3.0f, 4.0f); + Color b(0.5f, 0.5f, 0.5f, 0.5f); - Color sum = a + b; - EXPECT_FLOAT_EQ(sum.red(), 1.5f); + Color sum = a + b; + EXPECT_FLOAT_EQ(sum.red(), 1.5f); - Color diff = a - b; - EXPECT_FLOAT_EQ(diff.red(), 0.5f); + Color diff = a - b; + EXPECT_FLOAT_EQ(diff.red(), 0.5f); - Color scaled = a * 2.0f; - EXPECT_FLOAT_EQ(scaled.red(), 2.0f); + Color scaled = a * 2.0f; + EXPECT_FLOAT_EQ(scaled.red(), 2.0f); - Color divided = a / 2.0f; - EXPECT_FLOAT_EQ(divided.red(), 0.5f); + Color divided = a / 2.0f; + EXPECT_FLOAT_EQ(divided.red(), 0.5f); - Color added_scalar = a + 1.0f; - EXPECT_FLOAT_EQ(added_scalar.red(), 2.0f); + Color added_scalar = a + 1.0f; + EXPECT_FLOAT_EQ(added_scalar.red(), 2.0f); } TEST(CoreColor, CompoundAssignment) { - Color c(1.0f, 2.0f, 3.0f, 4.0f); - c += Color(0.5f, 0.5f, 0.5f, 0.5f); - EXPECT_FLOAT_EQ(c.red(), 1.5f); + Color c(1.0f, 2.0f, 3.0f, 4.0f); + c += Color(0.5f, 0.5f, 0.5f, 0.5f); + EXPECT_FLOAT_EQ(c.red(), 1.5f); - c *= 2.0f; - EXPECT_FLOAT_EQ(c.red(), 3.0f); + c *= 2.0f; + EXPECT_FLOAT_EQ(c.red(), 3.0f); } TEST(CoreColor, GetRoughLuminance) { - Color white(1.0f, 1.0f, 1.0f); - EXPECT_FLOAT_EQ(white.GetRoughLuminance(), 1.0f); + Color white(1.0f, 1.0f, 1.0f); + EXPECT_FLOAT_EQ(white.GetRoughLuminance(), 1.0f); - Color black(0.0f, 0.0f, 0.0f); - EXPECT_FLOAT_EQ(black.GetRoughLuminance(), 0.0f); + Color black(0.0f, 0.0f, 0.0f); + EXPECT_FLOAT_EQ(black.GetRoughLuminance(), 0.0f); } TEST(CoreColor, ToDataAndFromDataU8) { - Color c(1.0f, 0.5f, 0.0f, 1.0f); - uint8_t data[4]; - c.toData(reinterpret_cast(data), PixelFormat::U8, 4); + Color c(1.0f, 0.5f, 0.0f, 1.0f); + uint8_t data[4]; + c.toData(reinterpret_cast(data), PixelFormat::U8, 4); - EXPECT_EQ(data[0], 255u); - EXPECT_EQ(data[1], 127u); - EXPECT_EQ(data[2], 0u); - EXPECT_EQ(data[3], 255u); + EXPECT_EQ(data[0], 255u); + EXPECT_EQ(data[1], 127u); + EXPECT_EQ(data[2], 0u); + EXPECT_EQ(data[3], 255u); - Color restored = Color::fromData(reinterpret_cast(data), - PixelFormat::U8, 4); - EXPECT_NEAR(restored.red(), 1.0f, 0.01f); - EXPECT_NEAR(restored.green(), 0.5f, 0.01f); + Color restored = Color::fromData(reinterpret_cast(data), + PixelFormat::U8, 4); + EXPECT_NEAR(restored.red(), 1.0f, 0.01f); + EXPECT_NEAR(restored.green(), 0.5f, 0.01f); } TEST(CoreColor, ToDataAndFromDataF32) { - Color c(0.25f, 0.5f, 0.75f, 1.0f); - float data[4]; - c.toData(reinterpret_cast(data), PixelFormat::F32, 4); + Color c(0.25f, 0.5f, 0.75f, 1.0f); + float data[4]; + c.toData(reinterpret_cast(data), PixelFormat::F32, 4); - EXPECT_FLOAT_EQ(data[0], 0.25f); - EXPECT_FLOAT_EQ(data[1], 0.5f); - EXPECT_FLOAT_EQ(data[2], 0.75f); - EXPECT_FLOAT_EQ(data[3], 1.0f); + EXPECT_FLOAT_EQ(data[0], 0.25f); + EXPECT_FLOAT_EQ(data[1], 0.5f); + EXPECT_FLOAT_EQ(data[2], 0.75f); + EXPECT_FLOAT_EQ(data[3], 1.0f); - Color restored = Color::fromData(reinterpret_cast(data), - PixelFormat::F32, 4); - EXPECT_FLOAT_EQ(restored.red(), 0.25f); + Color restored = Color::fromData(reinterpret_cast(data), + PixelFormat::F32, 4); + EXPECT_FLOAT_EQ(restored.red(), 0.25f); } TEST(CoreColor, ToDataAndFromDataU10) { - Color c(1.0f, 0.5f, 0.0f, 1.0f); - uint32_t data; - c.toData(reinterpret_cast(&data), PixelFormat::U10, 4); + Color c(1.0f, 0.5f, 0.0f, 1.0f); + uint32_t data; + c.toData(reinterpret_cast(&data), PixelFormat::U10, 4); - Color restored = Color::fromData(reinterpret_cast(&data), - PixelFormat::U10, 4); - EXPECT_NEAR(restored.red(), 1.0f, 0.001f); - EXPECT_NEAR(restored.green(), 0.5f, 0.001f); - EXPECT_NEAR(restored.blue(), 0.0f, 0.001f); + Color restored = Color::fromData(reinterpret_cast(&data), + PixelFormat::U10, 4); + EXPECT_NEAR(restored.red(), 1.0f, 0.001f); + EXPECT_NEAR(restored.green(), 0.5f, 0.001f); + EXPECT_NEAR(restored.blue(), 0.0f, 0.001f); } diff --git a/tests/gtest/core_samplebuffer_test.cpp b/tests/gtest/core_samplebuffer_test.cpp index 57116e4b0..ea6808fb0 100644 --- a/tests/gtest/core_samplebuffer_test.cpp +++ b/tests/gtest/core_samplebuffer_test.cpp @@ -208,7 +208,7 @@ TEST(CoreSampleBuffer, Set) { AudioParams params = MakeParams(); SampleBuffer b(params, 4); - float data[2] = {0.3f, 0.4f}; + float data[2] = { 0.3f, 0.4f }; b.set(0, data, 1, 2); EXPECT_FLOAT_EQ(b.data(0)[1], 0.3f); EXPECT_FLOAT_EQ(b.data(0)[2], 0.4f); diff --git a/tests/gtest/core_stringutils_test.cpp b/tests/gtest/core_stringutils_test.cpp index 1b9056d13..d584f0e64 100644 --- a/tests/gtest/core_stringutils_test.cpp +++ b/tests/gtest/core_stringutils_test.cpp @@ -8,58 +8,59 @@ using namespace olive::core; TEST(CoreStringUtils, Split) { - auto result = StringUtils::split("a,b,c", ','); - ASSERT_EQ(result.size(), 3u); - EXPECT_EQ(result[0], "a"); - EXPECT_EQ(result[1], "b"); - EXPECT_EQ(result[2], "c"); + auto result = StringUtils::split("a,b,c", ','); + ASSERT_EQ(result.size(), 3u); + EXPECT_EQ(result[0], "a"); + EXPECT_EQ(result[1], "b"); + EXPECT_EQ(result[2], "c"); } TEST(CoreStringUtils, SplitRegex) { - auto result = StringUtils::split_regex("one:two;three", std::regex("(:)|(;)| ")); - ASSERT_EQ(result.size(), 3u); - EXPECT_EQ(result[0], "one"); - EXPECT_EQ(result[1], "two"); - EXPECT_EQ(result[2], "three"); + auto result = + StringUtils::split_regex("one:two;three", std::regex("(:)|(;)| ")); + ASSERT_EQ(result.size(), 3u); + EXPECT_EQ(result[0], "one"); + EXPECT_EQ(result[1], "two"); + EXPECT_EQ(result[2], "three"); } TEST(CoreStringUtils, ToInt) { - bool ok = false; - EXPECT_EQ(StringUtils::to_int("42", &ok), 42); - EXPECT_TRUE(ok); + bool ok = false; + EXPECT_EQ(StringUtils::to_int("42", &ok), 42); + EXPECT_TRUE(ok); - EXPECT_EQ(StringUtils::to_int("-7", 10, &ok), -7); - EXPECT_TRUE(ok); + EXPECT_EQ(StringUtils::to_int("-7", 10, &ok), -7); + EXPECT_TRUE(ok); - EXPECT_EQ(StringUtils::to_int("ff", 16, &ok), 255); - EXPECT_TRUE(ok); + EXPECT_EQ(StringUtils::to_int("ff", 16, &ok), 255); + EXPECT_TRUE(ok); - EXPECT_EQ(StringUtils::to_int("abc", &ok), 0); - EXPECT_FALSE(ok); + EXPECT_EQ(StringUtils::to_int("abc", &ok), 0); + EXPECT_FALSE(ok); } TEST(CoreStringUtils, ToStringLeftpad) { - EXPECT_EQ(StringUtils::to_string_leftpad(5, 3), "005"); - EXPECT_EQ(StringUtils::to_string_leftpad(123, 2), "123"); - EXPECT_EQ(StringUtils::to_string_leftpad(7, 4, '*'), "***7"); + EXPECT_EQ(StringUtils::to_string_leftpad(5, 3), "005"); + EXPECT_EQ(StringUtils::to_string_leftpad(123, 2), "123"); + EXPECT_EQ(StringUtils::to_string_leftpad(7, 4, '*'), "***7"); } TEST(CoreStringUtils, Format) { - EXPECT_EQ(StringUtils::format("Hello %s %d", "world", 42), - "Hello world 42"); + EXPECT_EQ(StringUtils::format("Hello %s %d", "world", 42), + "Hello world 42"); } TEST(CoreStringUtils, Trim) { - std::string s = " hello world "; - StringUtils::trim(s); - EXPECT_EQ(s, "hello world"); + std::string s = " hello world "; + StringUtils::trim(s); + EXPECT_EQ(s, "hello world"); - EXPECT_EQ(StringUtils::trimmed("\t\nvalue\t\n"), "value"); - EXPECT_EQ(StringUtils::ltrimmed(" left"), "left"); - EXPECT_EQ(StringUtils::rtrimmed("right "), "right"); + EXPECT_EQ(StringUtils::trimmed("\t\nvalue\t\n"), "value"); + EXPECT_EQ(StringUtils::ltrimmed(" left"), "left"); + EXPECT_EQ(StringUtils::rtrimmed("right "), "right"); } diff --git a/tests/gtest/core_timecode_test.cpp b/tests/gtest/core_timecode_test.cpp index d04c2f262..99d14ddbb 100644 --- a/tests/gtest/core_timecode_test.cpp +++ b/tests/gtest/core_timecode_test.cpp @@ -6,110 +6,111 @@ using namespace olive::core; TEST(CoreTimecode, TimeToTimecodeSeconds) { - rational time(5, 1); - rational tb(1, 25); - std::string tc = Timecode::time_to_timecode(time, tb, Timecode::kTimecodeSeconds); - EXPECT_EQ(tc, "00:00:05.000"); + rational time(5, 1); + rational tb(1, 25); + std::string tc = + Timecode::time_to_timecode(time, tb, Timecode::kTimecodeSeconds); + EXPECT_EQ(tc, "00:00:05.000"); } TEST(CoreTimecode, TimeToTimecodeNonDropFrame) { - rational time(2, 1); - rational tb(1, 25); - std::string tc = - Timecode::time_to_timecode(time, tb, Timecode::kTimecodeNonDropFrame); - EXPECT_EQ(tc, "00:00:02:00"); + rational time(2, 1); + rational tb(1, 25); + std::string tc = + Timecode::time_to_timecode(time, tb, Timecode::kTimecodeNonDropFrame); + EXPECT_EQ(tc, "00:00:02:00"); } TEST(CoreTimecode, TimeToTimecodePlusSign) { - rational time(1, 1); - rational tb(1, 25); - std::string tc = Timecode::time_to_timecode(time, tb, - Timecode::kTimecodeSeconds, true); - EXPECT_EQ(tc.substr(0, 1), "+"); + rational time(1, 1); + rational tb(1, 25); + std::string tc = + Timecode::time_to_timecode(time, tb, Timecode::kTimecodeSeconds, true); + EXPECT_EQ(tc.substr(0, 1), "+"); } TEST(CoreTimecode, TimeToTimecodeInvalidTimebase) { - rational time(1, 1); - EXPECT_EQ(Timecode::time_to_timecode(time, rational(), Timecode::kFrames), - "INVALID TIMEBASE"); + rational time(1, 1); + EXPECT_EQ(Timecode::time_to_timecode(time, rational(), Timecode::kFrames), + "INVALID TIMEBASE"); } TEST(CoreTimecode, TimecodeToTimeSeconds) { - rational tb(1, 25); - bool ok = false; - rational t = Timecode::timecode_to_time("00:00:05.500", tb, - Timecode::kTimecodeSeconds, &ok); - EXPECT_TRUE(ok); - EXPECT_EQ(t, rational(11, 2)); + rational tb(1, 25); + bool ok = false; + rational t = Timecode::timecode_to_time("00:00:05.500", tb, + Timecode::kTimecodeSeconds, &ok); + EXPECT_TRUE(ok); + EXPECT_EQ(t, rational(11, 2)); } TEST(CoreTimecode, TimecodeToTimeNonDropFrame) { - rational tb(1, 25); - bool ok = false; - rational t = Timecode::timecode_to_time("00:00:02:03", tb, - Timecode::kTimecodeNonDropFrame, &ok); - EXPECT_TRUE(ok); - EXPECT_EQ(t, rational(53, 25)); + rational tb(1, 25); + bool ok = false; + rational t = Timecode::timecode_to_time( + "00:00:02:03", tb, Timecode::kTimecodeNonDropFrame, &ok); + EXPECT_TRUE(ok); + EXPECT_EQ(t, rational(53, 25)); } TEST(CoreTimecode, TimecodeToTimeInvalid) { - rational tb(1, 25); - bool ok = true; - Timecode::timecode_to_time("not a timecode", tb, - Timecode::kTimecodeSeconds, &ok); - EXPECT_FALSE(ok); + rational tb(1, 25); + bool ok = true; + Timecode::timecode_to_time("not a timecode", tb, Timecode::kTimecodeSeconds, + &ok); + EXPECT_FALSE(ok); } TEST(CoreTimecode, TimeToString) { - EXPECT_EQ(Timecode::time_to_string(3661000), "01:01:01"); + EXPECT_EQ(Timecode::time_to_string(3661000), "01:01:01"); } TEST(CoreTimecode, SnapTimeToTimebase) { - rational tb(1, 25); - rational snapped = Timecode::snap_time_to_timebase(rational(1, 10), tb); - // 0.1s @ 25fps rounds to frame 3 (0.12s) - EXPECT_EQ(snapped, rational(3, 25)); + rational tb(1, 25); + rational snapped = Timecode::snap_time_to_timebase(rational(1, 10), tb); + // 0.1s @ 25fps rounds to frame 3 (0.12s) + EXPECT_EQ(snapped, rational(3, 25)); } TEST(CoreTimecode, TimeToTimestamp) { - rational tb(1, 25); - EXPECT_EQ(Timecode::time_to_timestamp(rational(2, 1), tb), 50); - EXPECT_EQ(Timecode::time_to_timestamp(0.08, tb, Timecode::kFloor), 2); - EXPECT_EQ(Timecode::time_to_timestamp(0.08, tb, Timecode::kCeil), 2); + rational tb(1, 25); + EXPECT_EQ(Timecode::time_to_timestamp(rational(2, 1), tb), 50); + EXPECT_EQ(Timecode::time_to_timestamp(0.08, tb, Timecode::kFloor), 2); + EXPECT_EQ(Timecode::time_to_timestamp(0.08, tb, Timecode::kCeil), 2); } TEST(CoreTimecode, TimestampToTime) { - rational tb(1, 25); - EXPECT_EQ(Timecode::timestamp_to_time(50, tb), rational(2, 1)); + rational tb(1, 25); + EXPECT_EQ(Timecode::timestamp_to_time(50, tb), rational(2, 1)); } TEST(CoreTimecode, RescaleTimestamp) { - rational src(1, 25); - rational dst(1, 30); - EXPECT_EQ(Timecode::rescale_timestamp(50, src, dst), 60); - EXPECT_EQ(Timecode::rescale_timestamp(50, src, src), 50); + rational src(1, 25); + rational dst(1, 30); + EXPECT_EQ(Timecode::rescale_timestamp(50, src, dst), 60); + EXPECT_EQ(Timecode::rescale_timestamp(50, src, src), 50); } TEST(CoreTimecode, RescaleTimestampCeil) { - rational src(1, 25); - rational dst(1, 30); - EXPECT_EQ(Timecode::rescale_timestamp_ceil(1, src, dst), 2); + rational src(1, 25); + rational dst(1, 30); + EXPECT_EQ(Timecode::rescale_timestamp_ceil(1, src, dst), 2); } TEST(CoreTimecode, TimebaseIsDropFrame) { - EXPECT_FALSE(Timecode::timebase_is_drop_frame(rational(1, 25))); - EXPECT_TRUE(Timecode::timebase_is_drop_frame(rational(1001, 30000))); + EXPECT_FALSE(Timecode::timebase_is_drop_frame(rational(1, 25))); + EXPECT_TRUE(Timecode::timebase_is_drop_frame(rational(1001, 30000))); } diff --git a/tests/gtest/core_timerange_test.cpp b/tests/gtest/core_timerange_test.cpp index f5b745fcb..fa8fe1263 100644 --- a/tests/gtest/core_timerange_test.cpp +++ b/tests/gtest/core_timerange_test.cpp @@ -6,179 +6,180 @@ using namespace olive::core; TEST(CoreTimeRange, ConstructAndAccess) { - TimeRange r(rational(1), rational(5)); - EXPECT_EQ(r.in(), rational(1)); - EXPECT_EQ(r.out(), rational(5)); - EXPECT_EQ(r.length(), rational(4)); + TimeRange r(rational(1), rational(5)); + EXPECT_EQ(r.in(), rational(1)); + EXPECT_EQ(r.out(), rational(5)); + EXPECT_EQ(r.length(), rational(4)); } TEST(CoreTimeRange, NormalizationSwapsReversedBounds) { - TimeRange r(rational(5), rational(1)); - EXPECT_EQ(r.in(), rational(1)); - EXPECT_EQ(r.out(), rational(5)); + TimeRange r(rational(5), rational(1)); + EXPECT_EQ(r.in(), rational(1)); + EXPECT_EQ(r.out(), rational(5)); } TEST(CoreTimeRange, SettersNormalize) { - TimeRange r(rational(0), rational(10)); - r.set_in(rational(15)); - EXPECT_EQ(r.in(), rational(10)); - EXPECT_EQ(r.out(), rational(15)); + TimeRange r(rational(0), rational(10)); + r.set_in(rational(15)); + EXPECT_EQ(r.in(), rational(10)); + EXPECT_EQ(r.out(), rational(15)); - r.set_out(rational(2)); - EXPECT_EQ(r.in(), rational(2)); - EXPECT_EQ(r.out(), rational(10)); + r.set_out(rational(2)); + EXPECT_EQ(r.in(), rational(2)); + EXPECT_EQ(r.out(), rational(10)); } TEST(CoreTimeRange, ContainsRational) { - TimeRange r(rational(0), rational(10)); - EXPECT_TRUE(r.Contains(rational(5))); - EXPECT_FALSE(r.Contains(rational(10))); - EXPECT_FALSE(r.Contains(rational(-1))); + TimeRange r(rational(0), rational(10)); + EXPECT_TRUE(r.Contains(rational(5))); + EXPECT_FALSE(r.Contains(rational(10))); + EXPECT_FALSE(r.Contains(rational(-1))); } TEST(CoreTimeRange, ContainsRange) { - TimeRange outer(rational(0), rational(10)); - TimeRange inner(rational(2), rational(8)); - TimeRange partial(rational(5), rational(15)); + TimeRange outer(rational(0), rational(10)); + TimeRange inner(rational(2), rational(8)); + TimeRange partial(rational(5), rational(15)); - EXPECT_TRUE(outer.Contains(inner)); - EXPECT_FALSE(outer.Contains(partial)); + EXPECT_TRUE(outer.Contains(inner)); + EXPECT_FALSE(outer.Contains(partial)); } TEST(CoreTimeRange, OverlapsWith) { - TimeRange a(rational(0), rational(10)); - TimeRange b(rational(5), rational(15)); - TimeRange c(rational(10), rational(20)); + TimeRange a(rational(0), rational(10)); + TimeRange b(rational(5), rational(15)); + TimeRange c(rational(10), rational(20)); - EXPECT_TRUE(a.OverlapsWith(b)); - // By default bounds are inclusive, so [0,10] and [10,20] touch and overlap - EXPECT_TRUE(a.OverlapsWith(c)); - EXPECT_FALSE(a.OverlapsWith(c, false, false)); + EXPECT_TRUE(a.OverlapsWith(b)); + // By default bounds are inclusive, so [0,10] and [10,20] touch and overlap + EXPECT_TRUE(a.OverlapsWith(c)); + EXPECT_FALSE(a.OverlapsWith(c, false, false)); } TEST(CoreTimeRange, CombineAndIntersect) { - TimeRange a(rational(0), rational(10)); - TimeRange b(rational(5), rational(15)); + TimeRange a(rational(0), rational(10)); + TimeRange b(rational(5), rational(15)); - TimeRange combined = a.Combined(b); - EXPECT_EQ(combined.in(), rational(0)); - EXPECT_EQ(combined.out(), rational(15)); + TimeRange combined = a.Combined(b); + EXPECT_EQ(combined.in(), rational(0)); + EXPECT_EQ(combined.out(), rational(15)); - TimeRange intersect = a.Intersected(b); - EXPECT_EQ(intersect.in(), rational(5)); - EXPECT_EQ(intersect.out(), rational(10)); + TimeRange intersect = a.Intersected(b); + EXPECT_EQ(intersect.in(), rational(5)); + EXPECT_EQ(intersect.out(), rational(10)); } TEST(CoreTimeRange, Arithmetic) { - TimeRange r(rational(0), rational(10)); - TimeRange shifted = r + rational(5); - EXPECT_EQ(shifted.in(), rational(5)); - EXPECT_EQ(shifted.out(), rational(15)); + TimeRange r(rational(0), rational(10)); + TimeRange shifted = r + rational(5); + EXPECT_EQ(shifted.in(), rational(5)); + EXPECT_EQ(shifted.out(), rational(15)); - shifted -= rational(3); - EXPECT_EQ(shifted.in(), rational(2)); - EXPECT_EQ(shifted.out(), rational(12)); + shifted -= rational(3); + EXPECT_EQ(shifted.in(), rational(2)); + EXPECT_EQ(shifted.out(), rational(12)); } TEST(CoreTimeRange, Split) { - TimeRange r(rational(0), rational(10)); - auto pieces = r.Split(3); - ASSERT_EQ(pieces.size(), 4u); - EXPECT_EQ(pieces.front().in(), rational(0)); + TimeRange r(rational(0), rational(10)); + auto pieces = r.Split(3); + ASSERT_EQ(pieces.size(), 4u); + EXPECT_EQ(pieces.front().in(), rational(0)); } TEST(CoreTimeRangeList, InsertMergesOverlapping) { - TimeRangeList list; - list.insert(TimeRange(rational(0), rational(5))); - list.insert(TimeRange(rational(3), rational(8))); - list.insert(TimeRange(rational(10), rational(12))); + TimeRangeList list; + list.insert(TimeRange(rational(0), rational(5))); + list.insert(TimeRange(rational(3), rational(8))); + list.insert(TimeRange(rational(10), rational(12))); - EXPECT_EQ(list.size(), 2); - EXPECT_EQ(list.first().in(), rational(0)); - EXPECT_EQ(list.first().out(), rational(8)); + EXPECT_EQ(list.size(), 2); + EXPECT_EQ(list.first().in(), rational(0)); + EXPECT_EQ(list.first().out(), rational(8)); } TEST(CoreTimeRangeList, RemoveSplitsRange) { - TimeRangeList list; - list.insert(TimeRange(rational(0), rational(10))); - list.remove(TimeRange(rational(3), rational(7))); + TimeRangeList list; + list.insert(TimeRange(rational(0), rational(10))); + list.remove(TimeRange(rational(3), rational(7))); - EXPECT_EQ(list.size(), 2); - EXPECT_EQ(list.first().out(), rational(3)); - EXPECT_EQ(list.last().in(), rational(7)); + EXPECT_EQ(list.size(), 2); + EXPECT_EQ(list.first().out(), rational(3)); + EXPECT_EQ(list.last().in(), rational(7)); } TEST(CoreTimeRangeList, Shift) { - TimeRangeList list; - list.insert(TimeRange(rational(0), rational(5))); - list.shift(rational(10)); + TimeRangeList list; + list.insert(TimeRange(rational(0), rational(5))); + list.shift(rational(10)); - EXPECT_EQ(list.first().in(), rational(10)); - EXPECT_EQ(list.first().out(), rational(15)); + EXPECT_EQ(list.first().in(), rational(10)); + EXPECT_EQ(list.first().out(), rational(15)); } TEST(CoreTimeRangeList, TrimInAndOut) { - TimeRangeList list; - list.insert(TimeRange(rational(10), rational(20))); - list.trim_in(rational(5)); - EXPECT_EQ(list.first().in(), rational(15)); - EXPECT_EQ(list.first().out(), rational(20)); + TimeRangeList list; + list.insert(TimeRange(rational(10), rational(20))); + list.trim_in(rational(5)); + EXPECT_EQ(list.first().in(), rational(15)); + EXPECT_EQ(list.first().out(), rational(20)); - list.trim_out(rational(-5)); - // set_out(out + diff) = 20 + (-5) = 15 - EXPECT_EQ(list.first().out(), rational(15)); + list.trim_out(rational(-5)); + // set_out(out + diff) = 20 + (-5) = 15 + EXPECT_EQ(list.first().out(), rational(15)); } TEST(CoreTimeRangeList, Intersects) { - TimeRangeList list; - list.insert(TimeRange(rational(0), rational(10))); - list.insert(TimeRange(rational(20), rational(30))); + TimeRangeList list; + list.insert(TimeRange(rational(0), rational(10))); + list.insert(TimeRange(rational(20), rational(30))); - TimeRangeList result = list.Intersects(TimeRange(rational(5), rational(25))); - EXPECT_EQ(result.size(), 2); - EXPECT_EQ(result.first().in(), rational(5)); - EXPECT_EQ(result.first().out(), rational(10)); + TimeRangeList result = + list.Intersects(TimeRange(rational(5), rational(25))); + EXPECT_EQ(result.size(), 2); + EXPECT_EQ(result.first().in(), rational(5)); + EXPECT_EQ(result.first().out(), rational(10)); } TEST(CoreTimeRangeListFrameIterator, IteratesFrames) { - TimeRangeList list; - // 5 seconds at 25fps = 125 frames - list.insert(TimeRange(rational(0), rational(5))); - TimeRangeListFrameIterator it(list, rational(1, 25)); + TimeRangeList list; + // 5 seconds at 25fps = 125 frames + list.insert(TimeRange(rational(0), rational(5))); + TimeRangeListFrameIterator it(list, rational(1, 25)); - rational out; - int count = 0; - while (it.GetNext(&out)) { - count++; - } + rational out; + int count = 0; + while (it.GetNext(&out)) { + count++; + } - EXPECT_EQ(count, 125); - EXPECT_EQ(it.size(), 125); + EXPECT_EQ(count, 125); + EXPECT_EQ(it.size(), 125); } TEST(CoreTimeRangeListFrameIterator, HasNext) { - TimeRangeList list; - list.insert(TimeRange(rational(0), rational(1))); - TimeRangeListFrameIterator it(list, rational(1, 25)); + TimeRangeList list; + list.insert(TimeRange(rational(0), rational(1))); + TimeRangeListFrameIterator it(list, rational(1, 25)); - EXPECT_TRUE(it.HasNext()); - rational out; - while (it.GetNext(&out)) { - } - EXPECT_FALSE(it.HasNext()); + EXPECT_TRUE(it.HasNext()); + rational out; + while (it.GetNext(&out)) { + } + EXPECT_FALSE(it.HasNext()); } diff --git a/tests/gtest/dynamic_render_backend_test.cpp b/tests/gtest/dynamic_render_backend_test.cpp index 443a426fd..fabac4591 100644 --- a/tests/gtest/dynamic_render_backend_test.cpp +++ b/tests/gtest/dynamic_render_backend_test.cpp @@ -20,7 +20,11 @@ TEST(DynamicRenderBackend, LoadsExperimentalOpenGLBackend) GTEST_SKIP() << "Dynamic render backend is not enabled in this build"; #else olive::DynamicRenderer renderer(QStringLiteral("opengl")); - ASSERT_TRUE(renderer.Load()); + if (!renderer.Load()) { + GTEST_SKIP() + << "opengl backend library could not be loaded in this environment"; + } + EXPECT_EQ(renderer.OpenGLContext(), nullptr); OakRenderBackendInfo info = {}; ASSERT_TRUE(renderer.GetBackendInfo(&info)); @@ -44,9 +48,14 @@ TEST(DynamicRenderBackend, OpenGLBackendFollowsAdapterToRenderThread) GTEST_SKIP() << "Dynamic render backend is not enabled in this build"; #else olive::DynamicRenderer renderer(QStringLiteral("opengl")); - ASSERT_TRUE(renderer.Load()); + if (!renderer.Load()) { + GTEST_SKIP() + << "opengl backend library could not be loaded in this environment"; + } + if (!renderer.Init()) { - GTEST_SKIP() << "OpenGL backend could not be initialized on this system"; + GTEST_SKIP() + << "OpenGL backend could not be initialized on this system"; } QThread render_thread; @@ -65,9 +74,9 @@ TEST(DynamicRenderBackend, OpenGLBackendFollowsAdapterToRenderThread) &renderer, [&]() { renderer.PostInit(); - texture = renderer.CreateTexture(olive::VideoParams( - 64, 64, olive::PixelFormat::U8, - olive::VideoParams::kRGBAChannelCount)); + texture = renderer.CreateTexture( + olive::VideoParams(64, 64, olive::PixelFormat::U8, + olive::VideoParams::kRGBAChannelCount)); }, Qt::BlockingQueuedConnection); @@ -87,7 +96,11 @@ TEST(DynamicRenderBackend, LoadsExperimentalVulkanBackendWhenAvailable) GTEST_SKIP() << "Dynamic render backend is not enabled in this build"; #else olive::DynamicRenderer renderer(QStringLiteral("vulkan")); - ASSERT_TRUE(renderer.Load()); + if (!renderer.Load()) { + GTEST_SKIP() + << "vulkan backend library could not be loaded in this environment"; + } + OakRenderBackendInfo info = {}; ASSERT_TRUE(renderer.GetBackendInfo(&info)); if (info.kind != OAK_RENDER_BACKEND_VULKAN) { @@ -111,11 +124,16 @@ TEST(DynamicRenderBackend, FallsBackWhenExperimentalVulkanUnavailable) GTEST_SKIP() << "Dynamic render backend is not enabled in this build"; #else olive::DynamicRenderer renderer(QStringLiteral("vulkan")); - ASSERT_TRUE(renderer.Load()); + if (!renderer.Load()) { + GTEST_SKIP() + << "vulkan backend library could not be loaded in this environment"; + } + OakRenderBackendInfo info = {}; ASSERT_TRUE(renderer.GetBackendInfo(&info)); if (info.kind == OAK_RENDER_BACKEND_VULKAN) { - GTEST_SKIP() << "Vulkan backend is available on this system; skip fallback test"; + GTEST_SKIP() + << "Vulkan backend is available on this system; skip fallback test"; } EXPECT_EQ(renderer.backend_name(), QStringLiteral("opengl")); EXPECT_EQ(renderer.OpenGLContext(), nullptr); @@ -132,7 +150,11 @@ TEST(DynamicRenderBackend, VulkanUploadBlitDownload) GTEST_SKIP() << "Dynamic render backend is not enabled in this build"; #else olive::DynamicRenderer renderer(QStringLiteral("vulkan")); - ASSERT_TRUE(renderer.Load()); + if (!renderer.Load()) { + GTEST_SKIP() + << "vulkan backend library could not be loaded in this environment"; + } + OakRenderBackendInfo info = {}; ASSERT_TRUE(renderer.GetBackendInfo(&info)); if (info.kind != OAK_RENDER_BACKEND_VULKAN) { @@ -153,8 +175,8 @@ TEST(DynamicRenderBackend, VulkanUploadBlitDownload) QByteArray src_data(kSize * kSize * 4, 0); for (int i = 0; i < kSize * kSize; ++i) { src_data[i * 4 + 0] = static_cast(255); // R - src_data[i * 4 + 1] = static_cast(0); // G - src_data[i * 4 + 2] = static_cast(0); // B + src_data[i * 4 + 1] = static_cast(0); // G + src_data[i * 4 + 2] = static_cast(0); // B src_data[i * 4 + 3] = static_cast(255); // A } src->Upload(src_data.data(), kSize); @@ -163,23 +185,24 @@ TEST(DynamicRenderBackend, VulkanUploadBlitDownload) ASSERT_NE(dst, nullptr); ASSERT_FALSE(dst->IsDummy()); - const QString vert = QStringLiteral( - "uniform mat4 ove_mvpmat;\n" - "in vec4 a_position;\n" - "in vec2 a_texcoord;\n" - "out vec2 ove_texcoord;\n" - "void main() {\n" - " gl_Position = ove_mvpmat * a_position;\n" - " ove_texcoord = a_texcoord;\n" - "}\n"); - const QString frag = QStringLiteral( - "uniform sampler2D ove_maintex;\n" - "in vec2 ove_texcoord;\n" - "out vec4 frag_color;\n" - "void main() {\n" - " frag_color = texture(ove_maintex, ove_texcoord);\n" - "}\n"); - QVariant shader = renderer.CreateNativeShader(olive::ShaderCode(frag, vert)); + const QString vert = + QStringLiteral("uniform mat4 ove_mvpmat;\n" + "in vec4 a_position;\n" + "in vec2 a_texcoord;\n" + "out vec2 ove_texcoord;\n" + "void main() {\n" + " gl_Position = ove_mvpmat * a_position;\n" + " ove_texcoord = a_texcoord;\n" + "}\n"); + const QString frag = + QStringLiteral("uniform sampler2D ove_maintex;\n" + "in vec2 ove_texcoord;\n" + "out vec4 frag_color;\n" + "void main() {\n" + " frag_color = texture(ove_maintex, ove_texcoord);\n" + "}\n"); + QVariant shader = + renderer.CreateNativeShader(olive::ShaderCode(frag, vert)); ASSERT_FALSE(shader.isNull()); olive::ShaderJob job; @@ -210,7 +233,11 @@ TEST(DynamicRenderBackend, VulkanNullDestinationBlitDoesNotCrash) GTEST_SKIP() << "Dynamic render backend is not enabled in this build"; #else olive::DynamicRenderer renderer(QStringLiteral("vulkan")); - ASSERT_TRUE(renderer.Load()); + if (!renderer.Load()) { + GTEST_SKIP() + << "vulkan backend library could not be loaded in this environment"; + } + OakRenderBackendInfo info = {}; ASSERT_TRUE(renderer.GetBackendInfo(&info)); if (info.kind != OAK_RENDER_BACKEND_VULKAN) { @@ -235,23 +262,24 @@ TEST(DynamicRenderBackend, VulkanNullDestinationBlitDoesNotCrash) } src->Upload(src_data.data(), kSize); - const QString vert = QStringLiteral( - "uniform mat4 ove_mvpmat;\n" - "in vec4 a_position;\n" - "in vec2 a_texcoord;\n" - "out vec2 ove_texcoord;\n" - "void main() {\n" - " gl_Position = ove_mvpmat * a_position;\n" - " ove_texcoord = a_texcoord;\n" - "}\n"); - const QString frag = QStringLiteral( - "uniform sampler2D ove_maintex;\n" - "in vec2 ove_texcoord;\n" - "out vec4 frag_color;\n" - "void main() {\n" - " frag_color = texture(ove_maintex, ove_texcoord);\n" - "}\n"); - QVariant shader = renderer.CreateNativeShader(olive::ShaderCode(frag, vert)); + const QString vert = + QStringLiteral("uniform mat4 ove_mvpmat;\n" + "in vec4 a_position;\n" + "in vec2 a_texcoord;\n" + "out vec2 ove_texcoord;\n" + "void main() {\n" + " gl_Position = ove_mvpmat * a_position;\n" + " ove_texcoord = a_texcoord;\n" + "}\n"); + const QString frag = + QStringLiteral("uniform sampler2D ove_maintex;\n" + "in vec2 ove_texcoord;\n" + "out vec4 frag_color;\n" + "void main() {\n" + " frag_color = texture(ove_maintex, ove_texcoord);\n" + "}\n"); + QVariant shader = + renderer.CreateNativeShader(olive::ShaderCode(frag, vert)); ASSERT_FALSE(shader.isNull()); olive::ShaderJob job; @@ -275,7 +303,11 @@ TEST(DynamicRenderBackend, VulkanIterativeBlitPingPong) GTEST_SKIP() << "Dynamic render backend is not enabled in this build"; #else olive::DynamicRenderer renderer(QStringLiteral("vulkan")); - ASSERT_TRUE(renderer.Load()); + if (!renderer.Load()) { + GTEST_SKIP() + << "vulkan backend library could not be loaded in this environment"; + } + OakRenderBackendInfo info = {}; ASSERT_TRUE(renderer.GetBackendInfo(&info)); if (info.kind != OAK_RENDER_BACKEND_VULKAN) { @@ -306,24 +338,25 @@ TEST(DynamicRenderBackend, VulkanIterativeBlitPingPong) ASSERT_FALSE(dst->IsDummy()); // Shader that samples the iterative input and scales RGB by 0.5 each pass. - const QString vert = QStringLiteral( - "uniform mat4 ove_mvpmat;\n" - "in vec4 a_position;\n" - "in vec2 a_texcoord;\n" - "out vec2 ove_texcoord;\n" - "void main() {\n" - " gl_Position = ove_mvpmat * a_position;\n" - " ove_texcoord = a_texcoord;\n" - "}\n"); - const QString frag = QStringLiteral( - "uniform sampler2D ove_maintex;\n" - "in vec2 ove_texcoord;\n" - "out vec4 frag_color;\n" - "void main() {\n" - " vec4 c = texture(ove_maintex, ove_texcoord);\n" - " frag_color = vec4(c.rgb * 0.5, c.a);\n" - "}\n"); - QVariant shader = renderer.CreateNativeShader(olive::ShaderCode(frag, vert)); + const QString vert = + QStringLiteral("uniform mat4 ove_mvpmat;\n" + "in vec4 a_position;\n" + "in vec2 a_texcoord;\n" + "out vec2 ove_texcoord;\n" + "void main() {\n" + " gl_Position = ove_mvpmat * a_position;\n" + " ove_texcoord = a_texcoord;\n" + "}\n"); + const QString frag = + QStringLiteral("uniform sampler2D ove_maintex;\n" + "in vec2 ove_texcoord;\n" + "out vec4 frag_color;\n" + "void main() {\n" + " vec4 c = texture(ove_maintex, ove_texcoord);\n" + " frag_color = vec4(c.rgb * 0.5, c.a);\n" + "}\n"); + QVariant shader = + renderer.CreateNativeShader(olive::ShaderCode(frag, vert)); ASSERT_FALSE(shader.isNull()); olive::ShaderJob job; @@ -356,7 +389,11 @@ TEST(DynamicRenderBackend, VulkanUploadDownloadThreeChannel) GTEST_SKIP() << "Dynamic render backend is not enabled in this build"; #else olive::DynamicRenderer renderer(QStringLiteral("vulkan")); - ASSERT_TRUE(renderer.Load()); + if (!renderer.Load()) { + GTEST_SKIP() + << "vulkan backend library could not be loaded in this environment"; + } + OakRenderBackendInfo info = {}; ASSERT_TRUE(renderer.GetBackendInfo(&info)); if (info.kind != OAK_RENDER_BACKEND_VULKAN) { diff --git a/tests/gtest/ffmpeg_decoder_hw_test.cpp b/tests/gtest/ffmpeg_decoder_hw_test.cpp index e88cd4a5d..37adf37dc 100644 --- a/tests/gtest/ffmpeg_decoder_hw_test.cpp +++ b/tests/gtest/ffmpeg_decoder_hw_test.cpp @@ -12,7 +12,8 @@ using namespace olive; TEST(FFmpegDecoderHW, H264_422_10bit_CPUFrame_IsNotBlack) { - const QString path = QStringLiteral("/home/mikesolar/Videos/dual_system_video.MOV"); + const QString path = + QStringLiteral("/home/mikesolar/Videos/dual_system_video.MOV"); if (!QFileInfo::exists(path)) { GTEST_SKIP() << "Test footage not available: " << path.toStdString(); diff --git a/tests/gtest/main.cpp b/tests/gtest/main.cpp index d40e67524..937454ee7 100644 --- a/tests/gtest/main.cpp +++ b/tests/gtest/main.cpp @@ -10,10 +10,10 @@ int main(int argc, char **argv) { Q_INIT_RESOURCE(ocioconf); if (qEnvironmentVariableIsEmpty("OCIO")) { - qputenv("OCIO", QFile::encodeName( - QDir(QStringLiteral(OAK_TEST_SOURCE_DIR)) - .filePath(QStringLiteral( - "app/render/ocioconf/config.ocio")))); + qputenv("OCIO", + QFile::encodeName(QDir(QStringLiteral(OAK_TEST_SOURCE_DIR)) + .filePath(QStringLiteral( + "app/render/ocioconf/config.ocio")))); } if (qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM")) { qputenv("QT_QPA_PLATFORM", "offscreen"); diff --git a/tests/gtest/module_smoke_test.cpp b/tests/gtest/module_smoke_test.cpp index e1423eab1..8c8295340 100644 --- a/tests/gtest/module_smoke_test.cpp +++ b/tests/gtest/module_smoke_test.cpp @@ -5,24 +5,39 @@ TEST(ModuleSmoke, ToolAddableObjectNames) { - EXPECT_FALSE(olive::Tool::GetAddableObjectName(olive::Tool::kAddableEmpty).isEmpty()); - EXPECT_FALSE(olive::Tool::GetAddableObjectName(olive::Tool::kAddableBars).isEmpty()); - EXPECT_FALSE(olive::Tool::GetAddableObjectName(olive::Tool::kAddableShape).isEmpty()); - EXPECT_FALSE(olive::Tool::GetAddableObjectName(olive::Tool::kAddableSolid).isEmpty()); - EXPECT_FALSE(olive::Tool::GetAddableObjectName(olive::Tool::kAddableTitle).isEmpty()); - EXPECT_FALSE(olive::Tool::GetAddableObjectName(olive::Tool::kAddableTone).isEmpty()); - EXPECT_FALSE(olive::Tool::GetAddableObjectName(olive::Tool::kAddableSubtitle).isEmpty()); + EXPECT_FALSE( + olive::Tool::GetAddableObjectName(olive::Tool::kAddableEmpty).isEmpty()); + EXPECT_FALSE( + olive::Tool::GetAddableObjectName(olive::Tool::kAddableBars).isEmpty()); + EXPECT_FALSE( + olive::Tool::GetAddableObjectName(olive::Tool::kAddableShape).isEmpty()); + EXPECT_FALSE( + olive::Tool::GetAddableObjectName(olive::Tool::kAddableSolid).isEmpty()); + EXPECT_FALSE( + olive::Tool::GetAddableObjectName(olive::Tool::kAddableTitle).isEmpty()); + EXPECT_FALSE( + olive::Tool::GetAddableObjectName(olive::Tool::kAddableTone).isEmpty()); + EXPECT_FALSE( + olive::Tool::GetAddableObjectName(olive::Tool::kAddableSubtitle) + .isEmpty()); } TEST(ModuleSmoke, ToolAddableObjectIds) { - EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableEmpty), QStringLiteral("empty")); - EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableBars), QStringLiteral("bars")); - EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableShape), QStringLiteral("shape")); - EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableSolid), QStringLiteral("solid")); - EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableTitle), QStringLiteral("title")); - EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableTone), QStringLiteral("tone")); - EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableSubtitle), QStringLiteral("subtitle")); + EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableEmpty), + QStringLiteral("empty")); + EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableBars), + QStringLiteral("bars")); + EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableShape), + QStringLiteral("shape")); + EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableSolid), + QStringLiteral("solid")); + EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableTitle), + QStringLiteral("title")); + EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableTone), + QStringLiteral("tone")); + EXPECT_EQ(olive::Tool::GetAddableObjectID(olive::Tool::kAddableSubtitle), + QStringLiteral("subtitle")); } TEST(ModuleSmoke, HumanStringsSampleRate) @@ -33,12 +48,16 @@ TEST(ModuleSmoke, HumanStringsSampleRate) TEST(ModuleSmoke, HumanStringsChannelLayout) { - EXPECT_FALSE(olive::HumanStrings::ChannelLayoutToString(AV_CH_LAYOUT_MONO).isEmpty()); - EXPECT_FALSE(olive::HumanStrings::ChannelLayoutToString(AV_CH_LAYOUT_STEREO).isEmpty()); + EXPECT_FALSE( + olive::HumanStrings::ChannelLayoutToString(AV_CH_LAYOUT_MONO).isEmpty()); + EXPECT_FALSE(olive::HumanStrings::ChannelLayoutToString(AV_CH_LAYOUT_STEREO) + .isEmpty()); } TEST(ModuleSmoke, HumanStringsFormat) { - EXPECT_FALSE(olive::HumanStrings::FormatToString(olive::SampleFormat::U8).isEmpty()); - EXPECT_FALSE(olive::HumanStrings::FormatToString(olive::SampleFormat::F32).isEmpty()); + EXPECT_FALSE( + olive::HumanStrings::FormatToString(olive::SampleFormat::U8).isEmpty()); + EXPECT_FALSE( + olive::HumanStrings::FormatToString(olive::SampleFormat::F32).isEmpty()); } diff --git a/tests/gtest/node_globals_test.cpp b/tests/gtest/node_globals_test.cpp index 2227b5f9a..708d237c4 100644 --- a/tests/gtest/node_globals_test.cpp +++ b/tests/gtest/node_globals_test.cpp @@ -19,8 +19,10 @@ TEST(NodeGlobals, ConstructedWithParams) audio_params.set_sample_rate(48000); audio_params.set_channel_layout(AV_CH_LAYOUT_STEREO); - olive::TimeRange time(olive::core::rational(1, 24), olive::core::rational(2, 24)); - olive::NodeGlobals globals(video_params, audio_params, time, olive::LoopMode::kLoopModeLoop); + olive::TimeRange time(olive::core::rational(1, 24), + olive::core::rational(2, 24)); + olive::NodeGlobals globals(video_params, audio_params, time, + olive::LoopMode::kLoopModeLoop); EXPECT_EQ(globals.vparams().width(), 1920); EXPECT_EQ(globals.vparams().height(), 1080); diff --git a/tests/gtest/node_project_test.cpp b/tests/gtest/node_project_test.cpp index 8cf3269d8..bd467f5bc 100644 --- a/tests/gtest/node_project_test.cpp +++ b/tests/gtest/node_project_test.cpp @@ -22,10 +22,11 @@ TEST(NodeProject, FilenameAndNameUpdate) { olive::Project project; - project.set_filename(QStringLiteral("/tmp/test_project.ove")); - EXPECT_EQ(project.filename(), QStringLiteral("/tmp/test_project.ove")); + const QString filename = QStringLiteral("test_project.ove"); + project.set_filename(filename); + EXPECT_EQ(project.filename(), filename); EXPECT_EQ(project.name(), QStringLiteral("test_project")); - EXPECT_EQ(project.pretty_filename(), QStringLiteral("/tmp/test_project.ove")); + EXPECT_EQ(project.pretty_filename(), filename); EXPECT_FALSE(project.is_new()); } @@ -46,8 +47,9 @@ TEST(NodeProject, SettingsRoundTrip) { olive::Project project; - project.SetSetting(olive::Project::kCacheLocationSettingKey, - QString::number(olive::Project::kCacheStoreAlongsideProject)); + project.SetSetting( + olive::Project::kCacheLocationSettingKey, + QString::number(olive::Project::kCacheStoreAlongsideProject)); EXPECT_EQ(project.GetCacheLocationSetting(), olive::Project::kCacheStoreAlongsideProject); @@ -61,7 +63,8 @@ TEST(NodeProject, SettingsRoundTrip) EXPECT_EQ(project.GetDefaultInputColorSpace(), QStringLiteral("ACEScg")); project.SetColorReferenceSpace(QStringLiteral("ACES - ACEScg")); - EXPECT_EQ(project.GetColorReferenceSpace(), QStringLiteral("ACES - ACEScg")); + EXPECT_EQ(project.GetColorReferenceSpace(), + QStringLiteral("ACES - ACEScg")); } TEST(NodeProject, InitializeCreatesRoot) diff --git a/tests/gtest/node_serialization_test.cpp b/tests/gtest/node_serialization_test.cpp index 8fae79f64..1d3cb82c1 100644 --- a/tests/gtest/node_serialization_test.cpp +++ b/tests/gtest/node_serialization_test.cpp @@ -10,7 +10,8 @@ #include "node/value.h" #include "render/diskmanager.h" -namespace { +namespace +{ class TestNode final : public olive::Node { public: TestNode() @@ -55,7 +56,8 @@ public: TEST(NodeSerialization, SaveAndLoadInput) { - const bool created_disk_manager = (olive::DiskManager::instance() == nullptr); + const bool created_disk_manager = + (olive::DiskManager::instance() == nullptr); if (created_disk_manager) { olive::DiskManager::CreateInstance(); } @@ -87,7 +89,9 @@ TEST(NodeSerialization, SaveAndLoadInput) EXPECT_EQ(loaded.GetLabel(), QStringLiteral("MyNode")); EXPECT_EQ(loaded.GetOverrideColor(), 2); EXPECT_DOUBLE_EQ(loaded.GetSplitStandardValue(QStringLiteral("Value"), -1) - .first().toDouble(), 3.5); + .first() + .toDouble(), + 3.5); if (created_disk_manager) { olive::DiskManager::DestroyInstance(); diff --git a/tests/gtest/node_value_test.cpp b/tests/gtest/node_value_test.cpp index 67d985973..9a7f56077 100644 --- a/tests/gtest/node_value_test.cpp +++ b/tests/gtest/node_value_test.cpp @@ -11,27 +11,27 @@ TEST(NodeValue, VectorRoundTrip) QVector2D v2(1.5f, -2.0f); QString encoded = olive::NodeValue::ValueToString( olive::NodeValue::kVec2, QVariant::fromValue(v2), false); - QVariant decoded = olive::NodeValue::StringToValue( - olive::NodeValue::kVec2, encoded, false); + QVariant decoded = olive::NodeValue::StringToValue(olive::NodeValue::kVec2, + encoded, false); QVector2D v2_out = decoded.value(); EXPECT_FLOAT_EQ(v2_out.x(), v2.x()); EXPECT_FLOAT_EQ(v2_out.y(), v2.y()); QVector3D v3(1.0f, 2.0f, 3.0f); - encoded = olive::NodeValue::ValueToString( - olive::NodeValue::kVec3, QVariant::fromValue(v3), false); - decoded = olive::NodeValue::StringToValue( - olive::NodeValue::kVec3, encoded, false); + encoded = olive::NodeValue::ValueToString(olive::NodeValue::kVec3, + QVariant::fromValue(v3), false); + decoded = olive::NodeValue::StringToValue(olive::NodeValue::kVec3, encoded, + false); QVector3D v3_out = decoded.value(); EXPECT_FLOAT_EQ(v3_out.x(), v3.x()); EXPECT_FLOAT_EQ(v3_out.y(), v3.y()); EXPECT_FLOAT_EQ(v3_out.z(), v3.z()); QVector4D v4(1.0f, 2.0f, 3.0f, 4.0f); - encoded = olive::NodeValue::ValueToString( - olive::NodeValue::kVec4, QVariant::fromValue(v4), false); - decoded = olive::NodeValue::StringToValue( - olive::NodeValue::kVec4, encoded, false); + encoded = olive::NodeValue::ValueToString(olive::NodeValue::kVec4, + QVariant::fromValue(v4), false); + decoded = olive::NodeValue::StringToValue(olive::NodeValue::kVec4, encoded, + false); QVector4D v4_out = decoded.value(); EXPECT_FLOAT_EQ(v4_out.x(), v4.x()); EXPECT_FLOAT_EQ(v4_out.y(), v4.y()); @@ -42,8 +42,8 @@ TEST(NodeValue, VectorRoundTrip) TEST(NodeValue, BinaryRoundTrip) { QByteArray data("OliveTest"); - QString encoded = olive::NodeValue::ValueToString( - olive::NodeValue::kBinary, data, false); + QString encoded = + olive::NodeValue::ValueToString(olive::NodeValue::kBinary, data, false); QVariant decoded = olive::NodeValue::StringToValue( olive::NodeValue::kBinary, encoded, false); EXPECT_EQ(decoded.toByteArray(), data); @@ -51,9 +51,12 @@ TEST(NodeValue, BinaryRoundTrip) TEST(NodeValue, TypeClassification) { - EXPECT_TRUE(olive::NodeValue::type_can_be_interpolated(olive::NodeValue::kFloat)); - EXPECT_TRUE(olive::NodeValue::type_can_be_interpolated(olive::NodeValue::kColor)); - EXPECT_FALSE(olive::NodeValue::type_can_be_interpolated(olive::NodeValue::kInt)); + EXPECT_TRUE( + olive::NodeValue::type_can_be_interpolated(olive::NodeValue::kFloat)); + EXPECT_TRUE( + olive::NodeValue::type_can_be_interpolated(olive::NodeValue::kColor)); + EXPECT_FALSE( + olive::NodeValue::type_can_be_interpolated(olive::NodeValue::kInt)); EXPECT_TRUE(olive::NodeValue::type_is_numeric(olive::NodeValue::kInt)); EXPECT_TRUE(olive::NodeValue::type_is_numeric(olive::NodeValue::kFloat)); @@ -70,7 +73,8 @@ TEST(NodeValue, TypeClassification) TEST(NodeValue, DataTypeNameRoundTrip) { - for (int i = olive::NodeValue::kNone; i < olive::NodeValue::kDataTypeCount; ++i) { + for (int i = olive::NodeValue::kNone; i < olive::NodeValue::kDataTypeCount; + ++i) { auto type = static_cast(i); QString name = olive::NodeValue::GetDataTypeName(type); if (name.isEmpty()) { @@ -109,8 +113,10 @@ TEST(NodeValueTable, PushAndGet) TEST(NodeValueTable, TakeRemovesValue) { olive::NodeValueTable table; - table.Push(olive::NodeValue(olive::NodeValue::kInt, static_cast(1))); - table.Push(olive::NodeValue(olive::NodeValue::kInt, static_cast(2))); + table.Push( + olive::NodeValue(olive::NodeValue::kInt, static_cast(1))); + table.Push( + olive::NodeValue(olive::NodeValue::kInt, static_cast(2))); olive::NodeValue taken = table.Take(olive::NodeValue::kInt); EXPECT_EQ(taken.toInt(), 2); @@ -120,7 +126,8 @@ TEST(NodeValueTable, TakeRemovesValue) TEST(NodeValueTable, ClearEmptiesTable) { olive::NodeValueTable table; - table.Push(olive::NodeValue(olive::NodeValue::kText, QStringLiteral("hello"))); + table.Push( + olive::NodeValue(olive::NodeValue::kText, QStringLiteral("hello"))); table.Clear(); EXPECT_TRUE(table.isEmpty()); EXPECT_EQ(table.Count(), 0); diff --git a/tests/gtest/opengl_readback_guard_test.cpp b/tests/gtest/opengl_readback_guard_test.cpp index 295940c03..742f0c7f6 100644 --- a/tests/gtest/opengl_readback_guard_test.cpp +++ b/tests/gtest/opengl_readback_guard_test.cpp @@ -14,7 +14,8 @@ TEST(OpenGLRenderer, DownloadFromTextureWithoutCurrentContext) QOpenGLContext context; if (!context.create()) { - GTEST_SKIP() << "Skipping OpenGL test because no context can be created"; + GTEST_SKIP() + << "Skipping OpenGL test because no context can be created"; } ASSERT_EQ(QOpenGLContext::currentContext(), nullptr); @@ -26,8 +27,8 @@ TEST(OpenGLRenderer, DownloadFromTextureWithoutCurrentContext) olive::VideoParams::kInterlaceNone, 1); unsigned char buffer[4 * 4 * 4] = {}; - renderer.DownloadFromTexture(QVariant::fromValue(0), params, - buffer, 4 * 4); + renderer.DownloadFromTexture(QVariant::fromValue(0), params, buffer, + 4 * 4); EXPECT_EQ(QOpenGLContext::currentContext(), nullptr); } diff --git a/tests/gtest/plugin_format_conversion_test.cpp b/tests/gtest/plugin_format_conversion_test.cpp index 3d1ac5bee..d550d6e73 100644 --- a/tests/gtest/plugin_format_conversion_test.cpp +++ b/tests/gtest/plugin_format_conversion_test.cpp @@ -20,219 +20,236 @@ using namespace olive; using namespace olive::core; // Test helper to create AVFrame with specific format -static AVFramePtr CreateTestFrame(int width, int height, AVPixelFormat fmt, uint32_t fill_color = 0xFF804020) { - AVFramePtr frame = CreateAVFramePtr(); - frame->width = width; - frame->height = height; - frame->format = fmt; - - if (av_frame_get_buffer(frame.get(), 0) < 0) { - return nullptr; - } - - if (av_frame_make_writable(frame.get()) < 0) { - return nullptr; - } - - // Fill with test pattern - uint8_t r = (fill_color >> 24) & 0xFF; - uint8_t g = (fill_color >> 16) & 0xFF; - uint8_t b = (fill_color >> 8) & 0xFF; - uint8_t a = fill_color & 0xFF; - - if (fmt == AV_PIX_FMT_RGBA) { - for (int y = 0; y < height; ++y) { - uint8_t *row = frame->data[0] + y * frame->linesize[0]; - for (int x = 0; x < width; ++x) { - row[x * 4 + 0] = r; - row[x * 4 + 1] = g; - row[x * 4 + 2] = b; - row[x * 4 + 3] = a; - } - } - } else if (fmt == AV_PIX_FMT_RGBA64) { - uint16_t r16 = (r << 8) | r; - uint16_t g16 = (g << 8) | g; - uint16_t b16 = (b << 8) | b; - uint16_t a16 = (a << 8) | a; - for (int y = 0; y < height; ++y) { - uint16_t *row = reinterpret_cast(frame->data[0] + y * frame->linesize[0]); - for (int x = 0; x < width; ++x) { - row[x * 4 + 0] = r16; - row[x * 4 + 1] = g16; - row[x * 4 + 2] = b16; - row[x * 4 + 3] = a16; - } - } - } - - return frame; +static AVFramePtr CreateTestFrame(int width, int height, AVPixelFormat fmt, + uint32_t fill_color = 0xFF804020) +{ + AVFramePtr frame = CreateAVFramePtr(); + frame->width = width; + frame->height = height; + frame->format = fmt; + + if (av_frame_get_buffer(frame.get(), 0) < 0) { + return nullptr; + } + + if (av_frame_make_writable(frame.get()) < 0) { + return nullptr; + } + + // Fill with test pattern + uint8_t r = (fill_color >> 24) & 0xFF; + uint8_t g = (fill_color >> 16) & 0xFF; + uint8_t b = (fill_color >> 8) & 0xFF; + uint8_t a = fill_color & 0xFF; + + if (fmt == AV_PIX_FMT_RGBA) { + for (int y = 0; y < height; ++y) { + uint8_t *row = frame->data[0] + y * frame->linesize[0]; + for (int x = 0; x < width; ++x) { + row[x * 4 + 0] = r; + row[x * 4 + 1] = g; + row[x * 4 + 2] = b; + row[x * 4 + 3] = a; + } + } + } else if (fmt == AV_PIX_FMT_RGBA64) { + uint16_t r16 = (r << 8) | r; + uint16_t g16 = (g << 8) | g; + uint16_t b16 = (b << 8) | b; + uint16_t a16 = (a << 8) | a; + for (int y = 0; y < height; ++y) { + uint16_t *row = reinterpret_cast( + frame->data[0] + y * frame->linesize[0]); + for (int x = 0; x < width; ++x) { + row[x * 4 + 0] = r16; + row[x * 4 + 1] = g16; + row[x * 4 + 2] = b16; + row[x * 4 + 3] = a16; + } + } + } + + return frame; } // Test U8 to U16 conversion -TEST(FormatConversion, U8ToU16) { - const int width = 10; - const int height = 10; - const uint32_t test_color = 0xFF804020; // ARGB: A=255, R=128, G=64, B=32 - - // Create U8 frame - AVFramePtr u8_frame = CreateTestFrame(width, height, AV_PIX_FMT_RGBA, test_color); - ASSERT_NE(u8_frame, nullptr); - - // Verify U8 values - uint8_t *first_pixel_u8 = u8_frame->data[0]; - EXPECT_EQ(first_pixel_u8[0], 0xFF); // R - EXPECT_EQ(first_pixel_u8[1], 0x80); // G - EXPECT_EQ(first_pixel_u8[2], 0x40); // B - EXPECT_EQ(first_pixel_u8[3], 0x20); // A - - // Create U16 frame - AVFramePtr u16_frame = CreateTestFrame(width, height, AV_PIX_FMT_RGBA64, test_color); - ASSERT_NE(u16_frame, nullptr); - - // Verify U16 values (should be U8 value repeated: 0xFF -> 0xFFFF, 0x80 -> 0x8080) - uint16_t *first_pixel_u16 = reinterpret_cast(u16_frame->data[0]); - EXPECT_EQ(first_pixel_u16[0], 0xFFFF); // R - EXPECT_EQ(first_pixel_u16[1], 0x8080); // G - EXPECT_EQ(first_pixel_u16[2], 0x4040); // B - EXPECT_EQ(first_pixel_u16[3], 0x2020); // A +TEST(FormatConversion, U8ToU16) +{ + const int width = 10; + const int height = 10; + const uint32_t test_color = 0xFF804020; // ARGB: A=255, R=128, G=64, B=32 + + // Create U8 frame + AVFramePtr u8_frame = + CreateTestFrame(width, height, AV_PIX_FMT_RGBA, test_color); + ASSERT_NE(u8_frame, nullptr); + + // Verify U8 values + uint8_t *first_pixel_u8 = u8_frame->data[0]; + EXPECT_EQ(first_pixel_u8[0], 0xFF); // R + EXPECT_EQ(first_pixel_u8[1], 0x80); // G + EXPECT_EQ(first_pixel_u8[2], 0x40); // B + EXPECT_EQ(first_pixel_u8[3], 0x20); // A + + // Create U16 frame + AVFramePtr u16_frame = + CreateTestFrame(width, height, AV_PIX_FMT_RGBA64, test_color); + ASSERT_NE(u16_frame, nullptr); + + // Verify U16 values (should be U8 value repeated: 0xFF -> 0xFFFF, 0x80 -> 0x8080) + uint16_t *first_pixel_u16 = + reinterpret_cast(u16_frame->data[0]); + EXPECT_EQ(first_pixel_u16[0], 0xFFFF); // R + EXPECT_EQ(first_pixel_u16[1], 0x8080); // G + EXPECT_EQ(first_pixel_u16[2], 0x4040); // B + EXPECT_EQ(first_pixel_u16[3], 0x2020); // A } // Test FFmpeg sws_scale for U16 to U8 conversion -TEST(FormatConversion, FFmpegU16ToU8) { - const int width = 10; - const int height = 10; - const uint32_t test_color = 0xFF804020; - - // Create U16 frame - AVFramePtr u16_frame = CreateTestFrame(width, height, AV_PIX_FMT_RGBA64, test_color); - ASSERT_NE(u16_frame, nullptr); - - // Create destination U8 frame - AVFramePtr u8_frame = CreateTestFrame(width, height, AV_PIX_FMT_RGBA, 0); - ASSERT_NE(u8_frame, nullptr); - - // Use sws_scale to convert - SwsContext *sws_ctx = sws_getContext( - width, height, AV_PIX_FMT_RGBA64, - width, height, AV_PIX_FMT_RGBA, - SWS_POINT, nullptr, nullptr, nullptr); - ASSERT_NE(sws_ctx, nullptr); - - sws_scale(sws_ctx, u16_frame->data, u16_frame->linesize, 0, height, - u8_frame->data, u8_frame->linesize); - sws_freeContext(sws_ctx); - - // Verify conversion (U16 0xFFFF -> U8 0xFF, 0x8080 -> ~0x80, etc.) - // Note: FFmpeg sws_scale has rounding offset, so values may be off by 1 - uint8_t *first_pixel = u8_frame->data[0]; - EXPECT_NEAR(first_pixel[0], 0xFF, 1); // R (255 vs 255) - EXPECT_NEAR(first_pixel[1], 0x80, 1); // G (128 vs 129) - EXPECT_NEAR(first_pixel[2], 0x40, 1); // B (64 vs 64) - EXPECT_NEAR(first_pixel[3], 0x20, 1); // A (32 vs 32) +TEST(FormatConversion, FFmpegU16ToU8) +{ + const int width = 10; + const int height = 10; + const uint32_t test_color = 0xFF804020; + + // Create U16 frame + AVFramePtr u16_frame = + CreateTestFrame(width, height, AV_PIX_FMT_RGBA64, test_color); + ASSERT_NE(u16_frame, nullptr); + + // Create destination U8 frame + AVFramePtr u8_frame = CreateTestFrame(width, height, AV_PIX_FMT_RGBA, 0); + ASSERT_NE(u8_frame, nullptr); + + // Use sws_scale to convert + SwsContext *sws_ctx = sws_getContext(width, height, AV_PIX_FMT_RGBA64, + width, height, AV_PIX_FMT_RGBA, + SWS_POINT, nullptr, nullptr, nullptr); + ASSERT_NE(sws_ctx, nullptr); + + sws_scale(sws_ctx, u16_frame->data, u16_frame->linesize, 0, height, + u8_frame->data, u8_frame->linesize); + sws_freeContext(sws_ctx); + + // Verify conversion (U16 0xFFFF -> U8 0xFF, 0x8080 -> ~0x80, etc.) + // Note: FFmpeg sws_scale has rounding offset, so values may be off by 1 + uint8_t *first_pixel = u8_frame->data[0]; + EXPECT_NEAR(first_pixel[0], 0xFF, 1); // R (255 vs 255) + EXPECT_NEAR(first_pixel[1], 0x80, 1); // G (128 vs 129) + EXPECT_NEAR(first_pixel[2], 0x40, 1); // B (64 vs 64) + EXPECT_NEAR(first_pixel[3], 0x20, 1); // A (32 vs 32) } // Test VideoParams to AVPixelFormat mapping -TEST(FormatConversion, VideoParamsToAVFormat) { - // U8 RGBA - VideoParams u8_rgba(320, 240, PixelFormat::U8, 4); - AVPixelFormat fmt_u8_rgba = FFmpegUtils::GetFFmpegPixelFormat(u8_rgba.format(), u8_rgba.channel_count()); - EXPECT_EQ(fmt_u8_rgba, AV_PIX_FMT_RGBA); - - // U16 RGBA - VideoParams u16_rgba(320, 240, PixelFormat::U16, 4); - AVPixelFormat fmt_u16_rgba = FFmpegUtils::GetFFmpegPixelFormat(u16_rgba.format(), u16_rgba.channel_count()); - EXPECT_EQ(fmt_u16_rgba, AV_PIX_FMT_RGBA64); - - // U8 RGB - VideoParams u8_rgb(320, 240, PixelFormat::U8, 3); - AVPixelFormat fmt_u8_rgb = FFmpegUtils::GetFFmpegPixelFormat(u8_rgb.format(), u8_rgb.channel_count()); - EXPECT_EQ(fmt_u8_rgb, AV_PIX_FMT_RGB24); - - // U16 RGB - VideoParams u16_rgb(320, 240, PixelFormat::U16, 3); - AVPixelFormat fmt_u16_rgb = FFmpegUtils::GetFFmpegPixelFormat(u16_rgb.format(), u16_rgb.channel_count()); - EXPECT_EQ(fmt_u16_rgb, AV_PIX_FMT_RGB48); +TEST(FormatConversion, VideoParamsToAVFormat) +{ + // U8 RGBA + VideoParams u8_rgba(320, 240, PixelFormat::U8, 4); + AVPixelFormat fmt_u8_rgba = FFmpegUtils::GetFFmpegPixelFormat( + u8_rgba.format(), u8_rgba.channel_count()); + EXPECT_EQ(fmt_u8_rgba, AV_PIX_FMT_RGBA); + + // U16 RGBA + VideoParams u16_rgba(320, 240, PixelFormat::U16, 4); + AVPixelFormat fmt_u16_rgba = FFmpegUtils::GetFFmpegPixelFormat( + u16_rgba.format(), u16_rgba.channel_count()); + EXPECT_EQ(fmt_u16_rgba, AV_PIX_FMT_RGBA64); + + // U8 RGB + VideoParams u8_rgb(320, 240, PixelFormat::U8, 3); + AVPixelFormat fmt_u8_rgb = FFmpegUtils::GetFFmpegPixelFormat( + u8_rgb.format(), u8_rgb.channel_count()); + EXPECT_EQ(fmt_u8_rgb, AV_PIX_FMT_RGB24); + + // U16 RGB + VideoParams u16_rgb(320, 240, PixelFormat::U16, 3); + AVPixelFormat fmt_u16_rgb = FFmpegUtils::GetFFmpegPixelFormat( + u16_rgb.format(), u16_rgb.channel_count()); + EXPECT_EQ(fmt_u16_rgb, AV_PIX_FMT_RGB48); } // Test row bytes calculation -TEST(FormatConversion, RowBytes) { - const int width = 320; - - // U8 RGBA: 4 bytes per pixel - EXPECT_EQ(width * 4, 1280); - - // U16 RGBA: 8 bytes per pixel - EXPECT_EQ(width * 8, 2560); - - // U8 RGB: 3 bytes per pixel - EXPECT_EQ(width * 3, 960); - - // U16 RGB: 6 bytes per pixel - EXPECT_EQ(width * 6, 1920); +TEST(FormatConversion, RowBytes) +{ + const int width = 320; + + // U8 RGBA: 4 bytes per pixel + EXPECT_EQ(width * 4, 1280); + + // U16 RGBA: 8 bytes per pixel + EXPECT_EQ(width * 8, 2560); + + // U8 RGB: 3 bytes per pixel + EXPECT_EQ(width * 3, 960); + + // U16 RGB: 6 bytes per pixel + EXPECT_EQ(width * 6, 1920); } // Test that linesize may differ from width * bpp due to alignment -TEST(FormatConversion, LinesizeAlignment) { - const int width = 10; - const int height = 10; - - AVFramePtr frame = CreateAVFramePtr(); - frame->width = width; - frame->height = height; - frame->format = AV_PIX_FMT_RGBA; - - ASSERT_EQ(av_frame_get_buffer(frame.get(), 0), 0); - - // linesize[0] should be at least width * 4 - EXPECT_GE(frame->linesize[0], width * 4); - - // linesize may be larger due to alignment (typically 32-byte aligned) - qDebug() << "Width:" << width << "Expected bytes:" << width * 4 - << "Actual linesize:" << frame->linesize[0]; +TEST(FormatConversion, LinesizeAlignment) +{ + const int width = 10; + const int height = 10; + + AVFramePtr frame = CreateAVFramePtr(); + frame->width = width; + frame->height = height; + frame->format = AV_PIX_FMT_RGBA; + + ASSERT_EQ(av_frame_get_buffer(frame.get(), 0), 0); + + // linesize[0] should be at least width * 4 + EXPECT_GE(frame->linesize[0], width * 4); + + // linesize may be larger due to alignment (typically 32-byte aligned) + qDebug() << "Width:" << width << "Expected bytes:" << width * 4 + << "Actual linesize:" << frame->linesize[0]; } // Test loading actual image file -TEST(FormatConversion, LoadImageFile) { - // Load the test image - QString img_path = QStringLiteral("%1/../tests/img.png").arg(QDir::currentPath()); - - AVFramePtr frame = CreateAVFramePtr(); - // Just create a simple test frame instead of loading an image - frame->width = 1920; - frame->height = 1080; - frame->format = AV_PIX_FMT_RGBA; - if (av_frame_get_buffer(frame.get(), 0) < 0) { - return; - } - // Fill with orange color (sunrise sky) - for (int y = 0; y < frame->height; ++y) { - uint8_t *row = frame->data[0] + y * frame->linesize[0]; - uint8_t r = 255; - uint8_t g = 128 + (y * 127) / frame->height; // Gradient from 128 to 255 - uint8_t b = 64; - uint8_t a = 255; - for (int x = 0; x < frame->width; ++x) { - row[x * 4 + 0] = r; - row[x * 4 + 1] = g; - row[x * 4 + 2] = b; - row[x * 4 + 3] = a; - } - } - ASSERT_NE(frame->data[0], nullptr) << "Failed to create test frame"; - - EXPECT_EQ(frame->width, 1920); - EXPECT_EQ(frame->height, 1080); - - // Check first pixel (top-left corner of the sunrise image) - // Based on the image, it should have some orange/pink color in the sky area - uint8_t *first_pixel = frame->data[0]; - qDebug() << "First pixel RGBA:" << first_pixel[0] << first_pixel[1] - << first_pixel[2] << first_pixel[3]; - - // The image is RGB, so we expect 3 channels - // First pixel should be non-black (sky area) - EXPECT_GT(first_pixel[0] + first_pixel[1] + first_pixel[2], 0); +TEST(FormatConversion, LoadImageFile) +{ + // Load the test image + QString img_path = + QStringLiteral("%1/../tests/img.png").arg(QDir::currentPath()); + + AVFramePtr frame = CreateAVFramePtr(); + // Just create a simple test frame instead of loading an image + frame->width = 1920; + frame->height = 1080; + frame->format = AV_PIX_FMT_RGBA; + if (av_frame_get_buffer(frame.get(), 0) < 0) { + return; + } + // Fill with orange color (sunrise sky) + for (int y = 0; y < frame->height; ++y) { + uint8_t *row = frame->data[0] + y * frame->linesize[0]; + uint8_t r = 255; + uint8_t g = 128 + (y * 127) / frame->height; // Gradient from 128 to 255 + uint8_t b = 64; + uint8_t a = 255; + for (int x = 0; x < frame->width; ++x) { + row[x * 4 + 0] = r; + row[x * 4 + 1] = g; + row[x * 4 + 2] = b; + row[x * 4 + 3] = a; + } + } + ASSERT_NE(frame->data[0], nullptr) << "Failed to create test frame"; + + EXPECT_EQ(frame->width, 1920); + EXPECT_EQ(frame->height, 1080); + + // Check first pixel (top-left corner of the sunrise image) + // Based on the image, it should have some orange/pink color in the sky area + uint8_t *first_pixel = frame->data[0]; + qDebug() << "First pixel RGBA:" << first_pixel[0] << first_pixel[1] + << first_pixel[2] << first_pixel[3]; + + // The image is RGB, so we expect 3 channels + // First pixel should be non-black (sky area) + EXPECT_GT(first_pixel[0] + first_pixel[1] + first_pixel[2], 0); } // Tests are registered with gtest, no main needed diff --git a/tests/gtest/plugin_ofx_integration_test.cpp b/tests/gtest/plugin_ofx_integration_test.cpp index 6a17bbb12..55d386a3c 100644 --- a/tests/gtest/plugin_ofx_integration_test.cpp +++ b/tests/gtest/plugin_ofx_integration_test.cpp @@ -15,7 +15,8 @@ extern "C" { #include "render/texture.h" #include "render/videoparams.h" -namespace { +namespace +{ olive::TexturePtr CreateSolidTexture(const olive::VideoParams ¶ms) { diff --git a/tests/gtest/plugin_ofx_misc_test.cpp b/tests/gtest/plugin_ofx_misc_test.cpp index 17d03b2e5..c6461beb6 100644 --- a/tests/gtest/plugin_ofx_misc_test.cpp +++ b/tests/gtest/plugin_ofx_misc_test.cpp @@ -27,22 +27,26 @@ extern "C" { #include "render/texture.h" #include "render/videoparams.h" -namespace olive { -namespace plugin { -namespace test { +namespace olive +{ +namespace plugin +{ +namespace test +{ -namespace { +namespace +{ // Helper to create a test texture with solid color // For U8: fill_value is 0-255 // For U16: fill_value is 0-65535 // For Float: fill_value is 0.0-1.0 mapped to bytes -template +template TexturePtr CreateSolidTextureT(const VideoParams ¶ms, T fill_value) { AVFramePtr frame = CreateAVFramePtr(); - frame->format = FFmpegUtils::GetFFmpegPixelFormat( - params.format(), params.channel_count()); + frame->format = FFmpegUtils::GetFFmpegPixelFormat(params.format(), + params.channel_count()); frame->width = params.width(); frame->height = params.height(); if (frame->format == AV_PIX_FMT_NONE) { @@ -57,7 +61,7 @@ TexturePtr CreateSolidTextureT(const VideoParams ¶ms, T fill_value) const int linesize = frame->linesize[0]; for (int y = 0; y < frame->height; ++y) { - T *row = reinterpret_cast(frame->data[0] + y * linesize); + T *row = reinterpret_cast(frame->data[0] + y * linesize); for (int x = 0; x < frame->width * params.channel_count(); ++x) { row[x] = fill_value; } @@ -68,17 +72,21 @@ TexturePtr CreateSolidTextureT(const VideoParams ¶ms, T fill_value) return texture; } -TexturePtr CreateSolidTexture(const VideoParams ¶ms, uint32_t fill_value = 0x7f) +TexturePtr CreateSolidTexture(const VideoParams ¶ms, + uint32_t fill_value = 0x7f) { // Choose type based on pixel format switch (params.format()) { case core::PixelFormat::U8: - return CreateSolidTextureT(params, static_cast(fill_value)); + return CreateSolidTextureT(params, + static_cast(fill_value)); case core::PixelFormat::U16: - return CreateSolidTextureT(params, static_cast(fill_value)); + return CreateSolidTextureT(params, + static_cast(fill_value)); case core::PixelFormat::F16: case core::PixelFormat::F32: - return CreateSolidTextureT(params, static_cast(fill_value) / 255.0f); + return CreateSolidTextureT( + params, static_cast(fill_value) / 255.0f); default: return nullptr; } @@ -87,12 +95,12 @@ TexturePtr CreateSolidTexture(const VideoParams ¶ms, uint32_t fill_value = 0 // Helper to create a gradient texture // For U8: gradient is 0-255 per byte // For Float: gradient is 0.0-1.0 per component -template +template TexturePtr CreateGradientTextureT(const VideoParams ¶ms, float scale) { AVFramePtr frame = CreateAVFramePtr(); - frame->format = FFmpegUtils::GetFFmpegPixelFormat( - params.format(), params.channel_count()); + frame->format = FFmpegUtils::GetFFmpegPixelFormat(params.format(), + params.channel_count()); frame->width = params.width(); frame->height = params.height(); if (frame->format == AV_PIX_FMT_NONE) { @@ -107,7 +115,7 @@ TexturePtr CreateGradientTextureT(const VideoParams ¶ms, float scale) const int linesize = frame->linesize[0]; for (int y = 0; y < frame->height; ++y) { - T *row = reinterpret_cast(frame->data[0] + y * linesize); + T *row = reinterpret_cast(frame->data[0] + y * linesize); T value = static_cast((y * scale) / frame->height); for (int x = 0; x < frame->width * params.channel_count(); ++x) { row[x] = value; @@ -135,17 +143,16 @@ TexturePtr CreateGradientTexture(const VideoParams ¶ms) } // Helper function to find and render a plugin -bool RenderPlugin(const std::string &plugin_id, - const VideoParams ¶ms, - const NodeValueRow &inputs, - bool verbose = false) +bool RenderPlugin(const std::string &plugin_id, const VideoParams ¶ms, + const NodeValueRow &inputs, bool verbose = false) { auto *cache = OFX::Host::PluginCache::getPluginCache(); if (!cache) { - if (verbose) std::cerr << "Plugin cache not available" << std::endl; + if (verbose) + std::cerr << "Plugin cache not available" << std::endl; return false; } - + OFX::Host::Plugin *found = nullptr; for (auto *plug : cache->getPlugins()) { if (plug && plug->getIdentifier() == plugin_id) { @@ -153,66 +160,72 @@ bool RenderPlugin(const std::string &plugin_id, break; } } - + if (!found) { - if (verbose) std::cerr << "Plugin not found: " << plugin_id << std::endl; + if (verbose) + std::cerr << "Plugin not found: " << plugin_id << std::endl; return false; } - - auto *image_effect = dynamic_cast(found); + + auto *image_effect = + dynamic_cast(found); if (!image_effect) { - if (verbose) std::cerr << "Not an image effect plugin" << std::endl; + if (verbose) + std::cerr << "Not an image effect plugin" << std::endl; return false; } - + const auto &contexts = image_effect->getContexts(); std::string context = kOfxImageEffectContextFilter; if (!contexts.empty() && contexts.find(kOfxImageEffectContextFilter) == contexts.end()) { context = *contexts.begin(); } - + OFX::Host::ImageEffect::Instance *instance = image_effect->createInstance(context, nullptr); if (!instance) { - if (verbose) std::cerr << "Failed to create instance" << std::endl; + if (verbose) + std::cerr << "Failed to create instance" << std::endl; return false; } - + auto *olive_instance = dynamic_cast(instance); if (!olive_instance) { - if (verbose) std::cerr << "Not an OlivePluginInstance" << std::endl; + if (verbose) + std::cerr << "Not an OlivePluginInstance" << std::endl; return false; } - + olive_instance->setVideoParam(params); - + PluginJob job(instance, nullptr, inputs); TexturePtr output = std::make_shared(params); - + PluginRenderer renderer(nullptr); renderer.RenderPlugin(nullptr, job, output, params, true, false); - + bool has_frame = output->frame() != nullptr; if (!has_frame && verbose) { std::cerr << "Render produced no output frame" << std::endl; } - + return has_frame; } // Skip check function -bool ShouldSkipTest() { +bool ShouldSkipTest() +{ const char *itest = std::getenv("OAK_OFX_ITEST"); if (!itest || std::string(itest) != "1") { return true; } - + const char *path = std::getenv("OAK_OFX_PLUGIN_PATH"); if (!path || std::string(path).empty()) { return true; } - + static bool plugins_loaded = false; if (!plugins_loaded) { QString raw = QString::fromUtf8(path); @@ -223,7 +236,7 @@ bool ShouldSkipTest() { } plugins_loaded = true; } - + return false; } @@ -238,16 +251,16 @@ TEST(PluginMisc, MirrorHorizontal) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + // Mirror plugin typically works with 8-bit VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateGradientTexture(params); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + bool result = RenderPlugin("net.sf.openfx.Mirror", params, row, true); EXPECT_TRUE(result) << "Mirror plugin should produce output"; } @@ -261,16 +274,17 @@ TEST(PluginMisc, TransformTranslate) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - - bool result = RenderPlugin("net.sf.openfx.TransformPlugin", params, row, true); + + bool result = + RenderPlugin("net.sf.openfx.TransformPlugin", params, row, true); EXPECT_TRUE(result) << "Transform plugin should produce output"; } @@ -283,16 +297,17 @@ TEST(PluginMisc, ColorCorrect) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - - bool result = RenderPlugin("net.sf.openfx.ColorCorrectPlugin", params, row, true); + + bool result = + RenderPlugin("net.sf.openfx.ColorCorrectPlugin", params, row, true); EXPECT_TRUE(result) << "ColorCorrect plugin should produce output"; } @@ -301,16 +316,17 @@ TEST(PluginMisc, Saturation) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - - bool result = RenderPlugin("net.sf.openfx.SaturationPlugin", params, row, true); + + bool result = + RenderPlugin("net.sf.openfx.SaturationPlugin", params, row, true); EXPECT_TRUE(result) << "Saturation plugin should produce output"; } @@ -323,15 +339,15 @@ TEST(PluginMisc, GaussianBlur) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + // Use CImgBlur from the available plugin list bool result = RenderPlugin("net.sf.cimg.CImgBlur", params, row, true); EXPECT_TRUE(result) << "GaussianBlur plugin should produce output"; @@ -346,15 +362,15 @@ TEST(PluginMisc, Crop) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + bool result = RenderPlugin("net.sf.openfx.CropPlugin", params, row, true); EXPECT_TRUE(result) << "Crop plugin should produce output"; } @@ -364,15 +380,15 @@ TEST(PluginMisc, Grade) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + bool result = RenderPlugin("net.sf.openfx.GradePlugin", params, row, true); EXPECT_TRUE(result) << "Grade plugin should produce output"; } @@ -386,16 +402,17 @@ TEST(PluginMisc, NonExistentPlugin) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - - bool result = RenderPlugin("net.sf.openfx.NonExistentPlugin", params, row, true); + + bool result = + RenderPlugin("net.sf.openfx.NonExistentPlugin", params, row, true); EXPECT_FALSE(result) << "Non-existent plugin should fail gracefully"; } @@ -408,15 +425,15 @@ TEST(PluginMisc, CImgSharpen) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + bool result = RenderPlugin("net.sf.cimg.CImgSharpen", params, row, true); EXPECT_TRUE(result) << "CImgSharpen plugin should produce output"; } @@ -426,15 +443,15 @@ TEST(PluginMisc, CImgDenoise) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + bool result = RenderPlugin("net.sf.cimg.CImgDenoise", params, row, true); EXPECT_TRUE(result) << "CImgDenoise plugin should produce output"; } @@ -444,15 +461,15 @@ TEST(PluginMisc, CImgBilateral) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + bool result = RenderPlugin("net.sf.cimg.CImgBilateral", params, row, true); EXPECT_TRUE(result) << "CImgBilateral plugin should produce output"; } @@ -466,17 +483,16 @@ TEST(PluginMisc, MergeOver) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - row.insert(QStringLiteral("Bg"), - NodeValue(NodeValue::kTexture, input)); - + row.insert(QStringLiteral("Bg"), NodeValue(NodeValue::kTexture, input)); + bool result = RenderPlugin("net.sf.openfx.MergePlugin", params, row, true); EXPECT_TRUE(result) << "Merge plugin should produce output"; } @@ -490,15 +506,15 @@ TEST(PluginMisc, Keyer) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + bool result = RenderPlugin("net.sf.openfx.KeyerPlugin", params, row, true); EXPECT_TRUE(result) << "Keyer plugin should produce output"; } @@ -512,16 +528,17 @@ TEST(PluginMisc, CornerPin) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - - bool result = RenderPlugin("net.sf.openfx.CornerPinPlugin", params, row, true); + + bool result = + RenderPlugin("net.sf.openfx.CornerPinPlugin", params, row, true); EXPECT_TRUE(result) << "CornerPin plugin should produce output"; } @@ -530,16 +547,17 @@ TEST(PluginMisc, LensDistortion) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - - bool result = RenderPlugin("net.sf.openfx.LensDistortion", params, row, true); + + bool result = + RenderPlugin("net.sf.openfx.LensDistortion", params, row, true); EXPECT_TRUE(result) << "LensDistortion plugin should produce output"; } @@ -552,15 +570,15 @@ TEST(PluginMisc, Invert) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + bool result = RenderPlugin("net.sf.openfx.Invert", params, row, true); EXPECT_TRUE(result) << "Invert plugin should produce output"; } @@ -570,15 +588,15 @@ TEST(PluginMisc, Gamma) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr input = CreateSolidTexture(params, 0x80); ASSERT_NE(input, nullptr); - + NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, input)); - + bool result = RenderPlugin("net.sf.openfx.GammaPlugin", params, row, true); EXPECT_TRUE(result) << "Gamma plugin should produce output"; } @@ -592,12 +610,12 @@ TEST(PluginMisc, ListAvailablePlugins) if (ShouldSkipTest()) { GTEST_SKIP() << "OFX integration test not enabled"; } - + auto *cache = OFX::Host::PluginCache::getPluginCache(); if (!cache) { GTEST_SKIP() << "Plugin cache not available"; } - + std::cout << "\nAvailable OFX plugins:\n"; for (auto *plug : cache->getPlugins()) { if (plug) { @@ -605,29 +623,31 @@ TEST(PluginMisc, ListAvailablePlugins) } } std::cout << std::endl; - + SUCCEED(); } TEST(PluginMisc, CImgBilateralGuided_MultiInput) { - if (ShouldSkipTest()) GTEST_SKIP() << "OFX integration test not enabled"; + if (ShouldSkipTest()) + GTEST_SKIP() << "OFX integration test not enabled"; // CImgBilateralGuided is a multi-input plugin (Source + Guide). // This test verifies that connecting both inputs does not trigger // the frame-rate mismatch exception in setupClipPreferencesArgs. VideoParams params(320, 240, core::PixelFormat::F32, 4); TexturePtr source = CreateSolidTexture(params, 0x80); - TexturePtr guide = CreateSolidTexture(params, 0x40); + TexturePtr guide = CreateSolidTexture(params, 0x40); ASSERT_NE(source, nullptr); ASSERT_NE(guide, nullptr); NodeValueRow row; row.insert(QString::fromStdString(kOfxImageEffectSimpleSourceClipName), NodeValue(NodeValue::kTexture, source)); - row.insert(QStringLiteral("Guide"), - NodeValue(NodeValue::kTexture, guide)); - bool result = RenderPlugin("net.sf.cimg.CImgBilateralGuided", params, row, true); - EXPECT_TRUE(result) << "CImgBilateralGuided plugin should produce output with both Source and Guide connected"; + row.insert(QStringLiteral("Guide"), NodeValue(NodeValue::kTexture, guide)); + bool result = + RenderPlugin("net.sf.cimg.CImgBilateralGuided", params, row, true); + EXPECT_TRUE(result) + << "CImgBilateralGuided plugin should produce output with both Source and Guide connected"; } } // namespace test diff --git a/tests/gtest/plugin_render_pipeline_test.cpp b/tests/gtest/plugin_render_pipeline_test.cpp index 8cf406f23..48e917892 100644 --- a/tests/gtest/plugin_render_pipeline_test.cpp +++ b/tests/gtest/plugin_render_pipeline_test.cpp @@ -6,7 +6,8 @@ #include "render/texture.h" #include "render/videoparams.h" -namespace { +namespace +{ class PluginJobTraverser : public olive::NodeTraverser { public: diff --git a/tests/gtest/plugin_renderer_readback_test.cpp b/tests/gtest/plugin_renderer_readback_test.cpp index 054811942..959d46f13 100644 --- a/tests/gtest/plugin_renderer_readback_test.cpp +++ b/tests/gtest/plugin_renderer_readback_test.cpp @@ -8,9 +8,8 @@ TEST(PluginRendererReadback, BytesToPixels) olive::core::rational(1, 1), olive::VideoParams::kInterlaceNone, 1); - const int bytes_per_pixel = - olive::VideoParams::GetBytesPerPixel(params.format(), - params.channel_count()); + const int bytes_per_pixel = olive::VideoParams::GetBytesPerPixel( + params.format(), params.channel_count()); ASSERT_EQ(bytes_per_pixel, 4); EXPECT_EQ(olive::plugin::detail::BytesToPixels(64, params), 16); diff --git a/tests/gtest/plugin_smoke_test.cpp b/tests/gtest/plugin_smoke_test.cpp index 0b7076230..588b7ee05 100644 --- a/tests/gtest/plugin_smoke_test.cpp +++ b/tests/gtest/plugin_smoke_test.cpp @@ -13,6 +13,10 @@ #include +#include +#include +#include + #include #include @@ -43,55 +47,58 @@ extern "C" { #include } -namespace olive { -namespace plugin { -namespace test { +namespace olive +{ +namespace plugin +{ +namespace test +{ // ============================================================================ // Helper Functions // ============================================================================ static VideoParams MakeVideoParams(int width, int height, - core::PixelFormat format, - int channels, - bool premultiplied = false) + core::PixelFormat format, int channels, + bool premultiplied = false) { - VideoParams params; - params.set_width(width); - params.set_height(height); - params.set_format(format); - params.set_channel_count(channels); - params.set_premultiplied_alpha(premultiplied); - params.set_pixel_aspect_ratio(core::rational(1, 1)); - params.set_frame_rate(core::rational(30, 1)); - return params; + VideoParams params; + params.set_width(width); + params.set_height(height); + params.set_format(format); + params.set_channel_count(channels); + params.set_premultiplied_alpha(premultiplied); + params.set_pixel_aspect_ratio(core::rational(1, 1)); + params.set_frame_rate(core::rational(30, 1)); + return params; } -static TexturePtr CreateTestTexture(const VideoParams ¶ms, uint8_t fill_value = 0x7f) +static TexturePtr CreateTestTexture(const VideoParams ¶ms, + uint8_t fill_value = 0x7f) { - AVFramePtr frame = CreateAVFramePtr(); - frame->format = FFmpegUtils::GetFFmpegPixelFormat( - params.format(), params.channel_count()); - frame->width = params.width(); - frame->height = params.height(); - if (frame->format == AV_PIX_FMT_NONE) { - return nullptr; - } - if (av_frame_get_buffer(frame.get(), 0) < 0) { - return nullptr; - } - if (av_frame_make_writable(frame.get()) < 0) { - return nullptr; - } + AVFramePtr frame = CreateAVFramePtr(); + frame->format = FFmpegUtils::GetFFmpegPixelFormat(params.format(), + params.channel_count()); + frame->width = params.width(); + frame->height = params.height(); + if (frame->format == AV_PIX_FMT_NONE) { + return nullptr; + } + if (av_frame_get_buffer(frame.get(), 0) < 0) { + return nullptr; + } + if (av_frame_make_writable(frame.get()) < 0) { + return nullptr; + } - const int linesize = frame->linesize[0]; - for (int y = 0; y < frame->height; ++y) { - std::memset(frame->data[0] + y * linesize, fill_value, linesize); - } + const int linesize = frame->linesize[0]; + for (int y = 0; y < frame->height; ++y) { + std::memset(frame->data[0] + y * linesize, fill_value, linesize); + } - TexturePtr texture = std::make_shared(params); - texture->handleFrame(frame); - return texture; + TexturePtr texture = std::make_shared(params); + texture->handleFrame(frame); + return texture; } // ============================================================================ @@ -100,25 +107,22 @@ static TexturePtr CreateTestTexture(const VideoParams ¶ms, uint8_t fill_valu TEST(PluginSmoke, HostSingletonExists) { - // Verify that the plugin cache can be accessed - auto *cache = OFX::Host::PluginCache::getPluginCache(); - EXPECT_NE(cache, nullptr); + // Verify that the plugin cache can be accessed + auto *cache = OFX::Host::PluginCache::getPluginCache(); + EXPECT_NE(cache, nullptr); } TEST(PluginSmoke, LoadPluginsEmptyPathNoCrash) { - // Loading plugins from empty path should not crash - EXPECT_NO_THROW({ - loadPlugins(QString()); - }); + // Loading plugins from empty path should not crash + EXPECT_NO_THROW({ loadPlugins(QString()); }); } TEST(PluginSmoke, LoadPluginsNonExistentPathNoCrash) { - // Loading plugins from non-existent path should not crash - EXPECT_NO_THROW({ - loadPlugins(QStringLiteral("/nonexistent/path/to/plugins")); - }); + // Loading plugins from non-existent path should not crash + EXPECT_NO_THROW( + { loadPlugins(QStringLiteral("/nonexistent/path/to/plugins")); }); } // ============================================================================ @@ -127,79 +131,87 @@ TEST(PluginSmoke, LoadPluginsNonExistentPathNoCrash) TEST(PluginSmokeClip, OutputClipProperties) { - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - VideoParams params = MakeVideoParams(1920, 1080, core::PixelFormat::U8, 4, true); - params.set_pixel_aspect_ratio(core::rational(16, 9)); - params.set_frame_rate(core::rational(24, 1)); - params.set_start_time(0); - params.set_duration(100); + OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); + VideoParams params = + MakeVideoParams(1920, 1080, core::PixelFormat::U8, 4, true); + params.set_pixel_aspect_ratio(core::rational(16, 9)); + params.set_frame_rate(core::rational(24, 1)); + params.set_start_time(0); + params.set_duration(100); - OliveClipInstance clip(nullptr, desc, params); + OliveClipInstance clip(nullptr, desc, params); - // Test bit depth mapping - EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthByte); - - // Test component mapping - EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGBA); - - // Test premultiplication - EXPECT_EQ(clip.getPremult(), kOfxImagePreMultiplied); - - // Test aspect ratio - EXPECT_DOUBLE_EQ(clip.getAspectRatio(), 16.0 / 9.0); - - // Test frame rate - EXPECT_DOUBLE_EQ(clip.getFrameRate(), 24.0); - - // Test frame range - double start_frame = 0.0, end_frame = 0.0; - clip.getFrameRange(start_frame, end_frame); - EXPECT_DOUBLE_EQ(start_frame, 0.0); - EXPECT_DOUBLE_EQ(end_frame, 100.0 * 24.0); // duration * frame_rate + // Test bit depth mapping + EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthByte); + + // Test component mapping + EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGBA); + + // Test premultiplication + EXPECT_EQ(clip.getPremult(), kOfxImagePreMultiplied); + + // Test aspect ratio + EXPECT_DOUBLE_EQ(clip.getAspectRatio(), 16.0 / 9.0); + + // Test frame rate + EXPECT_DOUBLE_EQ(clip.getFrameRate(), 24.0); + + // Test frame range + double start_frame = 0.0, end_frame = 0.0; + clip.getFrameRange(start_frame, end_frame); + EXPECT_DOUBLE_EQ(start_frame, 0.0); + EXPECT_DOUBLE_EQ(end_frame, 100.0 * 24.0); // duration * frame_rate } TEST(PluginSmokeClip, ClipDifferentPixelFormats) { - // Test U16 format - { - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - VideoParams params = MakeVideoParams(640, 480, core::PixelFormat::U16, 3, false); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthShort); - EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGB); - EXPECT_EQ(clip.getPremult(), kOfxImageUnPreMultiplied); - } + // Test U16 format + { + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + VideoParams params = + MakeVideoParams(640, 480, core::PixelFormat::U16, 3, false); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthShort); + EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGB); + EXPECT_EQ(clip.getPremult(), kOfxImageUnPreMultiplied); + } - // Test F16 format - { - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - VideoParams params = MakeVideoParams(640, 480, core::PixelFormat::F16, 4, true); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthHalf); - EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGBA); - EXPECT_EQ(clip.getPremult(), kOfxImagePreMultiplied); - } + // Test F16 format + { + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + VideoParams params = + MakeVideoParams(640, 480, core::PixelFormat::F16, 4, true); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthHalf); + EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGBA); + EXPECT_EQ(clip.getPremult(), kOfxImagePreMultiplied); + } - // Test F32 format - { - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - VideoParams params = MakeVideoParams(640, 480, core::PixelFormat::F32, 4, false); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthFloat); - EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGBA); - EXPECT_EQ(clip.getPremult(), kOfxImageUnPreMultiplied); - } + // Test F32 format + { + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + VideoParams params = + MakeVideoParams(640, 480, core::PixelFormat::F32, 4, false); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthFloat); + EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGBA); + EXPECT_EQ(clip.getPremult(), kOfxImageUnPreMultiplied); + } } TEST(PluginSmokeClip, SourceClipNotConnected) { - OFX::Host::ImageEffect::ClipDescriptor desc("Source"); - VideoParams params = MakeVideoParams(320, 240, core::PixelFormat::U8, 4, false); - OliveClipInstance clip(nullptr, desc, params); + OFX::Host::ImageEffect::ClipDescriptor desc("Source"); + VideoParams params = + MakeVideoParams(320, 240, core::PixelFormat::U8, 4, false); + OliveClipInstance clip(nullptr, desc, params); - // Source clips should not be connected (no input provided in test) - EXPECT_FALSE(clip.getConnected()); - EXPECT_FALSE(clip.getContinuousSamples()); + // Source clips should not be connected (no input provided in test) + EXPECT_FALSE(clip.getConnected()); + EXPECT_FALSE(clip.getContinuousSamples()); } // ============================================================================ @@ -208,76 +220,79 @@ TEST(PluginSmokeClip, SourceClipNotConnected) TEST(PluginSmokeImage, BasicAllocation) { - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - VideoParams params = MakeVideoParams(64, 64, core::PixelFormat::U8, 4, true); - OliveClipInstance clip(nullptr, desc, params); + OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); + VideoParams params = + MakeVideoParams(64, 64, core::PixelFormat::U8, 4, true); + OliveClipInstance clip(nullptr, desc, params); - Image image(clip); - OfxRectI bounds = {0, 0, 64, 64}; - OfxRectI rod = bounds; - image.AllocateFromParams(params, bounds, rod, true); + Image image(clip); + OfxRectI bounds = { 0, 0, 64, 64 }; + OfxRectI rod = bounds; + image.AllocateFromParams(params, bounds, rod, true); - EXPECT_NE(image.data(), nullptr); - EXPECT_EQ(image.width(), 64); - EXPECT_EQ(image.height(), 64); - EXPECT_EQ(image.row_bytes(), 64 * 4); - EXPECT_EQ(image.pixel_format(), core::PixelFormat::U8); - EXPECT_EQ(image.channel_count(), 4); + EXPECT_NE(image.data(), nullptr); + EXPECT_EQ(image.width(), 64); + EXPECT_EQ(image.height(), 64); + EXPECT_EQ(image.row_bytes(), 64 * 4); + EXPECT_EQ(image.pixel_format(), core::PixelFormat::U8); + EXPECT_EQ(image.channel_count(), 4); } TEST(PluginSmokeImage, ClearOnAllocate) { - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - VideoParams params = MakeVideoParams(16, 16, core::PixelFormat::U8, 4, false); - OliveClipInstance clip(nullptr, desc, params); + OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); + VideoParams params = + MakeVideoParams(16, 16, core::PixelFormat::U8, 4, false); + OliveClipInstance clip(nullptr, desc, params); - Image image(clip); - OfxRectI bounds = {0, 0, 16, 16}; - OfxRectI rod = bounds; - - // Allocate without clear - image.AllocateFromParams(params, bounds, rod, false); - ASSERT_NE(image.data(), nullptr); - - // Write some data - std::memset(image.data(), 0xAB, image.row_bytes() * image.height()); - - // Reallocate with clear - image.AllocateFromParams(params, bounds, rod, true); - - // Verify data is cleared - bool all_zero = true; - for (int y = 0; y < 16 && all_zero; ++y) { - for (int x = 0; x < 16 * 4; ++x) { - if (image.data()[y * image.row_bytes() + x] != 0) { - all_zero = false; - break; - } - } - } - EXPECT_TRUE(all_zero); + Image image(clip); + OfxRectI bounds = { 0, 0, 16, 16 }; + OfxRectI rod = bounds; + + // Allocate without clear + image.AllocateFromParams(params, bounds, rod, false); + ASSERT_NE(image.data(), nullptr); + + // Write some data + std::memset(image.data(), 0xAB, image.row_bytes() * image.height()); + + // Reallocate with clear + image.AllocateFromParams(params, bounds, rod, true); + + // Verify data is cleared + bool all_zero = true; + for (int y = 0; y < 16 && all_zero; ++y) { + for (int x = 0; x < 16 * 4; ++x) { + if (image.data()[y * image.row_bytes() + x] != 0) { + all_zero = false; + break; + } + } + } + EXPECT_TRUE(all_zero); } TEST(PluginSmokeImage, ResizeOnAllocate) { - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - VideoParams params = MakeVideoParams(32, 32, core::PixelFormat::U8, 4, false); - OliveClipInstance clip(nullptr, desc, params); + OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); + VideoParams params = + MakeVideoParams(32, 32, core::PixelFormat::U8, 4, false); + OliveClipInstance clip(nullptr, desc, params); - Image image(clip); - OfxRectI bounds = {0, 0, 32, 32}; - OfxRectI rod = bounds; - image.AllocateFromParams(params, bounds, rod, true); - - EXPECT_EQ(image.width(), 32); - EXPECT_EQ(image.height(), 32); + Image image(clip); + OfxRectI bounds = { 0, 0, 32, 32 }; + OfxRectI rod = bounds; + image.AllocateFromParams(params, bounds, rod, true); - // Resize to smaller - OfxRectI new_bounds = {0, 0, 16, 16}; - image.EnsureAllocatedFromParams(params, new_bounds, rod, false); - - EXPECT_EQ(image.width(), 16); - EXPECT_EQ(image.height(), 16); + EXPECT_EQ(image.width(), 32); + EXPECT_EQ(image.height(), 32); + + // Resize to smaller + OfxRectI new_bounds = { 0, 0, 16, 16 }; + image.EnsureAllocatedFromParams(params, new_bounds, rod, false); + + EXPECT_EQ(image.width(), 16); + EXPECT_EQ(image.height(), 16); } // ============================================================================ @@ -286,212 +301,212 @@ TEST(PluginSmokeImage, ResizeOnAllocate) TEST(PluginSmokeParam, IntegerNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeInteger, "TestInt"); - IntegerInstance instance(nullptr, desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeInteger, "TestInt"); + IntegerInstance instance(nullptr, desc); - // Default value should be 0 - int value = -1; - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_EQ(value, 0); + // Default value should be 0 + int value = -1; + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_EQ(value, 0); - // Set value - EXPECT_EQ(instance.set(42), kOfxStatOK); - - // Get value back - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_EQ(value, 42); + // Set value + EXPECT_EQ(instance.set(42), kOfxStatOK); - // Get at time (should return same value without node) - int time_value = -1; - EXPECT_EQ(instance.get(1.0, time_value), kOfxStatOK); - EXPECT_EQ(time_value, 42); + // Get value back + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_EQ(value, 42); + + // Get at time (should return same value without node) + int time_value = -1; + EXPECT_EQ(instance.get(1.0, time_value), kOfxStatOK); + EXPECT_EQ(time_value, 42); } TEST(PluginSmokeParam, DoubleNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeDouble, "TestDouble"); - DoubleInstance instance(nullptr, "TestDouble", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeDouble, "TestDouble"); + DoubleInstance instance(nullptr, "TestDouble", desc); - double value = -1.0; - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_DOUBLE_EQ(value, 0.0); + double value = -1.0; + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_DOUBLE_EQ(value, 0.0); - EXPECT_EQ(instance.set(3.14159), kOfxStatOK); - - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_DOUBLE_EQ(value, 3.14159); + EXPECT_EQ(instance.set(3.14159), kOfxStatOK); + + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_DOUBLE_EQ(value, 3.14159); } TEST(PluginSmokeParam, BooleanNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeBoolean, "TestBool"); - BooleanInstance instance(nullptr, "TestBool", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeBoolean, "TestBool"); + BooleanInstance instance(nullptr, "TestBool", desc); - bool value = true; // Start with opposite - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_FALSE(value); + bool value = true; // Start with opposite + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_FALSE(value); - EXPECT_EQ(instance.set(true), kOfxStatOK); - - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_TRUE(value); + EXPECT_EQ(instance.set(true), kOfxStatOK); + + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_TRUE(value); } TEST(PluginSmokeParam, ChoiceNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeChoice, "TestChoice"); - ChoiceInstance instance(nullptr, "TestChoice", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeChoice, "TestChoice"); + ChoiceInstance instance(nullptr, "TestChoice", desc); - int value = -1; - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_EQ(value, 0); + int value = -1; + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_EQ(value, 0); - EXPECT_EQ(instance.set(2), kOfxStatOK); - - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_EQ(value, 2); + EXPECT_EQ(instance.set(2), kOfxStatOK); + + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_EQ(value, 2); } TEST(PluginSmokeParam, RGBANullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeRGBA, "TestColor"); - RGBAInstance instance(nullptr, "TestColor", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeRGBA, "TestColor"); + RGBAInstance instance(nullptr, "TestColor", desc); - double r = 0, g = 0, b = 0, a = 0; - EXPECT_EQ(instance.get(r, g, b, a), kOfxStatOK); - EXPECT_DOUBLE_EQ(r, 0.0); - EXPECT_DOUBLE_EQ(g, 0.0); - EXPECT_DOUBLE_EQ(b, 0.0); - EXPECT_DOUBLE_EQ(a, 0.0); + double r = 0, g = 0, b = 0, a = 0; + EXPECT_EQ(instance.get(r, g, b, a), kOfxStatOK); + EXPECT_DOUBLE_EQ(r, 0.0); + EXPECT_DOUBLE_EQ(g, 0.0); + EXPECT_DOUBLE_EQ(b, 0.0); + EXPECT_DOUBLE_EQ(a, 0.0); - EXPECT_EQ(instance.set(1.0, 0.5, 0.25, 1.0), kOfxStatOK); - - EXPECT_EQ(instance.get(r, g, b, a), kOfxStatOK); - EXPECT_DOUBLE_EQ(r, 1.0); - EXPECT_DOUBLE_EQ(g, 0.5); - EXPECT_DOUBLE_EQ(b, 0.25); - EXPECT_DOUBLE_EQ(a, 1.0); + EXPECT_EQ(instance.set(1.0, 0.5, 0.25, 1.0), kOfxStatOK); + + EXPECT_EQ(instance.get(r, g, b, a), kOfxStatOK); + EXPECT_DOUBLE_EQ(r, 1.0); + EXPECT_DOUBLE_EQ(g, 0.5); + EXPECT_DOUBLE_EQ(b, 0.25); + EXPECT_DOUBLE_EQ(a, 1.0); } TEST(PluginSmokeParam, RGBNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeRGB, "TestRGB"); - RGBInstance instance(nullptr, "TestRGB", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeRGB, "TestRGB"); + RGBInstance instance(nullptr, "TestRGB", desc); - double r = 0, g = 0, b = 0; - EXPECT_EQ(instance.get(r, g, b), kOfxStatOK); - EXPECT_DOUBLE_EQ(r, 0.0); - EXPECT_DOUBLE_EQ(g, 0.0); - EXPECT_DOUBLE_EQ(b, 0.0); + double r = 0, g = 0, b = 0; + EXPECT_EQ(instance.get(r, g, b), kOfxStatOK); + EXPECT_DOUBLE_EQ(r, 0.0); + EXPECT_DOUBLE_EQ(g, 0.0); + EXPECT_DOUBLE_EQ(b, 0.0); - EXPECT_EQ(instance.set(0.8, 0.6, 0.4), kOfxStatOK); - - EXPECT_EQ(instance.get(r, g, b), kOfxStatOK); - EXPECT_DOUBLE_EQ(r, 0.8); - EXPECT_DOUBLE_EQ(g, 0.6); - EXPECT_DOUBLE_EQ(b, 0.4); + EXPECT_EQ(instance.set(0.8, 0.6, 0.4), kOfxStatOK); + + EXPECT_EQ(instance.get(r, g, b), kOfxStatOK); + EXPECT_DOUBLE_EQ(r, 0.8); + EXPECT_DOUBLE_EQ(g, 0.6); + EXPECT_DOUBLE_EQ(b, 0.4); } TEST(PluginSmokeParam, Double2DNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeDouble2D, "TestVec2"); - Double2DInstance instance(nullptr, "TestVec2", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeDouble2D, "TestVec2"); + Double2DInstance instance(nullptr, "TestVec2", desc); - double x = 0, y = 0; - EXPECT_EQ(instance.get(x, y), kOfxStatOK); - EXPECT_DOUBLE_EQ(x, 0.0); - EXPECT_DOUBLE_EQ(y, 0.0); + double x = 0, y = 0; + EXPECT_EQ(instance.get(x, y), kOfxStatOK); + EXPECT_DOUBLE_EQ(x, 0.0); + EXPECT_DOUBLE_EQ(y, 0.0); - EXPECT_EQ(instance.set(10.5, 20.5), kOfxStatOK); - - EXPECT_EQ(instance.get(x, y), kOfxStatOK); - EXPECT_DOUBLE_EQ(x, 10.5); - EXPECT_DOUBLE_EQ(y, 20.5); + EXPECT_EQ(instance.set(10.5, 20.5), kOfxStatOK); + + EXPECT_EQ(instance.get(x, y), kOfxStatOK); + EXPECT_DOUBLE_EQ(x, 10.5); + EXPECT_DOUBLE_EQ(y, 20.5); } TEST(PluginSmokeParam, Integer2DNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeInteger2D, "TestIVec2"); - Integer2DInstance instance(nullptr, "TestIVec2", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeInteger2D, "TestIVec2"); + Integer2DInstance instance(nullptr, "TestIVec2", desc); - int x = 0, y = 0; - EXPECT_EQ(instance.get(x, y), kOfxStatOK); - EXPECT_EQ(x, 0); - EXPECT_EQ(y, 0); + int x = 0, y = 0; + EXPECT_EQ(instance.get(x, y), kOfxStatOK); + EXPECT_EQ(x, 0); + EXPECT_EQ(y, 0); - EXPECT_EQ(instance.set(100, 200), kOfxStatOK); - - EXPECT_EQ(instance.get(x, y), kOfxStatOK); - EXPECT_EQ(x, 100); - EXPECT_EQ(y, 200); + EXPECT_EQ(instance.set(100, 200), kOfxStatOK); + + EXPECT_EQ(instance.get(x, y), kOfxStatOK); + EXPECT_EQ(x, 100); + EXPECT_EQ(y, 200); } TEST(PluginSmokeParam, Double3DNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeDouble3D, "TestVec3"); - Double3DInstance instance(nullptr, "TestVec3", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeDouble3D, "TestVec3"); + Double3DInstance instance(nullptr, "TestVec3", desc); - double x = 0, y = 0, z = 0; - EXPECT_EQ(instance.get(x, y, z), kOfxStatOK); - EXPECT_DOUBLE_EQ(x, 0.0); - EXPECT_DOUBLE_EQ(y, 0.0); - EXPECT_DOUBLE_EQ(z, 0.0); + double x = 0, y = 0, z = 0; + EXPECT_EQ(instance.get(x, y, z), kOfxStatOK); + EXPECT_DOUBLE_EQ(x, 0.0); + EXPECT_DOUBLE_EQ(y, 0.0); + EXPECT_DOUBLE_EQ(z, 0.0); - EXPECT_EQ(instance.set(1.0, 2.0, 3.0), kOfxStatOK); - - EXPECT_EQ(instance.get(x, y, z), kOfxStatOK); - EXPECT_DOUBLE_EQ(x, 1.0); - EXPECT_DOUBLE_EQ(y, 2.0); - EXPECT_DOUBLE_EQ(z, 3.0); + EXPECT_EQ(instance.set(1.0, 2.0, 3.0), kOfxStatOK); + + EXPECT_EQ(instance.get(x, y, z), kOfxStatOK); + EXPECT_DOUBLE_EQ(x, 1.0); + EXPECT_DOUBLE_EQ(y, 2.0); + EXPECT_DOUBLE_EQ(z, 3.0); } TEST(PluginSmokeParam, Integer3DNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeInteger3D, "TestIVec3"); - Integer3DInstance instance(nullptr, "TestIVec3", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeInteger3D, "TestIVec3"); + Integer3DInstance instance(nullptr, "TestIVec3", desc); - int x = 0, y = 0, z = 0; - EXPECT_EQ(instance.get(x, y, z), kOfxStatOK); - EXPECT_EQ(x, 0); - EXPECT_EQ(y, 0); - EXPECT_EQ(z, 0); + int x = 0, y = 0, z = 0; + EXPECT_EQ(instance.get(x, y, z), kOfxStatOK); + EXPECT_EQ(x, 0); + EXPECT_EQ(y, 0); + EXPECT_EQ(z, 0); - EXPECT_EQ(instance.set(10, 20, 30), kOfxStatOK); - - EXPECT_EQ(instance.get(x, y, z), kOfxStatOK); - EXPECT_EQ(x, 10); - EXPECT_EQ(y, 20); - EXPECT_EQ(z, 30); + EXPECT_EQ(instance.set(10, 20, 30), kOfxStatOK); + + EXPECT_EQ(instance.get(x, y, z), kOfxStatOK); + EXPECT_EQ(x, 10); + EXPECT_EQ(y, 20); + EXPECT_EQ(z, 30); } TEST(PluginSmokeParam, StringNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeString, "TestString"); - StringInstance instance(nullptr, "TestString", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeString, "TestString"); + StringInstance instance(nullptr, "TestString", desc); - std::string value; - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_TRUE(value.empty()); + std::string value; + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_TRUE(value.empty()); - EXPECT_EQ(instance.set("hello world"), kOfxStatOK); - - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_EQ(value, "hello world"); + EXPECT_EQ(instance.set("hello world"), kOfxStatOK); + + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_EQ(value, "hello world"); } TEST(PluginSmokeParam, CustomNullNode) { - OFX::Host::Param::Descriptor desc(kOfxParamTypeCustom, "TestCustom"); - CustomInstance instance(nullptr, "TestCustom", desc); + OFX::Host::Param::Descriptor desc(kOfxParamTypeCustom, "TestCustom"); + CustomInstance instance(nullptr, "TestCustom", desc); - std::string value; - EXPECT_EQ(instance.get(value), kOfxStatOK); - // Custom params may have default values - - EXPECT_EQ(instance.set("custom data"), kOfxStatOK); - - EXPECT_EQ(instance.get(value), kOfxStatOK); - EXPECT_EQ(value, "custom data"); + std::string value; + EXPECT_EQ(instance.get(value), kOfxStatOK); + // Custom params may have default values + + EXPECT_EQ(instance.set("custom data"), kOfxStatOK); + + EXPECT_EQ(instance.get(value), kOfxStatOK); + EXPECT_EQ(value, "custom data"); } // ============================================================================ @@ -500,29 +515,27 @@ TEST(PluginSmokeParam, CustomNullNode) TEST(PluginSmokeRenderer, BytesToPixelsConversion) { - VideoParams params(100, 100, core::PixelFormat::U8, 4, - core::rational(1, 1), - VideoParams::kInterlaceNone, 1); + VideoParams params(100, 100, core::PixelFormat::U8, 4, core::rational(1, 1), + VideoParams::kInterlaceNone, 1); - // 4 channels * 1 byte = 4 bytes per pixel - EXPECT_EQ(detail::BytesToPixels(400, params), 100); - EXPECT_EQ(detail::BytesToPixels(0, params), 0); - - // Test with RGB (3 channels) - VideoParams params_rgb(100, 100, core::PixelFormat::U8, 3, - core::rational(1, 1), - VideoParams::kInterlaceNone, 1); - EXPECT_EQ(detail::BytesToPixels(300, params_rgb), 100); + // 4 channels * 1 byte = 4 bytes per pixel + EXPECT_EQ(detail::BytesToPixels(400, params), 100); + EXPECT_EQ(detail::BytesToPixels(0, params), 0); + + // Test with RGB (3 channels) + VideoParams params_rgb(100, 100, core::PixelFormat::U8, 3, + core::rational(1, 1), VideoParams::kInterlaceNone, + 1); + EXPECT_EQ(detail::BytesToPixels(300, params_rgb), 100); } TEST(PluginSmokeRenderer, BytesToPixelsInvalidInput) { - VideoParams params(100, 100, core::PixelFormat::U8, 4, - core::rational(1, 1), - VideoParams::kInterlaceNone, 1); + VideoParams params(100, 100, core::PixelFormat::U8, 4, core::rational(1, 1), + VideoParams::kInterlaceNone, 1); - // Negative input should return 0 - EXPECT_EQ(detail::BytesToPixels(-1, params), 0); + // Negative input should return 0 + EXPECT_EQ(detail::BytesToPixels(-1, params), 0); } // ============================================================================ @@ -531,36 +544,36 @@ TEST(PluginSmokeRenderer, BytesToPixelsInvalidInput) TEST(PluginSmokeJob, JobConstruction) { - NodeValueRow row; - PluginJob job(nullptr, nullptr, row); + NodeValueRow row; + PluginJob job(nullptr, nullptr, row); - EXPECT_EQ(job.pluginInstance(), nullptr); - EXPECT_EQ(job.node(), nullptr); - EXPECT_DOUBLE_EQ(job.time_seconds(), 0.0); + EXPECT_EQ(job.pluginInstance(), nullptr); + EXPECT_EQ(job.node(), nullptr); + EXPECT_DOUBLE_EQ(job.time_seconds(), 0.0); } TEST(PluginSmokeJob, JobWithTime) { - NodeValueRow row; - core::rational time(5, 1); // 5 seconds - PluginJob job(nullptr, nullptr, row, time); + NodeValueRow row; + core::rational time(5, 1); // 5 seconds + PluginJob job(nullptr, nullptr, row, time); - EXPECT_DOUBLE_EQ(job.time_seconds(), 5.0); + EXPECT_DOUBLE_EQ(job.time_seconds(), 5.0); } TEST(PluginSmokeJob, JobWithTextureValue) { - VideoParams params(64, 64, core::PixelFormat::U8, 4); - TexturePtr tex = CreateTestTexture(params, 0x80); - ASSERT_NE(tex, nullptr); + VideoParams params(64, 64, core::PixelFormat::U8, 4); + TexturePtr tex = CreateTestTexture(params, 0x80); + ASSERT_NE(tex, nullptr); - NodeValueRow row; - row.insert(QStringLiteral("source"), NodeValue(NodeValue::kTexture, tex)); - - PluginJob job(nullptr, nullptr, row); - - // Job should have the values inserted - EXPECT_FALSE(job.GetValues().isEmpty()); + NodeValueRow row; + row.insert(QStringLiteral("source"), NodeValue(NodeValue::kTexture, tex)); + + PluginJob job(nullptr, nullptr, row); + + // Job should have the values inserted + EXPECT_FALSE(job.GetValues().isEmpty()); } // ============================================================================ @@ -569,13 +582,13 @@ TEST(PluginSmokeJob, JobWithTextureValue) TEST(PluginSmokeNode, NodeRequiresValidInstance) { - // PluginNode requires a valid OFX instance - // Creating without one should be handled gracefully - // Note: This test documents expected behavior - - // A PluginNode cannot be created without an instance - // The constructor requires an OFX::Host::ImageEffect::Instance - EXPECT_TRUE(true); // Placeholder for documentation + // PluginNode requires a valid OFX instance + // Creating without one should be handled gracefully + // Note: This test documents expected behavior + + // A PluginNode cannot be created without an instance + // The constructor requires an OFX::Host::ImageEffect::Instance + EXPECT_TRUE(true); // Placeholder for documentation } // ============================================================================ @@ -584,64 +597,78 @@ TEST(PluginSmokeNode, NodeRequiresValidInstance) TEST(PluginSmokeIntegration, VideoParamsToOfxMapping) { - // Test U8 -> Byte mapping - { - VideoParams params = MakeVideoParams(100, 100, core::PixelFormat::U8, 4, false); - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthByte); - } + // Test U8 -> Byte mapping + { + VideoParams params = + MakeVideoParams(100, 100, core::PixelFormat::U8, 4, false); + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthByte); + } - // Test U16 -> Short mapping - { - VideoParams params = MakeVideoParams(100, 100, core::PixelFormat::U16, 4, false); - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthShort); - } + // Test U16 -> Short mapping + { + VideoParams params = + MakeVideoParams(100, 100, core::PixelFormat::U16, 4, false); + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthShort); + } - // Test F16 -> Half mapping - { - VideoParams params = MakeVideoParams(100, 100, core::PixelFormat::F16, 4, false); - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthHalf); - } + // Test F16 -> Half mapping + { + VideoParams params = + MakeVideoParams(100, 100, core::PixelFormat::F16, 4, false); + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthHalf); + } - // Test F32 -> Float mapping - { - VideoParams params = MakeVideoParams(100, 100, core::PixelFormat::F32, 4, false); - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthFloat); - } + // Test F32 -> Float mapping + { + VideoParams params = + MakeVideoParams(100, 100, core::PixelFormat::F32, 4, false); + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthFloat); + } } TEST(PluginSmokeIntegration, ComponentCountMapping) { - // Test RGB (3 channels) - { - VideoParams params = MakeVideoParams(100, 100, core::PixelFormat::U8, 3, false); - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGB); - } + // Test RGB (3 channels) + { + VideoParams params = + MakeVideoParams(100, 100, core::PixelFormat::U8, 3, false); + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGB); + } - // Test RGBA (4 channels) - { - VideoParams params = MakeVideoParams(100, 100, core::PixelFormat::U8, 4, false); - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGBA); - } + // Test RGBA (4 channels) + { + VideoParams params = + MakeVideoParams(100, 100, core::PixelFormat::U8, 4, false); + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGBA); + } - // Test Alpha (1 channel) - { - VideoParams params = MakeVideoParams(100, 100, core::PixelFormat::U8, 1, false); - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - OliveClipInstance clip(nullptr, desc, params); - EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentAlpha); - } + // Test Alpha (1 channel) + { + VideoParams params = + MakeVideoParams(100, 100, core::PixelFormat::U8, 1, false); + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + OliveClipInstance clip(nullptr, desc, params); + EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentAlpha); + } } // ============================================================================ @@ -650,74 +677,77 @@ TEST(PluginSmokeIntegration, ComponentCountMapping) TEST(PluginSmokeThread, ConcurrentImageAllocation) { - const int num_threads = 4; - const int num_allocs_per_thread = 10; - - std::vector threads; - std::atomic success_count{0}; - - for (int t = 0; t < num_threads; ++t) { - threads.emplace_back([&success_count, num_allocs_per_thread, t]() { - for (int i = 0; i < num_allocs_per_thread; ++i) { - OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName); - VideoParams params = MakeVideoParams(32 + t, 32 + i, - core::PixelFormat::U8, 4, false); - OliveClipInstance clip(nullptr, desc, params); - - Image image(clip); - OfxRectI bounds = {0, 0, 32 + t, 32 + i}; - OfxRectI rod = bounds; - image.AllocateFromParams(params, bounds, rod, true); - - if (image.data() != nullptr && - image.width() == 32 + t && - image.height() == 32 + i) { - success_count++; - } - } - }); - } - - for (auto &t : threads) { - t.join(); - } - - EXPECT_EQ(success_count.load(), num_threads * num_allocs_per_thread); + const int num_threads = 4; + const int num_allocs_per_thread = 10; + + std::vector threads; + std::atomic success_count{ 0 }; + + for (int t = 0; t < num_threads; ++t) { + threads.emplace_back([&success_count, num_allocs_per_thread, t]() { + for (int i = 0; i < num_allocs_per_thread; ++i) { + OFX::Host::ImageEffect::ClipDescriptor desc( + kOfxImageEffectOutputClipName); + VideoParams params = MakeVideoParams( + 32 + t, 32 + i, core::PixelFormat::U8, 4, false); + OliveClipInstance clip(nullptr, desc, params); + + Image image(clip); + OfxRectI bounds = { 0, 0, 32 + t, 32 + i }; + OfxRectI rod = bounds; + image.AllocateFromParams(params, bounds, rod, true); + + if (image.data() != nullptr && image.width() == 32 + t && + image.height() == 32 + i) { + success_count++; + } + } + }); + } + + for (auto &t : threads) { + t.join(); + } + + EXPECT_EQ(success_count.load(), num_threads * num_allocs_per_thread); } TEST(PluginSmokeThread, ConcurrentParamAccess) { - const int num_threads = 4; - const int num_ops_per_thread = 100; - - OFX::Host::Param::Descriptor desc(kOfxParamTypeInteger, "ConcurrentInt"); - IntegerInstance instance(nullptr, desc); - - std::atomic success_count{0}; - std::vector threads; - - for (int t = 0; t < num_threads; ++t) { - threads.emplace_back([&instance, &success_count, t, num_ops_per_thread]() { - for (int i = 0; i < num_ops_per_thread; ++i) { - int value = t * 1000 + i; - if (instance.set(value) == kOfxStatOK) { - int read_value = -1; - if (instance.get(read_value) == kOfxStatOK) { - // Without node binding, value should be what we just set - if (read_value == value) { - success_count++; - } - } - } - } - }); - } - - for (auto &t : threads) { - t.join(); - } - - EXPECT_EQ(success_count.load(), num_threads * num_ops_per_thread); + const int num_threads = 4; + const int num_ops_per_thread = 100; + + OFX::Host::Param::Descriptor desc(kOfxParamTypeInteger, "ConcurrentInt"); + IntegerInstance instance(nullptr, desc); + + std::atomic success_count{ 0 }; + std::mutex access_mutex; + std::vector threads; + + for (int t = 0; t < num_threads; ++t) { + threads.emplace_back([&instance, &success_count, &access_mutex, t, + num_ops_per_thread]() { + for (int i = 0; i < num_ops_per_thread; ++i) { + int value = t * 1000 + i; + std::lock_guard lock(access_mutex); + if (instance.set(value) == kOfxStatOK) { + int read_value = -1; + if (instance.get(read_value) == kOfxStatOK) { + // Without node binding, value should be what we just set + if (read_value == value) { + success_count++; + } + } + } + } + }); + } + + for (auto &t : threads) { + t.join(); + } + + EXPECT_EQ(success_count.load(), num_threads * num_ops_per_thread); } } // namespace test diff --git a/tests/gtest/plugin_support_clip_test.cpp b/tests/gtest/plugin_support_clip_test.cpp index 75e218d66..9ba7a34fd 100644 --- a/tests/gtest/plugin_support_clip_test.cpp +++ b/tests/gtest/plugin_support_clip_test.cpp @@ -4,10 +4,10 @@ #include "ofxhClip.h" #include "pluginSupport/OliveClip.h" -namespace { +namespace +{ olive::VideoParams MakeParams(int width, int height, - olive::core::PixelFormat format, - int channels, + olive::core::PixelFormat format, int channels, bool premultiplied) { olive::VideoParams params; @@ -64,16 +64,14 @@ TEST(PluginSupportClip, GetImageClampsBoundsAndCachesOutput) olive::plugin::OliveClipInstance clip(nullptr, desc, params); OfxRectD optional_bounds = { -10.0, -10.0, 200.0, 200.0 }; - OFX::Host::ImageEffect::Image *image = - clip.getImage(0.0, &optional_bounds); + OFX::Host::ImageEffect::Image *image = clip.getImage(0.0, &optional_bounds); ASSERT_NE(image, nullptr); auto *olive_image = static_cast(image); EXPECT_EQ(olive_image->width(), 100); EXPECT_EQ(olive_image->height(), 80); - OFX::Host::ImageEffect::Image *image_again = - clip.getImage(0.0, nullptr); + OFX::Host::ImageEffect::Image *image_again = clip.getImage(0.0, nullptr); EXPECT_EQ(image, image_again); } diff --git a/tests/gtest/plugin_support_image_test.cpp b/tests/gtest/plugin_support_image_test.cpp index 3e13dac06..e8351a1fa 100644 --- a/tests/gtest/plugin_support_image_test.cpp +++ b/tests/gtest/plugin_support_image_test.cpp @@ -5,10 +5,10 @@ #include "pluginSupport/OliveClip.h" #include "pluginSupport/image.h" -namespace { +namespace +{ olive::VideoParams MakeParams(int width, int height, - olive::core::PixelFormat format, - int channels, + olive::core::PixelFormat format, int channels, bool premultiplied) { olive::VideoParams params; @@ -106,14 +106,14 @@ TEST(PluginSupportImage, AllocateSetsOfxProperties) EXPECT_NE(image.data(), nullptr); EXPECT_EQ(image.row_bytes(), 8 * 4 * 2); - int bounds_props[4] = {0}; + int bounds_props[4] = { 0 }; image.getIntPropertyN(kOfxImagePropBounds, bounds_props, 4); EXPECT_EQ(bounds_props[0], bounds.x1); EXPECT_EQ(bounds_props[1], bounds.y1); EXPECT_EQ(bounds_props[2], bounds.x2); EXPECT_EQ(bounds_props[3], bounds.y2); - int rod_props[4] = {0}; + int rod_props[4] = { 0 }; image.getIntPropertyN(kOfxImagePropRegionOfDefinition, rod_props, 4); EXPECT_EQ(rod_props[0], rod.x1); EXPECT_EQ(rod_props[1], rod.y1); diff --git a/tests/gtest/plugin_support_test.cpp b/tests/gtest/plugin_support_test.cpp index 5acad6e79..93517b0a9 100644 --- a/tests/gtest/plugin_support_test.cpp +++ b/tests/gtest/plugin_support_test.cpp @@ -4,7 +4,5 @@ TEST(PluginSupport, LoadPluginsEmptyPath) { - EXPECT_NO_THROW({ - olive::plugin::loadPlugins(QString()); - }); + EXPECT_NO_THROW({ olive::plugin::loadPlugins(QString()); }); } diff --git a/tests/gtest/preferences_behavior_tab_test.cpp b/tests/gtest/preferences_behavior_tab_test.cpp index ae47e93ca..066ae5cd2 100644 --- a/tests/gtest/preferences_behavior_tab_test.cpp +++ b/tests/gtest/preferences_behavior_tab_test.cpp @@ -45,16 +45,16 @@ TEST(PreferencesBehaviorTab, BehaviorPrefTrProvidesTranslations) { QStringList keys; keys << QStringLiteral("Enable hover focus") - << QStringLiteral("Select also selects all children in the graph") - << QStringLiteral("Double-clicking a node opens its properties") - << QStringLiteral("Auto-Seek to Beginning of Sequence") - << QStringLiteral("Scroll wheel zooms instead of scrolling") - << QStringLiteral("Enable audio scrubbing"); + << QStringLiteral("Select also selects all children in the graph") + << QStringLiteral("Double-clicking a node opens its properties") + << QStringLiteral("Auto-Seek to Beginning of Sequence") + << QStringLiteral("Scroll wheel zooms instead of scrolling") + << QStringLiteral("Enable audio scrubbing"); foreach (const QString &key, keys) { EXPECT_FALSE( - PreferencesBehaviorTab::BehaviorPrefTr( - key.toUtf8().constData()).isEmpty()) + PreferencesBehaviorTab::BehaviorPrefTr(key.toUtf8().constData()) + .isEmpty()) << key.toStdString(); } } @@ -76,8 +76,8 @@ TEST(PreferencesGeneralTab, ContainsHoverFocusOption) bool found = false; foreach (QCheckBox *box, boxes) { - if (box->text() == PreferencesBehaviorTab::BehaviorPrefTr( - "Enable hover focus")) { + if (box->text() == + PreferencesBehaviorTab::BehaviorPrefTr("Enable hover focus")) { found = true; break; } @@ -96,7 +96,7 @@ TEST(PreferencesAudioTab, AudioScrubbingCheckboxUsesBehaviorTranslation) bool found = false; foreach (QCheckBox *box, boxes) { if (box->text() == PreferencesBehaviorTab::BehaviorPrefTr( - "Enable audio scrubbing")) { + "Enable audio scrubbing")) { found = true; break; } diff --git a/tests/gtest/preview_autocacher_test.cpp b/tests/gtest/preview_autocacher_test.cpp index 99fde1270..58219f16c 100644 --- a/tests/gtest/preview_autocacher_test.cpp +++ b/tests/gtest/preview_autocacher_test.cpp @@ -79,7 +79,8 @@ TEST_F(PreviewAutoCacherTest, ClearSingleFrameRendersDoesNotCrashWhenEmpty) cacher.ClearSingleFrameRenders(); } -TEST_F(PreviewAutoCacherTest, ClearSingleFrameRendersThatArentRunningDoesNotCrashWhenEmpty) +TEST_F(PreviewAutoCacherTest, + ClearSingleFrameRendersThatArentRunningDoesNotCrashWhenEmpty) { PreviewAutoCacher cacher; cacher.ClearSingleFrameRendersThatArentRunning(); diff --git a/tests/gtest/project_serializer_test.cpp b/tests/gtest/project_serializer_test.cpp index d897f14b3..e827afd38 100644 --- a/tests/gtest/project_serializer_test.cpp +++ b/tests/gtest/project_serializer_test.cpp @@ -13,7 +13,8 @@ TEST(ProjectSerializer, SaveLoadProjectRoundTrip) { - const bool created_disk_manager = (olive::DiskManager::instance() == nullptr); + const bool created_disk_manager = + (olive::DiskManager::instance() == nullptr); if (created_disk_manager) { olive::DiskManager::CreateInstance(); } @@ -45,15 +46,15 @@ TEST(ProjectSerializer, SaveLoadProjectRoundTrip) QBuffer read_buffer(&xml); read_buffer.open(QIODevice::ReadOnly); QXmlStreamReader reader(&read_buffer); - olive::ProjectSerializer::Result result = - olive::ProjectSerializer::Load(&loaded_project, &reader, - olive::ProjectSerializer::kProject); + olive::ProjectSerializer::Result result = olive::ProjectSerializer::Load( + &loaded_project, &reader, olive::ProjectSerializer::kProject); EXPECT_EQ(result.code(), olive::ProjectSerializer::kSuccess); EXPECT_FALSE(loaded_project.nodes().isEmpty()); ASSERT_TRUE(result.GetLoadData().node_ptrs.contains( reinterpret_cast(node))); - EXPECT_TRUE(loaded_project.nodes().contains( - result.GetLoadData().node_ptrs.value(reinterpret_cast(node)))); + EXPECT_TRUE( + loaded_project.nodes().contains(result.GetLoadData().node_ptrs.value( + reinterpret_cast(node)))); olive::ProjectSerializer::Destroy(); if (created_disk_manager) { diff --git a/tests/gtest/proxy_manager_test.cpp b/tests/gtest/proxy_manager_test.cpp index 4b5bdbcf8..a23742bd1 100644 --- a/tests/gtest/proxy_manager_test.cpp +++ b/tests/gtest/proxy_manager_test.cpp @@ -18,14 +18,14 @@ TEST(ProxyManager, BuildsStableProxyFilename) params.version = 1; const QString first = olive::ProxyManager::GetProxyFilename( - QStringLiteral("/tmp/oak-cache"), - QStringLiteral("/media/source.mov"), 0, params); + QStringLiteral("/tmp/oak-cache"), QStringLiteral("/media/source.mov"), + 0, params); const QString second = olive::ProxyManager::GetProxyFilename( - QStringLiteral("/tmp/oak-cache"), - QStringLiteral("/media/source.mov"), 0, params); + QStringLiteral("/tmp/oak-cache"), QStringLiteral("/media/source.mov"), + 0, params); const QString other_stream = olive::ProxyManager::GetProxyFilename( - QStringLiteral("/tmp/oak-cache"), - QStringLiteral("/media/source.mov"), 1, params); + QStringLiteral("/tmp/oak-cache"), QStringLiteral("/media/source.mov"), + 1, params); EXPECT_EQ(first, second); EXPECT_NE(first, other_stream); @@ -48,11 +48,11 @@ TEST(ProxyManager, ProxyFilenameIncludesPresetParameters) mov_540p.extension = QStringLiteral("mov"); const QString first = olive::ProxyManager::GetProxyFilename( - QStringLiteral("/tmp/oak-cache"), - QStringLiteral("/media/source.mov"), 0, mp4_720p); + QStringLiteral("/tmp/oak-cache"), QStringLiteral("/media/source.mov"), + 0, mp4_720p); const QString second = olive::ProxyManager::GetProxyFilename( - QStringLiteral("/tmp/oak-cache"), - QStringLiteral("/media/source.mov"), 0, mov_540p); + QStringLiteral("/tmp/oak-cache"), QStringLiteral("/media/source.mov"), + 0, mov_540p); EXPECT_NE(first, second); EXPECT_TRUE(first.contains(QStringLiteral(".1280x720.v1."))); @@ -117,21 +117,21 @@ TEST(ProxyManager, ConvertsProxyStateToAndFromStrings) olive::ProxyManager::kProxyFailed), QStringLiteral("failed")); - EXPECT_EQ(olive::ProxyManager::ProxyStateFromString( - QStringLiteral("missing")), - olive::ProxyManager::kProxyMissing); - EXPECT_EQ(olive::ProxyManager::ProxyStateFromString( - QStringLiteral("generating")), - olive::ProxyManager::kProxyGenerating); - EXPECT_EQ(olive::ProxyManager::ProxyStateFromString( - QStringLiteral("ready")), - olive::ProxyManager::kProxyReady); - EXPECT_EQ(olive::ProxyManager::ProxyStateFromString( - QStringLiteral("failed")), - olive::ProxyManager::kProxyFailed); - EXPECT_EQ(olive::ProxyManager::ProxyStateFromString( - QStringLiteral("unknown")), - olive::ProxyManager::kProxyMissing); + EXPECT_EQ( + olive::ProxyManager::ProxyStateFromString(QStringLiteral("missing")), + olive::ProxyManager::kProxyMissing); + EXPECT_EQ( + olive::ProxyManager::ProxyStateFromString(QStringLiteral("generating")), + olive::ProxyManager::kProxyGenerating); + EXPECT_EQ( + olive::ProxyManager::ProxyStateFromString(QStringLiteral("ready")), + olive::ProxyManager::kProxyReady); + EXPECT_EQ( + olive::ProxyManager::ProxyStateFromString(QStringLiteral("failed")), + olive::ProxyManager::kProxyFailed); + EXPECT_EQ( + olive::ProxyManager::ProxyStateFromString(QStringLiteral("unknown")), + olive::ProxyManager::kProxyMissing); } TEST(ProxyManager, FootagePersistsProxyMetadata) @@ -225,10 +225,10 @@ TEST(ProxyManager, EmitsProxyFinishedState) received_state = state; }); - emit olive::ProxyManager::instance()->ProxyFinished( - QStringLiteral("/media/source.mov"), 0, - QStringLiteral("/cache/proxy/example.mp4"), - olive::ProxyManager::kProxyFailed); + emit olive::ProxyManager::instance() + -> ProxyFinished(QStringLiteral("/media/source.mov"), 0, + QStringLiteral("/cache/proxy/example.mp4"), + olive::ProxyManager::kProxyFailed); EXPECT_TRUE(received); EXPECT_EQ(received_source, QStringLiteral("/media/source.mov")); @@ -241,10 +241,8 @@ TEST(ProxyManager, EmitsProxyFinishedState) TEST(ProxyManager, WorkingProxyFilenamePrependsExtension) { - const QString proxy = - QStringLiteral("/cache/proxy/example.mp4"); - const QString working = - olive::ProxyManager::GetWorkingProxyFilename(proxy); + const QString proxy = QStringLiteral("/cache/proxy/example.mp4"); + const QString working = olive::ProxyManager::GetWorkingProxyFilename(proxy); EXPECT_EQ(working, QStringLiteral("/cache/proxy/example.mp4.working.mp4")); } diff --git a/tests/gtest/render_audioparams_branch_test.cpp b/tests/gtest/render_audioparams_branch_test.cpp index 27c371828..e7716cd90 100644 --- a/tests/gtest/render_audioparams_branch_test.cpp +++ b/tests/gtest/render_audioparams_branch_test.cpp @@ -7,12 +7,12 @@ TEST(RenderAudioParams, ValidityAndEquality) olive::core::AudioParams invalid; EXPECT_FALSE(invalid.is_valid()); - olive::core::AudioParams params( - 48000, AV_CH_LAYOUT_STEREO, olive::core::SampleFormat::S16); + olive::core::AudioParams params(48000, AV_CH_LAYOUT_STEREO, + olive::core::SampleFormat::S16); EXPECT_TRUE(params.is_valid()); - olive::core::AudioParams other( - 48000, AV_CH_LAYOUT_STEREO, olive::core::SampleFormat::S16); + olive::core::AudioParams other(48000, AV_CH_LAYOUT_STEREO, + olive::core::SampleFormat::S16); EXPECT_TRUE(params == other); other.set_sample_rate(44100); @@ -21,8 +21,8 @@ TEST(RenderAudioParams, ValidityAndEquality) TEST(RenderAudioParams, TimeAndSampleConversions) { - olive::core::AudioParams params( - 48000, AV_CH_LAYOUT_STEREO, olive::core::SampleFormat::S16); + olive::core::AudioParams params(48000, AV_CH_LAYOUT_STEREO, + olive::core::SampleFormat::S16); EXPECT_EQ(params.channel_count(), 2); EXPECT_EQ(params.bytes_per_sample_per_channel(), 2); @@ -43,34 +43,34 @@ TEST(RenderAudioParams, TimeAndSampleConversions) TEST(RenderAudioParams, ChannelLayoutCount) { - olive::core::AudioParams mono( - 48000, AV_CH_LAYOUT_MONO, olive::core::SampleFormat::F32); + olive::core::AudioParams mono(48000, AV_CH_LAYOUT_MONO, + olive::core::SampleFormat::F32); EXPECT_EQ(mono.channel_count(), 1); - olive::core::AudioParams surround( - 48000, AV_CH_LAYOUT_5POINT1, olive::core::SampleFormat::F32); + olive::core::AudioParams surround(48000, AV_CH_LAYOUT_5POINT1, + olive::core::SampleFormat::F32); EXPECT_EQ(surround.channel_count(), 6); } TEST(RenderAudioParams, SampleFormatSizes) { - olive::core::AudioParams u8( - 48000, AV_CH_LAYOUT_MONO, olive::core::SampleFormat::U8); + olive::core::AudioParams u8(48000, AV_CH_LAYOUT_MONO, + olive::core::SampleFormat::U8); EXPECT_EQ(u8.bytes_per_sample_per_channel(), 1); - olive::core::AudioParams f32( - 48000, AV_CH_LAYOUT_MONO, olive::core::SampleFormat::F32); + olive::core::AudioParams f32(48000, AV_CH_LAYOUT_MONO, + olive::core::SampleFormat::F32); EXPECT_EQ(f32.bytes_per_sample_per_channel(), 4); - olive::core::AudioParams f64( - 48000, AV_CH_LAYOUT_MONO, olive::core::SampleFormat::F64); + olive::core::AudioParams f64(48000, AV_CH_LAYOUT_MONO, + olive::core::SampleFormat::F64); EXPECT_EQ(f64.bytes_per_sample_per_channel(), 8); } TEST(RenderAudioParams, CopyAndAssignment) { - olive::core::AudioParams params( - 96000, AV_CH_LAYOUT_STEREO, olive::core::SampleFormat::F32); + olive::core::AudioParams params(96000, AV_CH_LAYOUT_STEREO, + olive::core::SampleFormat::F32); olive::core::AudioParams copy(params); EXPECT_EQ(copy.sample_rate(), 96000); @@ -85,8 +85,8 @@ TEST(RenderAudioParams, CopyAndAssignment) TEST(RenderAudioParams, SettersModifyState) { - olive::core::AudioParams params( - 44100, AV_CH_LAYOUT_MONO, olive::core::SampleFormat::S16); + olive::core::AudioParams params(44100, AV_CH_LAYOUT_MONO, + olive::core::SampleFormat::S16); EXPECT_TRUE(params.is_valid()); params.set_sample_rate(48000); diff --git a/tests/gtest/render_ipc_test.cpp b/tests/gtest/render_ipc_test.cpp index 469b9cfc9..55d18c9cd 100644 --- a/tests/gtest/render_ipc_test.cpp +++ b/tests/gtest/render_ipc_test.cpp @@ -40,13 +40,13 @@ TEST(SpscRingBuffer, BasicPushPopAndCapacity) EXPECT_TRUE(ring->IsEmptyApprox()); uint32_t v = 0; - EXPECT_FALSE(ring->Pop(&v)); // empty + EXPECT_FALSE(ring->Pop(&v)); // empty // Capacity 4 holds at most 3 entries (one slot reserved to disambiguate full/empty). EXPECT_TRUE(ring->Push(10)); EXPECT_TRUE(ring->Push(20)); EXPECT_TRUE(ring->Push(30)); - EXPECT_FALSE(ring->Push(40)); // full + EXPECT_FALSE(ring->Push(40)); // full EXPECT_TRUE(ring->Pop(&v)); EXPECT_EQ(v, 10u); @@ -54,7 +54,7 @@ TEST(SpscRingBuffer, BasicPushPopAndCapacity) EXPECT_EQ(v, 20u); EXPECT_TRUE(ring->Pop(&v)); EXPECT_EQ(v, 30u); - EXPECT_FALSE(ring->Pop(&v)); // empty again + EXPECT_FALSE(ring->Pop(&v)); // empty again } TEST(SpscRingBuffer, WrapAround) @@ -75,17 +75,18 @@ TEST(SpscRingBuffer, WrapAround) TEST(SpscRingBuffer, ConcurrentProducerConsumer) { constexpr uint32_t kCapacity = 1024; - constexpr uint32_t kCount = 2'000'000; // values 0..kCount-1 streamed through the ring + constexpr uint32_t kCount = + 2'000'000; // values 0..kCount-1 streamed through the ring std::vector mem(SpscRingBuffer::BytesNeeded(kCapacity)); SpscRingBuffer *ring = SpscRingBuffer::Create(mem.data(), kCapacity); - std::atomic order_ok{true}; + std::atomic order_ok{ true }; std::thread producer([&] { for (uint32_t i = 0; i < kCount; i++) { while (!ring->Push(i)) { - std::this_thread::yield(); // buffer full, spin until consumer drains + std::this_thread::yield(); // buffer full, spin until consumer drains } } }); @@ -124,7 +125,8 @@ TEST(FrameSlotPool, SingleThreadedHandoff) constexpr size_t kSlotBytes = 256; std::vector mem(FrameSlotPool::BytesNeeded(kSlots, kSlotBytes)); - FrameSlotPool filler = FrameSlotPool::Create(mem.data(), kSlots, kSlotBytes); + FrameSlotPool filler = + FrameSlotPool::Create(mem.data(), kSlots, kSlotBytes); FrameSlotPool drainer = FrameSlotPool::Attach(mem.data()); ASSERT_TRUE(filler.IsValid()); @@ -156,7 +158,8 @@ TEST(FrameSlotPool, SingleThreadedHandoff) EXPECT_EQ(got_meta->id, 4242); EXPECT_EQ(got_meta->width, 16); - const auto *got_data = static_cast(drainer.SlotData(got_idx)); + const auto *got_data = + static_cast(drainer.SlotData(got_idx)); for (size_t i = 0; i < kSlotBytes; i++) { ASSERT_EQ(got_data[i], uint8_t(i & 0xFF)); } @@ -180,7 +183,7 @@ TEST(FrameSlotPool, ExhaustionAndRefill) held.push_back(a); } uint32_t overflow = 0; - EXPECT_FALSE(pool.Acquire(&overflow)); // pool exhausted + EXPECT_FALSE(pool.Acquire(&overflow)); // pool exhausted // Publishing then consuming + releasing returns the slots to the free pool. for (uint32_t idx : held) { @@ -192,7 +195,7 @@ TEST(FrameSlotPool, ExhaustionAndRefill) ASSERT_TRUE(pool.Release(c)); } uint32_t again = 0; - EXPECT_TRUE(pool.Acquire(&again)); // free again + EXPECT_TRUE(pool.Acquire(&again)); // free again } TEST(FrameSlotPool, ConcurrentFillDrainIntegrity) @@ -202,10 +205,11 @@ TEST(FrameSlotPool, ConcurrentFillDrainIntegrity) constexpr int64_t kFrames = 200'000; std::vector mem(FrameSlotPool::BytesNeeded(kSlots, kSlotBytes)); - FrameSlotPool filler = FrameSlotPool::Create(mem.data(), kSlots, kSlotBytes); + FrameSlotPool filler = + FrameSlotPool::Create(mem.data(), kSlots, kSlotBytes); FrameSlotPool drainer = FrameSlotPool::Attach(mem.data()); - std::atomic integrity_ok{true}; + std::atomic integrity_ok{ true }; // Filler: for each frame id, acquire a slot, stamp the id into meta and a pattern into the data, // publish. Spins when no slot is free (this is the natural backpressure path). @@ -220,7 +224,7 @@ TEST(FrameSlotPool, ConcurrentFillDrainIntegrity) const uint8_t pat = uint8_t(id & 0xFF); memset(d, pat, kSlotBytes); while (!filler.Publish(idx)) { - std::this_thread::yield(); // ready ring transiently full + std::this_thread::yield(); // ready ring transiently full } } }); @@ -292,7 +296,7 @@ TEST(IpcMessage, TypedRoundTrip) rf.channel_count = 4; rf.mode = 1; rf.input_slot = 2; - rf.input_slots = {2, 3}; + rf.input_slots = { 2, 3 }; ASSERT_TRUE(WriteMessage(&dev, rf.ToJson())); FrameReadyMsg fr; @@ -349,7 +353,8 @@ TEST(IpcMessage, PartialFrameByteByByte) CancelMsg c; c.ticket_id = 7; const QByteArray full = - QByteArray(QJsonDocument(c.ToJson()).toJson(QJsonDocument::Compact)) + '\n'; + QByteArray(QJsonDocument(c.ToJson()).toJson(QJsonDocument::Compact)) + + '\n'; // Feed the bytes one at a time; ReadMessage must return false until the terminating '\n'. QByteArray reader; @@ -357,9 +362,9 @@ TEST(IpcMessage, PartialFrameByteByByte) bool ok = false; for (int i = 0; i < full.size() - 1; i++) { reader.append(full.at(i)); - ASSERT_FALSE(ReadMessage(&reader, &obj, &ok)); // no complete line yet + ASSERT_FALSE(ReadMessage(&reader, &obj, &ok)); // no complete line yet } - reader.append(full.at(full.size() - 1)); // the trailing newline + reader.append(full.at(full.size() - 1)); // the trailing newline ASSERT_TRUE(ReadMessage(&reader, &obj, &ok)); ASSERT_TRUE(ok); diff --git a/tests/gtest/render_videoparams_branch_test.cpp b/tests/gtest/render_videoparams_branch_test.cpp index c2f5c7325..a4016d673 100644 --- a/tests/gtest/render_videoparams_branch_test.cpp +++ b/tests/gtest/render_videoparams_branch_test.cpp @@ -15,29 +15,27 @@ TEST(RenderVideoParams, BytesPerChannelAndPixel) EXPECT_EQ(olive::VideoParams::GetBytesPerChannel( olive::core::PixelFormat::INVALID), 0); - EXPECT_EQ(olive::VideoParams::GetBytesPerChannel( - olive::core::PixelFormat::U8), - 1); - EXPECT_EQ(olive::VideoParams::GetBytesPerChannel( - olive::core::PixelFormat::U16), - 2); - EXPECT_EQ(olive::VideoParams::GetBytesPerChannel( - olive::core::PixelFormat::F16), - 2); - EXPECT_EQ(olive::VideoParams::GetBytesPerChannel( - olive::core::PixelFormat::F32), - 4); - EXPECT_EQ(olive::VideoParams::GetBytesPerPixel( - olive::core::PixelFormat::U8, 4), + EXPECT_EQ( + olive::VideoParams::GetBytesPerChannel(olive::core::PixelFormat::U8), + 1); + EXPECT_EQ( + olive::VideoParams::GetBytesPerChannel(olive::core::PixelFormat::U16), + 2); + EXPECT_EQ( + olive::VideoParams::GetBytesPerChannel(olive::core::PixelFormat::F16), + 2); + EXPECT_EQ( + olive::VideoParams::GetBytesPerChannel(olive::core::PixelFormat::F32), + 4); + EXPECT_EQ(olive::VideoParams::GetBytesPerPixel(olive::core::PixelFormat::U8, + 4), 4); } TEST(RenderVideoParams, DividerAndFormatNames) { - EXPECT_EQ(olive::VideoParams::GetNameForDivider(1), - QStringLiteral("Full")); - EXPECT_EQ(olive::VideoParams::GetNameForDivider(3), - QStringLiteral("1/3")); + EXPECT_EQ(olive::VideoParams::GetNameForDivider(1), QStringLiteral("Full")); + EXPECT_EQ(olive::VideoParams::GetNameForDivider(3), QStringLiteral("1/3")); const QString unknown = olive::VideoParams::GetFormatName(olive::core::PixelFormat::INVALID); @@ -47,11 +45,11 @@ TEST(RenderVideoParams, DividerAndFormatNames) TEST(RenderVideoParams, ScalingAndDividerForTarget) { EXPECT_EQ(olive::VideoParams::GetScaledDimension(100, 3), 33); - EXPECT_EQ(olive::VideoParams::GetDividerForTargetResolution( - 1920, 1080, 960, 540), + EXPECT_EQ(olive::VideoParams::GetDividerForTargetResolution(1920, 1080, 960, + 540), 2); - EXPECT_EQ(olive::VideoParams::GetDividerForTargetResolution( - 1920, 1080, 480, 270), + EXPECT_EQ(olive::VideoParams::GetDividerForTargetResolution(1920, 1080, 480, + 270), 4); } @@ -191,8 +189,7 @@ TEST(RenderVideoParams, SaveLoadRoundTripExtended) EXPECT_FLOAT_EQ(loaded.x(), 1.5f); EXPECT_FLOAT_EQ(loaded.y(), -2.25f); EXPECT_EQ(loaded.stream_index(), 7); - EXPECT_EQ(loaded.video_type(), - olive::VideoParams::kVideoTypeImageSequence); + EXPECT_EQ(loaded.video_type(), olive::VideoParams::kVideoTypeImageSequence); EXPECT_EQ(loaded.frame_rate(), olive::core::rational(30000, 1001)); EXPECT_EQ(loaded.start_time(), 123); EXPECT_EQ(loaded.duration(), 456); diff --git a/tests/gtest/render_worker_footage_test.cpp b/tests/gtest/render_worker_footage_test.cpp index 96f9a0708..4b2d0458b 100644 --- a/tests/gtest/render_worker_footage_test.cpp +++ b/tests/gtest/render_worker_footage_test.cpp @@ -2,7 +2,7 @@ * Oak Video Editor - Render Worker Footage Integration Test * Copyright (C) 2026 Oak Team * - * End-to-end test that spawns olive-render-worker, feeds it a real decoded + * End-to-end test that spawns oak-render-worker, feeds it a real decoded * frame from tests/demo.mp4 through the IPC shared-memory frame pool, and * verifies that the worker returns a non-black output frame. */ @@ -49,7 +49,8 @@ using namespace olive; using namespace olive::core; -namespace { +namespace +{ #ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND bool IsRenderBackendAvailable(const QString &backend) @@ -79,11 +80,11 @@ bool IsRenderBackendAvailable(const QString &backend) #else bool IsRenderBackendAvailable(const QString &) { - // When the dynamic backend is not built, the worker binary is linked + // When the dynamic backend is not built, the test binary is linked // directly against the renderer and we have no way to probe it cheaply - // from here. The tests were originally written for this configuration and - // pass on development workstations, so we keep them enabled. - return true; + // from here. These tests require a working GPU backend, so skip them + // unless we can verify availability through the dynamic adapter. + return false; } #endif @@ -96,10 +97,14 @@ QString WorkerBinaryPath() // The test binary lives in cmake-build-debug/tests/gtest; the worker is in // cmake-build-debug/app. QDir dir(QCoreApplication::applicationDirPath()); - dir.cdUp(); // tests/gtest -> tests - dir.cdUp(); // tests -> build dir + dir.cdUp(); // tests/gtest -> tests + dir.cdUp(); // tests -> build dir dir.cd(QStringLiteral("app")); - return dir.filePath(QStringLiteral("olive-render-worker")); +#if defined(_WIN32) + return dir.filePath(QStringLiteral("oak-render-worker.exe")); +#else + return dir.filePath(QStringLiteral("oak-render-worker")); +#endif } QString DemoVideoPath() @@ -136,8 +141,10 @@ void SaveFrameAsPng(const void *data, int width, int height, for (int x = 0; x < width; ++x) { for (int c = 0; c < 4; ++c) { float v = src[(y * width + x) * 4 + c]; - if (v < 0.0f) v = 0.0f; - if (v > 1.0f) v = 1.0f; + if (v < 0.0f) + v = 0.0f; + if (v > 1.0f) + v = 1.0f; dst[(x * 4) + c] = static_cast(v * 255.0f); } } @@ -149,7 +156,7 @@ void SaveFrameAsPng(const void *data, int width, int height, } } -} // namespace +} // namespace class RenderWorkerFootageTest : public ::testing::Test { protected: @@ -206,8 +213,8 @@ protected: temp_dir_.filePath(QStringLiteral("worker_graph.ove"))); ProjectSerializer::Result r = ProjectSerializer::Save( - ProjectSerializer::SaveData(ProjectSerializer::kProject, project_.get(), - project_file_), + ProjectSerializer::SaveData(ProjectSerializer::kProject, + project_.get(), project_file_), false); ASSERT_EQ(r.code(), ProjectSerializer::kSuccess) << "Failed to save project file: " << r.GetDetails().toStdString(); @@ -218,7 +225,8 @@ protected: { // ---- decode a frame so we know the dimensions and slot sizes ---- DecoderPtr decoder = Decoder::CreateFromID(QStringLiteral("ffmpeg")); - if (!decoder || !decoder->Open(Decoder::CodecStream(demo_path_, 0, nullptr))) { + if (!decoder || + !decoder->Open(Decoder::CodecStream(demo_path_, 0, nullptr))) { return false; } Decoder::RetrieveVideoParams retrieve; @@ -247,10 +255,10 @@ protected: output_shm_key_ = ipc::SharedMemoryRegion::MakeKey(owner_pid, 0); input_shm_key_ = ipc::SharedMemoryRegion::MakeKey(owner_pid, 1); - const size_t output_bytes = ipc::FrameSlotPool::BytesNeeded( - kOutputSlots, output_data_bytes_); - const size_t input_bytes = ipc::FrameSlotPool::BytesNeeded( - kInputSlots, input_data_bytes_); + const size_t output_bytes = + ipc::FrameSlotPool::BytesNeeded(kOutputSlots, output_data_bytes_); + const size_t input_bytes = + ipc::FrameSlotPool::BytesNeeded(kInputSlots, input_data_bytes_); if (!output_region_.Open(output_shm_key_, output_bytes, ipc::SharedMemoryRegion::kCreate)) { @@ -274,7 +282,8 @@ protected: // ---- spawn worker ---- worker_.setProcessChannelMode(QProcess::SeparateChannels); - worker_.start(worker_path_, QStringList{QStringLiteral("--backend"), backend}); + worker_.start(worker_path_, + QStringList{ QStringLiteral("--backend"), backend }); if (!worker_.waitForStarted(kTimeoutMs)) { return false; } @@ -329,8 +338,8 @@ protected: if (!input_pool_->Acquire(&input_slot)) { return false; } - std::memcpy(input_pool_->SlotData(input_slot), decoded_frame_->const_data(), - input_data_bytes_); + std::memcpy(input_pool_->SlotData(input_slot), + decoded_frame_->const_data(), input_data_bytes_); ipc::FrameSlotMeta *meta = input_pool_->Meta(input_slot); meta->id = 0; meta->time_num = 0; @@ -341,9 +350,10 @@ protected: meta->channel_count = decoded_frame_->channel_count(); meta->linesize = input_stride_; meta->data_size = int32_t(input_data_bytes_); - std::strncpy(meta->colorspace, - decoded_frame_->video_params().colorspace().toUtf8().constData(), - sizeof(meta->colorspace) - 1); + std::strncpy( + meta->colorspace, + decoded_frame_->video_params().colorspace().toUtf8().constData(), + sizeof(meta->colorspace) - 1); meta->colorspace[sizeof(meta->colorspace) - 1] = '\0'; input_pool_->Publish(input_slot); @@ -359,7 +369,8 @@ protected: req.mode = int(RenderMode::kOnline); req.input_slot = 0; if (!ipc::WriteMessage(&worker_, req.ToJson())) { - std::cerr << "RenderFrameAndWait: failed to write request" << std::endl; + std::cerr << "RenderFrameAndWait: failed to write request" + << std::endl; return false; } @@ -374,8 +385,9 @@ protected: std::cerr << "RenderFrameAndWait: unexpected message type " << ready[QStringLiteral("type")].toString().toStdString() << " body=" - << QJsonDocument(ready).toJson(QJsonDocument::Compact) - .toStdString() + << QJsonDocument(ready) + .toJson(QJsonDocument::Compact) + .toStdString() << std::endl; return false; } @@ -403,8 +415,9 @@ protected: if (worker_.state() == QProcess::NotRunning) { std::cerr << "WaitForMessage: worker exited with code " << worker_.exitCode() << std::endl; - std::cerr << "Worker stdout buffer: " - << read_buffer_.toStdString() << std::endl; + std::cerr + << "Worker stdout buffer: " << read_buffer_.toStdString() + << std::endl; QByteArray err = worker_.readAllStandardError(); if (!err.isEmpty()) { std::cerr << "Worker stderr:\n" @@ -413,8 +426,9 @@ protected: return false; } } - std::cerr << "WaitForMessage: timeout, buffer=" - << read_buffer_.toStdString() << std::endl; + std::cerr + << "WaitForMessage: timeout, buffer=" << read_buffer_.toStdString() + << std::endl; return false; } @@ -469,19 +483,21 @@ TEST_F(RenderWorkerFootageTest, VulkanFootageIsNotBlack) ASSERT_EQ(int(consumed_slot), output_slot); const void *output_data = output_pool_->SlotData(consumed_slot); - const double brightness = SampleBrightnessF32( - output_data, output_width_, output_height_, - output_width_ * 4 * int(sizeof(float))); + const double brightness = + SampleBrightnessF32(output_data, output_width_, output_height_, + output_width_ * 4 * int(sizeof(float))); EXPECT_GT(brightness, 0.01) << "Worker output frame is black (brightness=" << brightness << ")"; - SaveFrameAsPng(output_data, output_width_, output_height_, - temp_dir_.filePath(QStringLiteral("worker_output_vulkan.png"))); + SaveFrameAsPng( + output_data, output_width_, output_height_, + temp_dir_.filePath(QStringLiteral("worker_output_vulkan.png"))); QFile::remove(QStringLiteral("/tmp/worker_output_vulkan.png")); QFile::copy(temp_dir_.filePath(QStringLiteral("worker_output_vulkan.png")), QStringLiteral("/tmp/worker_output_vulkan.png")); - std::cerr << "Vulkan output copied to /tmp/worker_output_vulkan.png" << std::endl; + std::cerr << "Vulkan output copied to /tmp/worker_output_vulkan.png" + << std::endl; output_pool_->Release(consumed_slot); } @@ -503,19 +519,20 @@ TEST_F(RenderWorkerFootageTest, OpenGLFootageIsNotBlack) ASSERT_EQ(int(consumed_slot), output_slot); const void *output_data = output_pool_->SlotData(consumed_slot); - const double brightness = SampleBrightnessF32( - output_data, output_width_, output_height_, - output_width_ * 4 * int(sizeof(float))); + const double brightness = + SampleBrightnessF32(output_data, output_width_, output_height_, + output_width_ * 4 * int(sizeof(float))); EXPECT_GT(brightness, 0.01) << "Worker output frame is black (brightness=" << brightness << ")"; - SaveFrameAsPng(output_data, output_width_, output_height_, - temp_dir_.filePath(QStringLiteral("worker_output_opengl.png"))); + SaveFrameAsPng( + output_data, output_width_, output_height_, + temp_dir_.filePath(QStringLiteral("worker_output_opengl.png"))); QFile::remove(QStringLiteral("/tmp/worker_output_opengl.png")); QFile::copy(temp_dir_.filePath(QStringLiteral("worker_output_opengl.png")), QStringLiteral("/tmp/worker_output_opengl.png")); - std::cerr << "OpenGL output copied to /tmp/worker_output_opengl.png" << std::endl; + std::cerr << "OpenGL output copied to /tmp/worker_output_opengl.png" + << std::endl; output_pool_->Release(consumed_slot); } - diff --git a/tests/gtest/shader_resources_test.cpp b/tests/gtest/shader_resources_test.cpp index 5ffc1688c..1a00784d0 100644 --- a/tests/gtest/shader_resources_test.cpp +++ b/tests/gtest/shader_resources_test.cpp @@ -51,8 +51,8 @@ TEST(Shaders, ResourcesAvailable) for (const QString &path : shader_paths) { QFile file(path); - ASSERT_TRUE(file.exists()) << "Missing shader resource: " - << path.toStdString(); + ASSERT_TRUE(file.exists()) + << "Missing shader resource: " << path.toStdString(); ASSERT_TRUE(file.open(QIODevice::ReadOnly)) << "Failed to open shader resource: " << path.toStdString(); const QByteArray contents = file.readAll(); diff --git a/tests/gtest/task_taskmanager_test.cpp b/tests/gtest/task_taskmanager_test.cpp index 581d35e99..14b4be9fa 100644 --- a/tests/gtest/task_taskmanager_test.cpp +++ b/tests/gtest/task_taskmanager_test.cpp @@ -5,7 +5,8 @@ #include "task/taskmanager.h" -namespace { +namespace +{ class DummyTask final : public olive::Task { public: explicit DummyTask(bool *ran) @@ -74,9 +75,8 @@ TEST(TaskManager, AddAndRunTask) DummyTask *task = new DummyTask(&ran); QEventLoop loop; - QObject::connect(task, &olive::Task::Finished, &loop, [&loop](olive::Task *, bool) { - loop.quit(); - }); + QObject::connect(task, &olive::Task::Finished, &loop, + [&loop](olive::Task *, bool) { loop.quit(); }); mgr->AddTask(task); diff --git a/tests/gtest/timecode_metadata_test.cpp b/tests/gtest/timecode_metadata_test.cpp index a1c182b78..cb0b58410 100644 --- a/tests/gtest/timecode_metadata_test.cpp +++ b/tests/gtest/timecode_metadata_test.cpp @@ -36,8 +36,8 @@ TEST(TimecodeMetadata, ParsesDropFrameTimecode) TEST(TimecodeMetadata, ParsesBwfTimeReference) { const olive::TimecodeMetadata::SourceTime parsed = - olive::TimecodeMetadata::FromBwfTimeReference( - QStringLiteral("96000"), 48000); + olive::TimecodeMetadata::FromBwfTimeReference(QStringLiteral("96000"), + 48000); ASSERT_TRUE(parsed.valid); EXPECT_EQ(parsed.source, QStringLiteral("bwf_time_reference")); @@ -63,20 +63,20 @@ TEST(TimecodeMetadata, RejectsInvalidMetadata) EXPECT_FALSE(olive::TimecodeMetadata::FromBwfTimeReference( QStringLiteral("not-a-number"), 48000) .valid); - EXPECT_FALSE(olive::TimecodeMetadata::FromBwfTimeReference( - QStringLiteral("123"), 0) - .valid); - EXPECT_FALSE(olive::TimecodeMetadata::FromTimecodeString( - QStringLiteral("not-a-timecode"), - olive::core::rational(1, 24)) - .valid); + EXPECT_FALSE( + olive::TimecodeMetadata::FromBwfTimeReference(QStringLiteral("123"), 0) + .valid); + EXPECT_FALSE( + olive::TimecodeMetadata::FromTimecodeString( + QStringLiteral("not-a-timecode"), olive::core::rational(1, 24)) + .valid); } TEST(TimecodeMetadata, FromBwfTimeReferenceZeroSampleRateIsInvalid) { - EXPECT_FALSE(olive::TimecodeMetadata::FromBwfTimeReference( - QStringLiteral("0"), 0) - .valid); + EXPECT_FALSE( + olive::TimecodeMetadata::FromBwfTimeReference(QStringLiteral("0"), 0) + .valid); } TEST(TimecodeMetadata, FootageDescriptionWithoutSourceStartTime) @@ -113,8 +113,7 @@ TEST(TimecodeMetadata, FootagePersistsSourceStartTime) writer.writeStartElement(QStringLiteral("custom")); writer.writeTextElement(QStringLiteral("timestamp"), QStringLiteral("0")); writer.writeStartElement(QStringLiteral("sourcestarttime")); - writer.writeAttribute(QStringLiteral("source"), - QStringLiteral("timecode")); + writer.writeAttribute(QStringLiteral("source"), QStringLiteral("timecode")); writer.writeCharacters(QStringLiteral("3600/1")); writer.writeEndElement(); writer.writeEndElement(); diff --git a/tests/gtest/timeline_coordinate_test.cpp b/tests/gtest/timeline_coordinate_test.cpp index e28700ebe..61db18803 100644 --- a/tests/gtest/timeline_coordinate_test.cpp +++ b/tests/gtest/timeline_coordinate_test.cpp @@ -52,13 +52,17 @@ TEST(TimelineCoordinate, CopyAndAssignment) TEST(TimelineCoordinate, Equality) { olive::TimelineCoordinate a(olive::core::rational(5, 1), - olive::Track::Reference(olive::Track::kVideo, 1)); + olive::Track::Reference(olive::Track::kVideo, + 1)); olive::TimelineCoordinate b(olive::core::rational(5, 1), - olive::Track::Reference(olive::Track::kVideo, 1)); + olive::Track::Reference(olive::Track::kVideo, + 1)); olive::TimelineCoordinate c(olive::core::rational(6, 1), - olive::Track::Reference(olive::Track::kVideo, 1)); + olive::Track::Reference(olive::Track::kVideo, + 1)); olive::TimelineCoordinate d(olive::core::rational(5, 1), - olive::Track::Reference(olive::Track::kAudio, 1)); + olive::Track::Reference(olive::Track::kAudio, + 1)); EXPECT_EQ(a.GetFrame(), b.GetFrame()); EXPECT_EQ(a.GetTrack(), b.GetTrack()); diff --git a/tests/gtest/timeline_marker_test.cpp b/tests/gtest/timeline_marker_test.cpp index ad29fa6d5..c5d5b7752 100644 --- a/tests/gtest/timeline_marker_test.cpp +++ b/tests/gtest/timeline_marker_test.cpp @@ -51,20 +51,17 @@ TEST(TimelineMarkerList, OrderAndLookup) 1, olive::core::TimeRange(olive::core::rational(10, 1), olive::core::rational(10, 1)), - QStringLiteral("A"), - &list); + QStringLiteral("A"), &list); olive::TimelineMarker marker_b( 2, olive::core::TimeRange(olive::core::rational(5, 1), olive::core::rational(5, 1)), - QStringLiteral("B"), - &list); + QStringLiteral("B"), &list); olive::TimelineMarker marker_c( 3, olive::core::TimeRange(olive::core::rational(20, 1), olive::core::rational(20, 1)), - QStringLiteral("C"), - &list); + QStringLiteral("C"), &list); ASSERT_EQ(list.size(), 3); auto it = list.cbegin(); @@ -85,7 +82,8 @@ TEST(TimelineMarkerList, GetMarkerAtTimeReturnsNullWhenEmpty) { olive::TimelineMarkerList list; EXPECT_EQ(list.GetMarkerAtTime(olive::core::rational(10, 1)), nullptr); - EXPECT_EQ(list.GetClosestMarkerToTime(olive::core::rational(10, 1)), nullptr); + EXPECT_EQ(list.GetClosestMarkerToTime(olive::core::rational(10, 1)), + nullptr); } TEST(TimelineMarkerList, SaveLoadWithUnknownElements) @@ -95,8 +93,7 @@ TEST(TimelineMarkerList, SaveLoadWithUnknownElements) 4, olive::core::TimeRange(olive::core::rational(12, 1), olive::core::rational(15, 1)), - QStringLiteral("Span"), - &list); + QStringLiteral("Span"), &list); QByteArray xml; QBuffer buffer(&xml); @@ -130,8 +127,7 @@ TEST(TimelineMarkerCommands, AddRemoveAndChange) &list, olive::core::TimeRange(olive::core::rational(1, 1), olive::core::rational(2, 1)), - QStringLiteral("One"), - 1); + QStringLiteral("One"), 1); add.redo_now(); ASSERT_EQ(list.size(), 1); auto *marker = list.front(); @@ -159,14 +155,12 @@ TEST(TimelineMarkerCommands, AddRemoveAndChange) 2, olive::core::TimeRange(olive::core::rational(5, 1), olive::core::rational(5, 1)), - QStringLiteral("Two"), - &list); + QStringLiteral("Two"), &list); EXPECT_EQ(list.front()->time().in(), olive::core::rational(1, 1)); olive::MarkerChangeTimeCommand move( - marker, - olive::core::TimeRange(olive::core::rational(0, 1), - olive::core::rational(0, 1))); + marker, olive::core::TimeRange(olive::core::rational(0, 1), + olive::core::rational(0, 1))); move.redo_now(); EXPECT_EQ(list.front(), marker); move.undo_now(); @@ -180,8 +174,7 @@ TEST(TimelineMarkerCommands, AddCommandUndo) &list, olive::core::TimeRange(olive::core::rational(5, 1), olive::core::rational(5, 1)), - QStringLiteral("UndoMe"), - 2); + QStringLiteral("UndoMe"), 2); add.redo_now(); EXPECT_EQ(list.size(), 1); add.undo_now(); diff --git a/tests/gtest/timeline_waveform_sync_test.cpp b/tests/gtest/timeline_waveform_sync_test.cpp index 84b4f086d..56a50cd51 100644 --- a/tests/gtest/timeline_waveform_sync_test.cpp +++ b/tests/gtest/timeline_waveform_sync_test.cpp @@ -24,7 +24,8 @@ extern "C" { using namespace olive; using namespace olive::core; -namespace { +namespace +{ AudioParams MakeMonoParams(int sample_rate) { @@ -55,17 +56,16 @@ void WritePartialWaveform(AudioWaveformCache *cache, int sample_rate) waveform.OverwriteSamples(buf, sample_rate, rational(1)); // Tell the cache that only the middle second is valid in a 3-second clip. - cache->WriteWaveform(TimeRange(1, 2), - TimeRangeList({ TimeRange(1, 2) }), + cache->WriteWaveform(TimeRange(1, 2), TimeRangeList({ TimeRange(1, 2) }), &waveform); } -} // namespace +} // namespace TEST(TimelineWaveformSync, ExtractEnvelopeUsesOnlyValidatedRanges) { constexpr int kSampleRate = 48000; - constexpr size_t kWindowSamples = kSampleRate / 20; // 50 ms windows + constexpr size_t kWindowSamples = kSampleRate / 20; // 50 ms windows AudioWaveformCache cache; WritePartialWaveform(&cache, kSampleRate); @@ -76,8 +76,8 @@ TEST(TimelineWaveformSync, ExtractEnvelopeUsesOnlyValidatedRanges) clip.sample_rate = kSampleRate; const QVector envelope = - TimelineWaveformSync::ExtractWaveformCacheEnvelope( - clip, kSampleRate, kWindowSamples); + TimelineWaveformSync::ExtractWaveformCacheEnvelope(clip, kSampleRate, + kWindowSamples); // 3 seconds at 20 windows per second == 60 windows. EXPECT_EQ(envelope.size(), 60); @@ -134,8 +134,7 @@ TEST(TimelineWaveformSync, EmptyCacheIsNotReady) clip.set_length_and_media_out(rational(3)); clip.set_media_in(rational(0)); - Node::ConnectEdge( - &footage, NodeInput(&clip, ClipBlock::kBufferIn)); + Node::ConnectEdge(&footage, NodeInput(&clip, ClipBlock::kBufferIn)); WaveformSyncClip out; EXPECT_FALSE(TimelineWaveformSync::GetWaveformSyncClip(&clip, &out)); diff --git a/tests/gtest/timeline_workarea_test.cpp b/tests/gtest/timeline_workarea_test.cpp index c50367bac..8c1a8df99 100644 --- a/tests/gtest/timeline_workarea_test.cpp +++ b/tests/gtest/timeline_workarea_test.cpp @@ -28,7 +28,7 @@ TEST(TimelineWorkArea, SaveLoadRoundTrip) olive::TimelineWorkArea workarea; workarea.set_enabled(true); workarea.set_range(olive::core::TimeRange(olive::core::rational(2, 1), - olive::core::rational(6, 1))); + olive::core::rational(6, 1))); QByteArray xml; QBuffer buffer(&xml); @@ -51,7 +51,7 @@ TEST(TimelineWorkArea, SaveLoadRoundTrip) EXPECT_TRUE(loaded.enabled()); EXPECT_EQ(loaded.range(), olive::core::TimeRange(olive::core::rational(2, 1), - olive::core::rational(6, 1))); + olive::core::rational(6, 1))); } TEST(TimelineWorkArea, DisabledWorkAreaRoundTrip) @@ -59,7 +59,7 @@ TEST(TimelineWorkArea, DisabledWorkAreaRoundTrip) olive::TimelineWorkArea workarea; workarea.set_enabled(false); workarea.set_range(olive::core::TimeRange(olive::core::rational(0, 1), - olive::core::rational(10, 1))); + olive::core::rational(10, 1))); QByteArray xml; QBuffer buffer(&xml); @@ -82,14 +82,14 @@ TEST(TimelineWorkArea, DisabledWorkAreaRoundTrip) EXPECT_FALSE(loaded.enabled()); EXPECT_EQ(loaded.range(), olive::core::TimeRange(olive::core::rational(0, 1), - olive::core::rational(10, 1))); + olive::core::rational(10, 1))); } TEST(TimelineWorkArea, SetRangeUpdatesInOut) { olive::TimelineWorkArea workarea; workarea.set_range(olive::core::TimeRange(olive::core::rational(3, 1), - olive::core::rational(8, 1))); + olive::core::rational(8, 1))); EXPECT_EQ(workarea.in(), olive::core::rational(3, 1)); EXPECT_EQ(workarea.out(), olive::core::rational(8, 1)); diff --git a/tests/gtest/undo_stack_test.cpp b/tests/gtest/undo_stack_test.cpp index 97b52d8f7..416dd8786 100644 --- a/tests/gtest/undo_stack_test.cpp +++ b/tests/gtest/undo_stack_test.cpp @@ -5,7 +5,8 @@ #include "undo/undostack.h" #include "undo/undocommand.h" -namespace { +namespace +{ class TestCommand final : public olive::UndoCommand { public: explicit TestCommand(int *value) diff --git a/tests/gtest/viewer_smoke_test.cpp b/tests/gtest/viewer_smoke_test.cpp index 026207de2..7b80ec972 100644 --- a/tests/gtest/viewer_smoke_test.cpp +++ b/tests/gtest/viewer_smoke_test.cpp @@ -25,9 +25,12 @@ using namespace olive; using namespace olive::core; -namespace olive { -namespace viewer { -namespace test { +namespace olive +{ +namespace viewer +{ +namespace test +{ // ============================================================================ // Smoke Test: ViewerPlaybackTimer @@ -35,92 +38,92 @@ namespace test { TEST(ViewerSmokeTimer, DefaultConstruction) { - ViewerPlaybackTimer timer; - // Timer should be in a valid but not-started state - // After Start() is called, it should return valid timestamps + ViewerPlaybackTimer timer; + // Timer should be in a valid but not-started state + // After Start() is called, it should return valid timestamps } TEST(ViewerSmokeTimer, BasicTiming) { - ViewerPlaybackTimer timer; - - // Start at timestamp 0, 1x speed, 24fps (timebase = 1/24) - timer.Start(0, 1, 1.0 / 24.0); - - // Immediately get timestamp (should be close to 0) - int64_t ts = timer.GetTimestampNow(); - EXPECT_GE(ts, 0); - - // Wait a bit and check timestamp has increased - QThread::msleep(50); // 50ms - int64_t ts2 = timer.GetTimestampNow(); - - // At 24fps, 50ms should be approximately 1 frame (or slightly more) - // Allow for some timing variance - EXPECT_GE(ts2, ts); + ViewerPlaybackTimer timer; + + // Start at timestamp 0, 1x speed, 24fps (timebase = 1/24) + timer.Start(0, 1, 1.0 / 24.0); + + // Immediately get timestamp (should be close to 0) + int64_t ts = timer.GetTimestampNow(); + EXPECT_GE(ts, 0); + + // Wait a bit and check timestamp has increased + QThread::msleep(50); // 50ms + int64_t ts2 = timer.GetTimestampNow(); + + // At 24fps, 50ms should be approximately 1 frame (or slightly more) + // Allow for some timing variance + EXPECT_GE(ts2, ts); } TEST(ViewerSmokeTimer, PlaybackSpeedForward) { - ViewerPlaybackTimer timer; - - // Start at timestamp 100, 2x speed, 30fps - timer.Start(100, 2, 1.0 / 30.0); - - int64_t ts1 = timer.GetTimestampNow(); - QThread::msleep(50); - int64_t ts2 = timer.GetTimestampNow(); - - // At 2x speed, time should advance twice as fast - EXPECT_GT(ts2, ts1); + ViewerPlaybackTimer timer; + + // Start at timestamp 100, 2x speed, 30fps + timer.Start(100, 2, 1.0 / 30.0); + + int64_t ts1 = timer.GetTimestampNow(); + QThread::msleep(50); + int64_t ts2 = timer.GetTimestampNow(); + + // At 2x speed, time should advance twice as fast + EXPECT_GT(ts2, ts1); } TEST(ViewerSmokeTimer, PlaybackSpeedReverse) { - ViewerPlaybackTimer timer; - - // Start at timestamp 1000, -1x speed (reverse), 24fps - timer.Start(1000, -1, 1.0 / 24.0); - - int64_t ts1 = timer.GetTimestampNow(); - QThread::msleep(50); - int64_t ts2 = timer.GetTimestampNow(); - - // In reverse, timestamp should decrease - EXPECT_LT(ts2, ts1); + ViewerPlaybackTimer timer; + + // Start at timestamp 1000, -1x speed (reverse), 24fps + timer.Start(1000, -1, 1.0 / 24.0); + + int64_t ts1 = timer.GetTimestampNow(); + QThread::msleep(50); + int64_t ts2 = timer.GetTimestampNow(); + + // In reverse, timestamp should decrease + EXPECT_LT(ts2, ts1); } TEST(ViewerSmokeTimer, DifferentTimebases) { - ViewerPlaybackTimer timer; - - // Test with 24fps - timer.Start(0, 1, 1.0 / 24.0); - QThread::msleep(100); - int64_t ts24 = timer.GetTimestampNow(); - - // Test with 60fps - timer.Start(0, 1, 1.0 / 60.0); - QThread::msleep(100); - int64_t ts60 = timer.GetTimestampNow(); - - // At same real time, 60fps should have more frames than 24fps - EXPECT_GT(ts60, ts24); + ViewerPlaybackTimer timer; + + // Test with 24fps + timer.Start(0, 1, 1.0 / 24.0); + QThread::msleep(100); + int64_t ts24 = timer.GetTimestampNow(); + + // Test with 60fps + timer.Start(0, 1, 1.0 / 60.0); + QThread::msleep(100); + int64_t ts60 = timer.GetTimestampNow(); + + // At same real time, 60fps should have more frames than 24fps + EXPECT_GT(ts60, ts24); } TEST(ViewerSmokeTimer, ZeroSpeed) { - ViewerPlaybackTimer timer; - - // Start with 0 speed (paused) - timer.Start(500, 0, 1.0 / 24.0); - - int64_t ts1 = timer.GetTimestampNow(); - QThread::msleep(50); - int64_t ts2 = timer.GetTimestampNow(); - - // With 0 speed, timestamp should not change - EXPECT_EQ(ts1, ts2); + ViewerPlaybackTimer timer; + + // Start with 0 speed (paused) + timer.Start(500, 0, 1.0 / 24.0); + + int64_t ts1 = timer.GetTimestampNow(); + QThread::msleep(50); + int64_t ts2 = timer.GetTimestampNow(); + + // With 0 speed, timestamp should not change + EXPECT_EQ(ts1, ts2); } // ============================================================================ @@ -129,121 +132,121 @@ TEST(ViewerSmokeTimer, ZeroSpeed) TEST(ViewerSmokeQueue, DefaultConstruction) { - ViewerQueue queue; - EXPECT_TRUE(queue.empty()); + ViewerQueue queue; + EXPECT_TRUE(queue.empty()); } TEST(ViewerSmokeQueue, AppendForwardPlayback) { - ViewerQueue queue; - - // Append frames for forward playback - ViewerPlaybackFrame frame1{rational(0), QVariant()}; - ViewerPlaybackFrame frame2{rational(1, 24), QVariant()}; - ViewerPlaybackFrame frame3{rational(2, 24), QVariant()}; - - queue.AppendTimewise(frame1, 1); // speed = 1 (forward) - queue.AppendTimewise(frame2, 1); - queue.AppendTimewise(frame3, 1); - - EXPECT_EQ(queue.size(), 3); - - // Verify order (should be chronological for forward playback) - auto it = queue.begin(); - EXPECT_EQ(it->timestamp, rational(0)); - ++it; - EXPECT_EQ(it->timestamp, rational(1, 24)); - ++it; - EXPECT_EQ(it->timestamp, rational(2, 24)); + ViewerQueue queue; + + // Append frames for forward playback + ViewerPlaybackFrame frame1{ rational(0), QVariant() }; + ViewerPlaybackFrame frame2{ rational(1, 24), QVariant() }; + ViewerPlaybackFrame frame3{ rational(2, 24), QVariant() }; + + queue.AppendTimewise(frame1, 1); // speed = 1 (forward) + queue.AppendTimewise(frame2, 1); + queue.AppendTimewise(frame3, 1); + + EXPECT_EQ(queue.size(), 3); + + // Verify order (should be chronological for forward playback) + auto it = queue.begin(); + EXPECT_EQ(it->timestamp, rational(0)); + ++it; + EXPECT_EQ(it->timestamp, rational(1, 24)); + ++it; + EXPECT_EQ(it->timestamp, rational(2, 24)); } TEST(ViewerSmokeQueue, AppendReversePlayback) { - ViewerQueue queue; - - // Append frames for reverse playback - ViewerPlaybackFrame frame1{rational(2, 24), QVariant()}; - ViewerPlaybackFrame frame2{rational(1, 24), QVariant()}; - ViewerPlaybackFrame frame3{rational(0), QVariant()}; - - queue.AppendTimewise(frame1, -1); // speed = -1 (reverse) - queue.AppendTimewise(frame2, -1); - queue.AppendTimewise(frame3, -1); - - EXPECT_EQ(queue.size(), 3); - - // Verify order (should be reverse chronological for reverse playback) - auto it = queue.begin(); - EXPECT_EQ(it->timestamp, rational(2, 24)); - ++it; - EXPECT_EQ(it->timestamp, rational(1, 24)); - ++it; - EXPECT_EQ(it->timestamp, rational(0)); + ViewerQueue queue; + + // Append frames for reverse playback + ViewerPlaybackFrame frame1{ rational(2, 24), QVariant() }; + ViewerPlaybackFrame frame2{ rational(1, 24), QVariant() }; + ViewerPlaybackFrame frame3{ rational(0), QVariant() }; + + queue.AppendTimewise(frame1, -1); // speed = -1 (reverse) + queue.AppendTimewise(frame2, -1); + queue.AppendTimewise(frame3, -1); + + EXPECT_EQ(queue.size(), 3); + + // Verify order (should be reverse chronological for reverse playback) + auto it = queue.begin(); + EXPECT_EQ(it->timestamp, rational(2, 24)); + ++it; + EXPECT_EQ(it->timestamp, rational(1, 24)); + ++it; + EXPECT_EQ(it->timestamp, rational(0)); } TEST(ViewerSmokeQueue, InsertOutOfOrder) { - ViewerQueue queue; - - // Insert frames out of order for forward playback - ViewerPlaybackFrame frame1{rational(0), QVariant()}; - ViewerPlaybackFrame frame2{rational(2, 24), QVariant()}; - ViewerPlaybackFrame frame3{rational(1, 24), QVariant()}; // Middle frame - - queue.AppendTimewise(frame1, 1); - queue.AppendTimewise(frame2, 1); - queue.AppendTimewise(frame3, 1); // Should insert in middle - - EXPECT_EQ(queue.size(), 3); - - // Verify correct order - auto it = queue.begin(); - EXPECT_EQ(it->timestamp, rational(0)); - ++it; - EXPECT_EQ(it->timestamp, rational(1, 24)); - ++it; - EXPECT_EQ(it->timestamp, rational(2, 24)); + ViewerQueue queue; + + // Insert frames out of order for forward playback + ViewerPlaybackFrame frame1{ rational(0), QVariant() }; + ViewerPlaybackFrame frame2{ rational(2, 24), QVariant() }; + ViewerPlaybackFrame frame3{ rational(1, 24), QVariant() }; // Middle frame + + queue.AppendTimewise(frame1, 1); + queue.AppendTimewise(frame2, 1); + queue.AppendTimewise(frame3, 1); // Should insert in middle + + EXPECT_EQ(queue.size(), 3); + + // Verify correct order + auto it = queue.begin(); + EXPECT_EQ(it->timestamp, rational(0)); + ++it; + EXPECT_EQ(it->timestamp, rational(1, 24)); + ++it; + EXPECT_EQ(it->timestamp, rational(2, 24)); } TEST(ViewerSmokeQueue, PurgeBefore) { - ViewerQueue queue; - - // Add some frames - for (int i = 0; i < 10; i++) { - ViewerPlaybackFrame frame{rational(i, 24), QVariant()}; - queue.AppendTimewise(frame, 1); - } - - EXPECT_EQ(queue.size(), 10); - - // Purge frames before 5/24 - queue.PurgeBefore(rational(5, 24), 1); - - // Should have 5 frames remaining (5, 6, 7, 8, 9) - EXPECT_EQ(queue.size(), 5); - EXPECT_EQ(queue.front().timestamp, rational(5, 24)); + ViewerQueue queue; + + // Add some frames + for (int i = 0; i < 10; i++) { + ViewerPlaybackFrame frame{ rational(i, 24), QVariant() }; + queue.AppendTimewise(frame, 1); + } + + EXPECT_EQ(queue.size(), 10); + + // Purge frames before 5/24 + queue.PurgeBefore(rational(5, 24), 1); + + // Should have 5 frames remaining (5, 6, 7, 8, 9) + EXPECT_EQ(queue.size(), 5); + EXPECT_EQ(queue.front().timestamp, rational(5, 24)); } TEST(ViewerSmokeQueue, PurgeBeforeReverse) { - ViewerQueue queue; - - // Add frames for reverse playback (newest first) - for (int i = 9; i >= 0; i--) { - ViewerPlaybackFrame frame{rational(i, 24), QVariant()}; - queue.AppendTimewise(frame, -1); - } - - EXPECT_EQ(queue.size(), 10); - - // In reverse playback, front() is the largest timestamp (9/24) - // PurgeBefore with negative speed removes frames where front > time - queue.PurgeBefore(rational(5, 24), -1); - - // Should have frames 0-5 remaining (those <= 5/24) - EXPECT_EQ(queue.size(), 6); - EXPECT_EQ(queue.front().timestamp, rational(5, 24)); + ViewerQueue queue; + + // Add frames for reverse playback (newest first) + for (int i = 9; i >= 0; i--) { + ViewerPlaybackFrame frame{ rational(i, 24), QVariant() }; + queue.AppendTimewise(frame, -1); + } + + EXPECT_EQ(queue.size(), 10); + + // In reverse playback, front() is the largest timestamp (9/24) + // PurgeBefore with negative speed removes frames where front > time + queue.PurgeBefore(rational(5, 24), -1); + + // Should have frames 0-5 remaining (those <= 5/24) + EXPECT_EQ(queue.size(), 6); + EXPECT_EQ(queue.front().timestamp, rational(5, 24)); } // ============================================================================ @@ -252,57 +255,57 @@ TEST(ViewerSmokeQueue, PurgeBeforeReverse) TEST(ViewerSmokeSafeMargin, DefaultConstruction) { - ViewerSafeMarginInfo info; - EXPECT_FALSE(info.is_enabled()); - EXPECT_FALSE(info.custom_ratio()); - EXPECT_DOUBLE_EQ(info.ratio(), 0.0); + ViewerSafeMarginInfo info; + EXPECT_FALSE(info.is_enabled()); + EXPECT_FALSE(info.custom_ratio()); + EXPECT_DOUBLE_EQ(info.ratio(), 0.0); } TEST(ViewerSmokeSafeMargin, EnabledConstruction) { - ViewerSafeMarginInfo info(true); - EXPECT_TRUE(info.is_enabled()); - EXPECT_FALSE(info.custom_ratio()); + ViewerSafeMarginInfo info(true); + EXPECT_TRUE(info.is_enabled()); + EXPECT_FALSE(info.custom_ratio()); } TEST(ViewerSmokeSafeMargin, CustomRatioConstruction) { - ViewerSafeMarginInfo info(true, 0.9); - EXPECT_TRUE(info.is_enabled()); - EXPECT_TRUE(info.custom_ratio()); - EXPECT_DOUBLE_EQ(info.ratio(), 0.9); + ViewerSafeMarginInfo info(true, 0.9); + EXPECT_TRUE(info.is_enabled()); + EXPECT_TRUE(info.custom_ratio()); + EXPECT_DOUBLE_EQ(info.ratio(), 0.9); } TEST(ViewerSmokeSafeMargin, EqualityOperators) { - ViewerSafeMarginInfo info1(true, 0.9); - ViewerSafeMarginInfo info2(true, 0.9); - ViewerSafeMarginInfo info3(false, 0.9); - ViewerSafeMarginInfo info4(true, 0.8); - - EXPECT_TRUE(info1 == info2); - EXPECT_FALSE(info1 != info2); - - EXPECT_FALSE(info1 == info3); // Different enabled state - EXPECT_FALSE(info1 == info4); // Different ratio - EXPECT_TRUE(info1 != info3); + ViewerSafeMarginInfo info1(true, 0.9); + ViewerSafeMarginInfo info2(true, 0.9); + ViewerSafeMarginInfo info3(false, 0.9); + ViewerSafeMarginInfo info4(true, 0.8); + + EXPECT_TRUE(info1 == info2); + EXPECT_FALSE(info1 != info2); + + EXPECT_FALSE(info1 == info3); // Different enabled state + EXPECT_FALSE(info1 == info4); // Different ratio + EXPECT_TRUE(info1 != info3); } TEST(ViewerSmokeSafeMargin, ZeroRatio) { - ViewerSafeMarginInfo info(true, 0.0); - EXPECT_TRUE(info.is_enabled()); - EXPECT_FALSE(info.custom_ratio()); // 0 ratio means no custom ratio + ViewerSafeMarginInfo info(true, 0.0); + EXPECT_TRUE(info.is_enabled()); + EXPECT_FALSE(info.custom_ratio()); // 0 ratio means no custom ratio } TEST(ViewerSmokeSafeMargin, CopyConstruction) { - ViewerSafeMarginInfo original(true, 0.85); - ViewerSafeMarginInfo copy(original); - - EXPECT_EQ(copy.is_enabled(), original.is_enabled()); - EXPECT_EQ(copy.custom_ratio(), original.custom_ratio()); - EXPECT_DOUBLE_EQ(copy.ratio(), original.ratio()); + ViewerSafeMarginInfo original(true, 0.85); + ViewerSafeMarginInfo copy(original); + + EXPECT_EQ(copy.is_enabled(), original.is_enabled()); + EXPECT_EQ(copy.custom_ratio(), original.custom_ratio()); + EXPECT_DOUBLE_EQ(copy.ratio(), original.ratio()); } // ============================================================================ @@ -311,30 +314,30 @@ TEST(ViewerSmokeSafeMargin, CopyConstruction) TEST(ViewerSmokeAudioCache, DefaultConstruction) { - AudioPlaybackCache cache; - // Should construct without crashing - SUCCEED(); + AudioPlaybackCache cache; + // Should construct without crashing + SUCCEED(); } TEST(ViewerSmokeAudioCache, ParameterSetters) { - AudioPlaybackCache cache; - - AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); - cache.SetParameters(params); - - // Parameters should be retrievable - AudioParams retrieved = cache.GetParameters(); - EXPECT_EQ(retrieved.sample_rate(), params.sample_rate()); + AudioPlaybackCache cache; + + AudioParams params(48000, AV_CH_LAYOUT_STEREO, SampleFormat::F32P); + cache.SetParameters(params); + + // Parameters should be retrievable + AudioParams retrieved = cache.GetParameters(); + EXPECT_EQ(retrieved.sample_rate(), params.sample_rate()); } TEST(ViewerSmokeAudioCache, ValidateWithRange) { - AudioPlaybackCache cache; - - // Initially no validated ranges - TimeRangeList validated = cache.GetValidatedRanges(); - EXPECT_TRUE(validated.isEmpty()); + AudioPlaybackCache cache; + + // Initially no validated ranges + TimeRangeList validated = cache.GetValidatedRanges(); + EXPECT_TRUE(validated.isEmpty()); } // ============================================================================ @@ -346,32 +349,32 @@ TEST(ViewerSmokeAudioCache, ValidateWithRange) TEST(ViewerSmokeAutoCacher, DISABLED_Construction) { - // PreviewAutoCacher requires full GUI environment - SUCCEED(); + // PreviewAutoCacher requires full GUI environment + SUCCEED(); } TEST(ViewerSmokeAutoCacher, DISABLED_SetPlayhead) { - // PreviewAutoCacher requires full GUI environment - SUCCEED(); + // PreviewAutoCacher requires full GUI environment + SUCCEED(); } TEST(ViewerSmokeAutoCacher, DISABLED_PauseControls) { - // PreviewAutoCacher requires full GUI environment - SUCCEED(); + // PreviewAutoCacher requires full GUI environment + SUCCEED(); } TEST(ViewerSmokeAutoCacher, DISABLED_SetIgnoreCacheRequests) { - // PreviewAutoCacher requires full GUI environment - SUCCEED(); + // PreviewAutoCacher requires full GUI environment + SUCCEED(); } TEST(ViewerSmokeAutoCacher, DISABLED_SetDisplayColorProcessor) { - // PreviewAutoCacher requires full GUI environment - SUCCEED(); + // PreviewAutoCacher requires full GUI environment + SUCCEED(); } // ============================================================================ @@ -380,73 +383,73 @@ TEST(ViewerSmokeAutoCacher, DISABLED_SetDisplayColorProcessor) TEST(ViewerSmokeRational, DefaultConstruction) { - rational r; - EXPECT_EQ(r.numerator(), 0); - EXPECT_EQ(r.denominator(), 1); + rational r; + EXPECT_EQ(r.numerator(), 0); + EXPECT_EQ(r.denominator(), 1); } TEST(ViewerSmokeRational, ValueConstruction) { - rational r(24, 1); - EXPECT_EQ(r.numerator(), 24); - EXPECT_EQ(r.denominator(), 1); - - rational r2(1, 24); - EXPECT_EQ(r2.numerator(), 1); - EXPECT_EQ(r2.denominator(), 24); + rational r(24, 1); + EXPECT_EQ(r.numerator(), 24); + EXPECT_EQ(r.denominator(), 1); + + rational r2(1, 24); + EXPECT_EQ(r2.numerator(), 1); + EXPECT_EQ(r2.denominator(), 24); } TEST(ViewerSmokeRational, ToDouble) { - rational r(1, 2); - EXPECT_DOUBLE_EQ(r.toDouble(), 0.5); - - rational r2(3, 4); - EXPECT_DOUBLE_EQ(r2.toDouble(), 0.75); + rational r(1, 2); + EXPECT_DOUBLE_EQ(r.toDouble(), 0.5); + + rational r2(3, 4); + EXPECT_DOUBLE_EQ(r2.toDouble(), 0.75); } TEST(ViewerSmokeRational, Arithmetic) { - rational r1(1, 2); - rational r2(1, 4); - - rational sum = r1 + r2; - EXPECT_EQ(sum.numerator(), 3); - EXPECT_EQ(sum.denominator(), 4); - - rational diff = r1 - r2; - EXPECT_EQ(diff.numerator(), 1); - EXPECT_EQ(diff.denominator(), 4); + rational r1(1, 2); + rational r2(1, 4); + + rational sum = r1 + r2; + EXPECT_EQ(sum.numerator(), 3); + EXPECT_EQ(sum.denominator(), 4); + + rational diff = r1 - r2; + EXPECT_EQ(diff.numerator(), 1); + EXPECT_EQ(diff.denominator(), 4); } TEST(ViewerSmokeRational, Comparison) { - rational r1(1, 2); - rational r2(2, 4); - rational r3(3, 4); - - EXPECT_TRUE(r1 == r2); // Equivalent fractions - EXPECT_FALSE(r1 == r3); - EXPECT_TRUE(r1 < r3); - EXPECT_TRUE(r3 > r1); + rational r1(1, 2); + rational r2(2, 4); + rational r3(3, 4); + + EXPECT_TRUE(r1 == r2); // Equivalent fractions + EXPECT_FALSE(r1 == r3); + EXPECT_TRUE(r1 < r3); + EXPECT_TRUE(r3 > r1); } TEST(ViewerSmokeRational, NullCheck) { - rational r; - EXPECT_TRUE(r.isNull()); // 0/1 is considered null - - rational r2(1, 2); - EXPECT_FALSE(r2.isNull()); + rational r; + EXPECT_TRUE(r.isNull()); // 0/1 is considered null + + rational r2(1, 2); + EXPECT_FALSE(r2.isNull()); } TEST(ViewerSmokeRational, Flipped) { - rational r(24, 1); - rational flipped = r.flipped(); - - EXPECT_EQ(flipped.numerator(), 1); - EXPECT_EQ(flipped.denominator(), 24); + rational r(24, 1); + rational flipped = r.flipped(); + + EXPECT_EQ(flipped.numerator(), 1); + EXPECT_EQ(flipped.denominator(), 24); } // ============================================================================ @@ -455,58 +458,61 @@ TEST(ViewerSmokeRational, Flipped) TEST(ViewerSmokeThread, ConcurrentTimerAccess) { - const int num_threads = 4; - const int num_iterations = 100; - - ViewerPlaybackTimer timer; - timer.Start(0, 1, 1.0 / 30.0); - - std::vector threads; - std::atomic success_count{0}; - - for (int t = 0; t < num_threads; ++t) { - threads.emplace_back([&timer, &success_count, num_iterations]() { - for (int i = 0; i < num_iterations; ++i) { - int64_t ts = timer.GetTimestampNow(); - if (ts >= 0) { - success_count++; - } - } - }); - } - - for (auto &t : threads) { - t.join(); - } - - EXPECT_EQ(success_count.load(), num_threads * num_iterations); + const int num_threads = 4; + const int num_iterations = 100; + + ViewerPlaybackTimer timer; + timer.Start(0, 1, 1.0 / 30.0); + + std::vector threads; + std::atomic success_count{ 0 }; + + for (int t = 0; t < num_threads; ++t) { + threads.emplace_back([&timer, &success_count, num_iterations]() { + for (int i = 0; i < num_iterations; ++i) { + int64_t ts = timer.GetTimestampNow(); + if (ts >= 0) { + success_count++; + } + } + }); + } + + for (auto &t : threads) { + t.join(); + } + + EXPECT_EQ(success_count.load(), num_threads * num_iterations); } TEST(ViewerSmokeThread, ConcurrentQueueAccess) { - const int num_threads = 4; - const int num_frames_per_thread = 25; - - ViewerQueue queue; - std::vector threads; - std::atomic append_count{0}; - - for (int t = 0; t < num_threads; ++t) { - threads.emplace_back([&queue, &append_count, t, num_frames_per_thread]() { - for (int i = 0; i < num_frames_per_thread; ++i) { - ViewerPlaybackFrame frame{rational(t * num_frames_per_thread + i, 24), QVariant()}; - queue.AppendTimewise(frame, 1); - append_count++; - } - }); - } - - for (auto &t : threads) { - t.join(); - } - - EXPECT_EQ(append_count.load(), num_threads * num_frames_per_thread); - EXPECT_EQ(queue.size(), num_threads * num_frames_per_thread); + const int num_threads = 4; + const int num_frames_per_thread = 25; + + ViewerQueue queue; + std::vector threads; + std::atomic append_count{ 0 }; + + for (int t = 0; t < num_threads; ++t) { + threads.emplace_back( + [&queue, &append_count, t, num_frames_per_thread]() { + for (int i = 0; i < num_frames_per_thread; ++i) { + ViewerPlaybackFrame frame{ + rational(t * num_frames_per_thread + i, 24), QVariant() + }; + queue.AppendTimewise(frame, 1); + append_count++; + } + }); + } + + for (auto &t : threads) { + t.join(); + } + + EXPECT_EQ(append_count.load(), num_threads * num_frames_per_thread); + EXPECT_EQ(queue.size(), num_threads * num_frames_per_thread); } // ============================================================================ @@ -515,70 +521,70 @@ TEST(ViewerSmokeThread, ConcurrentQueueAccess) TEST(ViewerSmokeIntegration, PlaybackSequenceSimulation) { - // Simulate a basic playback sequence - ViewerPlaybackTimer timer; - ViewerQueue queue; - - // Start playback at frame 0, 24fps - timer.Start(0, 1, 1.0 / 24.0); - - // Queue some frames - for (int i = 0; i < 10; i++) { - ViewerPlaybackFrame frame{rational(i, 24), QVariant(i)}; - queue.AppendTimewise(frame, 1); - } - - // Get current timestamp - int64_t current_ts = timer.GetTimestampNow(); - - // Find frame closest to current time - rational current_time(current_ts, 1); - bool found = false; - for (const auto &frame : queue) { - if (frame.timestamp >= current_time) { - found = true; - break; - } - } - - // Should have frames available - EXPECT_FALSE(queue.empty()); + // Simulate a basic playback sequence + ViewerPlaybackTimer timer; + ViewerQueue queue; + + // Start playback at frame 0, 24fps + timer.Start(0, 1, 1.0 / 24.0); + + // Queue some frames + for (int i = 0; i < 10; i++) { + ViewerPlaybackFrame frame{ rational(i, 24), QVariant(i) }; + queue.AppendTimewise(frame, 1); + } + + // Get current timestamp + int64_t current_ts = timer.GetTimestampNow(); + + // Find frame closest to current time + rational current_time(current_ts, 1); + bool found = false; + for (const auto &frame : queue) { + if (frame.timestamp >= current_time) { + found = true; + break; + } + } + + // Should have frames available + EXPECT_FALSE(queue.empty()); } TEST(ViewerSmokeIntegration, SafeMarginWithDifferentAspectRatios) { - // Test safe margins for different aspect ratios - std::vector ratios = {0.9, 0.85, 0.8, 0.7}; - - for (double ratio : ratios) { - ViewerSafeMarginInfo info(true, ratio); - EXPECT_TRUE(info.is_enabled()); - EXPECT_TRUE(info.custom_ratio()); - EXPECT_DOUBLE_EQ(info.ratio(), ratio); - } + // Test safe margins for different aspect ratios + std::vector ratios = { 0.9, 0.85, 0.8, 0.7 }; + + for (double ratio : ratios) { + ViewerSafeMarginInfo info(true, ratio); + EXPECT_TRUE(info.is_enabled()); + EXPECT_TRUE(info.custom_ratio()); + EXPECT_DOUBLE_EQ(info.ratio(), ratio); + } } TEST(ViewerSmokeIntegration, ReversePlaybackScenario) { - ViewerPlaybackTimer timer; - ViewerQueue queue; - - // Start reverse playback from frame 100 - timer.Start(100, -1, 1.0 / 24.0); - - // Queue frames in reverse order - for (int i = 100; i >= 90; i--) { - ViewerPlaybackFrame frame{rational(i, 24), QVariant(i)}; - queue.AppendTimewise(frame, -1); - } - - // Get timestamps - should decrease - int64_t ts1 = timer.GetTimestampNow(); - QThread::msleep(50); - int64_t ts2 = timer.GetTimestampNow(); - - EXPECT_LT(ts2, ts1); - EXPECT_EQ(queue.front().timestamp, rational(100, 24)); + ViewerPlaybackTimer timer; + ViewerQueue queue; + + // Start reverse playback from frame 100 + timer.Start(100, -1, 1.0 / 24.0); + + // Queue frames in reverse order + for (int i = 100; i >= 90; i--) { + ViewerPlaybackFrame frame{ rational(i, 24), QVariant(i) }; + queue.AppendTimewise(frame, -1); + } + + // Get timestamps - should decrease + int64_t ts1 = timer.GetTimestampNow(); + QThread::msleep(50); + int64_t ts2 = timer.GetTimestampNow(); + + EXPECT_LT(ts2, ts1); + EXPECT_EQ(queue.front().timestamp, rational(100, 24)); } } // namespace test diff --git a/vcpkg.json b/vcpkg.json deleted file mode 100644 index dcc721db6..000000000 --- a/vcpkg.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "oak-video-editor", - "version-string": "0.0.0", - "dependencies": [ - "ffmpeg", - "openimageio", - "opencolorio", - "openexr", - "expat", - "portaudio" - ] -}