Commit Graph
92 Commits
Author SHA1 Message Date
Mike-Solar 547c2480e0 color: global LUT library, LUT error reporting, clamp + display fixes
- Add a global LUT library: user-configurable directories (new
  Preferences > LUT tab) scanned recursively for .cube/.3dl files; LUT
  node file pickers offer the library dirs as sidebar shortcuts via a
  'lut_library' input property handled by the param view bridge
- OCIOLutNode no longer fails silently: missing files, unsupported
  extensions and OCIO load errors are recorded in last_error() and
  surfaced in the status bar (input still passes through for rendering
  safety)
- ColorDialog: re-enable the display -> reference conversion using
  ColorProcessor::kInverse with a validity guard, and re-enable the
  Display tab in ColorValuesWidget; covered by a round-trip regression
  test proving the old OCIO inverse crash no longer occurs
- OCIOGradingTransformLinearNode: enforce the OCIO clampWhite >
  clampBlack invariant per frame in Value() so keyframed/connected
  values cannot produce invalid grading transforms, and constrain the
  white clamp UI minimum whenever the black clamp is static
- Regression tests for LUT extension checks, direction switching, node
  error reporting, LUT library scanning, display inverse round-trip and
  clamp enforcement
2026-07-16 22:53:33 +08:00
Mike-Solar ddca6a5e01 proxy: add dedicated Proxy dialog and preferences fields
- New ProxyDialog (Tools > Proxy Settings..., plus 'Proxy Settings...'
  in the project panel and timeline Proxy submenus) unifying global
  proxy settings, per-footage custom presets, generation and deletion
  in one place instead of three scattered entry points; this also fixes
  the Tools menu action opening the wrong preferences tab
- Preferences Disk tab gains an 'include audio in proxies' checkbox and
  an ffmpeg executable path field (blank = auto-detect)
- Add ProxyDialog smoke tests
2026-07-16 22:53:13 +08:00
Mike-Solar 6aaf37e2e5 proxy: per-footage presets, audio in proxies, configurable ffmpeg path
- Footage can store custom proxy parameters (width/height/crf/preset/
  extension/audio) that override the global settings; they are
  serialized with the project and used by every generation entry point
  via Footage::GetEffectiveProxyParams()
- Proxies now include the source audio streams (AAC) unless disabled;
  the proxy filename records the audio flag and offline audio rendering
  decodes from the proxy when present
- ProxyTask resolves ffmpeg from the new FFmpegPath config key first,
  then PATH, then common install locations (e.g. Homebrew on macOS),
  instead of relying on PATH only; the error message points at the
  preferences when no executable is found
- ProxyTask::BuildArguments() is extracted for testability
- Add ProxyIncludeAudio and FFmpegPath config defaults
- Add regression tests for the filename audio marker, config-backed
  params, ffmpeg resolution, argument building, and custom-param
  persistence
2026-07-16 22:31:37 +08:00
Mike-Solar 2b118836a7 tests: skip viewer display repro tests when the render backend is unusable
The CI runner has no Vulkan runtime (liboakvulkan.so fails to load) and
no display (offscreen QOpenGLWidget cannot create a context). The
viewer display tests only checked that the parameter was "vulkan", so
they ran on the OpenGL fallback and segfaulted with no usable GL
context. Probe the backend the same way the other render test fixtures
do (load, verify the backend kind actually matches the request, init)
and skip when it is unavailable. Also replace the stale "temporary
scratch test" file header now that this is a committed regression test.
2026-07-16 17:31:48 +08:00
Mike-Solar cb7e911c35 Fix CI crash 2026-07-16 16:21:18 +08:00
Mike-Solar 9957577cb9 ffmpeg_bridge: fix cross-platform CI failures (Ubuntu/macOS/Windows)
Ubuntu (FFmpeg 7.0) build failure: the public FB_PIX_FMT_* values were
hardcoded to AVPixelFormat enum values, but those shift between FFmpeg
releases (new formats are inserted mid-enum: X2RGB10 in 7.0,
RGBF16/GRAYF16 later), so the static_asserts in internal.h failed and
RGBF16LE/GRAYF16LE did not exist at all.

