OFX ビデオ プラグインの std::deque でビデオ バッファをプログラムしようとしています。現在の画像を処理するために、以前に処理した画像にアクセスしたいと考えています。私の考えは、処理された画像を両端キューの前にプッシュし、バッファが最大サイズを超えた場合は後ろからポップすることです。イメージをバッファから削除する前に、delete を使用してイメージのメモリを解放しようとすると、プラグインがクラッシュします。1つまたは複数の画像をバッファに追加し、その後すぐに問題なく削除および削除できることがわかりました。ただし、以前のサイクルで追加されたイメージを削除しようとすると、クラッシュします。プラグインは、メイン クラス OFXPlugin とプロセッサ クラス myplugin で構成されます。OFXPlugin のインスタンスは時間の経過とともに残り、
両端キューの使用方法が間違っているのか、myplugin の別のインスタンスによって割り当てられたメモリを解放することが許可されていないのか、または OFX に関連して違法なことを行っているのかはわかりません。 API。
以下のコードは、問題に関連するプラグインの抜粋を示しています。これは、OFX サポートの例に基づいています。delete videoBuffer_.back().img;
関数でクラッシュしますOFXPlugin::addToVBuff(OFX::Image *img, double t)
。例外をキャッチできません。どうやら OFX API で処理 (無視) されているようです。
助けてくれてどうもありがとう!
myplugin.h
#include "ofxsImageEffect.h"
#include "ofxsMultiThread.h"
#include "../Support/Plugins/include/ofxsProcessing.H"
#include <deque>
// Video Buffer Element
typedef struct vBuffEl
{
OFX::Image* img;
double time;
} vBuffEl;
inline
bool operator==(const vBuffEl &a, const double b)
{
return a.time == b;
}
class myplugin : public OFX::ImageProcessor {
protected :
OFX::Image *_srcImg;
double _time;
OFXPlugin *_opInstance;
public :
// ctor
myplugin(OFX::ImageEffect &instance)
: OFX::ImageProcessor(instance)
, _srcImg(0)
, _time(0)
{}
void multiThreadProcessImages(OfxRectI procWindow);
void setOFXPlugin(OFXPlugin* opInstance) {_opInstance = opInstance;}
OFXPlugin* getOFXPlugin() {return _opInstance;}
void setTime(double argsTime) {_time = argsTime;}
double getTime() {return _time;}
void setSrcImg(OFX::Image *v) {_srcImg = v;}
OFX::Image* getSrcImg() {return _srcImg;}
};
class OFXPlugin : public OFX::ImageEffect {
protected :
OFX::Clip *dstClip_;
OFX::Clip *srcClip_;
double time_;
std::deque<vBuffEl> videoBuffer_;
public :
/** @brief ctor */
OFXPlugin(OfxImageEffectHandle handle);
/** @brief dtor */
~OFXPlugin();
/* Override the render */
virtual void render(const OFX::RenderArguments &args);
/* get the source Clip */
OFX::Clip* getSrcClip();
/* get the current time */
double getTime();
/* set up and run a processor */
void setupAndProcess(myplugin &, const OFX::RenderArguments &args);
/* add to video buffer */
void addToVBuff(OFX::Image *img, double t);
/* fetch a dst image from buffer */
void fetchDstImageBuff(double t, OFX::Image* &img, bool &buff);
};
myplugin.cpp
#include "myplugin.h"
#include <algorithm>
void myplugin::multiThreadProcessImages(OfxRectI procWindow)
{
// Do some filtering of the source image and store result in destination image
myfiltering(_dstImg, _srcImg, procWindow);
// add to buffer
_opInstance->addToVBuff(_dstImg, _time);
}
/* set up and run a processor */
void
OFXPlugin::setupAndProcess(myplugin &processor, const OFX::RenderArguments &args)
{
// get a dst image
std::auto_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
// fetch main input image
std::auto_ptr<OFX::Image> src(srcClip_->fetchImage(args.time));
// set the images
processor.setDstImg(dst.get());
processor.setSrcImg(src.get());
// set the render window
processor.setRenderWindow(args.renderWindow);
// set time
processor.setTime(args.time);
time_ = args.time;
// set OFXPlugin instance
processor.setOFXPlugin(this);
// Call the base class process member, this will call the derived templated process code
processor.process();
}
OFX::Clip* OFXPlugin::getSrcClip()
{
return srcClip_;
}
/* get the current time */
double
OFXPlugin::getTime()
{
return time_;
}
// the overridden render function
void
OFXPlugin::render(const OFX::RenderArguments &args)
{
try {
myplugin fred(*this);
setupAndProcess(fred, args);
} catch (...) {
outputMessage("ERROR: An unknown error happened!");
}
}
/* add to video buffer */
void
OFXPlugin::addToVBuff(OFX::Image *img, double t)
{
try {
// if frame already exists in buffer, remove
std::deque<vBuffEl>::iterator it;
it = find(videoBuffer_.begin(), videoBuffer_.end(), t);
if(it != videoBuffer_.end())
{
delete it->img;
videoBuffer_.erase(it);
}
// add new frame to the front
vBuffEl e;
e.time = t;
e.img = new OFX::Image(img->getPropertySet().propSetHandle());
memcpy(e.img, img, sizeof(img));
videoBuffer_.push_front(e);
// remove elements at the end, if the buffer exceeds the max size
int LASTIMG_ARRAY_SIZE = 10;
while(videoBuffer_.size() > LASTIMG_ARRAY_SIZE)
{
delete videoBuffer_.back().img;
videoBuffer_.erase(--(videoBuffer_.end()));
}
} catch (...) {
outputMessage("ERROR: An unknown error happened!");
}
}
/* fetch a dst image from buffer */
void
OFXPlugin::fetchDstImageBuff(double t, OFX::Image* &img, bool &buff)
{
try {
std::deque<vBuffEl>::iterator it;
it = find(videoBuffer_.begin(), videoBuffer_.end(), t);
if(it != videoBuffer_.end())
{
img = it->img; // return buffered dst image
buff = true;
}
else
{
img = getSrcClip()->fetchImage(t); // fetch and return src image
buff = false;
}
} catch (...) {
outputMessage("ERROR: An unknown error happened!");
}
}