News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

OpenFX examples

Started by guga, June 11, 2024, 10:05:34 AM

Previous topic - Next topic

guga

Someone succeeded to port OpenFX to masm ? (For 32 and 64 bits)

A long time ago i gave a try to create a ".ofx" plugin to use in Sony Vegas using RosAsm. But now, Sony Vegas seems to not accept 32 bits ofx any longer.

I lost the project, so, if anyone tried or have a working example to be used in SonyVegas, pls post. Or a way to load a 32bit dll from a 64bit ofx would also be handy. (Perhaps using a type of wrapper that can load 32bits dlls on a 64bit ofx to be used in SonyVegas)

https://www.codeproject.com/Articles/5336312/Load-a-x86-DLL-into-a-x64-Executable-Mission-Possi
https://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

ChatGPT answered me this (Untested).

To properly integrate your 32-bit DLL with the 64-bit OFX plugin, you need to load the 32-bit DLL in the 32-bit helper process and use IPC to send pixel data between the 64-bit OFX plugin and the 32-bit helper process. Here's a more detailed example to illustrate how to achieve this.
32-bit DLL (example_dll.c)

First, create a 32-bit DLL with an export function that processes pixel data.
#include <windows.h>

__declspec(dllexport) void ProcessPixels(unsigned char* inputPixels, unsigned char* outputPixels, int width, int height) {
    // Example processing: Copy input to output
    for (int i = 0; i < width * height * 4; ++i) {
        outputPixels[i] = inputPixels[i];
    }
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
    return TRUE;
}


32-bit Helper Process (32bit_helper.c)

Next, create a 32-bit helper process that loads the DLL and processes pixel data.

#include <windows.h>
#include <stdio.h>

typedef void (*ProcessPixelsFunc)(unsigned char*, unsigned char*, int, int);

int main() {
    HMODULE hDll = LoadLibrary("example_dll.dll");
    if (!hDll) {
        fprintf(stderr, "Failed to load DLL\n");
        return 1;
    }

    ProcessPixelsFunc processPixels = (ProcessPixelsFunc)GetProcAddress(hDll, "ProcessPixels");
    if (!processPixels) {
        fprintf(stderr, "Failed to get ProcessPixels function\n");
        FreeLibrary(hDll);
        return 1;
    }

    // Read pixel data from the parent process
    unsigned char inputPixels[256 * 256 * 4]; // Example size
    unsigned char outputPixels[256 * 256 * 4];
    int width, height;
   
    while (1) {
        // Read width and height
        DWORD bytesRead;
        ReadFile(GetStdHandle(STD_INPUT_HANDLE), &width, sizeof(int), &bytesRead, NULL);
        ReadFile(GetStdHandle(STD_INPUT_HANDLE), &height, sizeof(int), &bytesRead, NULL);

        // Read input pixels
        ReadFile(GetStdHandle(STD_INPUT_HANDLE), inputPixels, width * height * 4, &bytesRead, NULL);

        // Process pixels
        processPixels(inputPixels, outputPixels, width, height);

        // Write output pixels
        DWORD bytesWritten;
        WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), outputPixels, width * height * 4, &bytesWritten, NULL);
    }

    FreeLibrary(hDll);
    return 0;
}


64-bit OFX Plugin (plugin.c)

Finally, create a 64-bit OFX plugin that communicates with the helper process.

#include <ofxPlugin.h>
#include <ofxImageEffect.h>
#include <windows.h>
#include <stdio.h>

#define PLUGIN_UID "com.example.PixelProcessor"
#define PLUGIN_VERSION 1

static HANDLE hChildProcess = NULL;
static HANDLE hInputWrite = NULL;
static HANDLE hOutputRead = NULL;

static BOOL CreateChildProcess() {
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFO siStartInfo;
    BOOL bSuccess = FALSE;
    SECURITY_ATTRIBUTES saAttr;
   
    // Set the bInheritHandle flag so pipe handles are inherited.
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    // Create pipes for the child process's STDOUT and STDIN.
    HANDLE hOutputWrite, hInputRead;
    if (!CreatePipe(&hOutputRead, &hOutputWrite, &saAttr, 0)) return FALSE;
    if (!CreatePipe(&hInputRead, &hInputWrite, &saAttr, 0)) return FALSE;
    if (!SetHandleInformation(hOutputRead, HANDLE_FLAG_INHERIT, 0)) return FALSE;
    if (!SetHandleInformation(hInputWrite, HANDLE_FLAG_INHERIT, 0)) return FALSE;

    // Set up members of the PROCESS_INFORMATION structure.
    ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));

    // Set up members of the STARTUPINFO structure.
    ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.hStdError = hOutputWrite;
    siStartInfo.hStdOutput = hOutputWrite;
    siStartInfo.hStdInput = hInputRead;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

    // Create the child process.
    bSuccess = CreateProcess(NULL,
        "32bit_helper.exe", // Name of the executable
        NULL,               // Process security attributes
        NULL,               // Primary thread security attributes
        TRUE,               // Handles are inherited
        0,                  // Creation flags
        NULL,               // Use parent's environment
        NULL,               // Use parent's current directory
        &siStartInfo,       // Pointer to STARTUPINFO structure
        &piProcInfo);       // Pointer to PROCESS_INFORMATION structure

    CloseHandle(hOutputWrite);
    CloseHandle(hInputRead);

    if (!bSuccess) return FALSE;

    hChildProcess = piProcInfo.hProcess;
    CloseHandle(piProcInfo.hThread);

    return TRUE;
}