The FB pixel format values are now fixed identifiers translated inside
the library by pixel format name (stable across releases):
- fb::PixFmtToAV/PixFmtFromAV resolve the static table by name;
  formats a decoder produces that have no static identifier (hardware
  downloads like nv12/p010le/p210le) receive process-local dynamic ids
  >= 1000 so they keep round-tripping through the API (scaler etc.)
  instead of collapsing to NONE and crashing sws.
- All crossing points translated: scaler, frame get/set format,
  decoder/probe stream info, encoder config and write_video_frame,
  fb_pix_fmt_* utilities, fb_find_best_pix_fmt_of_list (which also
  reinterpret_cast the caller's list; now translated element-wise and
  properly NONE-terminated).
- nv12 and p010le get static identifiers as the common hardware
  download formats.
- Hardware frame detection no longer compares pixel formats (breaks
  across format spaces); it uses the existing fb_frame_is_hw().

macOS test failures (FFmpegBridgeEncoder.WritePngVideoAndProbeBack,
WritePcmAudioAndProbeBack): config.filename held a dangling pointer to
a temporary QByteArray (UB; happened to work on Linux). Keep the
QByteArray alive for the encoder's lifetime.

Windows (MSYS2 UCRT64) build failure: timecodefunctions.h used int64_t
without including <cstdint> (previously pulled in transitively).

Full gtest suite: 584 passed.
2026-07-16 08:35:19 +08:00
Mike-Solar c203ce1dbf fix: black preview when footage connects directly to a clip
ClipBlock::kBufferIn is declared as NodeValue::kNone with no value
hint, so when a footage node is connected straight to a clip's buffer
input (no effect node in between), the traverser has no type to look
up in the footage's value table and falls back to its last entry. A
footage pushes its video texture first and its audio samples last, so
a video clip ended up fed with audio samples, produced no texture and
the preview went silently black. With any node in between, the table
only carries the passthrough texture, which is why the bug only showed
on direct connections.

Make Node::GetValueHintForInput virtual and override it in ClipBlock
to prefer the value type matching the clip's track (kTexture on video
tracks, kSamples on audio tracks).

Regression tests cover the exact application render path
(PreviewAutoCacher -> RenderManager -> RenderWorkerPool ->
oak-render-worker) for both the direct and indirect cases, the hint
following the track type, and viewer display widgets. The direct-case
test reproduces the black frame without the fix and passes with it.
Full suite: 584 passed.
2026-07-16 01:06:24 +08:00
Mike-Solar e1d3019659 tests: migrate gtest suite to the ffmpeg_bridge API and add bridge coverage
- Replace direct FFmpeg usage in the test suite (channel layout masks,
  pixel/sample format constants, AVFrame field access, sws_scale) with
  the bridge equivalents and the olive::AVFrame adapter
- Drop CoreRational.ToAVRational (API removed with core's FFmpeg
  dependency) and the GetSwsColorspaceFromAVColorSpace tests (helper
  moved inside the bridge)
- New ffmpeg_bridge_test.cpp exercises the C API directly: constants vs
  core, error strings, pixel format utilities, frames/packets, scaler,
  resampler, audio graph tempo processing, probe/decoder round-trip on
  tests/demo.mp4 (including hw-frame transfer), SRT subtitle reading,
  and encoder end-to-end tests (PNG video and PCM audio probed back)
2026-07-15 23:00:13 +08:00
Mike-Solar f03b6b58ff style: reformat C/C++ sources and headers with clang-format
Run clang-format over all project C/C++ source and header files
(.c, .cpp, .cc, .h, .hpp, .hh, .m, .mm) under app/ and tests/.
Non-source files (svg, qm, qrc, etc.) were not touched.
2026-07-13 15:34:11 +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 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 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 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 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 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 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 800859b0ef Fix OCIO LUT async processor black screen and freeze
- Pass through input texture when the LUT processor is not ready yet,
  preventing black frames while the processor is being generated.
