Exemplo n.º 1
0
// the process code  that the host sees
static OfxStatus render( OfxImageEffectHandle  instance,
                         OfxPropertySetHandle inArgs,
                         OfxPropertySetHandle outArgs)
{
  // get the render window and the time from the inArgs
  OfxTime time;
  OfxRectI renderWindow;
  OfxStatus status = kOfxStatOK;

  gPropHost->propGetDouble(inArgs, kOfxPropTime, 0, &time);
  gPropHost->propGetIntN(inArgs, kOfxImageEffectPropRenderWindow, 4, &renderWindow.x1);

  // retrieve any instance data associated with this effect
  MyInstanceData *myData = getMyInstanceData(instance);

  // property handles and members of each image
  // in reality, we would put this in a struct as the C++ support layer does
  OfxPropertySetHandle sourceImg = NULL, outputImg = NULL, maskImg = NULL;
  int srcRowBytes, srcBitDepth, dstRowBytes, dstBitDepth, maskRowBytes, maskBitDepth;
  bool srcIsAlpha, dstIsAlpha, maskIsAlpha;
  OfxRectI dstRect, srcRect, maskRect;
  void *src, *dst, *mask = NULL;

  try {
    // get the source image
    sourceImg = ofxuGetImage(myData->sourceClip, time, srcRowBytes, srcBitDepth, srcIsAlpha, srcRect, src);
    if(sourceImg == NULL) throw OfxuNoImageException();

    // get the output image
    outputImg = ofxuGetImage(myData->outputClip, time, dstRowBytes, dstBitDepth, dstIsAlpha, dstRect, dst);
    if(outputImg == NULL) throw OfxuNoImageException();

    if(myData->isGeneralEffect) {
      // is the mask connected?
      if(ofxuIsClipConnected(instance, "Mask")) {
        maskImg = ofxuGetImage(myData->maskClip, time, maskRowBytes, maskBitDepth, maskIsAlpha, maskRect, mask);

        if(maskImg != NULL) {                        
          // and see that it is a single component
          if(!maskIsAlpha || maskBitDepth != srcBitDepth) {
            throw OfxuStatusException(kOfxStatErrImageFormat);
          }  
        }
      }
    }

    // see if they have the same depths and bytes and all
    if(srcBitDepth != dstBitDepth || srcIsAlpha != dstIsAlpha) {
      throw OfxuStatusException(kOfxStatErrImageFormat);
    }

    // are we compenent scaling
    bool scaleComponents;
    gParamHost->paramGetValueAtTime(myData->perComponentScaleParam, time, &scaleComponents);

    // get the scale parameters
    double scale, rScale = 1, gScale = 1, bScale = 1, aScale = 1;
    gParamHost->paramGetValueAtTime(myData->scaleParam, time, &scale);

    if(scaleComponents) {
      gParamHost->paramGetValueAtTime(myData->scaleRParam, time, &rScale);
      gParamHost->paramGetValueAtTime(myData->scaleGParam, time, &gScale);
      gParamHost->paramGetValueAtTime(myData->scaleBParam, time, &bScale);
      gParamHost->paramGetValueAtTime(myData->scaleAParam, time, &aScale);
    }
    rScale *= scale; gScale *= scale; bScale *= scale; aScale *= scale;
  
    // do the rendering
    if(!dstIsAlpha) {
      switch(dstBitDepth) {
      case 8 : {      
        ProcessRGBA<OfxRGBAColourB, unsigned char, 255, 0> fred(instance, rScale, gScale, bScale, aScale,
                                                                src, srcRect, srcRowBytes,
                                                                dst, dstRect, dstRowBytes,
                                                                mask, maskRect, maskRowBytes,
                                                                renderWindow);
        fred.process();                                          
      }
        break;

      case 16 : {
        ProcessRGBA<OfxRGBAColourS, unsigned short, 65535, 0> fred(instance, rScale, gScale, bScale, aScale,
                                                                   src, srcRect, srcRowBytes,
                                                                   dst, dstRect, dstRowBytes,
                                                                   mask, maskRect, maskRowBytes,
                                                                   renderWindow);
        fred.process();           
      }                          
        break;

      case 32 : {
        ProcessRGBA<OfxRGBAColourF, float, 1, 1> fred(instance, rScale, gScale, bScale, aScale,
                                                      src, srcRect, srcRowBytes,
                                                      dst, dstRect, dstRowBytes,
                                                      mask, maskRect, maskRowBytes,
                                                      renderWindow);
        fred.process();                                          
        break;
      }
      }
    }
    else {
      switch(dstBitDepth) {
      case 8 : {
        ProcessAlpha<unsigned char, unsigned char, 255, 0> fred(instance, scale, 
                                                                src, srcRect, srcRowBytes,
                                                                dst, dstRect, dstRowBytes,
                                                                mask, maskRect, maskRowBytes,
                                                                renderWindow);
        fred.process();                                                                                  
      }
        break;

      case 16 : {
        ProcessAlpha<unsigned short, unsigned short, 65535, 0> fred(instance, scale, 
                                                                    src, srcRect, srcRowBytes,
                                                                    dst, dstRect, dstRowBytes,
                                                                    mask, maskRect, maskRowBytes,
                                                                    renderWindow);
        fred.process();           
      }                          
        break;

      case 32 : {
        ProcessAlpha<float, float, 1, 1> fred(instance, scale, 
                                              src, srcRect, srcRowBytes,
                                              dst, dstRect, dstRowBytes,
                                              mask, maskRect, maskRowBytes,
                                              renderWindow);
        fred.process();           
      }                          
        break;
      }
    }
  }
  catch(OfxuNoImageException &ex) {
    // if we were interrupted, the failed fetch is fine, just return kOfxStatOK
    // otherwise, something wierd happened
    if(!gEffectHost->abort(instance)) {
      status = kOfxStatFailed;
    }
  }
  catch(OfxuStatusException &ex) {
    status = ex.status();
  }

  // release the data pointers
  if(maskImg)
    gEffectHost->clipReleaseImage(maskImg);
  if(sourceImg)
    gEffectHost->clipReleaseImage(sourceImg);
  if(outputImg)
    gEffectHost->clipReleaseImage(outputImg);
  
  return status;
}
Exemplo n.º 2
0
// the process code  that the host sees
static OfxStatus render(OfxImageEffectHandle effect,
                        OfxPropertySetHandle inArgs,
                        OfxPropertySetHandle outArgs)
{
  // get the render window and the time from the inArgs
  OfxTime time;
  OfxRectI renderWindow;
  OfxStatus status = kOfxStatOK;
  
  gPropHost->propGetDouble(inArgs, kOfxPropTime, 0, &time);
  gPropHost->propGetIntN(inArgs, kOfxImageEffectPropRenderWindow, 4, &renderWindow.x1);

  // retrieve any instance data associated with this effect
  MyInstanceData *myData = getMyInstanceData(effect);

  // property handles and members of each image
  // in reality, we would put this in a struct as the C++ support layer does
  OfxPropertySetHandle sourceImg = NULL, outputImg = NULL;
  int srcRowBytes, srcBitDepth, dstRowBytes, dstBitDepth;
  bool srcIsAlpha, dstIsAlpha;
  OfxRectI dstRect, srcRect;
  void *src, *dst;

  try {
    outputImg = ofxuGetImage(myData->outputClip, time, dstRowBytes, dstBitDepth, dstIsAlpha, dstRect, dst);
    if(outputImg == NULL) throw OfxuNoImageException();

    sourceImg = ofxuGetImage(myData->sourceClip, time, srcRowBytes, srcBitDepth, srcIsAlpha, srcRect, src);
    if(sourceImg == NULL) throw OfxuNoImageException();
    
    int nComponents = dstIsAlpha ? 1 : 4;
    
    // set up the processor that we pass to the individual constructors
    Processor proc(effect, nComponents,
                   src, srcRect, srcRowBytes,
                   dst, dstRect, dstRowBytes,
                   renderWindow);
    
    // now instantiate the templated processor depending on src and dest pixel types, 9 cases in all
    switch(dstBitDepth) {
    case 8 : {
      switch(srcBitDepth) {
      case 8 :  {ProcessPix<unsigned char,  255,   0, unsigned char, 255, 0> pixProc(proc); break;}
      case 16 : {ProcessPix<unsigned short, 65535, 0, unsigned char, 255, 0> pixProc(proc); break;}
      case 32 : {ProcessPix<float,          1,     1, unsigned char, 255, 0> pixProc(proc); break;}
      }
    }
      break;

    case 16 : {
      switch(srcBitDepth) {
      case 8 :  {ProcessPix<unsigned char,  255,   0, unsigned short, 65535, 0> pixProc(proc); break;}
      case 16 : {ProcessPix<unsigned short, 65535, 0, unsigned short, 65535, 0> pixProc(proc); break;}
      case 32 : {ProcessPix<float,          1,     1, unsigned short, 65535, 0> pixProc(proc); break;}
      }
    }
      break;

    case 32 : {
      switch(srcBitDepth) {
      case 8 :  {ProcessPix<unsigned char,  255,   0, float, 1, 1> pixProc(proc); break;}
      case 16 : {ProcessPix<unsigned short, 65535, 0, float, 1, 1> pixProc(proc); break;}
      case 32 : {ProcessPix<float,          1,     1, float, 1, 1> pixProc(proc); break;}
      }
    }                          
      break;
    }
  }
  catch(OfxuNoImageException &ex) {
    // if we were interrupted, the failed fetch is fine, just return kOfxStatOK
    // otherwise, something wierd happened
    if(!gEffectHost->abort(effect)) {
      status = kOfxStatFailed;
    }
  }

  // release the data pointers;
  if(sourceImg)
    gEffectHost->clipReleaseImage(sourceImg);
  if(outputImg)
    gEffectHost->clipReleaseImage(outputImg);
  
  return status;
}
Exemplo n.º 3
0
// the process code  that the host sees
static OfxStatus render( OfxImageEffectHandle  instance,
                         OfxPropertySetHandle inArgs,
                         OfxPropertySetHandle outArgs)
{
  // get the render window and the time from the inArgs
  OfxTime time;
  OfxRectI renderWindow;
  OfxStatus status = kOfxStatOK;

  gPropHost->propGetDouble(inArgs, kOfxPropTime, 0, &time);
  gPropHost->propGetIntN(inArgs, kOfxImageEffectPropRenderWindow, 4, &renderWindow.x1);

  // Retrieve instance data associated with this effect
  MyInstanceData *myData = getMyInstanceData(instance);

  // property handles and members of each image
  OfxPropertySetHandle sourceImg = NULL, outputImg = NULL;
  int srcRowBytes, srcBitDepth, dstRowBytes, dstBitDepth;
  bool srcIsAlpha, dstIsAlpha;
  OfxRectI dstRect, srcRect;
  void *src, *dst;

  DPRINT(("Render: window = [%d, %d - %d, %d]\n",
	  renderWindow.x1, renderWindow.y1,
	  renderWindow.x2, renderWindow.y2));

  int isOpenCLEnabled = 0;
  if (gHostSupportsOpenCL)
  {
      gPropHost->propGetInt(inArgs, kOfxImageEffectPropOpenCLEnabled, 0, &isOpenCLEnabled);
      DPRINT(("render: OpenCL rendering %s\n", isOpenCLEnabled ? "enabled" : "DISABLED"));
  }

  cl_context clContext = NULL;
  cl_command_queue cmdQ = NULL;
  cl_device_id deviceId = NULL;
  if (isOpenCLEnabled)
  {
      void* voidPtrCmdQ;
      gPropHost->propGetPointer(inArgs, kOfxImageEffectPropOpenCLCommandQueue, 0, &voidPtrCmdQ);
      cmdQ = reinterpret_cast<cl_command_queue>(voidPtrCmdQ);

      clGetCommandQueueInfo(cmdQ, CL_QUEUE_CONTEXT, sizeof(cl_context), &clContext, NULL);
      clGetCommandQueueInfo(cmdQ, CL_QUEUE_DEVICE, sizeof(cl_device_id), &deviceId, NULL);
  }
  else
  {
      clContext = GetContext(deviceId);
      cmdQ = clCreateCommandQueue(clContext, deviceId, 0, NULL);
  }

  char deviceName[128];
  clGetDeviceInfo(deviceId, CL_DEVICE_NAME, 128, deviceName, NULL);
  DPRINT(("Using %s for plugin\n", deviceName));

  cl_kernel kernel = GetKernel(clContext);

  // get the source image
  sourceImg = ofxuGetImage(myData->sourceClip, time, srcRowBytes, srcBitDepth, srcIsAlpha, srcRect, src);

  // get the output image
  outputImg = ofxuGetImage(myData->outputClip, time, dstRowBytes, dstBitDepth, dstIsAlpha, dstRect, dst);

  // get the scale parameter
  double rGain = 1, gGain = 1, bGain = 1;
  gParamHost->paramGetValueAtTime(myData->rGainParam, time, &rGain);
  gParamHost->paramGetValueAtTime(myData->gGainParam, time, &gGain);
  gParamHost->paramGetValueAtTime(myData->bGainParam, time, &bGain);
  DPRINT(("Gain(%f %f %f)\n", rGain, gGain, bGain));

  float w = (renderWindow.x2 - renderWindow.x1);
  float h = (renderWindow.y2 - renderWindow.y1);

  const size_t rowSize = w * 4 * sizeof(float);

  if (isOpenCLEnabled)
  {
      DPRINT(("Using OpenCL transfers (same device)\n"));

      RunKernel(cmdQ, deviceId, kernel, w, h, rGain, gGain, bGain, (cl_mem)src, (cl_mem)dst);
  }
  else
  {
      DPRINT(("Using CPU transfers\n"));

      const size_t bufferSize = w * h * 4 * sizeof(float);

      // Allocate the temporary buffers on the plugin device
      cl_mem inBuffer = clCreateBuffer(clContext, CL_MEM_READ_ONLY, bufferSize, NULL, NULL);
      cl_mem outBuffer = clCreateBuffer(clContext, CL_MEM_WRITE_ONLY, bufferSize, NULL, NULL);

      // Copy the buffer from the CPU to the plugin device
      clEnqueueWriteBuffer(cmdQ, inBuffer, CL_TRUE, 0, bufferSize, src, 0, NULL, NULL);

      RunKernel(cmdQ, deviceId, kernel, w, h, rGain, gGain, bGain, inBuffer, outBuffer);

      // Copy the buffer from the plugin device to the CPU
      clEnqueueReadBuffer(cmdQ, outBuffer, CL_TRUE, 0, bufferSize, dst, 0, NULL, NULL);

      clFinish(cmdQ);

      // Free the temporary buffers on the plugin device
      clReleaseMemObject(inBuffer);
      clReleaseMemObject(outBuffer);
  }

  if (sourceImg)
  {
      gEffectHost->clipReleaseImage(sourceImg);
  }

  if (outputImg)
  {
      gEffectHost->clipReleaseImage(outputImg);
  }

  return status;
}