solve problem invalid roi and param
This commit is contained in:
@@ -24,6 +24,111 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <olive/core/core.h>
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <QVariant>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
|
||||
namespace {
|
||||
QHash<QString, QHash<QString, QVariant>> g_plugin_param_defaults;
|
||||
|
||||
QVariant DefaultValueForParam(const OFX::Host::Param::Base *param)
|
||||
{
|
||||
if (!param) {
|
||||
return QVariant();
|
||||
}
|
||||
const std::string &ofxType = param->getType();
|
||||
const auto &props = param->getProperties();
|
||||
|
||||
if (ofxType == kOfxParamTypeInteger ||
|
||||
ofxType == kOfxParamTypeChoice) {
|
||||
return props.getIntProperty(kOfxParamPropDefault);
|
||||
}
|
||||
if (ofxType == kOfxParamTypeBoolean) {
|
||||
return props.getIntProperty(kOfxParamPropDefault) != 0;
|
||||
}
|
||||
if (ofxType == kOfxParamTypeDouble) {
|
||||
return props.getDoubleProperty(kOfxParamPropDefault);
|
||||
}
|
||||
if (ofxType == kOfxParamTypeString ||
|
||||
ofxType == kOfxParamTypeStrChoice ||
|
||||
ofxType == kOfxParamTypeCustom) {
|
||||
return QString::fromStdString(
|
||||
props.getStringProperty(kOfxParamPropDefault));
|
||||
}
|
||||
if (ofxType == kOfxParamTypeRGB ||
|
||||
ofxType == kOfxParamTypeRGBA) {
|
||||
const int count = (ofxType == kOfxParamTypeRGBA) ? 4 : 3;
|
||||
double values[4] = {0.0, 0.0, 0.0, 1.0};
|
||||
props.getDoublePropertyN(kOfxParamPropDefault, values, count);
|
||||
const double alpha = (count == 4) ? values[3] : 1.0;
|
||||
return QVariant::fromValue(
|
||||
olive::core::Color(values[0], values[1], values[2], alpha));
|
||||
}
|
||||
if (ofxType == kOfxParamTypeDouble2D ||
|
||||
ofxType == kOfxParamTypeDouble3D ||
|
||||
ofxType == kOfxParamTypeInteger2D ||
|
||||
ofxType == kOfxParamTypeInteger3D) {
|
||||
const bool is_double =
|
||||
(ofxType == kOfxParamTypeDouble2D ||
|
||||
ofxType == kOfxParamTypeDouble3D);
|
||||
const int count = (ofxType == kOfxParamTypeDouble2D ||
|
||||
ofxType == kOfxParamTypeInteger2D)
|
||||
? 2
|
||||
: 3;
|
||||
if (is_double) {
|
||||
double values[3] = {0.0, 0.0, 0.0};
|
||||
props.getDoublePropertyN(kOfxParamPropDefault, values, count);
|
||||
if (count == 2) {
|
||||
return QVector2D(values[0], values[1]);
|
||||
}
|
||||
return QVector3D(values[0], values[1], values[2]);
|
||||
}
|
||||
int values[3] = {0, 0, 0};
|
||||
props.getIntPropertyN(kOfxParamPropDefault, values, count);
|
||||
if (count == 2) {
|
||||
return QVector2D(values[0], values[1]);
|
||||
}
|
||||
return QVector3D(values[0], values[1], values[2]);
|
||||
}
|
||||
if (ofxType == kOfxParamTypeBytes) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<QString, QVariant>
|
||||
BuildDefaultValues(const std::map<std::string, OFX::Host::Param::Instance *> ¶ms)
|
||||
{
|
||||
QHash<QString, QVariant> defaults;
|
||||
for (const auto ¶m : params) {
|
||||
const std::string &ofxType = param.second->getType();
|
||||
if (ofxType == kOfxParamTypeGroup ||
|
||||
ofxType == kOfxParamTypePage ||
|
||||
ofxType == kOfxParamTypePushButton) {
|
||||
continue;
|
||||
}
|
||||
const auto &props = param.second->getProperties();
|
||||
if (props.getIntProperty(kOfxParamPropSecret) != 0) {
|
||||
continue;
|
||||
}
|
||||
const QString input_id =
|
||||
QString::fromStdString(param.second->getName());
|
||||
if (input_id.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
QVariant default_value = DefaultValueForParam(param.second);
|
||||
if (!default_value.isValid()) {
|
||||
continue;
|
||||
}
|
||||
defaults.insert(input_id, default_value);
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
}
|
||||
static QString ClipLabelForName(const std::string &name,
|
||||
const OFX::Host::ImageEffect::ClipDescriptor *desc)
|
||||
{
|
||||
@@ -58,6 +163,14 @@ olive::plugin::PluginNode::PluginNode(
|
||||
QHash<QString, QString> page_for_param;
|
||||
|
||||
auto params=plugin_instance_->getParams();
|
||||
const QString plugin_id = QString::fromStdString(
|
||||
plugin_instance_->getPlugin()->getIdentifier());
|
||||
auto defaults_iter = g_plugin_param_defaults.find(plugin_id);
|
||||
if (defaults_iter == g_plugin_param_defaults.end()) {
|
||||
g_plugin_param_defaults.insert(plugin_id, BuildDefaultValues(params));
|
||||
defaults_iter = g_plugin_param_defaults.find(plugin_id);
|
||||
}
|
||||
const QHash<QString, QVariant> &defaults = defaults_iter.value();
|
||||
for (auto param: params) {
|
||||
const std::string &ofxType = param.second->getType();
|
||||
if (ofxType == kOfxParamTypeGroup) {
|
||||
@@ -135,7 +248,15 @@ olive::plugin::PluginNode::PluginNode(
|
||||
if (type == NodeValue::kNone) {
|
||||
continue;
|
||||
}
|
||||
QVariant default_value = defaults.value(input_id, QVariant());
|
||||
if (default_value.isValid()) {
|
||||
AddInput(input_id, type, default_value);
|
||||
if (type != NodeValue::kPushButton) {
|
||||
SetStandardValue(input_id, default_value);
|
||||
}
|
||||
} else {
|
||||
AddInput(input_id, type);
|
||||
}
|
||||
const QString label =
|
||||
QString::fromStdString(param.second->getLabel());
|
||||
if (!label.isEmpty()) {
|
||||
|
||||
@@ -365,24 +365,18 @@ bool olive::plugin::OliveClipInstance::getConnected() const
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
for (auto it = images_.cbegin(); it != images_.cend(); ++it) {
|
||||
if (it.value()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(images_.empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#ifdef OFX_SUPPORTS_OPENGLRENDER
|
||||
if (!input_textures_.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
for (auto it = images_.cbegin(); it != images_.cend(); ++it) {
|
||||
if (it.value()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(images_.empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
double olive::plugin::OliveClipInstance::getUnmappedFrameRate() const
|
||||
{
|
||||
@@ -492,13 +486,7 @@ void olive::plugin::OliveClipInstance::setInputTexture(TexturePtr texture, OfxTi
|
||||
return;
|
||||
}
|
||||
VideoParams incoming = texture->params();
|
||||
// AI wrote this. Why?
|
||||
if (params_.format() != PixelFormat::INVALID &&
|
||||
params_.channel_count() > 0) {
|
||||
incoming.set_format(params_.format());
|
||||
incoming.set_channel_count(params_.channel_count());
|
||||
incoming.set_premultiplied_alpha(params_.premultiplied_alpha());
|
||||
}
|
||||
|
||||
this->params_ = incoming;
|
||||
#ifdef OFX_SUPPORTS_OPENGLRENDER
|
||||
input_textures_.insert(time, texture);
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#ifndef PARAM_INSTANCE_H
|
||||
#define PARAM_INSTANCE_H
|
||||
|
||||
#include "olive/core/util/rational.h"
|
||||
#include "pluginSupport/OlivePluginInstance.h"
|
||||
#include <QString>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
@@ -30,6 +32,8 @@
|
||||
#include "node/plugins/Plugin.h"
|
||||
#include "core.h"
|
||||
#include "undo/undocommand.h"
|
||||
#include <iostream>
|
||||
#include <qlogging.h>
|
||||
namespace olive
|
||||
{
|
||||
namespace plugin
|
||||
@@ -247,6 +251,11 @@ protected:
|
||||
OFX::Host::Param::Descriptor& _descriptor;
|
||||
bool has_value_ = false;
|
||||
bool value_ = false;
|
||||
bool DefaultValue() const
|
||||
{
|
||||
return _descriptor.getProperties()
|
||||
.getIntProperty(kOfxParamPropDefault) != 0;
|
||||
}
|
||||
public:
|
||||
BooleanInstance(std::shared_ptr<PluginNode> effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor)
|
||||
: OFX::Host::Param::BooleanInstance(descriptor)
|
||||
@@ -270,8 +279,8 @@ public:
|
||||
data = variant.toBool();
|
||||
return kOfxStatOK;
|
||||
}
|
||||
data = false;
|
||||
return kOfxStatErrValue;
|
||||
data = DefaultValue();
|
||||
return kOfxStatOK;
|
||||
}
|
||||
OfxStatus get(OfxTime time, bool& data)
|
||||
{
|
||||
@@ -282,12 +291,20 @@ public:
|
||||
QVariant variant =
|
||||
node->GetValueAtTime(_descriptor.getName().c_str(),
|
||||
rational::fromDouble(time));
|
||||
if (variant.isNull()){
|
||||
qWarning().noquote()<<"Boolean get failed: Varient is null" << time << rational::fromDouble(time).toDouble();
|
||||
}
|
||||
if (!variant.isValid()) {
|
||||
qWarning().noquote()
|
||||
<< "Boolean get failed: Varient is invalid" << time
|
||||
<< rational::fromDouble(time).toDouble();
|
||||
}
|
||||
if (variant.canConvert<bool>()) {
|
||||
data = variant.toBool();
|
||||
return kOfxStatOK;
|
||||
}
|
||||
data = false;
|
||||
return kOfxStatErrValue;
|
||||
data = DefaultValue();
|
||||
return kOfxStatOK;
|
||||
}
|
||||
OfxStatus set(bool data)
|
||||
{
|
||||
|
||||
@@ -1369,11 +1369,11 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
|
||||
int numFramesToRender=1;
|
||||
|
||||
// Output Clip
|
||||
OliveClipInstance *output_clip=dynamic_cast<plugin::OliveClipInstance *>(instance->getClip("Output"));
|
||||
if (!output_clip) {
|
||||
return;
|
||||
}
|
||||
output_clip->setParams(destination_params);
|
||||
|
||||
// ensure the instance was created
|
||||
OfxStatus stat = kOfxStatOK;
|
||||
@@ -1386,7 +1386,7 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
}
|
||||
}
|
||||
|
||||
// call get region of interest on each of the inputs
|
||||
|
||||
OfxTime frame = job.time_seconds();
|
||||
|
||||
const auto &clips = olive_instance->getDescriptor().getClips();
|
||||
@@ -1441,13 +1441,45 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
input_clips[entry.first] = input_clip;
|
||||
}
|
||||
}
|
||||
|
||||
// call getClipPreferences to know which format plugin requires
|
||||
OFX::Host::Property::Set args;
|
||||
args.setDoubleProperty(kOfxPropTime, frame);
|
||||
double render_scale_array[] = {
|
||||
renderScale.x, renderScale.y
|
||||
} ;args.setDoublePropertyN(kOfxImageEffectPropRenderScale, render_scale_array, 2);
|
||||
};
|
||||
args.setDoublePropertyN(kOfxImageEffectPropRenderScale, render_scale_array, 2);
|
||||
instance->setupClipPreferencesArgs(args);
|
||||
instance->getClipPreferences();
|
||||
// now we need to call getClipPreferences on the instance so that it does
|
||||
// the clip component/depth logic and caches away the components and depth.
|
||||
bool ok = instance->getClipPreferences();
|
||||
if (!ok) {
|
||||
qWarning().noquote() << "OFX getClipPreferences failed for plugin="
|
||||
<< PluginIdForInstance(instance);
|
||||
MarkRenderFailure(destination);
|
||||
return;
|
||||
}
|
||||
/// RoI is in canonical coords.
|
||||
OfxRectD regionOfInterest;
|
||||
regionOfInterest.x1 = 0.0;
|
||||
regionOfInterest.y1 = 0.0;
|
||||
regionOfInterest.x2 = destination_params.width() * destination_params.pixel_aspect_ratio().toDouble();
|
||||
regionOfInterest.y2 = destination_params.height();
|
||||
|
||||
OfxRectD regionOfDefinition = regionOfInterest;
|
||||
|
||||
output_clip->setRegionOfDefinition(regionOfDefinition, frame);
|
||||
output_clip->setOutputTexture(destination, frame);
|
||||
|
||||
// get the RoI for each input clip
|
||||
// the regions of interest for each input clip are returned in a std::map
|
||||
// on a real host, these will be the regions of each input clip that the
|
||||
// effect needs to render a given frame (clipped to the RoD).
|
||||
//
|
||||
// In our example we are doing full frame fetches regardless.
|
||||
|
||||
|
||||
// set correct format for input
|
||||
for (const auto &entry : input_clips) {
|
||||
if (entry.first == kOfxImageEffectOutputClipName) {
|
||||
continue;
|
||||
@@ -1472,21 +1504,35 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
VideoParams params = input_tex->params();
|
||||
params.set_format(PixelFormat::from_ofx(bitdepth));
|
||||
params.set_channel_count(component);
|
||||
ConvertTextureForParams(input_tex, params) ;
|
||||
ConvertTextureForParams(input_tex, params);
|
||||
OfxRectD rod;
|
||||
rod.x1 = 0;
|
||||
rod.y1 = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
// now we need to call getClipPreferences on the instance so that it does
|
||||
// the clip component/depth logic and caches away the components and depth.
|
||||
bool ok = instance->getClipPreferences();
|
||||
if (!ok) {
|
||||
qWarning().noquote()
|
||||
<< "OFX getClipPreferences failed for plugin="
|
||||
<< PluginIdForInstance(instance);
|
||||
std::map<OFX::Host::ImageEffect::ClipInstance *, OfxRectD> rois;
|
||||
stat = instance->getRegionOfInterestAction(frame, renderScale,
|
||||
regionOfInterest, rois);
|
||||
if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) {
|
||||
LogOfxFailure("getRegionOfInterest", stat, instance);
|
||||
MarkRenderFailure(destination);
|
||||
return;
|
||||
}
|
||||
// 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);
|
||||
output_clip->setParams(output_params);
|
||||
|
||||
// The render window is in pixel coordinates
|
||||
// ie: render scale and a PAR of not 1
|
||||
OfxRectI renderWindow;
|
||||
@@ -1494,17 +1540,6 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
renderWindow.x2 = destination_params.width();
|
||||
renderWindow.y2 = destination_params.height();
|
||||
|
||||
/// RoI is in canonical coords.
|
||||
OfxRectD regionOfInterest;
|
||||
regionOfInterest.x1 = 0.0;
|
||||
regionOfInterest.y1 = 0.0;
|
||||
regionOfInterest.x2 = destination_params.width();
|
||||
regionOfInterest.y2 = destination_params.height();
|
||||
|
||||
OfxRectD regionOfDefinition = regionOfInterest;
|
||||
|
||||
output_clip->setRegionOfDefinition(regionOfDefinition, frame);
|
||||
output_clip->setOutputTexture(destination, frame);
|
||||
|
||||
stat = instance->beginRenderAction(frame, numFramesToRender,
|
||||
1.0, false, renderScale, true,
|
||||
@@ -1521,22 +1556,9 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
AttachOutputTexture(destination);
|
||||
}
|
||||
#endif
|
||||
// get the RoI for each input clip
|
||||
// the regions of interest for each input clip are returned in a std::map
|
||||
// on a real host, these will be the regions of each input clip that the
|
||||
// effect needs to render a given frame (clipped to the RoD).
|
||||
//
|
||||
// In our example we are doing full frame fetches regardless.
|
||||
std::map<OFX::Host::ImageEffect::ClipInstance *, OfxRectD> rois;
|
||||
stat = instance->getRegionOfInterestAction(frame, renderScale,
|
||||
regionOfInterest, rois);
|
||||
if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) {
|
||||
LogOfxFailure("getRegionOfInterest", stat, instance);
|
||||
MarkRenderFailure(destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!destination_params.is_valid()) {
|
||||
|
||||
if (!output_params.is_valid()) {
|
||||
qWarning().noquote()
|
||||
<< "OFX render skipped due to invalid output params for plugin="
|
||||
<< PluginIdForInstance(instance);
|
||||
@@ -1547,12 +1569,12 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
}
|
||||
|
||||
// render a frame
|
||||
const char *render_field = GetRenderFieldForParams(destination_params);
|
||||
const char *render_field = GetRenderFieldForParams(output_params);
|
||||
stat = instance->renderAction(frame, render_field, renderWindow, renderScale,
|
||||
true, interactive, interactive);
|
||||
if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) {
|
||||
LogOfxFailure("render", stat, instance);
|
||||
LogClipState("output", output_clip, &destination_params);
|
||||
LogClipState("output", output_clip, &output_params);
|
||||
for (const auto &entry : input_clips) {
|
||||
const auto params_it = input_params.find(entry.first);
|
||||
const olive::VideoParams *params =
|
||||
@@ -1601,11 +1623,9 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
}
|
||||
|
||||
if (!use_opengl) {
|
||||
AVFramePtr frame_ptr = create_avframe_from_ofx_image(*output_image);
|
||||
if (!frame_ptr) {
|
||||
frame_ptr = create_avframe_from_ofx_image_with_params(
|
||||
*output_image, destination_params);
|
||||
}
|
||||
AVFramePtr frame_ptr =
|
||||
create_avframe_from_ofx_image_with_params(*output_image,
|
||||
output_params);
|
||||
if (!frame_ptr) {
|
||||
qWarning().noquote()
|
||||
<< "OFX output image conversion failed for plugin="
|
||||
@@ -1614,20 +1634,20 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
renderScale, true, interactive);
|
||||
return;
|
||||
}
|
||||
//AVFramePtr converted = ConvertFrameIfNeeded(frame_ptr, destination_params);
|
||||
AVFramePtr converted = ConvertFrameIfNeeded(frame_ptr, destination_params);
|
||||
const AVPixelFormat expected_fmt =
|
||||
GetDestinationAVPixelFormat(destination_params);
|
||||
destination->handleFrame(frame_ptr);
|
||||
if (destination->renderer() && frame_ptr && frame_ptr->data[0] &&
|
||||
destination->handleFrame(converted);
|
||||
if (destination->renderer() && converted && converted->data[0] &&
|
||||
(expected_fmt == AV_PIX_FMT_NONE ||
|
||||
frame_ptr->format == expected_fmt)) {
|
||||
converted->format == expected_fmt)) {
|
||||
int linesize_pixels =
|
||||
LinesizeToPixels(destination_params, frame_ptr->linesize[0]);
|
||||
LinesizeToPixels(destination_params, converted->linesize[0]);
|
||||
if (linesize_pixels <= 0) {
|
||||
linesize_pixels = destination_params.effective_width();
|
||||
}
|
||||
destination->Upload(frame_ptr->data[0], linesize_pixels);
|
||||
} else if (destination->renderer() && frame_ptr && frame_ptr->data[0]) {
|
||||
//destination->Upload(converted->data[0], linesize_pixels);
|
||||
} else if (destination->renderer() && converted && converted->data[0]) {
|
||||
qWarning().noquote()
|
||||
<< "OFX output pixel format mismatch for plugin="
|
||||
<< PluginIdForInstance(instance);
|
||||
@@ -1639,8 +1659,6 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
DetachOutputTexture();
|
||||
instance->contextDetachedAction();
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
if (frame_ptr && destination) {
|
||||
AVFramePtr converted =
|
||||
ConvertFrameIfNeeded(frame_ptr, destination_params);
|
||||
@@ -1650,8 +1668,8 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
if (destination->renderer() && converted && converted->data[0] &&
|
||||
(expected_fmt == AV_PIX_FMT_NONE ||
|
||||
converted->format == expected_fmt)) {
|
||||
int linesize_pixels =
|
||||
LinesizeToPixels(destination_params, converted->linesize[0]);
|
||||
int linesize_pixels = LinesizeToPixels(destination_params,
|
||||
converted->linesize[0]);
|
||||
if (linesize_pixels <= 0) {
|
||||
linesize_pixels = destination_params.effective_width();
|
||||
}
|
||||
@@ -1664,7 +1682,7 @@ void olive::plugin::PluginRenderer::RenderPlugin(TexturePtr src, olive::plugin::
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
instance->endRenderAction(frame, numFramesToRender, 1.0, interactive, renderScale, true,interactive
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user