Commit Graph
100 Commits
Author SHA1 Message Date
Mike-Solar d88341f9db Revert OCIO LUT processor generation to synchronous
Background generation caused the UI to freeze indefinitely when
switching LUT files, likely due to a deadlock between the worker
process, the preview autocacher, and the asynchronous set_processor
path. Synchronous generation is fast enough for typical 33^3 .cube
files and keeps the cache invalidation logic simple and safe.

The passthrough fix in OCIOBaseNode::Value() is retained so the
viewer shows the input frame while a processor is being created.
2026-07-13 10:19:30 +08:00
Mike-Solar 8636ee0dc6 Remove automatic full-cache invalidation on LUT processor change
InvalidateAll() on the OCIO LUT node caused the preview autocacher to
re-render the entire timeline, freezing the UI when switching LUT files.
Instead, let the new processor be used naturally on the next render
request (scrubbing/playback).
2026-07-13 10:19:30 +08:00
Mike-Solar 63a4008ce4 Avoid full cache invalidation in render worker after LUT processor is ready
InvalidateAll() on the OCIO LUT node triggered the worker's
PreviewAutoCacher to re-cache the entire timeline, causing the main
process to freeze while waiting for frames. Only invalidate in the
main GUI process so the viewer refreshes; the worker will naturally
use the new processor on its next render request.
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 30e7153154 fix Windows and macOS symbol error 2026-07-13 10:19:30 +08:00
Mike-Solar 83424e3c79 fix Linux outdated package name 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 cd5efa8ea4 Update dynamic backend plan to reflect Vulkan real-render progress
- Document that Vulkan now passes an end-to-end upload/blit/download test
  on real hardware.
- List recently landed fixes: shared vertex/fragment UBO, descriptor set
  layout, render pass dependencies, image layout transitions, framebuffer
  and sampler caching, grayscale swizzle, texture-enable uniforms.
- Add remaining gaps: iterative/pin-pong multi-pass Blit, 1/3-channel
  upload/download alignment, and full viewer/proxy/export smoke tests.
2026-07-13 10:19:30 +08:00
Mike-Solar e908786d43 Improve Vulkan Blit: caching, interpolation, swizzle, enable flags
- Cache a VkFramebuffer per texture to avoid creating/destroying one for
  every Blit() call.
- Create and cache both linear and nearest samplers; honor
  Texture::Interpolation in descriptor writes.
- Add single-channel image-view component swizzle (R -> RGB, A = 1) to
  match OpenGL grayscale behavior.
- Set texture-enable uniforms (NAME_enabled) when shaders declare them.
- Guard Blit() with null destination and emit a clear warning instead of
  recording an invalid render pass.

ctest passes 4/4 in both dynamic-backend ON and OFF builds.
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 f1d19a03f8 Harden Vulkan init/device selection and resource teardown
- Remove unconditional VK_KHR_swapchain request; offscreen renderer needs
  no device extensions, fixing failures on headless/CI setups.
- Enumerate physical devices properly and pick the first one with a
  graphics queue family instead of blindly choosing device 0.
- Check vkEnumeratePhysicalDevices/vkBindImageMemory/vkBindBufferMemory
  results.
- Validate FindMemoryType() result before allocation and log clear errors.
- Add a persistent linear sampler created in PostInit and destroy it in
  DestroyInternal.
- Fix DestroyInternal() early-return leak: now tears down the instance
  even if device creation failed.

ctest passes 4/4.
2026-07-13 10:19:30 +08:00
Mike-Solar 55271a53c7 Document RenderManager backend sync and manual test checkpoints
- dynamic plan: mark that RenderManager::backend() now syncs with
  DynamicRenderer's actual loaded backend after internal fallback.
- manual test plan: add checks in 10.2/10.3 that RenderManager reports
  the actual runtime backend (OpenGL after Vulkan fallback).

