Plugin API

The API manual documentation can be found here.


There are two requirements for XIMEA CamTool plugins to be detected and loaded at startup:


  1. There has to be exactly one class in the project, that derives from QObject and CxPlugin, and also declares Q_OBJECT, Q_PLUGIN_METADATA and Q_INTERFACES(CxPlugin) in its header.
  2. The compiled library file name must have "xvp" prefix.
    Application loads all plugins at startup after all cameras are connected.


The plugin can use all exported functions and classes present in xiCore library.
The plugin may communicate with several items in the application itself by using class IxAppDelegate.


The task for the CxPlugin class is to add new possibilities to the application.
This means to register new processing objects, or add new docked windows and other GUI objects.
All this registration has to be done in CxPlugin::init method.

Correct minimal header file for the main plugin class may look like:

#include <Plugin.h>
#include <QObject>
class MyPlugin : public QObject, public CxPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "com.example.MyPlugin")
    Q_INTERFACES(CxPlugin)
public:
    virtual bool init();
};

Plugins with GUI

The plugin can create additional GUI in the application. Everything is done using Qt Widgets library.


  • To add a toolbar button, add a QAction to IxAppDelegate::mainToolbar
  • To add a new menu popup, add a QAction to the menu at IxAppDelegate::mainWindow
  • To add a new docked window, use IxAppDelegate::addDockedWidget


Please see Mean Gray Measurement for an example.

All available docked windows are listed in the View menu in the application

Object for the processing chain

Any type of image processing can be added to the application.
For example contrast enhancement, edge detection, custom denoising.
The implementation is again very similar to file format plugin, but you derive from CxChainable.

To register it to the system, call the following in the plugin CxPlugin::init method:

xiRTTI_REGISTER(MyImageProcessing, "CxChainable"); 

There are lots of functions available to override in CxChainable, but most of them can be left with the default implementation.
Please see CxNegativeChnbl for a simple example.


New processing chain objects automatically appear in the Processing Chain Editor window, under '+' button.
The name of the object is set in Q_CLASSINFO

Some minimal header file for the processing chain object may look like this:

#include <Chainable.h>
class MyProcessingChnbl : public CxImageProvider
{
    Q_OBJECT
    Q_CLASSINFO("CustomName", "My Processing")
public:
    Q_INVOKABLE MyProcessingChnbl();    // constructor must be 
                                        // marked as invokable
    //CxChainable
public:
    virtual QString title() const;    
    virtual bool acceptsDataFrom(CxChainable *pPrecedessor);
    virtual int buffersCountInMemoryPool() const;
    virtual CxChainable* clone();
protected:
    virtual IxChainData* processData(IxChainData *pReceivedData);
    // CxImageProvider
public:
    virtual bool queryOutputImageInfo(const SxPicBufInfo &picInfoInput, 
SxPicBufInfo &picInfoOutput);
};

Increase BUFFERS_QUEUE_SIZE

In default, BUFFERS_QUEUE_SIZE is set to minimum in CamTool. However, when the goal is the highest possible frame rate and reduction of skipped frames, BUFFERS_QUEUE_SIZE should be increased. If custom param "use_max_queue_size" is set to "true" in camera source object (as shown in the code snippet bellow), buffers queue size is increased to maximum possible size. Then BUFFERS_QUEUE_SIZE can be changed from any other parts of the plugin or from Lua script.

#include <ChainManager.h>
#include <CameraSource.h>

CxChainManager *pChainMan = CxChainManager::instance();
CxCameraSource *pCamSrc = pChainMan->cameraSource(m_hCamera);
if (pCamSrc == NULL)
{
    pCamSrc = pChainMan->createCameraSource(m_hCamera);
}
// use "true" to set max XI_PRM_BUFFERS_QUEUE_SIZE
pCamSrc->setCustomParam(QString("use_max_queue_size"), QVariant(true));
// or "false" (default) in case of default XI_PRM_BUFFERS_QUEUE_SIZE
pCamSrc->setCustomParam(QString("use_max_queue_size"), QVariant(false));

File format implementation

You can add the support for new file formats using a plugin.
The key is to implement class derived from IxImageDataLoader or IxImageDataSaver.

To register it to the system, call the following in plugin CxPlugin::init method.

xiRTTI_REGISTER(MyDataLoader, "IxImageDataLoader"); 

Please note that you can implement and register more xiRTTI classes in a single plugin.

If you fill all necessary functions, the new file format option automatically appears in the application's File - Open and File - Save dialog windows.

Header file for the loader may look like this:

#include <DataLoader.h>
class MyDataLoader : public QObject, public IxImageDataLoader
{
    Q_OBJECT
public:
    Q_INVOKABLE MyDataLoader();    // constructor must be marked as invokable
    // IxChainDataLoader interface
public:
    virtual qint32 sequenceSize();
    virtual IxChainData *loadedData(qint32 iSeqIdx = 0);
    virtual bool load();
    virtual QString inputFile();
    virtual void setInputFile(const QString &sFileName);
    // IxImageDataLoader interface
public:
    virtual double loadedFps();
    virtual TxImageFormatList supportedImageFormats();
};