Merge branch 'plugin'
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
CompileFlags:
|
||||
Add: []
|
||||
Remove: [-mlongcalls, -fstrict-volatile-bitfields, -fno-shrink-wrap, -fno-tree-switch-conversion, -mno-direct-extern-access]
|
||||
CompileFlags:
|
||||
CompilationDatabase: build
|
||||
Diagnostics:
|
||||
Suppress: ['drv_unknown_argument', 'unused-includes', 'pp_file_not_found']
|
||||
@@ -0,0 +1,153 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build-test:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-2022]
|
||||
env:
|
||||
CMAKE_BUILD_TYPE: Release
|
||||
RUN_OFX_ITEST: "0"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Install dependencies (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
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 libavfilter-dev libavutil-dev libswscale-dev libswresample-dev \
|
||||
libopencolorio-dev libopenimageio-dev libopenexr-dev libexpat1-dev \
|
||||
portaudio19-dev libgl1-mesa-dev libxkbcommon-dev
|
||||
|
||||
- name: Install dependencies (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
brew update
|
||||
brew install ninja pkg-config qt@6 ffmpeg openimageio opencolorio openexr portaudio expat
|
||||
echo "$(brew --prefix qt@6)/bin" >> "$GITHUB_PATH"
|
||||
echo "CMAKE_PREFIX_PATH=$(brew --prefix qt@6)" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build OpenTimelineIO (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
git clone --depth 1 --branch v0.16.0 https://github.com/PixarAnimationStudios/OpenTimelineIO.git
|
||||
cmake -S OpenTimelineIO -B OpenTimelineIO/build -G Ninja \
|
||||
-DOTIO_SHARED_LIBS=ON \
|
||||
-DOTIO_PYTHON_BINDINGS=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX="${PWD}/otio-install"
|
||||
cmake --build OpenTimelineIO/build
|
||||
cmake --install OpenTimelineIO/build
|
||||
echo "OTIO_LOCATION=${PWD}/otio-install" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Install Qt (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: 6.5.3
|
||||
cache: true
|
||||
tools: 'tools_ninja'
|
||||
|
||||
- name: Install dependencies (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
choco install -y ninja
|
||||
$env:VCPKG_ROOT = "C:\vcpkg"
|
||||
& "$env:VCPKG_ROOT\vcpkg.exe" install ffmpeg openimageio opencolorio openexr expat portaudio --triplet x64-windows
|
||||
echo "VCPKG_ROOT=$env:VCPKG_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
echo "CMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
- name: Setup MSVC (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
- name: Configure (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
cmake -S . -B build -G Ninja \
|
||||
-DBUILD_TESTS=ON \
|
||||
-DBUILD_QT6=ON \
|
||||
-DOCIO_LOCATION=/usr \
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
|
||||
- name: Configure (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
cmake -S . -B build -G Ninja \
|
||||
-DBUILD_TESTS=ON \
|
||||
-DBUILD_QT6=ON \
|
||||
-DOCIO_LOCATION=$(brew --prefix opencolorio) \
|
||||
-DOTIO_LOCATION=${OTIO_LOCATION} \
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
|
||||
- name: Configure (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$toolchain = "$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake"
|
||||
$ninja = "$env:ChocolateyInstall\bin\ninja.exe"
|
||||
cmake -S . -B build -G Ninja `
|
||||
-DBUILD_TESTS=ON `
|
||||
-DBUILD_QT6=ON `
|
||||
-DCMAKE_BUILD_TYPE=$env:CMAKE_BUILD_TYPE `
|
||||
-DCMAKE_TOOLCHAIN_FILE=$toolchain `
|
||||
-DCMAKE_MAKE_PROGRAM=$ninja `
|
||||
-DCMAKE_PREFIX_PATH=$env:Qt6_DIR
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build --config ${{ env.CMAKE_BUILD_TYPE }}
|
||||
|
||||
- name: Build OpenFX misc plugins (Linux, optional)
|
||||
if: runner.os == 'Linux' && env.RUN_OFX_ITEST == '1'
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/NatronGitHub/openfx-misc.git
|
||||
cmake -S openfx-misc -B openfx-misc/build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build openfx-misc/build
|
||||
echo "OAK_OFX_ITEST=1" >> "$GITHUB_ENV"
|
||||
echo "OAK_OFX_PLUGIN_PATH=${PWD}/openfx-misc/build" >> "$GITHUB_ENV"
|
||||
echo "OAK_OFX_PLUGIN_ID=net.sf.openfx.ChromaKeyerPlugin" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build OpenFX misc plugins (macOS, optional)
|
||||
if: runner.os == 'macOS' && env.RUN_OFX_ITEST == '1'
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/NatronGitHub/openfx-misc.git
|
||||
cmake -S openfx-misc -B openfx-misc/build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build openfx-misc/build
|
||||
echo "OAK_OFX_ITEST=1" >> "$GITHUB_ENV"
|
||||
echo "OAK_OFX_PLUGIN_PATH=${PWD}/openfx-misc/build" >> "$GITHUB_ENV"
|
||||
echo "OAK_OFX_PLUGIN_ID=net.sf.openfx.ChromaKeyerPlugin" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build OpenFX misc plugins (Windows, optional)
|
||||
if: runner.os == 'Windows' && env.RUN_OFX_ITEST == '1'
|
||||
shell: pwsh
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/NatronGitHub/openfx-misc.git
|
||||
cmake -S openfx-misc -B openfx-misc/build -G Ninja `
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build openfx-misc/build
|
||||
"OAK_OFX_ITEST=1" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
"OAK_OFX_PLUGIN_PATH=$env:GITHUB_WORKSPACE\\openfx-misc\\build" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
"OAK_OFX_PLUGIN_ID=net.sf.openfx.ChromaKeyerPlugin" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
- name: Test (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
env:
|
||||
QT_QPA_PLATFORM: offscreen
|
||||
run: ctest --test-dir build --output-on-failure -C ${{ env.CMAKE_BUILD_TYPE }}
|
||||
|
||||
- name: Test (macOS/Windows)
|
||||
if: runner.os != 'Linux'
|
||||
run: ctest --test-dir build --output-on-failure -C ${{ env.CMAKE_BUILD_TYPE }}
|
||||
@@ -0,0 +1,47 @@
|
||||
name: Deploy Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, master]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: pages
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
- name: Build docs
|
||||
run: npm run docs:build
|
||||
env:
|
||||
BASE: /${{ github.event.repository.name }}/
|
||||
- name: Upload Pages artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: docs/.vuepress/dist
|
||||
deploy:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
+7
-3
@@ -1,8 +1,7 @@
|
||||
# CMake artifacts
|
||||
/build*/
|
||||
|
||||
build
|
||||
# Doxygen
|
||||
/docs/
|
||||
|
||||
# Visual Studio (Code)
|
||||
.localhistory/
|
||||
@@ -99,4 +98,9 @@ compile_flags.txt
|
||||
|
||||
*_qmlcache.qrc
|
||||
.idea/
|
||||
.vimspector.json
|
||||
.vimspector.json
|
||||
|
||||
AGENTS.md
|
||||
.codex
|
||||
operations-log.md
|
||||
verification.md
|
||||
+4
-2
@@ -1,6 +1,8 @@
|
||||
[submodule "ext/core"]
|
||||
path = ext/core
|
||||
url = https://github.com/olive-editor/core
|
||||
url = https://github.com/OliveCommunity/core.git
|
||||
branch = dev
|
||||
[submodule "ext/KDDockWidgets"]
|
||||
path = ext/KDDockWidgets
|
||||
url = https://github.com/olive-editor/KDDockWidgets.git
|
||||
url = https://github.com/OliveCommunity/KDDockWidgets.git
|
||||
branch = main
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
From 6b0ef44eb189411d36c739ccde8a081a3e62034a Mon Sep 17 00:00:00 2001
|
||||
From: Mike Solar <iam@mikesolar.com>
|
||||
Date: Mon, 24 Nov 2025 20:57:12 +0800
|
||||
Subject: [PATCH] Fix include path for Window_p.h in qtcommon directory
|
||||
|
||||
---
|
||||
src/qtcommon/Window_p.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/qtcommon/Window_p.h b/src/qtcommon/Window_p.h
|
||||
index f29b209a5..d1d6b47ad 100644
|
||||
--- a/src/qtcommon/Window_p.h
|
||||
+++ b/src/qtcommon/Window_p.h
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
-#include "core/Window_p.h"
|
||||
+#include "../core/Window_p.h"
|
||||
#include "Screen_p.h"
|
||||
|
||||
#include <QPointer>
|
||||
--
|
||||
2.52.0
|
||||
|
||||
+24
-1
@@ -1,5 +1,6 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2023 Olive Studios LLC
|
||||
# Modifications Copyright (C) 2025 mikesolar
|
||||
#
|
||||
# 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
|
||||
@@ -17,7 +18,15 @@
|
||||
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
|
||||
|
||||
project(olive-editor VERSION 0.2.0 LANGUAGES CXX)
|
||||
if(${CMAKE_BUILD_TYPE} EQUAL Debug)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory -g")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=memory -g")
|
||||
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory)
|
||||
endif ()
|
||||
|
||||
|
||||
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -DOFX_SUPPORTS_OPENGLRENDER)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOFX_SUPPORTS_OPENGLRENDER")
|
||||
option(BUILD_QT6 "Build with Qt 6 over 5 (experimental)" ON)
|
||||
option(BUILD_DOXYGEN "Build Doxygen documentation" OFF)
|
||||
option(BUILD_TESTS "Build unit tests" OFF)
|
||||
@@ -51,6 +60,7 @@ if(MSVC)
|
||||
/external:W0
|
||||
"$<$<CONFIG:RELEASE>:/O2>"
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:/MP>"
|
||||
/DOFX_SUPPORTS_OPENGLRENDER
|
||||
)
|
||||
if (USE_WERROR)
|
||||
list(APPEND OLIVE_COMPILE_OPTIONS "/WX")
|
||||
@@ -64,6 +74,8 @@ else()
|
||||
-Wextra
|
||||
-Wno-unused-parameter
|
||||
-Wshadow
|
||||
-DOFX_SUPPORTS_OPENGLRENDER
|
||||
|
||||
)
|
||||
if (USE_WERROR)
|
||||
list(APPEND OLIVE_COMPILE_OPTIONS "-Werror")
|
||||
@@ -77,6 +89,12 @@ endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
# OFX HostSupport requires expat::expat
|
||||
find_package(EXPAT REQUIRED)
|
||||
if (TARGET EXPAT::EXPAT AND NOT TARGET expat::expat)
|
||||
add_library(expat::expat ALIAS EXPAT::EXPAT)
|
||||
endif()
|
||||
|
||||
# Link OpenGL
|
||||
if(UNIX AND NOT APPLE AND NOT DEFINED OpenGL_GL_PREFERENCE)
|
||||
set(OpenGL_GL_PREFERENCE LEGACY)
|
||||
@@ -103,6 +121,7 @@ list(APPEND OLIVE_INCLUDE_DIRS ${OPENEXR_INCLUDES})
|
||||
list(APPEND OLIVE_LIBRARIES olivecore)
|
||||
list(APPEND OLIVE_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/core/include)
|
||||
|
||||
|
||||
# Link Qt
|
||||
set(QT_LIBRARIES
|
||||
Core
|
||||
@@ -167,8 +186,11 @@ list(APPEND OLIVE_LIBRARIES
|
||||
KDAB::kddockwidgets
|
||||
)
|
||||
|
||||
# Link OFX HostSupport wherever libolive-editor objects are used.
|
||||
list(APPEND OLIVE_LIBRARIES OfxHost)
|
||||
|
||||
# Link FFmpeg
|
||||
find_package(FFMPEG 3.0 REQUIRED
|
||||
find_package(FFMPEG REQUIRED
|
||||
COMPONENTS
|
||||
avutil
|
||||
avcodec
|
||||
@@ -257,6 +279,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
list(APPEND OLIVE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/ext)
|
||||
|
||||
add_subdirectory(ext)
|
||||
add_subdirectory(third_party/openfx/HostSupport)
|
||||
add_subdirectory(app)
|
||||
|
||||
if (BUILD_TESTS)
|
||||
|
||||
@@ -16,3 +16,21 @@ of code comments, including Javadoc in header files. Feel free to reach out via
|
||||
an issue or pull request if you have questions about the architecture or
|
||||
implementation details.
|
||||
|
||||
### Code Standards
|
||||
|
||||
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)
|
||||
* `lowercase_underscored_variable_names`
|
||||
* `lowercase_underscored_functions()` or `SentenceCaseFunctions()`
|
||||
* `class SentenceCaseClassesAndStructs {}`
|
||||
* `kSentenceCaseConstants` prepended with a lowercase `k`
|
||||
* `UPPERCASE_UNDERSCORED_MACROS` for variables or same style as functions for macro functions
|
||||
* `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
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
# Olive Video Editor Community Edition[](https://github.com/olive-editor/olive/actions?query=branch%3Amaster)
|
||||
# Oak Video Editor[](https://github.com/olive-editor/olive/actions?query=branch%3Amaster)
|
||||
|
||||
Olive is a free non-linear video editor for Windows, macOS, and Linux.
|
||||
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.
|
||||
|
||||
Now, we are maintaining a community edition for this project.
|
||||
This project is a community-maintained fork of Olive Video Editor.
|
||||

|
||||
|
||||
This project could now be successfully built with ffmpeg 7. I'm working for a plugin system for it.
|
||||
|
||||
**NOTE: Olive is alpha software and is considered highly unstable. While we highly appreciate users testing and providing usage information, please use at your own risk.**
|
||||
|
||||
## Current Status
|
||||
|
||||
I am working on the plugin branch to add OpenFX plugins support. After that I'll try to fix the issues which was submitted on the origin project.
|
||||
**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)
|
||||
- [0.2.0 unstable development build](https://github.com/olive-editor/olive/releases/tag/0.2.0-nightly)
|
||||
|
||||
## OpenFX Support TODO
|
||||
- Implement plugin discovery/loading from a given path and populate the cache (currently creates host/cache only). `app/pluginSupport/OliveHost.cpp`
|
||||
- Wire output clip image storage: allocate a backing buffer, set `kOfxImagePropData`, and update bounds/rowBytes before render. `app/pluginSupport/OliveClip.cpp`
|
||||
- Provide real input clip image fetches (currently returns an empty `Image` for inputs). `app/pluginSupport/OliveClip.cpp`
|
||||
- Ensure render path sets per-frame output data and handles ROD/bounds correctly. `app/render/plugin/pluginrenderer.cpp`
|
||||
- Add missing param instance types (String, Double3D/Integer3D, Group/Page, Custom/Bytes) and mapping to node inputs. `app/pluginSupport/OlivePluginInstance.cpp`, `app/node/plugins/Plugin.cpp`
|
||||
- Implement `editBegin`/`editEnd`, progress, and timeline hooks instead of stubs. `app/pluginSupport/OlivePluginInstance.cpp`, `app/pluginSupport/OlivePluginInstance.h`
|
||||
- Integrate persistent message handling with the app UI (currently TODO placeholders). `app/pluginSupport/OlivePluginInstance.cpp`
|
||||
- Decide and enforce project extent/fielding behavior instead of the current placeholder comment. `app/pluginSupport/OlivePluginInstance.cpp`
|
||||
- Add OpenGL texture render suite support or explicitly disable it (currently `loadTexture` returns null). `app/pluginSupport/OliveClip.h`
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
# 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 纹理缓存。
|
||||
@@ -0,0 +1,92 @@
|
||||
# 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.
|
||||
+18
-7
@@ -1,5 +1,6 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2022 Olive Team
|
||||
# Modifications Copyright (C) 2025 mikesolar
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -26,7 +27,6 @@ set(OLIVE_SOURCES
|
||||
add_subdirectory(audio)
|
||||
add_subdirectory(cli)
|
||||
add_subdirectory(codec)
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(config)
|
||||
add_subdirectory(dialog)
|
||||
add_subdirectory(node)
|
||||
@@ -56,6 +56,10 @@ configure_file(ts/translations.qrc.in ts/translations.qrc @ONLY)
|
||||
set(OLIVE_RESOURCES
|
||||
${OLIVE_RESOURCES}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ts/translations.qrc
|
||||
render/job/pluginjob.cpp
|
||||
render/job/pluginjob.h
|
||||
widget/nodeparamview/nodeparambutton.cpp
|
||||
widget/nodeparamview/nodeparambutton.h
|
||||
)
|
||||
|
||||
# Add version object
|
||||
@@ -73,7 +77,13 @@ add_library(libolive-editor
|
||||
${OLIVE_SOURCES}
|
||||
${OLIVE_RESOURCES}
|
||||
)
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(pluginSupport)
|
||||
|
||||
|
||||
target_compile_features(libolive-editor PUBLIC cxx_std_23)
|
||||
include_directories(../third_party/openfx/include
|
||||
../third_party/openfx/HostSupport/include)
|
||||
# Remove prefix - prevents CMake calling it "liblibolive-editor"
|
||||
set_target_properties(libolive-editor PROPERTIES PREFIX "")
|
||||
|
||||
@@ -83,10 +93,11 @@ add_executable(olive-editor
|
||||
$<TARGET_OBJECTS:libolive-editor>
|
||||
$<TARGET_OBJECTS:olive-version-obj>
|
||||
)
|
||||
|
||||
target_include_directories(olive-editor PUBLIC pluginSupport)
|
||||
target_link_libraries(olive-editor PUBLIC OfxHost)
|
||||
# Create docs if doxygen was found
|
||||
if(DOXYGEN_FOUND)
|
||||
set(DOXYGEN_PROJECT_NAME "Olive")
|
||||
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")
|
||||
@@ -110,13 +121,13 @@ elseif(APPLE)
|
||||
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.olivevideoeditor.Olive
|
||||
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 "Olive"
|
||||
MACOSX_BUNDLE_INFO_STRING "Olive ${PROJECT_LONG_VERSION}"
|
||||
MACOSX_BUNDLE_COPYRIGHT "©2018-2021 Olive Studios LLC and others. Published under the GNU General Public License version 3.0."
|
||||
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"
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
@@ -318,7 +319,7 @@ AudioManager::AudioManager()
|
||||
#ifdef PA_HAS_JACK
|
||||
// PortAudio doesn't do a strcpy, so we need a const char that's readily accessible (i.e. not
|
||||
// a QString converted to UTF-8)
|
||||
PaJack_SetClientName("Olive");
|
||||
PaJack_SetClientName("Oak Video Editor");
|
||||
#endif
|
||||
|
||||
Pa_Initialize();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "conformmanager.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFORMMANAGER_H
|
||||
#define CONFORMMANAGER_H
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,11 +28,7 @@
|
||||
#include "codec/ffmpeg/ffmpegdecoder.h"
|
||||
#include "codec/planarfiledevice.h"
|
||||
#include "codec/oiio/oiiodecoder.h"
|
||||
#include "common/ffmpegutils.h"
|
||||
#include "common/filefunctions.h"
|
||||
#include "conformmanager.h"
|
||||
#include "node/project.h"
|
||||
#include "task/taskmanager.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -146,6 +143,11 @@ Decoder::RetrieveAudio(SampleBuffer &dest, const TimeRange &range,
|
||||
return kInvalid;
|
||||
}
|
||||
|
||||
if (params.sample_rate() <= 0 || params.channel_count() <= 0) {
|
||||
qWarning() << "Invalid audio parameters, skipping audio retrieve";
|
||||
return kInvalid;
|
||||
}
|
||||
|
||||
// Get conform state from ConformManager
|
||||
ConformManager::Conform conform =
|
||||
ConformManager::instance()->GetConformState(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -21,8 +22,6 @@
|
||||
#include "exportcodec.h"
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
}
|
||||
|
||||
namespace olive
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
+138
-116
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -22,22 +23,17 @@
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/avutil.h>
|
||||
#include <libavutil/frame.h>
|
||||
}
|
||||
|
||||
#include <OpenImageIO/imagebuf.h>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QString>
|
||||
#include <QtMath>
|
||||
#include <QThread>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#include "codec/planarfiledevice.h"
|
||||
#include "common/ffmpegutils.h"
|
||||
@@ -51,6 +47,44 @@ namespace olive
|
||||
QVariant Yuv2RgbShader;
|
||||
QVariant DeinterlaceShader;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int64_t kAnalyzeDurationUs = 5000000;
|
||||
constexpr int64_t kProbeSizeBytes = 20000000;
|
||||
|
||||
void ApplyFormatOpenOptions(AVDictionary **opts)
|
||||
{
|
||||
av_dict_set_int(opts, "analyzeduration", kAnalyzeDurationUs, 0);
|
||||
av_dict_set_int(opts, "probesize", kProbeSizeBytes, 0);
|
||||
}
|
||||
|
||||
void TuneFormatContext(AVFormatContext *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->probesize = kProbeSizeBytes;
|
||||
ctx->max_analyze_duration = kAnalyzeDurationUs;
|
||||
}
|
||||
|
||||
void DiscardSubtitleStreams(AVFormatContext *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < ctx->nb_streams; i++) {
|
||||
AVStream *stream = ctx->streams[i];
|
||||
if (stream && stream->codecpar &&
|
||||
stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
stream->discard = AVDISCARD_ALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FFmpegDecoder::FFmpegDecoder()
|
||||
: sws_ctx_(nullptr)
|
||||
, working_packet_(nullptr)
|
||||
@@ -139,7 +173,7 @@ TexturePtr FFmpegDecoder::ProcessFrameIntoTexture(AVFramePtr f,
|
||||
break;
|
||||
}
|
||||
|
||||
AVFrame *hw_in = f.get();
|
||||
AVFramePtr hw_in = f;
|
||||
|
||||
VideoParams plane_params = vp;
|
||||
plane_params.set_channel_count(1);
|
||||
@@ -147,7 +181,7 @@ TexturePtr FFmpegDecoder::ProcessFrameIntoTexture(AVFramePtr f,
|
||||
|
||||
TexturePtr y_plane = p.renderer->CreateTexture(
|
||||
plane_params, hw_in->data[0], hw_in->linesize[0] / px_size);
|
||||
|
||||
y_plane->handleFrame(hw_in);
|
||||
switch (f->format) {
|
||||
case AV_PIX_FMT_YUV420P:
|
||||
case AV_PIX_FMT_YUV422P:
|
||||
@@ -169,8 +203,11 @@ TexturePtr FFmpegDecoder::ProcessFrameIntoTexture(AVFramePtr f,
|
||||
|
||||
TexturePtr u_plane = p.renderer->CreateTexture(
|
||||
plane_params, hw_in->data[1], hw_in->linesize[1] / px_size);
|
||||
u_plane->handleFrame(hw_in);
|
||||
|
||||
TexturePtr v_plane = p.renderer->CreateTexture(
|
||||
plane_params, hw_in->data[2], hw_in->linesize[2] / px_size);
|
||||
v_plane->handleFrame(hw_in);
|
||||
|
||||
ShaderJob job;
|
||||
job.Insert(QStringLiteral("y_channel"),
|
||||
@@ -206,6 +243,7 @@ TexturePtr FFmpegDecoder::ProcessFrameIntoTexture(AVFramePtr f,
|
||||
case AV_PIX_FMT_RGBA:
|
||||
case AV_PIX_FMT_RGBA64LE:
|
||||
// RGBA can be uploaded directly to the texture
|
||||
tex->handleFrame(f);
|
||||
tex->Upload(f->data[0], f->linesize[0] / vp.GetBytesPerPixel());
|
||||
break;
|
||||
}
|
||||
@@ -281,14 +319,17 @@ TexturePtr FFmpegDecoder::RetrieveVideoInternal(const RetrieveVideoParams &p)
|
||||
AVCOL_RANGE_MPEG;
|
||||
|
||||
// Perform any CPU processing required
|
||||
f = PreProcessFrame(f, p);
|
||||
AVFramePtr ptr = PreProcessFrame(f, p);
|
||||
f=std::move(ptr);
|
||||
if (!f) {
|
||||
// Error occurred while software scaling
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Finally, perform any GPU processing required
|
||||
return ProcessFrameIntoTexture(f, p, original);
|
||||
TexturePtr texture = ProcessFrameIntoTexture(f, p, original);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -340,7 +381,12 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename,
|
||||
|
||||
// Open file in a format context
|
||||
AVFormatContext *fmt_ctx = nullptr;
|
||||
error_code = avformat_open_input(&fmt_ctx, filename_c, nullptr, nullptr);
|
||||
AVDictionary *format_opts = nullptr;
|
||||
ApplyFormatOpenOptions(&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);
|
||||
|
||||
// Handle format context error
|
||||
if (error_code == 0) {
|
||||
@@ -382,116 +428,77 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename,
|
||||
VideoParams::kInterlaceNone;
|
||||
|
||||
{
|
||||
// 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();
|
||||
|
||||
{
|
||||
Instance instance;
|
||||
instance.Open(filename_c, avstream->index);
|
||||
VideoParams::Interlacing interlacing = VideoParams::kInterlaceNone;
|
||||
AVRational pixel_aspect_ratio = {1, 1};
|
||||
AVRational frame_rate = avstream->avg_frame_rate;
|
||||
AVPixelFormat compatible_pix_fmt =
|
||||
FFmpegUtils::GetCompatiblePixelFormat(
|
||||
static_cast<AVPixelFormat>(avstream->codecpar->format));
|
||||
bool image_is_still = false;
|
||||
|
||||
// Read first frame and retrieve some metadata
|
||||
if (instance.GetFrame(pkt, frame) >= 0) {
|
||||
// Check if video is interlaced and what field dominance it has if so
|
||||
if (frame->interlaced_frame) {
|
||||
if (frame->top_field_first) {
|
||||
interlacing =
|
||||
VideoParams::kInterlacedTopFirst;
|
||||
} else {
|
||||
interlacing =
|
||||
VideoParams::kInterlacedBottomFirst;
|
||||
}
|
||||
}
|
||||
{
|
||||
Instance instance;
|
||||
if (instance.Open(filename_c, avstream->index) != 0)
|
||||
goto cleanup;
|
||||
|
||||
pixel_aspect_ratio =
|
||||
av_guess_sample_aspect_ratio(
|
||||
instance.fmt_ctx(), instance.avstream(),
|
||||
frame);
|
||||
AVCodecContext *avctx = instance.codec_ctx();
|
||||
interlacing = FFmpegFieldOrderToOlive(avctx->field_order);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
compatible_pix_fmt =
|
||||
FFmpegUtils::GetCompatiblePixelFormat(
|
||||
static_cast<AVPixelFormat>(
|
||||
avstream->codecpar->format));
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// Read second frame
|
||||
int ret = instance.GetFrame(pkt, frame);
|
||||
instance.Close();
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
// Check if we need a manual duration
|
||||
if (avstream->duration == AV_NOPTS_VALUE ||
|
||||
duration_guessed_from_bitrate) {
|
||||
if (footage_duration == AV_NOPTS_VALUE ||
|
||||
duration_guessed_from_bitrate) {
|
||||
// Manually read through file for duration
|
||||
int64_t new_dur;
|
||||
cleanup:
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
do {
|
||||
new_dur =
|
||||
frame->best_effort_timestamp;
|
||||
} while (instance.GetFrame(
|
||||
pkt, frame) >= 0 &&
|
||||
(!cancelled ||
|
||||
!cancelled->IsCancelled()));
|
||||
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);
|
||||
|
||||
avstream->duration = new_dur;
|
||||
|
||||
} else {
|
||||
// Fallback to footage duration
|
||||
avstream->duration =
|
||||
Timecode::rescale_timestamp_ceil(
|
||||
footage_duration,
|
||||
rational(1, AV_TIME_BASE),
|
||||
avstream->time_base);
|
||||
}
|
||||
}
|
||||
} else if (ret == AVERROR_EOF) {
|
||||
// Video has only one frame in it, treat it like a still image
|
||||
image_is_still = true;
|
||||
}
|
||||
|
||||
instance.Close();
|
||||
}
|
||||
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
desc.AddVideoStream(stream);
|
||||
image_is_still ? still_streams++ : video_streams++;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// Defaults to false, requires user intervention if incorrect
|
||||
stream.set_premultiplied_alpha(false);
|
||||
|
||||
desc.AddVideoStream(stream);
|
||||
|
||||
if (image_is_still) {
|
||||
still_streams++;
|
||||
} else {
|
||||
video_streams++;
|
||||
}
|
||||
|
||||
} else if (avstream->codecpar->codec_type ==
|
||||
AVMEDIA_TYPE_AUDIO) {
|
||||
@@ -629,7 +636,7 @@ bool FFmpegDecoder::ConformAudioInternal(const QVector<QString> &filenames,
|
||||
}
|
||||
// Create resampling context
|
||||
AVChannelLayout layout = params.channel_layout();
|
||||
SwrContext *resampler;
|
||||
SwrContext *resampler=NULL;
|
||||
swr_alloc_set_opts2(
|
||||
&resampler, &layout,
|
||||
FFmpegUtils::GetFFmpegSampleFormat(params.format()),
|
||||
@@ -837,7 +844,7 @@ AVFramePtr FFmpegDecoder::PreProcessFrame(AVFramePtr f,
|
||||
dest->format = f->format;
|
||||
dest->color_range = f->color_range;
|
||||
dest->colorspace = f->colorspace;
|
||||
|
||||
dest->hw_frames_ctx = nullptr;
|
||||
if (p.divider > 1) {
|
||||
dest->width = VideoParams::GetScaledDimension(dest->width, p.divider);
|
||||
dest->height = VideoParams::GetScaledDimension(dest->height, p.divider);
|
||||
@@ -890,8 +897,8 @@ AVFramePtr FFmpegDecoder::PreProcessFrame(AVFramePtr f,
|
||||
dest->color_range == AVCOL_RANGE_JPEG ? 1 : 0, 0, 0x10000, 0x10000);
|
||||
}
|
||||
|
||||
r = sws_scale(sws_ctx_, f->data, f->linesize, 0, f->height, dest->data,
|
||||
dest->linesize);
|
||||
r = sws_scale_frame(sws_ctx_, dest.get(), f.get());
|
||||
|
||||
if (r < 0) {
|
||||
FFmpegError(r);
|
||||
return nullptr;
|
||||
@@ -941,6 +948,7 @@ AVFramePtr FFmpegDecoder::RetrieveFrame(const rational &time,
|
||||
int ret;
|
||||
AVFramePtr return_frame = nullptr;
|
||||
AVFramePtr filtered = nullptr;
|
||||
bool retried_after_eof = false;
|
||||
|
||||
while (true) {
|
||||
// Break out of loop if we've cancelled
|
||||
@@ -988,6 +996,15 @@ AVFramePtr FFmpegDecoder::RetrieveFrame(const rational &time,
|
||||
cache_at_eof_ = true;
|
||||
|
||||
if (cached_frames_.empty()) {
|
||||
if (!retried_after_eof) {
|
||||
retried_after_eof = true;
|
||||
ClearFrameCache();
|
||||
instance_.Seek(min_seek);
|
||||
cache_at_zero_ = true;
|
||||
still_seeking = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
qCritical()
|
||||
<< "Unexpected codec EOF - unable to retrieve frame";
|
||||
} else {
|
||||
@@ -1104,7 +1121,12 @@ FFmpegDecoder::Instance::Instance()
|
||||
bool FFmpegDecoder::Instance::Open(const char *filename, int stream_index)
|
||||
{
|
||||
// Open file in a format context
|
||||
int error_code = avformat_open_input(&fmt_ctx_, filename, nullptr, nullptr);
|
||||
AVDictionary *format_opts = nullptr;
|
||||
ApplyFormatOpenOptions(&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_);
|
||||
|
||||
// Handle format context error
|
||||
if (error_code != 0) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
@@ -42,6 +43,20 @@ extern "C" {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
// 头文件里先备好枚举映射
|
||||
static VideoParams::Interlacing FFmpegFieldOrderToOlive(AVFieldOrder fo)
|
||||
{
|
||||
switch (fo) {
|
||||
case AV_FIELD_TT: // 隔行,顶场在前
|
||||
return VideoParams::kInterlacedTopFirst;
|
||||
case AV_FIELD_BB: // 隔行,底场在前
|
||||
return VideoParams::kInterlacedBottomFirst;
|
||||
case AV_FIELD_PROGRESSIVE:
|
||||
default:
|
||||
return VideoParams::kInterlaceNone;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A Decoder derivative that wraps FFmpeg functions as on Olive decoder
|
||||
*/
|
||||
@@ -124,6 +139,10 @@ private:
|
||||
{
|
||||
return avstream_;
|
||||
}
|
||||
AVCodecContext *codec_ctx()
|
||||
{
|
||||
return codec_ctx_;
|
||||
}
|
||||
|
||||
private:
|
||||
AVFormatContext *fmt_ctx_;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,6 +25,7 @@ extern "C" {
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavformat/avformat.h>
|
||||
}
|
||||
|
||||
#include <QFile>
|
||||
@@ -868,7 +870,7 @@ void FFmpegEncoder::FlushEncoders()
|
||||
}
|
||||
|
||||
if (fmt_ctx_) {
|
||||
if (fmt_ctx_->oformat->flags & AVFMT_ALLOW_FLUSH) {
|
||||
if (fmt_ctx_->oformat->flags) {
|
||||
int r = av_interleaved_write_frame(fmt_ctx_, nullptr);
|
||||
if (r < 0) {
|
||||
FFmpegError(tr("Failed to write interleaved packet"), r);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,10 +26,7 @@
|
||||
#include <QFileInfo>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "common/define.h"
|
||||
#include "common/oiioutils.h"
|
||||
#include "config/config.h"
|
||||
#include "core.h"
|
||||
#include "render/renderer.h"
|
||||
|
||||
namespace olive
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
+40
-39
@@ -1,5 +1,6 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2022 Olive Team
|
||||
# Modifications Copyright (C) 2025 mikesolar
|
||||
#
|
||||
# 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
|
||||
@@ -14,43 +15,43 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
common/cancelableobject.h
|
||||
common/channellayout.h
|
||||
common/commandlineparser.cpp
|
||||
common/commandlineparser.h
|
||||
common/crashpadinterface.cpp
|
||||
common/crashpadinterface.h
|
||||
common/crashpadutils.h
|
||||
common/debug.cpp
|
||||
common/debug.h
|
||||
common/decibel.h
|
||||
common/define.h
|
||||
common/ffmpegutils.cpp
|
||||
common/ffmpegutils.h
|
||||
common/filefunctions.cpp
|
||||
common/filefunctions.h
|
||||
common/html.cpp
|
||||
common/html.h
|
||||
common/jobtime.cpp
|
||||
common/jobtime.h
|
||||
common/lerp.h
|
||||
common/memorypool.h
|
||||
common/ocioutils.cpp
|
||||
common/ocioutils.h
|
||||
common/oiioutils.cpp
|
||||
common/oiioutils.h
|
||||
common/otioutils.h
|
||||
common/qtutils.cpp
|
||||
common/qtutils.h
|
||||
common/range.h
|
||||
common/ratiodialog.cpp
|
||||
common/ratiodialog.h
|
||||
common/threadsafemap.h
|
||||
common/tohex.h
|
||||
common/util.h
|
||||
common/xmlutils.cpp
|
||||
common/xmlutils.h
|
||||
PARENT_SCOPE
|
||||
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
|
||||
)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Current.h"
|
||||
|
||||
Current Current::current;
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CURRENT_H
|
||||
#define CURRENT_H
|
||||
#include "pluginSupport/OliveHost.h"
|
||||
#include "render/videoparams.h"
|
||||
#include "render/job/pluginjob.h"
|
||||
|
||||
class Current {
|
||||
public:
|
||||
static Current& getInstance()
|
||||
{
|
||||
return current;
|
||||
}
|
||||
olive::VideoParams& currentVideoParams()
|
||||
{
|
||||
return currentVideoParams_;
|
||||
}
|
||||
olive::AudioParams& currentAudioParams()
|
||||
{
|
||||
return currentAudioParams_;
|
||||
}
|
||||
void setCurrentVideoParams(olive::VideoParams& params)
|
||||
{
|
||||
currentVideoParams_ = params;
|
||||
}
|
||||
void setCurrentAudioParams(olive::AudioParams& params)
|
||||
{
|
||||
currentAudioParams_ = params;
|
||||
}
|
||||
void setCurrentVideoParams(olive::VideoParams&& params)
|
||||
{
|
||||
currentVideoParams_ = params;
|
||||
}
|
||||
void setCurrentAudioParams(olive::AudioParams&& params)
|
||||
{
|
||||
currentAudioParams_ = params;
|
||||
}
|
||||
bool interactive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<olive::plugin::OliveHost> pluginHost()
|
||||
{
|
||||
return myHost;
|
||||
}
|
||||
|
||||
void setPluginHost(std::shared_ptr<olive::plugin::OliveHost> host)
|
||||
{
|
||||
myHost = host;
|
||||
}
|
||||
|
||||
std::shared_ptr<OFX::Host::ImageEffect::PluginCache> pluginCache()
|
||||
{
|
||||
return plugin_cache_;
|
||||
}
|
||||
|
||||
void setPluginCache(std::shared_ptr<OFX::Host::ImageEffect::PluginCache> cache)
|
||||
{
|
||||
plugin_cache_ = cache;
|
||||
}
|
||||
private:
|
||||
static Current current;
|
||||
olive::VideoParams currentVideoParams_;
|
||||
olive::AudioParams currentAudioParams_;
|
||||
std::shared_ptr<olive::plugin::OliveHost> myHost;
|
||||
std::shared_ptr<OFX::Host::ImageEffect::PluginCache> plugin_cache_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //CURRENT_H
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
@@ -113,7 +114,7 @@ void CommandLineParser::PrintHelp(const char *filename)
|
||||
printf("%s %s\n", QCoreApplication::applicationName().toUtf8().constData(),
|
||||
QCoreApplication::applicationVersion().toUtf8().constData());
|
||||
|
||||
printf("Copyright (C) 2018-2022 Olive Team\n");
|
||||
printf("Copyright (C) 2018-2022 Oak Video Editor Team\n");
|
||||
|
||||
QString positional_args;
|
||||
for (int i = 0; i < positional_args_.size(); i++) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
@@ -164,7 +165,9 @@ AVPixelFormat FFmpegUtils::GetFFmpegPixelFormat(const PixelFormat &pix_fmt,
|
||||
case PixelFormat::U16:
|
||||
return AV_PIX_FMT_RGB48;
|
||||
case PixelFormat::F16:
|
||||
return AV_PIX_FMT_RGBF16;
|
||||
case PixelFormat::F32:
|
||||
return AV_PIX_FMT_RGBF32;
|
||||
case PixelFormat::INVALID:
|
||||
case PixelFormat::COUNT:
|
||||
break;
|
||||
@@ -176,7 +179,9 @@ AVPixelFormat FFmpegUtils::GetFFmpegPixelFormat(const PixelFormat &pix_fmt,
|
||||
case PixelFormat::U16:
|
||||
return AV_PIX_FMT_RGBA64;
|
||||
case PixelFormat::F16:
|
||||
return AV_PIX_FMT_RGBAF16;
|
||||
case PixelFormat::F32:
|
||||
return AV_PIX_FMT_RGBAF32;
|
||||
case PixelFormat::INVALID:
|
||||
case PixelFormat::COUNT:
|
||||
break;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
@@ -87,7 +88,7 @@ public:
|
||||
using AVFramePtr = std::shared_ptr<AVFrame>;
|
||||
inline AVFramePtr CreateAVFramePtr(AVFrame *f)
|
||||
{
|
||||
return std::shared_ptr<AVFrame>(f, [](AVFrame *g) { av_frame_free(&g); });
|
||||
return std::shared_ptr<AVFrame>(f, [](AVFrame *g) { av_frame_free(&g); });
|
||||
}
|
||||
inline AVFramePtr CreateAVFramePtr()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "html.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HTML_H
|
||||
#define HTML_H
|
||||
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "jobtime.h"
|
||||
|
||||
#include <QMutex>
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef JOBTIME_H
|
||||
#define JOBTIME_H
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef THREADSAFEMAP_H
|
||||
#define THREADSAFEMAP_H
|
||||
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOHEX_H
|
||||
#define TOHEX_H
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -35,6 +36,7 @@
|
||||
#include "timeline/timelinecommon.h"
|
||||
#include "ui/colorcoding.h"
|
||||
#include "ui/style/style.h"
|
||||
#include "widget/timelinewidget/tool/import.h"
|
||||
#include "window/mainwindow/mainwindow.h"
|
||||
|
||||
namespace olive
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
+127
-13
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -28,6 +29,7 @@
|
||||
#include <QHBoxLayout>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QStatusBar>
|
||||
#include <QStyleFactory>
|
||||
#include "window/mainwindow/mainwindowundo.h"
|
||||
#ifdef Q_OS_WINDOWS
|
||||
@@ -73,11 +75,74 @@
|
||||
#include "ui/style/style.h"
|
||||
#include "undo/undostack.h"
|
||||
#include "widget/menu/menushared.h"
|
||||
#include "widget/taskview/taskviewitem.h"
|
||||
#include "widget/viewer/viewer.h"
|
||||
#include "window/mainwindow/mainstatusbar.h"
|
||||
#include "window/mainwindow/mainwindow.h"
|
||||
|
||||
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")
|
||||
};
|
||||
}
|
||||
|
||||
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")
|
||||
};
|
||||
}
|
||||
|
||||
QStringList FootageImageExtensions()
|
||||
{
|
||||
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,
|
||||
const QStringList &extensions)
|
||||
{
|
||||
QStringList patterns;
|
||||
patterns.reserve(extensions.size());
|
||||
for (const QString &ext : extensions) {
|
||||
patterns.append(QStringLiteral("*.%1").arg(ext));
|
||||
}
|
||||
|
||||
return QStringLiteral("%1 (%2)")
|
||||
.arg(label, patterns.join(QLatin1Char(' ')));
|
||||
}
|
||||
|
||||
QString BuildFootageFileDialogFilter()
|
||||
{
|
||||
QStringList all = FootageVideoExtensions() + FootageAudioExtensions() +
|
||||
FootageImageExtensions();
|
||||
all.removeDuplicates();
|
||||
|
||||
QStringList groups;
|
||||
groups << BuildFootageFilterGroup(QObject::tr("Common Media Files"), all);
|
||||
groups << BuildFootageFilterGroup(QObject::tr("Video Files"),
|
||||
FootageVideoExtensions());
|
||||
groups << BuildFootageFilterGroup(QObject::tr("Audio Files"),
|
||||
FootageAudioExtensions());
|
||||
groups << BuildFootageFilterGroup(QObject::tr("Image Files"),
|
||||
FootageImageExtensions());
|
||||
|
||||
return groups.join(QStringLiteral(";;"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
@@ -106,6 +171,29 @@ Core *Core::instance()
|
||||
return instance_;
|
||||
}
|
||||
|
||||
QString Core::FootageFileDialogFilter()
|
||||
{
|
||||
return BuildFootageFileDialogFilter();
|
||||
}
|
||||
|
||||
QStringList Core::AllowedFootageExtensions()
|
||||
{
|
||||
QStringList all = FootageVideoExtensions() + FootageAudioExtensions() +
|
||||
FootageImageExtensions();
|
||||
all.removeDuplicates();
|
||||
return all;
|
||||
}
|
||||
|
||||
bool Core::IsFootageExtensionAllowed(const QString &path)
|
||||
{
|
||||
const QString ext = QFileInfo(path).suffix().toLower();
|
||||
if (ext.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return AllowedFootageExtensions().contains(ext);
|
||||
}
|
||||
|
||||
void Core::DeclareTypesForQt()
|
||||
{
|
||||
qRegisterMetaType<olive::core::rational>();
|
||||
@@ -244,7 +332,31 @@ void Core::ImportFiles(const QStringList &urls, Folder *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectImportTask *pim = new ProjectImportTask(parent, urls);
|
||||
QStringList filtered_urls;
|
||||
QStringList rejected_urls;
|
||||
filtered_urls.reserve(urls.size());
|
||||
|
||||
for (const QString &url : urls) {
|
||||
if (IsFootageExtensionAllowed(url)) {
|
||||
filtered_urls.append(url);
|
||||
} else {
|
||||
rejected_urls.append(url);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rejected_urls.isEmpty()) {
|
||||
QMessageBox::warning(
|
||||
main_window_, tr("Unsupported media"),
|
||||
tr("Skipped %1 file(s) that are not allowed by the current media "
|
||||
"type filter.")
|
||||
.arg(rejected_urls.size()));
|
||||
}
|
||||
|
||||
if (filtered_urls.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectImportTask *pim = new ProjectImportTask(parent, filtered_urls);
|
||||
|
||||
if (!pim->GetFileCount()) {
|
||||
// No files to import
|
||||
@@ -337,8 +449,9 @@ void Core::DialogAboutShow()
|
||||
void Core::DialogImportShow()
|
||||
{
|
||||
// Open dialog for user to select files
|
||||
QStringList files =
|
||||
QFileDialog::getOpenFileNames(main_window_, tr("Import footage..."));
|
||||
QStringList files = QFileDialog::getOpenFileNames(
|
||||
main_window_, tr("Import footage..."), QString(),
|
||||
FootageFileDialogFilter());
|
||||
|
||||
// Check if the user actually selected files to import
|
||||
if (!files.isEmpty()) {
|
||||
@@ -776,6 +889,7 @@ void Core::StartGUI(bool full_screen)
|
||||
connect(qApp, &QApplication::focusChanged, PanelManager::instance(),
|
||||
&PanelManager::FocusChanged);
|
||||
|
||||
KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtWidgets);
|
||||
// Set KDDockWidgets flags
|
||||
auto &config = KDDockWidgets::Config::self();
|
||||
auto flags = config.flags();
|
||||
@@ -1063,7 +1177,7 @@ void Core::SaveAutorecovery()
|
||||
QMessageBox::critical(
|
||||
main_window_, tr("Auto-Recovery Error"),
|
||||
tr("Failed to save auto-recovery to \"%1\". "
|
||||
"Olive may not have permission to this directory.")
|
||||
"Oak Video Editor may not have permission to this directory.")
|
||||
.arg(project_autorecovery_dir.absolutePath()));
|
||||
}
|
||||
}
|
||||
@@ -1136,11 +1250,11 @@ QString Core::PasteStringFromClipboard()
|
||||
QString Core::GetProjectFilter(bool include_any_filter)
|
||||
{
|
||||
static const QVector<QPair<QString, QString>> FILTERS = {
|
||||
// Standard compressed Olive project
|
||||
{ tr("Olive Project"), QStringLiteral("ove") },
|
||||
// Standard compressed Oak project
|
||||
{ tr("Oak Project"), QStringLiteral("ove") },
|
||||
|
||||
// Uncompressed XML Olive project
|
||||
{ tr("Olive Project (Uncompressed XML)"), QStringLiteral("ovexml") },
|
||||
// Uncompressed XML Oak project
|
||||
{ tr("Oak Project (Uncompressed XML)"), QStringLiteral("ovexml") },
|
||||
|
||||
// OpenTimelineIO project, if available
|
||||
#ifdef USE_OTIO
|
||||
@@ -1251,7 +1365,7 @@ void Core::CheckForAutoRecoveries()
|
||||
QString::fromUtf8(autorecovery_index.readAll()).split('\n');
|
||||
|
||||
AutoRecoveryDialog ard(
|
||||
tr("The following projects had unsaved changes when Olive "
|
||||
tr("The following projects had unsaved changes when Oak Video Editor "
|
||||
"forcefully quit. Would you like to load them?"),
|
||||
recovery_filenames, true, main_window_);
|
||||
ard.exec();
|
||||
@@ -1308,7 +1422,7 @@ void Core::WarnCacheFull()
|
||||
|
||||
QMessageBox::warning(
|
||||
main_window_, tr("Disk Cache Full"),
|
||||
tr("The disk cache is currently full and Olive is having to delete old "
|
||||
tr("The disk cache is currently full and Oak Video Editor is having to delete old "
|
||||
"frames to keep it within the limits set in the Disk preferences. This "
|
||||
"will result in SIGNIFICANTLY reduced cache performance.\n\n"
|
||||
"To remedy this, please do one of the following:\n\n"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
@@ -134,6 +135,10 @@ public:
|
||||
*/
|
||||
static Core *instance();
|
||||
|
||||
static QString FootageFileDialogFilter();
|
||||
static QStringList AllowedFootageExtensions();
|
||||
static bool IsFootageExtensionAllowed(const QString &path);
|
||||
|
||||
const CoreParams &core_params() const
|
||||
{
|
||||
return core_params_;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
@@ -45,7 +46,7 @@ namespace olive
|
||||
|
||||
CrashHandlerDialog::CrashHandlerDialog(const QString &report_path)
|
||||
{
|
||||
setWindowTitle(tr("Olive"));
|
||||
setWindowTitle(tr("Oak Video Editor"));
|
||||
setWindowFlags(Qt::WindowStaysOnTopHint);
|
||||
|
||||
report_filename_ = report_path;
|
||||
@@ -54,7 +55,7 @@ CrashHandlerDialog::CrashHandlerDialog(const QString &report_path)
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
layout->addWidget(new QLabel(
|
||||
tr("We're sorry, Olive has crashed. Please help us fix it by "
|
||||
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);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
+11
-13
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +26,6 @@
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "common/qtutils.h"
|
||||
#include "config/config.h"
|
||||
#include "patreon.h"
|
||||
#include "scrollinglabel.h"
|
||||
@@ -55,7 +55,7 @@ AboutDialog::AboutDialog(bool welcome_dialog, QWidget *parent)
|
||||
horiz_layout->setSpacing(fm.height() * 2);
|
||||
|
||||
QLabel *icon = new QLabel(
|
||||
QStringLiteral("<html><img src=':/graphics/olive-splash.png'></html>"));
|
||||
QStringLiteral("<html><img src=':/graphics/oak-logo.png'></html>"));
|
||||
icon->setAlignment(Qt::AlignCenter);
|
||||
horiz_layout->addWidget(icon);
|
||||
|
||||
@@ -63,15 +63,15 @@ AboutDialog::AboutDialog(bool welcome_dialog, QWidget *parent)
|
||||
QLabel *label = new QLabel(
|
||||
QStringLiteral("<html><head/><body>"
|
||||
"<p><b>%1</b> %2</p>" // AppName (version identifier)
|
||||
"<p><a href=\"https://www.olivevideoeditor.org/\">"
|
||||
"https://www.olivevideoeditor.org/"
|
||||
"</a></p>"
|
||||
"<p>%3</p>" // First statement
|
||||
"<p>%3</p>" // Description
|
||||
"<p>%4</p>" // Fork notice
|
||||
"</body></html>")
|
||||
.arg(QApplication::applicationName(),
|
||||
QApplication::applicationVersion(),
|
||||
tr("Olive is a free open source non-linear video editor. "
|
||||
"This software is licensed under the GNU GPL Version 3.")));
|
||||
tr("Oak Video Editor is a free open source non-linear video editor. "
|
||||
"This software is licensed under the GNU GPL Version 3."),
|
||||
tr("This project is a fork of "
|
||||
"<a href=\"https://github.com/olive-editor/olive\">Olive Video Editor</a>.")));
|
||||
|
||||
// Set text formatting
|
||||
label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
@@ -92,18 +92,16 @@ AboutDialog::AboutDialog(bool welcome_dialog, QWidget *parent)
|
||||
|
||||
if (welcome_dialog || patrons.isEmpty()) {
|
||||
opening_statement = tr(
|
||||
"<b>Olive relies on support from the community to continue its development.</b>");
|
||||
"<b>Oak Video Editor relies on support from the community to continue its development.</b>");
|
||||
} else {
|
||||
opening_statement = tr(
|
||||
"Olive wouldn't be possible without the support of gracious donations from the following people.");
|
||||
"Oak Video Editor wouldn't be possible without the support of gracious donations from the following people.");
|
||||
}
|
||||
|
||||
QLabel *support_lbl = new QLabel(
|
||||
tr("<html>%1 "
|
||||
"If you like this project, please consider making a "
|
||||
"<a href='https://olivevideoeditor.org/donate.php'>one-time donation</a> or "
|
||||
"<a href='https://www.patreon.com/olivevideoeditor'>pledging monthly</a> to "
|
||||
"support its development.</html>")
|
||||
"one-time donation or pledging monthly to support its development.</html>")
|
||||
.arg(opening_statement));
|
||||
support_lbl->setWordWrap(true);
|
||||
support_lbl->setAlignment(Qt::AlignCenter);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PATREON_H
|
||||
#define PATREON_H
|
||||
|
||||
|
||||
@@ -1,3 +1,54 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# /***
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# ***/
|
||||
#
|
||||
|
||||
import json
|
||||
import requests
|
||||
import os
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user