Commit Graph
6982 Commits
Author SHA1 Message Date
Mike-Solar e5eeaddf2f format: reformatting files 2026-07-13 15:30:43 +08:00
Mike-Solar 7522543c48 docs: update README binary link to v0.4.0-alpha 2026-07-13 15:29:13 +08:00
Mike-Solar 64abc9cc76 docs: update CONTRIBUTING.md to Linux Kernel Coding Style
- Reference Linux Kernel Coding Style instead of Google C++ Style Guide.
- Require tabs for indentation.
- Keep Javadoc-style documentation comments.
- Preserve the original naming rules section.
- Update project name to Oak Video Editor.
2026-07-13 15:27:57 +08:00
Mike-Solar f0d41eae52 build: rebrand output artifacts to Oak and fix macOS QML deployment
- Rename macOS bundle output from Olive.app to Oak.app.
- Rename editor binary to oak-editor and render worker to oak-render-worker.
- Rename crash handler output to oak-crashhandler.
- Update worker lookup, NSIS installer, Linux desktop/AppRun, crashhandler
  symbol paths, and documentation for the new binary names.
- Update CD workflow paths and add -qmldir flags to macdeployqt so QtQuick
  / QML plugins required by KDDockWidgets are bundled, fixing the launch
  crash on macOS.
- Update user-facing GitHub URLs to OakVideoEditorCommunity/oak.
2026-07-13 15:26:15 +08:00
Mike-Solar a4a2903e49 ci: Update CI/CD to use 32x runner for Windows. 2026-07-13 15:10:48 +08:00
Mike-Solar c31415e847 build: drop lib prefix from oakgl/oakvulkan DLLs on Windows
MinGW CMake defaults to prefixing shared libraries with 'lib', producing liboakgl.dll which the dynamic backend loader cannot find. Set PREFIX empty on Windows so the output names match the runtime names oakgl.dll / oakvulkan.dll.
2026-07-13 14:56:40 +08:00
Mike-Solar 8fa32f5df4 cd: switch RPM build back to job container with pre-checkout git install
Install git in the Fedora container before actions/checkout so the checkout step can clone the repository normally instead of falling back to the REST API.
2026-07-13 14:54:35 +08:00
Mike-Solar c786469a58 cd: fix Arch tarball creation and Fedora container checkout
- Arch: create the source tarball in /tmp to avoid file changed as we read it and exclude existing tarballs from the archive.

- RPM: run the Fedora build inside docker instead of a job container so actions/checkout is not hampered by a missing Git in the base image.
2026-07-13 14:52:19 +08:00
Mike-Solar 2f0beeb7da cd: add DEB, RPM and Arch Linux packages
- Add CPack configuration in CMakeLists.txt for .deb and .rpm generation
  with declared runtime dependencies.
- Add Arch Linux PKGBUILD template under app/packaging/arch/ and build it
  inside the official archlinux:base-devel Docker container.
- Extend CD workflow with deb, rpm and archlinux jobs and attach the
  resulting packages to the draft release.
2026-07-13 14:47:46 +08:00
Mike-Solar 847abbfd5c ci: Update CI/CD to use 32x runner for Windows. 2026-07-13 14:39:30 +08:00
Mike-Solar 2e1c40af63 test: use olive-render-worker.exe on Windows in render worker footage test
QFileInfo::exists() does not auto-append .exe on Windows, so the test
failed to locate the worker binary even though it was built.
2026-07-13 14:34:05 +08:00
Mike-Solar 2a11988b77 dpcs: Update build instructions 2026-07-13 14:32:17 +08:00
Mike-Solar 43773c430a docs: update build guides for official macOS support and sync Fedora deps
- English and Chinese build.md now list macOS as a fully supported
  platform and point to the dedicated macOS build guide.
- Chinese build.md Fedora dependency list synced with English: use
  ffmpeg-free-devel and add bzip2-devel.