- Serialize processor generation with a single in-flight task to avoid
  concurrent OCIO lock contention that could freeze the UI.
- Invalidate cached frames after the async processor is set so the viewer
  refreshes automatically without requiring the playhead to be moved.
- Add OAK_DISABLE_HWACCEL environment variable to force software decoding.
- Add FFmpegDecoderHW regression test for H.264 4:2:2 10-bit decoding.
2026-07-13 10:19:30 +08:00
Mike-Solar 68c0477715 Add hardware decoding support 2026-07-13 10:19:30 +08:00
Mike-Solar f6211f97a5 Fix render worker reuse and stabilize out-of-process video rendering 2026-07-13 10:19:30 +08:00
Mike-Solar e77de49406 add Comments 2026-07-13 10:19:30 +08:00
Mike-Solar 3c9592da45 完成Vulkan渲染后端 2026-07-13 10:19:30 +08:00
Mike-Solar f4906862a1 Make Vulkan shader/UBO/layout path real enough for end-to-end blits
- Add shared UBO layout across vertex + fragment stages so vertex
  uniforms like ove_mvpmat compile and bind correctly.
- Rewrite uniform extraction/injection to avoid corrupting the UBO
  block and to keep explicit sampler bindings stable.
- Make the UBO and sampler descriptor bindings visible to both vertex
  and fragment stages.
- Add layout locations for vertex varyings (ove_texcoord) and fragment
  inputs so SPIR-V generation succeeds.
- Extend TransitionImageLayout() to cover all layout pairs used by
  upload/download/clear/blit.
- Add subpass dependencies to the cached render pass and leave
  destinations in SHADER_READ_ONLY_OPTIMAL after Blit().
- Move descriptor allocation before command recording and abort cleanly
  if allocation fails; switch Blit() to the persistent linear sampler.
- Add a gtest that creates a Vulkan backend, uploads a red U8 RGBA
  texture, blits through the default pass-through shader, and verifies
  the downloaded pixel is red. This test passes on the current system.

ctest passes 4/4; DynamicRenderBackend.* passes 3/1 (Vulkan fallback
skipped because Vulkan is available).
2026-07-13 10:19:30 +08:00
Mike-Solar b4e39e5bcd Address ChatGPT Vulkan review items
- Add PickRenderableFormat / IsColorAttachmentSupported so 3-channel
  Vulkan formats fall back to 4-channel when unsupported.
- Make oakvulkan target and C ABI check conditional on Vulkan_FOUND;
  skip liboakvulkan build/dependencies when Vulkan headers/libs are
  absent.
- Update Preferences tooltip to reflect Vulkan is an experimental
  prototype that may fall back to OpenGL.
- Revise dynamic backend plan doc: phase 3/4/5 described as prototype
  frameworks with runtime validation pending, and list recent Vulkan
  fixes (init idempotency, descriptor/sampler lifetime, dynamic
  viewport/scissor, render pass clear, format probing).

Both OAK_ENABLE_DYNAMIC_RENDER_BACKEND=ON and OFF configurations
build and pass ctest (4/4).
2026-07-13 10:19:29 +08:00
Mike-Solar 225f8505c2 feat(render): dynamic OpenGL/Vulkan backend split and backend-neutral viewer
- Extract libolive-rendercore static library to minimize backend link boundary.
- Add DynamicRenderer adapter with C ABI (oakgl/oakvulkan shared libs).
- Make OAK_ENABLE_DYNAMIC_RENDER_BACKEND default ON with OpenGL fallback.
- Implement VulkanRenderer prototype (textures, shaders, UBO blit, readback).
- Add backend-neutral viewer readback path (offscreen -> QImage -> QPainter).
- Refactor PluginRenderer to be renderer-agnostic; OFX plugins fall back to CPU
  path on non-OpenGL backends while preserving OpenGL render path.
