DCTLs and Resolve OFX

I made a few adjustments and added an extra parameter. There are apparently some limitations with how you can define default parameter settings, but I've tried to make the values concurrent with expected signal response.


SwAAZoyh.png



Still working on Display Matte and Invert options. Don't know how to import bool parameters into the CudaKernel.cu file. Anyone know how?
 
Last edited:
Display matte works perfectly with standard Resolve shortcuts (opt+H or shift+opt+H), not waste your time.


Standard approach does indeed work, but I wanted to be able to trigger alpha display by swapping it into the RGB channels. Anyway, I figured out how to import switches into the Cuda and OpenCL files, so now both the Display and Invert options work. Here's the latest (and fully functional) version:


I hope to use the luminance keyer as an additional (optional) component in future plugins.
 
Last edited:
Here's a very simple (but possibly useful) plugin. Although allegedly very protective of his grading techniques, the colourist Peter Doyle did describe a particular method of removing blue spill from shadows in a podcast once, so I've applied that to a plugin and called it BlueBox in his honour :)

It basically limits the blue channel to the red channel, and the effect can be qualified with the built-in Matte components. No need to right click Use OFX Alpha, though you still can if you want to pass the alpha channel downstream. Future editions will include more options, covering other channels and conditionals.

khe9KIrh.png






Are the plugins compiling ok on Win systems? In theory they should, but I've only tested on OSX.
 
Last edited:
Hi Paul,

Not sure if this is any use to you but your plugins compile ok for Windows (with a few minor warnings) up to the latest versions (OFX 19_07_16) where there is a problem with cuda (unresolved symbols).

Here's the error log:


Code:
Build started 21-Jul-16 2:23:33 AM.
    1>Project "C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\OpenFX\MattePlugin2\MattePlugin.vcxproj" on node 2 (Build target(s)).
    1>ClCompile:
        C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64\CL.exe /c /I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include" /Zi /nologo /W3 /WX- /Od /D WIN32 /D _DEBUG /D _WINDOWS /D _USRDLL /D _WINDLL /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"x64\Debug\\" /Fd"x64\Debug\vc120.pdb" /Gd /TP /errorReport:prompt MattePlugin.cpp
        MattePlugin.cpp
    1>MattePlugin.cpp(301): warning C4244: 'argument' : conversion from 'double' to 'float', possible loss of data
      Link:
        C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64\link.exe /ERRORREPORT:PROMPT /OUT:"C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\OpenFX\MattePlugin2\x64\Debug\MattePlugin.dll" /INCREMENTAL /NOLOGO /LIBPATH:"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\x64" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cuda.lib cudart.lib OpenCL.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\OpenFX\MattePlugin2\x64\Debug\MattePlugin.pdb" /SUBSYSTEM:WINDOWS /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\OpenFX\MattePlugin2\x64\Debug\MattePlugin.lib" /MACHINE:X64 /DLL x64\Debug\CudaKernel.cu.obj
        x64\Debug\ofxsCore.obj
        x64\Debug\ofxsImageEffect.obj
        x64\Debug\ofxsInteract.obj
        x64\Debug\ofxsLog.obj
        x64\Debug\ofxsMultiThread.obj
        x64\Debug\ofxsParams.obj
        x64\Debug\ofxsProperty.obj
        x64\Debug\ofxsPropertyValidation.obj
        x64\Debug\MattePlugin.obj
        x64\Debug\OpenCLKernel.obj
            Creating library C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\OpenFX\MattePlugin2\x64\Debug\MattePlugin.lib and object C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\OpenFX\MattePlugin2\x64\Debug\MattePlugin.exp
    1>MattePlugin.obj : error LNK2019: unresolved external symbol "void __cdecl RunCudaKernel(int,int,float *,bool *,float const *,float *)" (?RunCudaKernel@@YAXHHPEAMPEA_NPEBM0@Z) referenced in function "public: virtual void __cdecl ImageScaler::processImagesCUDA(void)" (?processImagesCUDA@ImageScaler@@UEAAXXZ)
    1>MattePlugin.obj : error LNK2019: unresolved external symbol "void __cdecl RunOpenCLKernel(void *,int,int,float *,bool *,float const *,float *)" (?RunOpenCLKernel@@YAXPEAXHHPEAMPEA_NPEBM1@Z) referenced in function "public: virtual void __cdecl ImageScaler::processImagesOpenCL(void)" (?processImagesOpenCL@ImageScaler@@UEAAXXZ)
    1>C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\OpenFX\MattePlugin2\x64\Debug\MattePlugin.dll : fatal error LNK1120: 2 unresolved externals
    1>Done Building Project "C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\OpenFX\MattePlugin2\MattePlugin.vcxproj" (Build target(s)) -- FAILED.
 