2026-07-13 14:29:14 +08:00
Mike-Solar e797914c62 Edit README 2026-07-13 14:25:23 +08:00
Mike-Solar 8f3c06555f test: skip worker/backend tests when GPU backend unavailable and fix cross-platform path test
- RenderWorkerFootageTest: skip when the dynamic render backend is not
  built; we cannot verify backend availability without it, and the tests
  fail on headless/GPU-less CI runners.
- NodeProject.FilenameAndNameUpdate: use a plain filename instead of
  /tmp/... so the expected name does not depend on POSIX temp paths or
  Windows backslash normalization.
2026-07-13 14:25:02 +08:00
Mike-Solar a5c98e1297 Edit README 2026-07-13 14:23:05 +08:00
Mike-Solar 288e9050e1 fix: guard SIGPIPE ignore with #ifndef _WIN32
SIGPIPE is not available on Windows (MSYS2 UCRT64), causing a build
failure. The signal handling is only needed on POSIX systems.
2026-07-13 14:03:26 +08:00
Mike-Solar ea78558a31 render: reference-count graph snapshots to prevent premature deletion
Proxy generation modifies the project, causing graph snapshots to be
rewritten. The old implementation deleted the previous snapshot
immediately, even though queued render jobs still held its path. The
worker then failed to load the deleted file.

Add per-path reference counting:
- Increment when a job is created with a snapshot path.
- Decrement when the job is processed, cancelled or removed.
- Only delete a snapshot when its reference count reaches zero and it
  is no longer the cached snapshot for the project.

Also keep snapshots in the system temp directory as before, since the
location itself was not the bug.
2026-07-13 13:43:20 +08:00
Mike-Solar 8580542ac7 render: write graph snapshots to AppLocalData instead of system temp
The worker process on macOS could not see the graph snapshot when it
was placed in /var/folders/.../T (likely sandbox/working-directory
visibility). Write snapshots to a 'render-graphs' subdirectory of the
application's persistent data location instead, which both the editor
and the worker can access on all platforms.
2026-07-13 13:29:55 +08:00
Mike-Solar 5a5ad3bc14 render: add diagnostics for worker graph load failures
- Report QFile::errorString() when ProjectSerializer::Load() fails to open
  the graph file, so the worker log shows why instead of an empty detail.
- In olive-render-worker LoadGraph(), check file existence, size and
  readability before delegating to the serializer and log the attempt.
2026-07-13 13:25:25 +08:00
Mike-Solar 3abb4ff75b docs: update README and remove obsolete documentation/files
- Update CI badge URL to OakVideoEditorCommunity in README.
- Remove outdated TODO files, vcpkg.json, patch file and stale log.
- Clean up obsolete docs and move ofx-pluginrenderer-functions-zh.md
  into docs/zh/.
2026-07-13 13:14:37 +08:00
Mike-Solar 182bfd0aad build: bundle render worker/backends and fix concurrent param test
- Make olive-editor depend on olive-render-worker on all platforms so the
  worker is always built with the main app.
- Copy olive-render-worker and dynamic render backends (oakgl, oakvulkan)
  into the macOS app bundle next to the executable.
- Include oakgl.dll and oakvulkan.dll in the Windows NSIS installer.
- Fix PluginSmokeThread.ConcurrentParamAccess CI failure by adding a mutex
  around IntegerInstance's no-node fallback storage and serializing the
  test's set/get pair.
- Hide the render worker's Dock icon on macOS via
  NSApplicationActivationPolicyProhibited.
2026-07-13 13:12:28 +08:00
Mike-Solar 4f23051b2b Fix waveform sync using stale selection and add Ctrl+Shift+W shortcut 2026-07-13 11:09:32 +08:00
Mike-Solar f3389fe6ba Allow waveform sync with partially cached audio and add regression tests 2026-07-13 10:54:12 +08:00
Mike-Solar 0410ff2fe7 Skip GPU-dependent tests when Vulkan/OpenGL backend is unavailable in CI 2026-07-13 10:44:27 +08:00
Mike-Solar e881bb049f Remove some logs 2026-07-13 10:29:02 +08:00
Mike-Solar 942ffd1635 test: extend coverage for file/qt/xml utilities and core audio/math
Add/extend tests for:
- FileFunctions: config/temp paths, autorecovery, directory overwrite/copy
- QtUtils: word wrap, formatted date/time, qHash for rational/TimeRange
- XMLUtils: cancel atom integration
- Core rational: construction, arithmetic, comparisons, NaN handling
- Core SampleBuffer: allocation, channel ops, volume/silence/reverse/speed