No code changes; ctest passes 4/4.
2026-07-13 10:19:30 +08:00
Mike-Solar 8b8aa945f0 Sync RenderManager::backend_ after DynamicRenderer fallback
DynamicRenderer::Load() can internally fall back from Vulkan to
OpenGL when the Vulkan library is missing or is_available() fails.
Previously RenderManager::backend_ stayed at kVulkan, so callers
asking RenderManager::backend() got the wrong answer. After a
successful dynamic load, sync backend_ from
DynamicRenderer::backend_name() and log any fallback.

ctest still passes 4/4 in build-default-on.
2026-07-13 10:19:29 +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 76a98e5a93 Route viewer through dynamic backend in experimental builds 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 2d6b2107af Enable experimental OpenGL backend library build 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 4d52267c4a Merge pull request #13 from riffpointer/main
Update build dependencies for Fedora 44
2026-07-13 10:07:42 +08:00
Mike-Solar cac5a40b58 Implement color LUT v0.4 features 2026-06-07 00:24:08 +08:00
Mike-Solar 0daad22129 Complete render process isolation phases 4 and 5 2026-06-06 23:31:52 +08:00
Mike-Solar 042f008a02 Add decoded input slots for render workers 2026-06-04 21:32:43 +08:00
Mike-Solar 98c884c381 Wire render worker pool into render manager 2026-06-04 16:23:36 +08:00
Mike-Solar b23e01b916 Add render worker IPC loop 2026-06-04 13:57:36 +08:00
Mike-Solar 8c1c7658d9 fix(macos): skip self-copy when lib already in Frameworks 2026-06-03 20:59:50 +08:00
Mike-Solar 3fc6d0f485 chore: bump version to 0.3.0-alpha, unify all icons from icon.png 2026-06-03 20:43:31 +08:00
Mike-Solar 830f5f76af fix(macos): replace dylibbundler with custom Python script for dependency bundling 2026-06-03 20:34:56 +08:00
Mike-Solar 3205a27985 fix(macos): add dylibbundler search paths and debug output 2026-06-03 20:25:01 +08:00
Mike-Solar ef8cefcbed fix(windows): add OutFile directive to nsis script 2026-06-03 20:11:06 +08:00
Mike-Solar 7a3ac3186a ci: cache MSYS2 packages in Windows builds 2026-06-03 20:06:56 +08:00
Mike-Solar 9406704f6c fix(windows): replace ShellExecAsUser plugin with built-in ExecShell 2026-06-03 20:00:24 +08:00
Mike-Solar 34ed808d42 change: Change CI OpenFX -j 2026-06-03 19:49:01 +08:00
Mike-Solar 6c9d53d01b fix(cd): fix AppStream validation, update runners to Warp, verify bundled libs 2026-06-03 19:43:34 +08:00
Mike-Solar 04aad3415f fix(cd): bundle all runtime dependencies for Windows, macOS and Linux 2026-06-03 18:30:48 +08:00
Mike-Solar f731470c0f fix macOS timer bug 2026-06-03 17:49:21 +08:00
Mike-Solar a2af4b5bf6 fix ci 2026-06-03 14:52:32 +08:00
Mike-Solar 2181669825 Add libavfilter-dev to CI/CD dependencies 2026-05-29 00:54:46 +08:00
Mike-Solar a3724d3ec9 Update CI/CD to use Ubuntu 24.04 and distro FFmpeg 6.x 2026-05-29 00:50:02 +08:00
Mike-Solar 5c40a3376f Fix Arch Linux CD. 2026-05-29 00:12:03 +08:00
Mike-Solar 8657c3f549 add GitHub Actions CD. 2026-05-29 00:01:33 +08:00
Mike-Solar e6fe406318 fix Ubuntu and Windows CI 2026-05-28 23:26:33 +08:00
Mike-Solar 4802b897fa fix Ubuntu and Windows CI 2026-05-28 22:29:37 +08:00
Mike-Solar 9a4d635a7a Merge branch 'main' of https://github.com/OakVideoEditorCommunity/oak 2026-05-28 21:43:57 +08:00
Mike-Solar 9cae5d9c5f fix Ubuntu and Windows CI 2026-05-28 21:43:33 +08:00
Mike-Solar 6b94ceea14 docs:Add plan of spilting into multi-library 2026-05-21 20:31:17 +08:00
Mike-Solar 295c5eaa24 fix: Use makefile to compile OpenFX-Misc 2026-05-21 17:46:08 +08:00
Mike-Solar 0984756c19 fix: Compile v8.1.1 instead of latest ffmpeg for Ubuntu, remove override for MainWindow::nativeEvent, and change Windows packages to UCRT. 2026-05-21 17:40:24 +08:00
Mike-Solar 444a8e5287 fix: Compile latest ffmpeg for Ubuntu, install fmt for Windows. 2026-05-21 17:26:37 +08:00
Mike-Solar 3f238ce08e fix: Define WIN32 and WINDOWS for MSYS2, and remove <qtypes.h> in image.h. 2026-05-21 17:06:29 +08:00
Mike-Solar 027476e691 docs: update roadmap 2026-05-21 17:01:36 +08:00
Mike-Solar 0daef48b62 fix: remove <qtypes.h> to fix Linux CI. 2026-05-21 16:53:55 +08:00
Mike-Solar 393a9eda63 docs: add build guide and CI. 2026-05-21 16:50:17 +08:00
Mike-Solar a0abf9cfb0 Fixed: fixed black screen when pulling playhead back. 2026-05-21 16:29:39 +08:00
Mike-Solar 2a84027ff9 fix(renderer): macOS TBDR cross-context sync and OFX instance thread-safety
This commit fixes crashes (SIGSEGV in CImg blur_bilateral) and black-frame
corruption artifacts during playback and scrubbing on macOS Apple Silicon.