- Add Renderer::AttachOutputTexture/DetachOutputTexture and C ABI forwards.
- Update docs/zh/render-backend-dynamic-plan.md for Phase 3/4/5.
2026-07-13 10:19:29 +08:00
Mike-Solar 5fc8232671 Add render backend capability info ABI 2026-07-13 10:19:29 +08:00
Mike-Solar 38c5afb13d Add Vulkan backend placeholder with dynamic fallback 2026-07-13 10:19:29 +08:00
Mike-Solar 3f43073261 Add dynamic backend load smoke test 2026-07-13 10:19:29 +08:00
Mike-Solar 14778873b9 Fix LUT tests for OCIO 2.1 2026-07-13 10:19:29 +08:00
Mike-Solar d5d70d0151 Add dynamic render backend adapter scaffold 2026-07-13 10:19:29 +08:00
Mike-Solar 341283b1cd Add graphics backend selection 2026-07-13 10:19:29 +08:00
Mike-Solar c74cc92879 Set default OCIO config for gtests 2026-07-13 10:19:29 +08:00
Mike-Solar 5b069b47fd Fix CI compatibility for LUT and decoder tests 2026-07-13 10:19:29 +08:00
Mike-Solar 8ae8e3a159 Implement proxy media workflow 2026-07-13 10:19:29 +08:00
Mike-Solar 9c1fba4932 Add timeline audio sync actions 2026-07-13 10:19:29 +08:00
Mike-Solar 08b1c6d562 Implement audio sync foundations 2026-07-13 10:19:29 +08:00
Mike-Solar cac5a40b58 Implement color LUT v0.4 features 2026-06-07 00:24:08 +08:00
Mike-Solar 042f008a02 Add decoded input slots for render workers 2026-06-04 21:32:43 +08:00
Mike-Solar b23e01b916 Add render worker IPC loop 2026-06-04 13:57:36 +08:00
Mike-Solar a2af4b5bf6 fix ci 2026-06-03 14:52:32 +08:00
Mike-Solar e6fe406318 fix Ubuntu and Windows CI 2026-05-28 23:26:33 +08:00
Mike-Solar 3845c31b37 perf(plugin): eliminate GPU↔CPU ping-pong in OFX render path
This commit removes redundant readbacks and uploads in the OpenFX
  plugin pipeline, achieving zero-copy rendering for GL-capable
  plugins and reducing CPU path overhead.

  PluginRenderer (OpenGL path):
  - Skip ReadbackTextureToFrame + ConvertFrameIfNeeded + Upload after
    plugin render. The destination texture is already valid on GPU.
  - Pass readback_cpu=false to setInputTexture() so input textures are
    provided via loadTexture() (GL texture IDs) instead of being
    downloaded to CPU Image buffers.
  - Remove duplicate ReadbackTextureToFrame block between
    getClipPreferences and the second setInputTexture call.

  OliveClipInstance:
  - Add optional bool readback_cpu=true to setInputTexture(). When
    false, only params and input_textures_ are updated; CPU readback
    and memcpy into Image are skipped.
  - Add pruneImagesCache() to prevent unbounded growth of images_.
    Input clips are limited to 8 cached frames; output clips are
    left untouched.

  Micro-optimizations:
  - Replace per-row memcpy loops with single block memcpy when
    src/dst strides are contiguous (common case in Olive pipeline).
  - Remove dead GL_PREAMBLE macro definition.

  fix(viewer): resolve playback head lag, frozen frames, and pause delay

  Three playback pipeline behavioral issues are fixed:

  1. Prequeue blocked playhead start:
     Reduce kVideoPlaybackInterval from 0.5s to 0.1s. This lowers
     prequeue length from 15–30 frames to 3–6 frames, so the
     playback timer starts much sooner after pressing Play.

  2. Frozen display during playback:
     Relax the hard frame-drop logic in RendererGeneratedFrameForQueue.
     When the queue has fewer than 2 frames, keep late frames instead
     of dropping them, preventing the viewer from freezing entirely
     when rendering cannot keep up with playback speed.

  3. Delayed frame update after pause:
     Cancel in-flight render tickets in PauseInternal() before
     deleting queue watchers. Previously the render thread continued
     processing stale playback frames, blocking the single-frame
     render requested by UpdateTextureFromNode().
