Allocating Your Own Images

Under OFX, the images you fetch from the host have already had their memory allocated. If a plug-in needs to define its owns temporary images buffers during processing, or to cache images between actions, then the plug-in should use the image memory allocation routines declared in OfxImageEffectSuiteV1. The reason for this is that many host have special purpose memory pools they manage to optimise memory usage as images can chew up memory very rapidly (eg: a 2K RGBA floating point film plate is 48 MBytes).

For general purpose (as in less than a megabyte) memory allocation, you should use the memory suite in ofxMemory.h

OFX provides four functions to deal with image memory. These are,

A host needs to be able defragment its image memory pool, potentially moving the contents of the memory you have allocated to another address, even saving it to disk under its own virtual memory caching scheme. Because of this when you request a block of memory, you are actually returned a handle to the memory, not the memory itself. To use the memory you must first lock the memory via the imageMemoryLock call, which will then return a pointer to the locked block of memory.

During an single action, there is generally no need to lock/unlock any temporary buffers you may have allocated via this mechanism. However image memory that is cached between actions should always be unlocked while it is not actually being used. This allows a host to do what it needs to do to optimise memory usage.

Note that locks and unlocks nest. This implies that there is a lock count kept on the memory handle, also not that this lock count cannot be negative. So unlocking a completely unlocked handle has no effect.

An example is below....

  // get a memory handle
  OfxImageMemoryHandle memHandle;
  gEffectSuite->imageMemoryAlloc(0, imageSize, &memHandle);

  // lock the handle and get a pointer
  void *memPtr;
  gEffectSuite->imageMemoryLock(memHandle, &memPtr);
  
  ... // do stuff with our pointer

  // now unlock it
  gEffectSuite->imageMemoryUnlock(memHandle);

  
  // lock it again, note that this may give a completely different address to the last lock
  gEffectSuite->imageMemoryLock(memHandle, &memPtr);
  
  ... // do more stuff

  // unlock it again
  gEffectSuite->imageMemoryUnlock(memHandle);

  // delete it all
  gEffectSuite->imageMemoryFree(memHandle);