Build FAILED.
 
Time Elapsed 00:00:00.67


I'm happy to compile and send you the Windows versions if needed so you can bundle them.
 
Thanks Andrew, it would be great if you were to compile the errant ones. What was the solution to the unresolved external symbol, if you don't mind me asking? Feel free to post them here directly as well (along with any further notes and recommendations you might have). The code in general is that of a clumsy beginner (me) so all and any advice is most welcome. I'm currently working on a HSL keyer (as much an exercise as anything else), followed probably by a split-signal/soft-clip concoction, so there's more on the way :)
 
The plugins don't appear to register on the App Store version of Resolve, but there is a workaround. It involves disabling the Cuda related parts of the compile. OpenCL still works.

Only the Makefile and GainPlugin.cpp file need to be altered.

Original Makefile:

Code:
CUDAPATH = /usr/local/cuda
NVCC = ${CUDAPATH}/bin/nvcc
CXXFLAGS = -I../OpenFX-1.3/include -I../Support/include
OPTIMIZER = -g
 
GainPlugin.ofx: GainPlugin.o CudaKernel.o OpenCLKernel.o ofxsCore.o ofxsImageEffect.o ofxsInteract.o ofxsLog.o ofxsMultiThread.o ofxsParams.o ofxsProperty.o ofxsPropertyValidation.o
    $(CXX) -bundle $^ -o $@ -L${CUDAPATH}/lib -lcuda -lcudart -F/Library/Frameworks -framework CUDA -framework OpenCL
    mkdir -p GainPlugin.ofx.bundle/Contents/MacOS/
    cp GainPlugin.ofx GainPlugin.ofx.bundle/Contents/MacOS/
 
CudaKernel.o: CudaKernel.cu
    ${NVCC} -c $<
 
%.o: ../Support/Library/%.cpp
    $(CXX) -c $< $(CXXFLAGS)
 
clean:
    rm -f *.o *.ofx
    rm -fr GainPlugin.ofx.bundle


Here is the modified version:

Code:
CXXFLAGS = -I../OpenFX-1.3/include -I../Support/include
OPTIMIZER = -g
 
GainPlugin.ofx: GainPlugin.o OpenCLKernel.o ofxsCore.o ofxsImageEffect.o ofxsInteract.o ofxsLog.o ofxsMultiThread.o ofxsParams.o ofxsProperty.o ofxsPropertyValidation.o
    $(CXX) -bundle $^ -o $@ -F/Library/Frameworks -framework OpenCL
    mkdir -p GainPlugin.ofx.bundle/Contents/MacOS/
    cp GainPlugin.ofx GainPlugin.ofx.bundle/Contents/MacOS/
 
%.o: ../Support/Library/%.cpp
    $(CXX) -c $< $(CXXFLAGS)
 
clean:
    rm -f *.o *.ofx
    rm -fr GainPlugin.ofx.bundle


GainPlugin.cpp:28, and GainPlugin.cpp:45 to GainPlugin.cpp:57 can simply be turned into comments to disable them.

Original code:

Code:
    virtual void processImagesCUDA();
.
.
.
.
 
extern void RunCudaKernel(int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output);
 
void ImageScaler::processImagesCUDA()
{
    const OfxRectI& bounds = _srcImg->getBounds();
    const int width = bounds.x2 - bounds.x1;
    const int height = bounds.y2 - bounds.y1;
 
    float* input = static_cast<float*>(_srcImg->getPixelData());
    float* output = static_cast<float*>(_dstImg->getPixelData());
 
    RunCudaKernel(width, height, _scales, input, output);
}


Modified version

Code:
//    virtual void processImagesCUDA();
.
.
.
.
 