Coverage improvements:
- filefunctions.cpp: 74% -> 90%
- qtutils.cpp: 41% -> 73%
- xmlutils.cpp: 88% -> 100%
- rational.cpp: 74% -> 92%
- samplebuffer.cpp: 55% -> 96%
2026-07-13 10:19:30 +08:00
Mike-Solar c57608b8f8 test: expand gtest coverage for common/core utilities
Add unit tests for:
- CommandLineParser, Debug handler, Decibel, Digit, JobTime, FFmpegUtils
- Core StringUtils, Timecode, TimeRange, Bezier, Color
- Extend Frame tests to cover pixel access, interlace, conversion

Coverage improvements (app + ext/core):
- commandlineparser.cpp: 0% -> 93%
- debug.cpp: 0% -> 85%
- decibel.h: 25% -> 88%
- digit.h: 0% -> 100%
- ffmpegutils.cpp: 29% -> 90%
- frame.cpp: 53% -> 97%
- bezier.cpp: 16% -> 98%
- color.cpp: 13% -> 71%
- Overall line coverage: 17% -> 19%
2026-07-13 10:19:30 +08:00
Mike-Solar 748c53ac5c Expand Google Test coverage across core subsystems
Add and extend unit tests for:
- Task manager (failed tasks, progress signals, multiple tasks)
- Undo stack (multiple undo/redo, push-after-undo, clear, multi-command)
- Config defaults and graphics backend string conversion
- Node keyframe serialization and default state
- Node value string round-trips and table operations
- Node globals and project settings/serialization
- Timeline coordinate, workarea, and marker commands
- Color LUT processor and OCIO transform handling
- Common utilities (range, file functions, Qt helpers, XML utils)
- Render enums (loop mode, alpha association)
- Shader resource availability
- Module smoke tests for Tool and HumanStrings

All tests pass including RenderWorkerFootage GPU worker tests after
rebuilding the stale olive-render-worker binary.
2026-07-13 10:19:30 +08:00
Mike-Solar b7ff687220 Expand gtest coverage across recently changed modules
Adds ~60 new unit tests covering the modules touched in recent bug-fix
passes and UI refactors:

- RenderTicket: result/finish-count semantics, empty watcher defaults,
  ticket-reuse rejection
- Preferences tabs: behavior options migrated into General/Audio tabs,
  translation context helper, audio-tab initialization
- NodeView: context management, 'Show in Parameter Editor' action wiring
- PreviewAutoCacher: construction, pause toggles, single-frame render
  cancellation, force-cache range
- SeekableWidget/TimeBasedWidget: scroll, marker editing, context reset
- OCIOLutNode: empty/missing/unsupported LUT paths, string direction
  values, file-switching regression coverage
- ProxyManager: working filename, disabled state, empty proxy fields
- Frame/VideoParams/AudioParams/Timecode/ExportFormat/ExportCodec:
  additional edge-case and enumeration coverage

Also fixes the PreferencesAudioTab test crash by initializing
AudioManager in the offscreen test environment.