Root cause analysis:
1. macOS uses Tile-Based Deferred Rendering (TBDR). glFlush() does not
   guarantee tile memory writeback, causing glReadPixels to read incomplete
   tiles (black/corrupted frames) and cache them to disk.
2. Olive uses multiple shared OpenGL contexts (RenderProcessor contexts vs.
   thread-local PluginRenderer context). glFinish() only waits for the
   current context, not the shared context that produced the texture. CPU
   readback in PluginRenderer could read partially-rendered tiles.
3. OlivePluginInstance and OliveClipInstance are not thread-safe. Concurrent
   RenderProcessors could corrupt internal QMap/images_ and params_ via
   setInputTexture/renderAction races.

Fixes:
- OpenGLRenderer::Flush() on macOS now uses glFinish() unconditionally.
- OpenGLRenderer::DownloadFromTexture() and OpenGLRenderer::Blit() insert
  glFinish() before readback/detach to ensure tile writeback completes.
- PluginRenderer::RenderPlugin() now acquires a per-instance mutex to
  serialize concurrent OFX render calls.
- Before CPU readback in PluginRenderer, flush the renderer that originally
  produced each input texture, ensuring cross-context synchronization.
- RenderProcessor::ProcessVideoFootage() flushes after BlitColorManaged.
- Add black-frame detection in ProcessVideoCacheJob() to auto-purge TBDR-
   corrupted cache files.
- Add diagnostic qDebug() logging in viewer, decoder, renderer, and plugin
  paths to aid future debugging.
