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.
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
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.
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.
This commit extends the OFX plugin support in Olive by:
- Initializing and scanning for OFX plugins
- Updating PluginNode to handle OFX plugin parameters and inputs
- Adding necessary methods and properties for OFX plugin integration
- Enhancing NodeFactory to include OFX plugin nodes
- Refactoring and renaming OliveInstance to OlivePluginInstance
- Introducing new classes for parameter handling (ParamInstance)
- Adding PluginJob for rendering OFX plugins
- Adjusting CMakeLists.txt files to include new source files