All tests pass: ctest --output-on-failure
2026-07-13 10:19:30 +08:00
Mike-Solar b47887e127 Defer parameter editor panel raise/focus to queued invocation
KDDockWidgets may need an event-loop iteration to finish opening or
tabifying a dock widget before raise() can switch to it. Defer raise(),
activateWindow(), and setFocus() via QMetaObject::invokeMethod with
Qt::QueuedConnection after show().
2026-07-13 10:19:30 +08:00
Mike-Solar 21ae1125f5 Activate parameter editor panel when jumping from node view
Call setAsCurrentTab() and activateWindow() on the ParamPanel dock widget
in ShowSelectedNodeInParamEditor so the parameter editor becomes the active
tab/window when invoked from the node view context menu or Shift+P shortcut.
2026-07-13 10:19:30 +08:00
Mike-Solar dba76ea9f2 Switch to the correct dock/tab when jumping to parameter editor
In NodeParamView::SetSelectedNodes, after locating the target node item,
expand and raise its containing NodeParamViewContext dock widget so the
active tab/folded section switches to the one that actually holds the node.
2026-07-13 10:19:30 +08:00
Mike-Solar a7fdab607d Fix node context-menu jump to parameter editor and drag-release crash
- Ensure right-clicking a node that isn't currently selected makes it the
  sole selection before showing the context menu, so 'Show in Parameter Editor'
  operates on the clicked node.
- Emit all selected node/context pairs when jumping to the parameter editor.
- Guard dragging_items_ iteration in mouseReleaseEvent against deleted items
  by snapshotting keys as QPointer and skipping null entries.
2026-07-13 10:19:30 +08:00
Mike-Solar 5c8f80480d UI: flatten preferences behavior tabs and add node parameter editor shortcut
- Move Behavior-General options (hover focus, slider ladder, scroll zooms)
  into the General preferences tab.
- Move Behavior-Audio option (audio scrubbing) into the Audio preferences tab.
- Promote remaining Behavior categories (Timeline, Playback, Project, Nodes,
  Rendering) to top-level sidebar entries without the 'Behavior - ' prefix.
- Update Chinese translations for the new sidebar titles and fill unfinished
  Behavior tab strings.

NodeView:
- Remove double-click jump-to-parameter-editor behavior; keep expand/collapse.
- Add right-click context menu item 'Show in Parameter Editor'.
- Add Shift+P shortcut bound to the same action.

Render:
- Fix crash in PreviewAutoCacher::ClearSingleFrameRenders when proxy playback
  causes a render ticket to finish synchronously before the watcher pointer is
  returned. Defer the watcher Finished signal via queued connection so the
  caller can safely register the watcher before it is deleted.
2026-07-13 10:19:30 +08:00
Mike-Solar f57ffa482f Flatten Behavior preferences into sidebar categories and scroll to node on double-click
Behavior preferences used a nested QTreeWidget with groups like General,
Audio, Timeline, etc. Replace it with one tab per group in the left sidebar
so users can jump directly to a category without expanding a secondary menu.

Also wire double-clicking a node in the node graph to emit a selection
signal with its context, causing the parameter panel to scroll to that
node's parameters (in addition to showing/raising the panel as before).
2026-07-13 10:19:30 +08:00
Mike-Solar 1f446f55b4 Cache color processors in render worker and canonicalize OCIO roles
ColorProcessor creation was done for every exported frame and the input
reference space was passed as a role string (e.g. "scene_linear"). If
getProcessor() rejected the role name the worker would crash, the pool
would retry the frame, and export throughput would drop to near zero with
minimal CPU/GPU usage.

- Canonicalize role names to colorspace names in ColorProcessor so
  "scene_linear" resolves to the config's actual colorspace.
- Wrap processor creation in a try/catch and initialize cpu_processor_ to
  nullptr on failure instead of dereferencing a null processor.
- Cache created ColorProcessor objects in the worker keyed by transform
  so OCIO processor/shader setup is only paid once per export.
2026-07-13 10:19:30 +08:00
Mike-Solar b3c124fe7a Default viewer display transform to config display/view instead of input colorspace
When no explicit color transform was set, ManagedDisplayWidget fell back to
the project's default input colorspace. For scene-referred reference spaces
like ACEScg / Linear this produced a raw, greenish image on the viewer
instead of a monitor-ready picture. Default to the OCIO config's default
display and view so the viewer looks correct out of the box, while still
honoring any Color Space / Display / View choice the user makes from the
context menu.
2026-07-13 10:19:30 +08:00
Mike-Solar 69cbe37f4f Update project file reference with bilingual Chinese/English docs
Expand docs/project-file-reference.md to cover the full .ove format
implemented in the current codebase, including:

- Root document and project container structure
- Project data: uuid, plugins, nodes, settings
- Detailed Node serialization (inputs, keyframes, connections, hints,
  context, caches)
- Node-specific custom data: Footage proxy/sourcestarttime, ViewerOutput
  workarea/markers, Track height, NodeGroup passthroughs
- VideoParams and AudioParams field lists
- MainWindowLayoutInfo layout block
- Partial documents (markers, keyframes, nodes/timeline)
- Versioning and OpenFX notes

All sections are provided in English with Chinese translations.
2026-07-13 10:19:30 +08:00
Mike-Solar d66779d281 Apply export color transform in render worker
The export color transform was passed to RenderTask as a ColorProcessor,
but the worker IPC render_frame message never carried it. The worker
always set the ticket's coloroutput to null, so frames were returned in
the project's reference space and encoded without the chosen output
transform (e.g. Rec.709 / sRGB), causing the exported video to look
wrongly tinted.

Serialize the ColorTransform through the render_frame control message
and reconstruct the ColorProcessor on the worker side before rendering.
Also expose ColorTransform as a Qt metatype so it can be stored in a
ticket QVariant.
2026-07-13 10:19:30 +08:00
Mike-Solar 43599dba9e Add batch proxy menu to Project Explorer and persist Use Proxy state
The Project Explorer previously only had an old Pre-Cache submenu that
required choosing a sequence. Replace it with the same Proxy menu that
the timeline uses:

- Generate Proxy: batch-generates proxies for all selected footage items
  that have an enabled video stream, using ProxyManager and the current
  proxy settings.
- Use Proxy: checkable toggle that enables/disables proxy playback for the
  selected footage.
- Reveal Proxy / Delete Proxy: consistent with the timeline context menu.

Also make Footage::SaveCustom() write the <proxy> element whenever
proxy_enabled_ is true, even if proxy_path_ is empty, and load it back
in LoadCustom(). This preserves the user's Use Proxy preference across
project saves so it is restored on the next open.

Translation files updated with lupdate; zh_CN and zh_TW translations for
the new Project Explorer strings (and the matching timeline strings) are
filled in.
2026-07-13 10:19:30 +08:00
Mike-Solar ea37dc5da6 Prevent main-process crash when render worker dies during IPC write
When a render-worker process crashed or exited while the worker-pool
thread was writing a control message (e.g. right after an audio-sync and
drag operation triggered a new render), the main process received SIGPIPE
and terminated at WriteControlMessage().

- Ignore SIGPIPE in main() so QProcess can report the broken pipe through
  its normal error path instead of killing the application.
- Harden WriteControlMessage() / TryWriteControlMessage() to check the
  process state and the number of bytes written before waiting.
2026-07-13 10:19:30 +08:00
Mike-Solar 01f8be7267 Fix crash when closing export dialog while export is running
TaskDialog::closeEvent() was calling deleteLater() immediately when the
user closed the window. The ExportTask was a child QObject of the dialog,
so it got destroyed while its Run() method was still executing in the
worker thread, leading to a use-after-free on encoder_->Close().

Defer deletion until the QFutureWatcher reports that the task has actually
finished. A new task_finished_ flag tracks this so closeEvent only deletes
when it is safe, and TaskFinished() closes the dialog (which now deletes
instead of calling close() again while the task is still alive).
2026-07-13 10:19:30 +08:00
Mike-Solar 8d3bde5a50 Implement software scope rendering for backend-neutral display paths
The Waveform, Vectorscope and Histogram panels were black when running on
the Vulkan / backend-neutral render path because ScopeBase::OnPaint()
returned early with a TODO. The viewer emits GPU textures that live in the
viewer's own renderer; on Vulkan each ManagedDisplayWidget has a separate
device, so those textures cannot be sampled directly.

Fix by:

- Adding a backend-neutral branch in ScopeBase::OnPaint() that downloads the
  reference texture (cross-renderer if needed), color-manages it into a U8
  offscreen texture, downloads it to a QImage, and draws via QPainter.