/*extern void RunCudaKernel(int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output);
 
void ImageScaler::processImagesCUDA()
{
    const OfxRectI& bounds = _srcImg->getBounds();
    const int width = bounds.x2 - bounds.x1;
    const int height = bounds.y2 - bounds.y1;
 
    float* input = static_cast<float*>(_srcImg->getPixelData());
    float* output = static_cast<float*>(_dstImg->getPixelData());
 
    RunCudaKernel(width, height, _scales, input, output);
}*/
 
Thanks Andrew, it would be great if you were to compile the errant ones. What was the solution to the unresolved external symbol, if you don't mind me asking? Feel free to post them here directly as well (along with any further notes and recommendations you might have). The code in general is that of a clumsy beginner (me) so all and any advice is most welcome. I'm currently working on a HSL keyer (as much an exercise as anything else), followed probably by a split-signal/soft-clip concoction, so there's more on the way :)

A diff check between the code of the plugins that compile vs the ones that don't should (hopefully) point to the problem but I haven't had a chance to look through your code yet.

A couple of tips that will definitely save headaches later:

Comment everything you do! - It's so easy to lose track of what you have done especially if you come back to the code after some time or regularly move between projects. Adding intelligible comments will help you and anyone that contributes to see what has been added or changed, what functions do etc. Comments should be simple but descriptive.

Consider using Git (Github or Bitbucket) to host your code. It's much easier to upload, modify and share code in a central repository - especially if it's something open source. Other devs can review, contribute and advise. You can pull their code submissions into the main repo through pull requests and you can easily compare, undo and generally keep control. This all contributes to learning better coding. Search 'Git and Xcode'.

Set up a versioning regime to separate development versions and final releases.
 
Thanks Andrew, I'm going to follow all that advice. My file organisation is starting to get very messy, so a proper system is definitely needed. I may also have inadvertently fried my brain by non-stop coding and compiling this week, so that isn't helping with information management :0

The necessary support files for successful compiling may not be present in the App Store version of Resolve 12.5, but then can be obtained by installing the regular version and going to Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer, and there you'll find a folder called OpenFX. The plugin folders need to be inside this folder to access support file when compiling. I use Terminal on OSX and simply cd the plugin folder and type
Code:
make


I added a range offset control to both plugins. It was original meant just for hue rotation as part of a HSL keyer, but turns out it's useful in other ways too.

These plugins have been adapted to work on the App Store version (OpenCL compliant)
 
Last edited:
This next batch contains a separate Saturation and Hue keyer, along with a combined Luminance, Saturation, and Hue keyer. The range offset of the hue section doesn't respond yet, though it works in the separate keyer.

QQdRL4m.png


I've started adding the code files to GitHub, accessible here:

GitHub

The plugins are still OpenCL compliant, but the Cuda files are updated too so enabling is fairly straightforward.

Edit: Quick tip for adjusting parameters. After clicking on the grey ball, you can use the scroll wheel on your mouse to adjust in 0.001 increments for extra precision.
 
Last edited:
Still having difficulty compiling these for Windows with Cuda support enabled but here are the OpenCL versions. I've only compiled them and didn't change any code.

Caution: They load ok but I've not tested them!

Download Paul's OFX plugins for Windows

To install - Extract and copy the folders to "C:\Program Files\Common Files\OFX\Plugins"


BTW, have you tried switching Cuda and OpenCL support on/off using flags? Not sure if it will work but look for the comment "// Setup OpenCL and CUDA render capability flags" in the .cpp file.

You may also want to setup your own OFX grouping just incase someone builds plugins with conflicting names:

change

Code:
#define kPluginGrouping "OpenFX Sample"

to

Code:
#define kPluginGrouping "SomeOtherName"


You could also change #define kPluginIdentifier "com.blackmagicdesign.OpenFXSample.Qualifier to something else if you want (it doesn't always need the com.blackmagicdesign part).
 
Many thanks again Andrew for compiling these. With regards Cuda, I did purposely disable it so that the plugins register on the App Store version as well, but this can be revoked by reversing the procedure set out in post #10. Using the original Makefile (with the appropriate plugin name throughout), and removing the comment markers from the Cuda related entries in the main .cpp file should enable it once more.