2026-05-17 14:54:49 +08:00
Mike-Solar ff0eee3a88 perf(plugin): cache PluginRenderer per-thread and skip redundant clip prefs
Fix three performance traps in the OFX plugin preview pipeline that
  caused slideshow-like performance when any plugin was active.

  1. Eliminate per-frame PluginRenderer creation (GL FBO alloc/free)

     RenderProcessor is stack-allocated per ticket, so its
     plugin_renderer_ member was constructed and destroyed every frame.
     PluginRenderer inherits OpenGLRenderer, whose PostInit() calls
     glGenFramebuffers() and whose destructor calls glDeleteFramebuffers().
     On Apple Silicon's TBDR this is pathologically expensive.

     Fix: use a thread_local cached PluginRenderer so each render thread
     creates it only once and reuses it forever.

  2. Call getClipPreferences() conditionally

     The code unconditionally called instance->getClipPreferences() on
     every single frame. This dispatches kOfxImageEffectActionGetClipPreferences
     into the plugin even when no inputs or parameters have changed.

     Fix: check areClipPrefsDirty() first. The OpenFX Host Support library
     already tracks this flag and sets it to true when slave params or clip
     connections change.

  3. Call ApplyParamOverrides() before renderAction

     ApplyParamOverrides() was defined but never invoked, so animated
     plugin parameters were never pushed into the OFX instance before
     rendering.

     Fix: call it after beginRenderAction() and before renderAction(),
     injecting the current NodeValueRow values at the correct OfxTime.
2026-05-16 17:34:29 +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 4aa4d59770 feat: hide non-texture OFX params from node graph + host coordinate standardization
Hide non-texture OFX params from node graph
  --------------------------------------------
  OFX plugins like ColorCorrect expose dozens of scalar parameters as
  node inputs, making nodes extremely tall and pushing Source/Mask far
  down. Previously attempted via kInputFlagHidden, but that also hid
  them from the parameter panel.

  Fix: move the filter to NodeViewItem::IsInputValid() instead.
  For OFX plugin nodes (getPluginInstance() != nullptr), only
  kTexture inputs are rendered as ports. Scalar parameters remain
  fully visible in the parameter panel.

  Files: app/widget/nodeview/nodeviewitem.cpp
         app/node/plugins/Plugin.cpp

  Standardize OFX host coordinate system
  --------------------------------------
  Olive's OFX host had partial and inconsistent coordinate handling.

  1. Fix Project coordinate methods
     - getProjectSize() / getProjectExtent() / getProjectOffset()
       now multiply X by pixel_aspect_ratio(), returning canonical
       coordinates per the OFX spec.

  2. Fix Clip default RoD
     - OliveClipInstance::getRegionOfDefinition() default now returns
       {0, 0, width*PAR, height} instead of raw pixel coords.

  3. Add parameter coordinate system conversion
     - DoubleInstance / Double2DInstance / Double3DInstance now check
       _descriptor.getDefaultCoordinateSystem().
     - For kOfxParamCoordinatesNormalised:
         get: internal pixel value -> normalised (divide by extent)
         set: normalised plugin value -> pixel (multiply by extent)
     - DefaultValueForParam() also converts normalised defaults to
       canonical before storing in Node, keeping Olive internal/UI
       values consistently in pixel space.

  Files: app/pluginSupport/OlivePluginInstance.cpp
         app/pluginSupport/OliveClip.cpp
         app/pluginSupport/paraminstance.h
         app/node/plugins/Plugin.cpp
2026-05-14 21:54:18 +08:00
Mike-Solar e012f16083 feat: group OpenFX plugins under dedicated "OpenFX" category with sub-groups
All OpenFX plugins were previously hardcoded to return kCategoryUnknown,
  causing them to pile up under "Uncategorized" in the node creation menu.

  This commit introduces a two-level grouping system for OFX plugins:

  1. Add new kCategoryOpenFX top-level category
     - Node::CategoryID enum extended with kCategoryOpenFX
     - PluginNode::Category() now returns {kCategoryOpenFX}
     - Node::GetCategoryName() returns "OpenFX"

  2. Add secondary sub-grouping support
     - Node base class gains virtual SubCategory() method
     - PluginNode implements SubCategory() backed by sub_category_ member
     - sub_category_ is set in the constructor from the plugin's OFX context:
         Filter     → "Filter"
         Generator  → "Generator"
         Transition → "Transition"
         others     → "General"

  3. Update NodeFactory::CreateMenu()
     - When a node belongs to kCategoryOpenFX and provides a non-empty
       SubCategory(), creates a second-level submenu under "OpenFX"
     - Nodes without a sub-category are placed directly in the top menu

  Expected menu layout:
    OpenFX
      ├── Filter
      │     ├── ColorCorrect
      │     └── ...
      ├── Generator
      ├── Transition
      └── General

  All 4 test suites pass.