- Adding a pure virtual DrawScopeSoftware() to ScopeBase and implementing it
  for WaveformScope, VectorscopeScope and HistogramScope.
- Fixing the managed_tex_up_to_date_ flag that was never set to true in the
  OpenGL path, which caused the color-managed scope texture to be recreated
  on every paint.

All gtest suites pass.
2026-07-13 10:19:30 +08:00
Mike-Solar f0119a910c Enable video auto-cache by default
- Default ViewerOutput::autocache_input_video_ to true so new sequences
  and viewer outputs use the frame cache without requiring the user to
  manually enable Auto-Cache.
- Update the DefaultSequenceAutoCache2 config default to true for
  consistency.
2026-07-13 10:19:30 +08:00
Mike-Solar 468b6f1d1b Fix playback backup timer interval and waveform-only prequeue
- The playback backup timer was using timebase_dbl() in seconds as its
  QTimer interval, which truncated to 0 ms for normal frame rates. This
  caused the timer to fire continuously and starve the event loop when
  the video display was hidden, e.g. in Show Waveform Only mode, freezing
  the UI and stopping the playhead. Multiply by 1000 to use milliseconds.
- If PlayInternal has neither video nor audio to prequeue, call
  FinishPlayPreprocess immediately so the backup timer starts and the
  playhead advances even in waveform-only mode with no audio.
2026-07-13 10:19:30 +08:00
Mike-Solar 094f4a8e44 Fix audio waveform view scene rect and timebase refresh
- AudioWaveformView now uses the video frame rate as its timebase
  (falling back to the default sequence frame rate), preventing the
  enormous scene rect that froze the UI when it previously used the
  audio sample rate.
- Call UpdateSceneRect() after changing the waveform timebase so the
  QGraphicsScene bounds are recomputed immediately.
- Refresh the waveform view's viewer/timebase whenever the waveform
  visibility mode changes, ensuring the correct timebase is applied
  even if the node was connected earlier with a different setting.
2026-07-13 10:19:30 +08:00
Mike-Solar 282a06b777 Default to full-resolution preview and fix audio-waveform freeze
- Use a divider of 1 (full resolution) for new sequences and for
  footage-derived viewer parameters instead of the auto-downscaling
  heuristic, so the viewer defaults to full-res preview.
- In AudioWaveformView, base the view timebase on the video frame rate
  when video is present; fall back to the audio sample rate only for
  audio-only sources. Using the audio sample rate as the view timebase
  created an enormous scene rect (time * sample_rate * scale), which
  froze the waveform view and stalled playback updates when showing
  the audio waveform.
2026-07-13 10:19:30 +08:00
Mike-Solar 51ea3ca24e Use 10-bit packed preview format and add OCIO LUT regression tests
Renderer / preview:
- Switch the preview/display readback format from F16 to packed
  10-bit RGBA (PixelFormat::U10) to halve GPU->CPU/IPC bandwidth
  while keeping 10-bit panel precision.
- Add U10 support to VideoParams, FFmpeg/OIIO/OCIO utility mappings,
  OpenGL (GL_RGB10_A2), Vulkan (VK_FORMAT_A2B10G10R10_UNORM_PACK32),
  and plugin bit-depth lookups.
- Update preview autocacher comment to reflect the new behavior.

OCIO LUT tests:
- Add four E2E-style ColorLutNode gtests that drive a SolidGenerator
  -> OCIOLutNode graph through NodeTraverser and compare resulting
  pixels on the CPU. They cover forward/inverse transforms and verify
  that switching LUT direction and LUT file updates both the processor
  and the output pixels.

Cleanup:
- Remove a leftover SolidGenerator::Value debug fprintf.
- Capture render worker stderr in RenderWorkerFootageTest for better
  diagnostics.
2026-07-13 10:19:30 +08:00
Mike-Solar a7f7890db0 Use F16 for preview frames to halve GPU-to-CPU readback bandwidth 2026-07-13 10:19:30 +08:00