Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Support/Plugins/GPUGain/GPUGain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,6 @@ void GPUGainFactory::describeInContext(OFX::ImageEffectDescriptor& p_Desc, OFX::
// Create the mandated output clip
ClipDescriptor* dstClip = p_Desc.defineClip(kOfxImageEffectOutputClipName);
dstClip->addSupportedComponent(ePixelComponentRGBA);
dstClip->addSupportedComponent(ePixelComponentAlpha);
dstClip->setSupportsTiles(kSupportsTiles);

// Make some pages and to things in
Expand Down
28 changes: 19 additions & 9 deletions Support/Plugins/Generator/noise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@

#include "../include/ofxsProcessing.H"

#include <random>
#include <cstdint>

/** @brief mix the bits of v thoroughly (the splitmix64 finaliser) */
static inline uint64_t hash64(uint64_t v)
{
v += 0x9e3779b97f4a7c15ULL;
v = (v ^ (v >> 30)) * 0xbf58476d1ce4e5b9ULL;
v = (v ^ (v >> 27)) * 0x94d049bb133111ebULL;
return v ^ (v >> 31);
}

////////////////////////////////////////////////////////////////////////////////
// base class for the noise
Expand Down Expand Up @@ -46,24 +55,25 @@ public :
// and do some processing
void multiThreadProcessImages(OfxRectI procWindow)
{
float noiseLevel = _noiseLevel;

// set up a random number generator
// Distribution is from 0 to pixel max level times noise level
std::random_device rd;
std::mt19937_64 mt(rd());
mt.seed(_seed + procWindow.y1);
std::uniform_real_distribution<double> dist(0.0, max * noiseLevel);
double scale = max * _noiseLevel;

// Each pixel's noise is a hash of the seed and its position, so a frame
// comes out the same however it is split into tiles and threads
uint64_t seedHash = hash64(_seed);

// push pixels
for(int y = procWindow.y1; y < procWindow.y2; y++) {
if(_effect.abort()) break;

PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
uint64_t rowHash = hash64(seedHash ^ uint32_t(y));

for(int x = procWindow.x1; x < procWindow.x2; x++) {
uint64_t pixelHash = hash64(rowHash ^ uint32_t(x));
for(int c = 0; c < nComponents; c++) {
double randValue = dist(mt);
// the top 32 bits of the hash, as a uniform random number in [0, 1)
double randValue = scale * (double(hash64(pixelHash + c) >> 32) / 4294967296.0);

if(max == 1) // implies floating point, so don't clamp
dstPix[c] = PIX(randValue);
Expand Down
4 changes: 3 additions & 1 deletion Support/Plugins/MultiBundle/multibundle1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ public :
{
for(int c = 0; c < nComponents; c++)
{
float v = (float)(pow((double)srcPix[c], (double)scales[c])) * maskScale + (1.0f - maskScale) * srcPix[c];
// apply the gamma to the magnitude and keep the sign, since pow of a negative value is NaN for a fractional exponent
double s = srcPix[c];
float v = (float)(copysign(pow(fabs(s), (double)scales[c]), s)) * maskScale + (1.0f - maskScale) * srcPix[c];
if(max == 1)
dstPix[c] = PIX(v);
else
Expand Down
33 changes: 19 additions & 14 deletions Support/Plugins/Retimer/retimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ public :
/* override the time domain action, only for the general context */
virtual bool getTimeDomain(OfxRangeD &range);

/* the time on the source clip that the output at time comes from */
double getSourceTime(double time);

/* set up and run a processor */
void
setupAndProcess(OFX::ImageBlenderBase &, const OFX::RenderArguments &args);
Expand Down Expand Up @@ -120,6 +123,20 @@ static void framesNeeded(double sourceTime, OFX::FieldEnum fieldToRender, double
*blendp = blend;
}

/* figure the frame we should be retiming from */
double
RetimerPlugin::getSourceTime(double time)
{
if(getContext() == OFX::eContextRetimer) {
// the host is specifying it, so fetch it from the kOfxImageEffectRetimerParamName pseudo-param
return sourceTime_->getValueAtTime(time);
}
else {
// we have our own param, which is a speed, so we integrate it to get the time we want
return speed_->integrate(0, time);
}
}

/* set up and run a processor */
void
RetimerPlugin::setupAndProcess(OFX::ImageBlenderBase &processor, const OFX::RenderArguments &args)
Expand All @@ -129,22 +146,10 @@ RetimerPlugin::setupAndProcess(OFX::ImageBlenderBase &processor, const OFX::Rend
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();

// figure the frame we should be retiming from
double sourceTime;

if(getContext() == OFX::eContextRetimer) {
// the host is specifying it, so fetch it from the kOfxImageEffectRetimerParamName pseudo-param
sourceTime = sourceTime_->getValueAtTime(args.time);
}
else {
// we have our own param, which is a speed, so we integrate it to get the time we want
sourceTime = speed_->integrate(0, args.time);
}

// figure the two images we are blending between
double fromTime, toTime;
double blend;
framesNeeded(sourceTime, args.fieldToRender, &fromTime, &toTime, &blend);
framesNeeded(getSourceTime(args.time), args.fieldToRender, &fromTime, &toTime, &blend);

// fetch the two source images
std::unique_ptr<OFX::Image> fromImg(srcClip_->fetchImage(fromTime));
Expand Down Expand Up @@ -177,7 +182,7 @@ RetimerPlugin::getFramesNeeded(const OFX::FramesNeededArguments &args,
double fromTime, toTime;
double blend;
// whatever the rendered field is, the frames are the same
framesNeeded(args.time, OFX::eFieldNone, &fromTime, &toTime, &blend);
framesNeeded(getSourceTime(args.time), OFX::eFieldNone, &fromTime, &toTime, &blend);
OfxRangeD range;
range.min = fromTime;
range.max = toTime;
Expand Down
4 changes: 4 additions & 0 deletions release-notes-next.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ This is version NEXT of the OpenFX API.
- Fixed the ColourSpace example's `OfxSetHost` to have the proper signature so it actually gets called.
- Fixed the `@propdef` metadata of `kOfxParamPropChoiceEnum` (a string array, not a bool) and `kOfxParamPropDimensionLabel` (one label per dimension, not one).
- Fixed the Invert example never releasing its output image (a shadowed handle variable).
- Fixed the Support Noise example giving a different image when a frame is rendered in tiles: it seeded its noise per render call, and now each pixel's noise depends only on its position, the time and the noise level.
- Fixed the Support GPUGain example failing to render when the host chose Alpha for its output: it declared Alpha output but processes only RGBA, so its output clip now supports only RGBA.
- Fixed the Support Gamma example producing NaNs from negative float input: it now applies the gamma to a value's magnitude and keeps its sign.
- Fixed the Support Retimer example asking for source frames around the output time rather than the retimed source time it then fetches.

## Deprecations

Expand Down
Loading