From 3b16824f34302ebbce911afe1e488527dd9e5f85 Mon Sep 17 00:00:00 2001 From: Mike Solar Date: Sun, 4 Jan 2026 22:40:05 +0800 Subject: [PATCH] Ensure render path sets per-frame output data and handles ROD/bounds correctly. --- app/node/plugins/Plugin.cpp | 29 +++++++++++++++++++++++++++- app/pluginSupport/OliveClip.cpp | 18 ++++++++++------- app/pluginSupport/OliveClip.h | 4 ++++ app/render/plugin/pluginrenderer.cpp | 7 +++++-- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/app/node/plugins/Plugin.cpp b/app/node/plugins/Plugin.cpp index fcfb5d88e..d20b57984 100644 --- a/app/node/plugins/Plugin.cpp +++ b/app/node/plugins/Plugin.cpp @@ -20,6 +20,30 @@ #include "render/rendermanager.h" #include "render/job/pluginjob.h" +static QString ClipLabelForName(const std::string &name, + const OFX::Host::ImageEffect::ClipDescriptor *desc) +{ + if (name == kOfxImageEffectSimpleSourceClipName) { + return olive::plugin::PluginNode::tr("Source"); + } + if (name == kOfxImageEffectTransitionSourceFromClipName) { + return olive::plugin::PluginNode::tr("From"); + } + if (name == kOfxImageEffectTransitionSourceToClipName) { + return olive::plugin::PluginNode::tr("To"); + } + + if (desc) { + const std::string &label = + desc->getProps().getStringProperty(kOfxPropLabel); + if (!label.empty()) { + return QString::fromStdString(label); + } + } + + return QString::fromStdString(name); +} + olive::plugin::PluginNode::PluginNode( OFX::Host::ImageEffect::Instance *plugin) { @@ -76,11 +100,14 @@ olive::plugin::PluginNode::PluginNode( if (entry.first == kOfxImageEffectOutputClipName) { continue; } - AddInput(entry.first.data(), NodeValue::kTexture); + QString input_id = QString::fromStdString(entry.first); + AddInput(input_id, NodeValue::kTexture); + SetInputName(input_id, ClipLabelForName(entry.first, entry.second)); has_texture_input = true; } if (!has_texture_input) { AddInput(kTextureInput, NodeValue::kTexture); + SetInputName(kTextureInput, tr("Texture")); } } QString olive::plugin::PluginNode::Name() const diff --git a/app/pluginSupport/OliveClip.cpp b/app/pluginSupport/OliveClip.cpp index 9a9162422..7b65c3ff4 100644 --- a/app/pluginSupport/OliveClip.cpp +++ b/app/pluginSupport/OliveClip.cpp @@ -123,19 +123,23 @@ OFX::Host::ImageEffect::Image * olive::plugin::OliveClipInstance::getImage(OfxTime time, const OfxRectD *optionalBounds) { - OfxRectI bounds = {0, 0, params_.width(), params_.height()}; + OfxRectD rod_d = getRegionOfDefinition(time); + OfxRectI rod = { static_cast(std::floor(rod_d.x1)), + static_cast(std::floor(rod_d.y1)), + static_cast(std::ceil(rod_d.x2)), + static_cast(std::ceil(rod_d.y2)) }; + OfxRectI bounds = rod; if (optionalBounds) { bounds.x1 = static_cast(std::floor(optionalBounds->x1)); bounds.y1 = static_cast(std::floor(optionalBounds->y1)); bounds.x2 = static_cast(std::ceil(optionalBounds->x2)); bounds.y2 = static_cast(std::ceil(optionalBounds->y2)); } - - OfxRectD rod_d = getRegionOfDefinition(time); - OfxRectI rod = { static_cast(std::floor(rod_d.x1)), - static_cast(std::floor(rod_d.y1)), - static_cast(std::ceil(rod_d.x2)), - static_cast(std::ceil(rod_d.y2)) }; + // Clamp bounds to ROD to keep host/plugin coords consistent. + bounds.x1 = std::max(bounds.x1, rod.x1); + bounds.y1 = std::max(bounds.y1, rod.y1); + bounds.x2 = std::min(bounds.x2, rod.x2); + bounds.y2 = std::min(bounds.y2, rod.y2); if (name_ == "Output") { if (!images_.contains(time)) { diff --git a/app/pluginSupport/OliveClip.h b/app/pluginSupport/OliveClip.h index 265648acb..2cb56962b 100644 --- a/app/pluginSupport/OliveClip.h +++ b/app/pluginSupport/OliveClip.h @@ -65,6 +65,10 @@ public: void setRegionOfDefinition(OfxRectD regionOfDefinition, OfxTime time); void setDefaultRegionOfDefinition(OfxRectD regionOfDefinition); + void setParams(const VideoParams ¶ms) + { + params_ = params; + } # ifdef OFX_SUPPORTS_OPENGLRENDER OFX::Host::ImageEffect::Texture* loadTexture(OfxTime time, const char *format, const OfxRectD *optionalBounds) { return NULL; }; # endif diff --git a/app/render/plugin/pluginrenderer.cpp b/app/render/plugin/pluginrenderer.cpp index 6be95abba..d4e464cd1 100644 --- a/app/render/plugin/pluginrenderer.cpp +++ b/app/render/plugin/pluginrenderer.cpp @@ -220,8 +220,8 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: renderWindow.x1 = renderWindow.y1 = 0; - renderWindow.x2 = src->params().width(); - renderWindow.y2 = src->params().height(); + renderWindow.x2 = destination_params.width(); + renderWindow.y2 = destination_params.height(); /// RoI is in canonical coords, OfxRectD regionOfInterest; @@ -253,6 +253,9 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: // call get region of interest on each of the inputs OfxTime frame = 0; + clip->setParams(destination_params); + clip->setRegionOfDefinition(regionOfDefinition, frame); + const NodeValueRow &values = job.GetValues(); const auto &clips = instance->getDescriptor().getClips(); for (const auto &entry : clips) {