static void SendMessageToChild(const void* message, DWORD size) {
    DWORD bytesWritten;
    WriteFile(hInputWrite, message, size, &bytesWritten, NULL);
}

static void ReceiveMessageFromChild(void* buffer, DWORD size) {
    DWORD bytesRead;
    ReadFile(hOutputRead, buffer, size, &bytesRead, NULL);
}

static OfxStatus pluginMain(OfxImageEffectHandle instance, const OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs) {
    return kOfxStatOK;
}

static OfxStatus describe(OfxImageEffectHandle effect) {
    OfxPropertySetHandle props;
    OfxStatus status;

    status = gEffectSuite->getPropertySet(effect, &props);
    if (status != kOfxStatOK) return status;

    gPropertySuite->propSetString(props, kOfxPropLabel, 0, "Pixel Processor");

    return kOfxStatOK;
}

static OfxStatus describeInContext(OfxImageEffectHandle effect, OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs) {
    return kOfxStatOK;
}

static OfxStatus createInstance(OfxImageEffectHandle effect) {
    if (!CreateChildProcess()) {
        return kOfxStatErrMemory;
    }
    return kOfxStatOK;
}

static OfxStatus destroyInstance(OfxImageEffectHandle effect) {
    if (hChildProcess) {
        TerminateProcess(hChildProcess, 0);
        CloseHandle(hChildProcess);
    }
    if (hInputWrite) CloseHandle(hInputWrite);
    if (hOutputRead) CloseHandle(hOutputRead);
    return kOfxStatOK;
}

static OfxStatus render(OfxImageEffectHandle instance, OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs) {
    // Example image dimensions
    int width = 256;
    int height = 256;
    unsigned char inputPixels[256 * 256 * 4];
    unsigned char outputPixels[256 * 256 * 4];

    // Prepare input data (just an example, replace with actual pixel data)
    for (int i = 0; i < width * height * 4; ++i) {
        inputPixels[i] = (unsigned char)i;
    }

    // Send width, height, and input pixels to the child process
    SendMessageToChild(&width, sizeof(width));
    SendMessageToChild(&height, sizeof(height));
    SendMessageToChild(inputPixels, sizeof(inputPixels));

    // Receive processed output pixels from the child process
    ReceiveMessageFromChild(outputPixels, sizeof(outputPixels));

    // Use the processed output pixels (e.g., send back to Sony Vegas)
    // ...

    return kOfxStatOK;
}

static OfxImageEffectSuiteV1 gEffectSuite = {
    createInstance,
    destroyInstance,
    describe,
    describeInContext,
    render,
    pluginMain
};

OfxExport OfxPlugin *OfxGetPlugin(int nth) {
    static OfxPlugin plugin = {
        kOfxImageEffectPluginApi,
        PLUGIN_VERSION,
        PLUGIN_UID,
        NULL,
        pluginMain,
        &gEffectSuite
    };

    if (nth == 0) return &plugin;
    return NULL;
}

OfxExport int OfxGetNumberOfPlugins(void) {
    return 1;
}


Compilation:

    Compile the 32-bit DLL with Pelles C as a 32-bit DLL.
    Compile the 32-bit helper process with Pelles C as a 32-bit executable.
    Compile the 64-bit OFX plugin with Pelles C as a 64-bit DLL.

Usage:

    Place the 32-bit DLL and the 32-bit helper process executable in the appropriate directories.
    Load the 64-bit OFX plugin in Sony Vegas. The plugin will create the helper process, send pixel data for processing, and receive the processed data.

This setup allows the 64-bit OFX plugin to communicate with the 32-bit DLL through a separate process, enabling the usage of 32-bit code in a 64-bit environment. Adjustments may be needed based on


But, i have no idea how to implement it. Openfx is in c++ and i completely lost a basic wrapper i created years ago.

I didnĀ“t understood how to make this works properly
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com