2026-05-14 21:05:29 +08:00
Mike-Solar b2de04962d feat: heuristic semantic display for OFX RGBA parameters
ColorCorrectOFX and similar plugins declare per-channel controls
  (Gamma, Contrast, Saturation, Gain, Offset) as kOfxParamTypeRGBA.
  Olive previously mapped every RGBA param to NodeValue::kColor and
  rendered it as a ColorButton, which is semantically wrong for
  adjustment sliders.

  This commit adds heuristic semantic detection to distinguish
  "true color" inputs (color pickers) from "per-channel scalar"
  inputs (float sliders):

    - label/hint/name keywords ("gamma", "contrast", "gain", ...)
    - display range outside [0, 1]
    - uniform default values across all channels

  The detected semantic ("color" or "scalar") is stored as the
  node input property "color_semantic".  The display range and hint
  are also persisted as "min" / "max" / "tooltip".

  NodeParamViewWidgetBridge now branches on "color_semantic":
    - "scalar"  → 4× FloatSlider (reuses existing ProcessSlider /
      keyframe-track logic, since kColor already splits into 4 tracks)
    - otherwise → ColorButton (unchanged)

  All 4 test suites pass.
2026-05-14 20:50:45 +08:00
Mike-Solar 43ba1c4642 fix ofx plugin bug 2026-05-14 20:26:17 +08:00
Mike-Solar 599c876d03 全链路强制F32 2026-05-14 01:51:14 +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
Mike-Solar eb79be87a4 add smoke test 2026-04-12 01:26:41 +08:00
Mike-Solar 843b8762f6 fix audio bug 2026-04-12 01:08:22 +08:00
Mike-Solar c1b77ceec5 Merge branch 'plugin' 2026-01-17 17:03:39 +08:00
Mike-Solar 648de07b00 Add LRU TODO 2026-01-17 16:53:54 +08:00
Mike-Solar c1bcfeb78b finish plugin suppoirt 2026-01-17 16:49:21 +08:00
Mike-Solar a2698e7ef4 solve problem invalid roi and param 2026-01-17 16:41:03 +08:00
Mike-Solar 894ee5c0da update copyright 2026-01-16 22:29:47 +08:00
Mike-Solar bfb1b2fce4 update copyright back 2026-01-16 21:22:05 +08:00
Mike-Solar e851653fa3 尝试修复粉紫屏未果 2026-01-16 21:11:24 +08:00
Mike-Solar 3f774dfa53 update core 2026-01-10 18:57:46 +08:00
Mike-Solar 4d393f3d23 尝试解决插件bug 2026-01-10 18:56:58 +08:00
Mike-Solar e37972b227 Try to fix plugin issue 2026-01-05 21:31:35 +08:00
Mike-Solar 8ed5660faf solve some bugs 2026-01-05 18:01:13 +08:00
Mike-Solar 6b64abb1fa Limit import files 2026-01-05 16:36:43 +08:00
Mike-Solar 4bd453bab0 Undate core 2026-01-05 16:23:11 +08:00
Mike-Solar b8669f6a11 Change project name; 2026-01-05 16:22:26 +08:00
Mike-Solar 86e82b13e2 remove unused includes 2026-01-05 14:24:28 +08:00
Mike-Solar cdc66d1a02 fix no video shown 2026-01-05 13:52:02 +08:00
Mike-Solar b107370550 Fix CI 2026-01-05 13:19:36 +08:00
Mike-Solar eea983b3a2 Fix CI 2026-01-05 13:13:41 +08:00
Mike-Solar 12bca573f1 Fix CI 2026-01-05 13:06:35 +08:00
Mike-Solar ffc634ab42 Fix CI 2026-01-05 12:42:03 +08:00