There's a lot of tidying up to do with regards to sensible naming procedure and appropriate commenting (as well as removal of unnecessary code), and I do intend to get started on all that, but for the time being I'm focusing on building new plugins while the creative source is in the ascendancy. Once that has slowed down I thoroughly intend to do a proper spring clean :)
 
No problem :)

Yes, I already uncommented the .cpp but no luck. The Makefile is not needed for Windows because there is a VS solution and a project with the required settings.

The main error happens when compiling CudaKernal.cu (calling a host function from a global function is not allowed). I don't think it's my Cuda setup because I can compile other Cuda code. I'll post something on Stackoverflow.com if I don't get anywhere with it - Cuda is :confused:
 
I had a look over the code in the Cuda.cu files, and I did indeed do a poor job in updating them, so you're absolutely right Andrew in your assessment. I did the necessary tweaks for the compile to go through, so hopefully they'll work in Windows as well. Attached are the new, Re-Cuda-fied versions.




Let me know how you get on with them.
 
Last edited:
Had to read up on Cuda.

The compiler error is because you call pow with 2 double precision arguments which isn't allowed in Cuda. If you change it to a single:double precision argument (i.e. change 1.0 to 1 after the pow call) it compiles :)

Example from your Matte code CudaKernal.cu (line 24):

Code:
    const float w = (r) == 0.0 ? 0.0 : ((r) - (1.0 - (g)) >= (n)? 1.0 : ((r) >= (n) ? pow(((r) - (n)) / (1.0 - (g)), (d)) : 0.0));

change to

Code:
    const float w = (r) == 0.0 ? 0.0 : ((r) - (1.0 - (g)) >= (n)? 1.0 : ((r) >= (n) ? pow(((r) - (n)) / (1 - (g)), (d)) : 0.0));

Not sure why you wouldn't get this error in Xcode o_O but check that it still compiles with the change.

I'll upload the recompiled Windows versions later and fork your Git repo.


Useful Cuda reference
 
I got them to compile with Cuda for Windows 64bit and did a quick test in Resolve. They all seem to be working and are definitely making use of Cuda :)

Download for Windows 64bit

Changed to from double:double precision to float:double - should be accurate enough.

Maybe create a download folder on your Git repo to host all builds and keep them in the same place!?
 
Thanks again Andrew. I reckon most (if not all) the plugins could do with some performance tweaking.

I've completed a Soft-Clip plugin that also lets you view and adjust values over 1.0

The signal splitter method has been posted about previously, and can be easily achieved using LUTs or DCTLs:

Code:
__DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
{
    const float r = p_R > 1.0f ? 1.0f : p_R;
    const float g = p_G > 1.0f ? 1.0f : p_G;
    const float b = p_B > 1.0f ? 1.0f : p_B;
 
    return make_float3(r, g, b);
}

Code:
__DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
{
    const float r = (p_R < 1.0f ? 1.0f : p_R) - 1.0f;
    const float g = (p_G < 1.0f ? 1.0f : p_G) - 1.0f;
    const float b = (p_B < 1.0f ? 1.0f : p_B) - 1.0f;
 
    return make_float3(r, g, b);
}

The plugin has a fairly simple interface. A drop-down menu gives 3 choices: Bypass involves only highlight and soft-clip controls, Cineon does a cineon log to BT.1886 conversion, and LogC Alexa Wide does a LogC Alexa Wide Gamut to BT.1886 Rec.709 Primaries. The highlight and soft-clip controls are applied to the linear stage of the conversion.

BSS84Tk.png


2fRdGH8.png


KoQ57Y5.png


Display Highlights shows in the viewer the part of the signal over 1.0 but offset to 0.0

Slope is multiplication applied only to the signal over 1.0, and power is like gamma in the normal LGG controls. They allow for the rescaling and compression redistribution of highlight information. Soft-clip off by default (at 0.000) but once activated it compresses signal over 1.0 to a threshold region defined by the parameter. A threshold values of 0.2 means the signal up to 0.8 is unaffected and any highlight information is compressed into the top 0.2.

You can download the plugin for OSX (both Cuda and OpenCL versions) from it's GitHub page.
 
Last edited:
Back
Top