From 3b5b0187cb9dadde5283af9b691d7d0614d58391 Mon Sep 17 00:00:00 2001 From: Mike Solar Date: Sun, 12 Apr 2026 01:42:27 +0800 Subject: [PATCH] fix chroma keyer --- app/pluginSupport/OliveClip.cpp | 12 +++++++ app/pluginSupport/OliveClip.h | 5 +-- app/render/plugin/pluginrenderer.cpp | 38 ++++++++++++++------- tests/gtest/plugin_ofx_integration_test.cpp | 3 +- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/app/pluginSupport/OliveClip.cpp b/app/pluginSupport/OliveClip.cpp index a1a464d7b..dda45a28e 100644 --- a/app/pluginSupport/OliveClip.cpp +++ b/app/pluginSupport/OliveClip.cpp @@ -481,6 +481,15 @@ void olive::plugin::OliveClipInstance::setDefaultRegionOfDefinition( { defaultRegionOfDefinitions_ = regionOfDefinition; } + +void olive::plugin::OliveClipInstance::setParams(const VideoParams ¶ms) +{ + params_ = params; + // Sync with OpenFX Host Support's _pixelDepth and _components + setPixelDepth(getUnmappedBitDepth()); + setComponents(getUnmappedComponents()); +} + void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, OfxTime time){ if (!texture) { return; @@ -488,6 +497,9 @@ void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, OfxTi VideoParams incoming = texture->params(); this->params_ = incoming; + // Sync with OpenFX Host Support's _pixelDepth and _components + setPixelDepth(getUnmappedBitDepth()); + setComponents(getUnmappedComponents()); #ifdef OFX_SUPPORTS_OPENGLRENDER input_textures_.insert(time, texture); #endif diff --git a/app/pluginSupport/OliveClip.h b/app/pluginSupport/OliveClip.h index 85a4c9b13..cf1df9eaa 100644 --- a/app/pluginSupport/OliveClip.h +++ b/app/pluginSupport/OliveClip.h @@ -62,10 +62,7 @@ public: void setRegionOfDefinition(OfxRectD regionOfDefinition, OfxTime time); void setDefaultRegionOfDefinition(OfxRectD regionOfDefinition); - void setParams(const VideoParams ¶ms) - { - params_ = params; - } + void setParams(const VideoParams ¶ms); # ifdef OFX_SUPPORTS_OPENGLRENDER OFX::Host::ImageEffect::Texture* loadTexture(OfxTime time, const char *format, diff --git a/app/render/plugin/pluginrenderer.cpp b/app/render/plugin/pluginrenderer.cpp index f4a6bc471..9b4fd8826 100644 --- a/app/render/plugin/pluginrenderer.cpp +++ b/app/render/plugin/pluginrenderer.cpp @@ -1497,13 +1497,19 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: } if (is_usable_input(input_tex)) { input_textures[entry.first] = input_tex; - std::string bitdepth = input_clip->getProps() - .getStringProperty(kOfxImageEffectPropPixelDepth); - std::string component = input_clip->getProps() - .getStringProperty(kOfxImageEffectPropComponents); + // First set the input texture (updates params_) + input_clip->setInputTexture(input_tex, frame); + // Then get the bitdepth/component from the instance + std::string bitdepth = input_clip->getUnmappedBitDepth(); + std::string component = input_clip->getUnmappedComponents(); VideoParams params = input_tex->params(); - params.set_format(PixelFormat::from_ofx(bitdepth)); - params.set_channel_count(component); + PixelFormat plugin_format = PixelFormat::from_ofx(bitdepth); + if (plugin_format != PixelFormat::INVALID) { + params.set_format(plugin_format); + } + if (!component.empty() && component != kOfxImageComponentNone) { + params.set_channel_count(component); + } ConvertTextureForParams(input_tex, params); OfxRectD rod; rod.x1 = 0; @@ -1511,7 +1517,6 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: rod.x2 = params.width() * params.pixel_aspect_ratio().toDouble(); rod.y2 = params.height(); input_clip->setRegionOfDefinition(rod, frame); - input_clip->setInputTexture(input_tex,frame); input_clips[entry.first] = input_clip; } } @@ -1525,13 +1530,20 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin:: } // set correct format for output VideoParams output_params = destination_params; // params for plugin - std::string bitdepth = - output_clip->getProps().getStringProperty(kOfxImageEffectPropPixelDepth); - std::string component = - output_clip->getProps().getStringProperty(kOfxImageEffectPropComponents); - output_params.set_format(PixelFormat::from_ofx(bitdepth)); - output_params.set_channel_count(component); + // First set the destination params on the clip output_clip->setParams(output_params); + // Get the plugin's preferred bitdepth/component from the instance (not descriptor) + // Use getUnmappedBitDepth/Components which use the instance's params_ + std::string bitdepth = output_clip->getUnmappedBitDepth(); + std::string component = output_clip->getUnmappedComponents(); + // If plugin returns a valid format different from destination, update output_params + PixelFormat plugin_format = PixelFormat::from_ofx(bitdepth); + if (plugin_format != PixelFormat::INVALID) { + output_params.set_format(plugin_format); + } + if (!component.empty() && component != kOfxImageComponentNone) { + output_params.set_channel_count(component); + } // The render window is in pixel coordinates // ie: render scale and a PAR of not 1 diff --git a/tests/gtest/plugin_ofx_integration_test.cpp b/tests/gtest/plugin_ofx_integration_test.cpp index 25e2bbf56..5585de241 100644 --- a/tests/gtest/plugin_ofx_integration_test.cpp +++ b/tests/gtest/plugin_ofx_integration_test.cpp @@ -98,7 +98,8 @@ TEST(PluginIntegration, ChromaKeyerCreateAndRender) dynamic_cast(instance); ASSERT_TRUE(olive_instance); - olive::VideoParams params(320, 240, olive::core::PixelFormat::U8, 4); + // Use U16 format as the ChromaKeyer plugin expects 16-bit input + olive::VideoParams params(320, 240, olive::core::PixelFormat::U16, 4); olive_instance->setVideoParam(params); olive::TexturePtr input = CreateSolidTexture(params);