2026-05-16 16:45:13 +08:00
Mike-Solar 7ebfebb29a Fix OFX plugin render failures and stabilize integration tests
This commit resolves several categories of OFX plugin failures that
  manifested as magenta (pink) render output or crashes:

  1. Param default-value initialization
     - IntegerInstance, DoubleInstance, BooleanInstance, ChoiceInstance,
       and StringInstance now read kOfxParamPropDefault from the descriptor
       at construction time. Previously, when no PluginNode was attached
       (integration-test mode), get() returned 0/0.0/false, causing
       generator plugins to receive invalid extent/format/PAR values and
       crash in coordinate assertions.
     - IntegerInstance also fixed uninitialized `id` that caused
       kOfxStatErrBadHandle in CImg plugins.

  2. Clip property initialization
     - newClipInstance() now seeds pixelDepth and components from the
       host VideoParams instead of leaving them as None. This prevents
       Transform3x3Plugin and similar plugins from asserting on
       getPixelComponentCount() during fetchClip inside createInstance.
     - getAspectRatio() and getProjectPixelAspectRatio() now fall back
       to 1.0 when the project's PAR is not yet set, avoiding division-
       by-zero in coordinate conversion.

  3. Frame-rate and time-base preservation
     - setInputTexture() no longer overwrites the clip's frame_rate or
       time_base with the input texture's values. Multi-input plugins
       were crashing because setupClipPreferencesArgs throws when inputs
     have mismatched rates.

  4. Render loop hardening
     - getClipPreferences() is now wrapped in try/catch so that frame-
       rate mismatch exceptions mark render failure instead of aborting
       the render thread.
     - getRegionOfInterestAction() treats kOfxStatErrBadHandle as non-
       fatal and falls back to default RoI.
     - RenderPlugin syncs all clip instances after setVideoParam so that
       getAspectRatio/getFrameRate return valid values before
       createInstanceAction queries them.

  5. Test suite updates
     - All PluginMisc tests now use F32 input to match the host pipeline
       default.
     - CreateGradientTexture fixed to support F32 pixel format.
     - Added CImgBilateral and CImgGuided_MultiInput tests.
     - Secret parameters are now registered as hidden Node inputs so that
       getClipPreferences can read them (fixes generator pink screen).

  6. Debug logging in HostSupport
     - clipGetImage and clipGetRegionOfDefinition now catch exceptions
       and log the failing clip name for easier debugging.
2026-05-15 21:32:28 +08:00
Mike-Solar e85c6cf60a fix: OFX param instance lifecycle and thread-safety fixes
- Fix SIGSEGV in PluginMisc.Keyer by linking Param::SetInstance to instances.
    Olive's custom param instances (IntegerInstance, DoubleInstance, etc.) were
    not passing the SetInstance pointer to the OpenFX HostSupport base class,
    leaving _paramSetInstance as nullptr. When Keyer called paramSetValue during
    createInstanceAction, the suite function dereferenced the null pointer in
    paramChangedByPlugin(). Now newParam() passes 'this' to every constructor.

  - Fix render-thread crash when OFX plugins set params during rendering.
    MinOFX calls paramSetValue inside createInstanceAction from the render
    thread. SubmitUndoCommand() used to push undo commands directly to
    UndoStack, which modifies QAction state (GUI-only). Added IsGuiThread()
    check: non-GUI threads execute redo_now() and discard the command without
    touching the undo stack.

  - Enable PluginMisc.MergeOver and PluginMisc.Keyer integration tests.
    MergeOver now supplies both Source and Bg textures; Keyer uses U16 format.
    Both pass in the full test suite.

  - Make ViewerQueue thread-safe with QMutex around AppendTimewise/PurgeBefore.
    Adds copy ctor and assignment to support mutex-per-instance semantics.
2026-05-14 22:32:34 +08:00
Mike-Solar f3c50017e9 rendering still not correct 2026-04-19 18:59:56 +08:00
Mike-Solar 3b5b0187cb fix chroma keyer 2026-04-12 01:42:27 +08:00