diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp index 7a5e3851be..d153afccfc 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp @@ -1,340 +1,344 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkUSTelemedDevice.h" #include "mitkUSTelemedSDKHeader.h" mitk::USTelemedDevice::USTelemedDevice(std::string manufacturer, std::string model) : mitk::USDevice(manufacturer, model), m_ControlsProbes(mitk::USTelemedProbesControls::New(this)), m_ControlsBMode(mitk::USTelemedBModeControls::New(this)), m_ControlsDoppler(mitk::USTelemedDopplerControls::New(this)), m_ImageSource(mitk::USTelemedImageSource::New()), m_UsgMainInterface(0), m_Probe(0), m_UsgDataView(0), m_ProbesCollection(0) { SetNumberOfOutputs(1); SetNthOutput(0, this->MakeOutput(0)); } mitk::USTelemedDevice::~USTelemedDevice() { } std::string mitk::USTelemedDevice::GetDeviceClass() { return "org.mitk.modules.us.USTelemedDevice"; } mitk::USControlInterfaceBMode::Pointer mitk::USTelemedDevice::GetControlInterfaceBMode() { return m_ControlsBMode.GetPointer(); } mitk::USControlInterfaceProbes::Pointer mitk::USTelemedDevice::GetControlInterfaceProbes() { return m_ControlsProbes.GetPointer(); }; mitk::USControlInterfaceDoppler::Pointer mitk::USTelemedDevice::GetControlInterfaceDoppler() { return m_ControlsDoppler.GetPointer(); }; bool mitk::USTelemedDevice::OnInitialization() { CoInitialize(NULL); // initialize COM library return true; } bool mitk::USTelemedDevice::OnConnection() { // create main Telemed API COM library object HRESULT hr; hr = CoCreateInstance(Usgfw2Lib::CLSID_Usgfw2, NULL, CLSCTX_INPROC_SERVER, Usgfw2Lib::IID_IUsgfw2,(LPVOID*) &m_UsgMainInterface); if (FAILED(hr)) { SAFE_RELEASE(m_UsgMainInterface); MITK_ERROR("USDevice")("USTelemedDevice") << "Error at connecting to ultrasound device (" << hr << ")."; return false; } this->ConnectDeviceChangeSink(); return true; } bool mitk::USTelemedDevice::OnDisconnection() { // control objects cannot be active anymore m_ControlsBMode->SetIsActive(false); m_ControlsDoppler->SetIsActive(false); m_ControlsProbes->SetIsActive(false); ReleaseUsgControls(); return true; } bool mitk::USTelemedDevice::OnActivation() { // probe controls are available now m_ControlsProbes->SetIsActive(true); if ( m_ControlsProbes->GetProbesCount() < 1 ) { MITK_WARN("USDevice")("USTelemedDevice") << "No probe found."; return false; } // select first probe as a default m_ControlsProbes->SelectProbe(0); // set scan mode b as default for activation - // control interfaces can override this later HRESULT hr = m_UsgDataView->put_ScanMode(Usgfw2Lib::SCAN_MODE_B); if (FAILED(hr)) { MITK_ERROR("USDevice")("USTelemedDevice") << "Could not set scan mode b (" << hr << ")."; return false; } // start ultrasound scanning with selected scan mode hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN); if (FAILED(hr)) { MITK_ERROR("USDevice")("USTelemedDevice") << "Start scanning failed (" << hr << ")."; return false; } m_ControlsBMode->ReinitializeControls(); return true; } bool mitk::USTelemedDevice::OnDeactivation() { this->StopScanning(); return true; } void mitk::USTelemedDevice::OnFreeze(bool freeze) { if ( freeze ) { m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_FREEZE); } else { m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN); } } mitk::USImageSource::Pointer mitk::USTelemedDevice::GetUSImageSource() { return m_ImageSource.GetPointer(); } void mitk::USTelemedDevice::ReleaseUsgControls() { if (m_UsgDataView) { this->StopScanning(); }; SAFE_RELEASE(m_UsgMainInterface); SAFE_RELEASE(m_Probe); SAFE_RELEASE(m_UsgDataView); SAFE_RELEASE(m_ProbesCollection); } void mitk::USTelemedDevice::StopScanning() { if ( ! m_UsgDataView ) { MITK_WARN("USDevice")("USTelemedDevice") << "Cannot stop scanning as Telemed Data View is null."; return; } HRESULT hr; hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_STOP); if (FAILED(hr)) { MITK_ERROR("USDevice")("USTelemedDevice") << "Stop scanning failed (" << hr << ")."; mitkThrow() << "Stop scanning failed (" << hr << ")."; } } Usgfw2Lib::IUsgfw2* mitk::USTelemedDevice::GetUsgMainInterface() { return m_UsgMainInterface; } void mitk::USTelemedDevice::SetActiveDataView(Usgfw2Lib::IUsgDataView* usgDataView) { - // scan converter plugin is conected to IUsgDataView -> a new plugin - // must be created when changing IUsgDataView - m_UsgDataView = usgDataView; - if ( ! m_ImageSource->CreateAndConnectConverterPlugin(m_UsgDataView, Usgfw2Lib::SCAN_MODE_B)) { return; } + // do nothing if the usg data view hasn't changed + if ( m_UsgDataView != usgDataView ) + { + // scan converter plugin is connected to IUsgDataView -> a new plugin + // must be created when changing IUsgDataView + m_UsgDataView = usgDataView; + if ( ! m_ImageSource->CreateAndConnectConverterPlugin(m_UsgDataView, Usgfw2Lib::SCAN_MODE_B)) { return; } - // b mode control object must know about active data view - m_ControlsBMode->SetUsgDataView(m_UsgDataView); + // b mode control object must know about active data view + m_ControlsBMode->SetUsgDataView(m_UsgDataView); + } } void mitk::USTelemedDevice::ConnectDeviceChangeSink( ) { IConnectionPointContainer* cpc = NULL; HRESULT hr = m_UsgMainInterface->QueryInterface(IID_IConnectionPointContainer, (void**)&cpc); if (hr != S_OK) cpc = NULL; if (cpc != NULL) hr = cpc->FindConnectionPoint(Usgfw2Lib::IID_IUsgDeviceChangeSink, &m_UsgDeviceChangeCpnt); if (hr != S_OK) { m_UsgDeviceChangeCpnt = NULL; m_UsgDeviceChangeCpntCookie = 0; } SAFE_RELEASE(cpc); if (m_UsgDeviceChangeCpnt != NULL) hr = m_UsgDeviceChangeCpnt->Advise((IUnknown*)((Usgfw2Lib::IUsgDeviceChangeSink*)this), &m_UsgDeviceChangeCpntCookie); } // --- Methods for Telemed API Interfaces HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerArrive(IUnknown *pUsgBeamformer, ULONG *reserved) { this->Connect(); return S_OK; } HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerRemove(IUnknown *pUsgBeamformer, ULONG *reserved) { if ( this->GetIsActive() ) { this->Deactivate(); } this->Disconnect(); return S_OK; } HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeArrive(IUnknown*, ULONG* probeIndex) { m_ControlsProbes->ProbeAdded(static_cast(*probeIndex)); this->Activate(); return S_OK; }; HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeRemove(IUnknown*, ULONG* probeIndex) { m_ControlsProbes->ProbeRemoved(static_cast(*probeIndex)); if ( this->GetIsActive() ) { this->Deactivate(); } return S_OK; }; STDMETHODIMP_(ULONG) mitk::USTelemedDevice::AddRef() { ++m_RefCount; return m_RefCount; } STDMETHODIMP_(ULONG) mitk::USTelemedDevice::Release() { --m_RefCount; return m_RefCount; } STDMETHODIMP mitk::USTelemedDevice::QueryInterface(REFIID riid, void** ppv) { if (riid == IID_IUnknown || riid == Usgfw2Lib::IID_IUsgDeviceChangeSink) { *ppv = (IUsgDeviceChangeSink*)this; return S_OK; } if (riid == IID_IDispatch) { *ppv = (IDispatch*)this; return S_OK; } return E_NOINTERFACE; } HRESULT mitk::USTelemedDevice::GetTypeInfoCount(UINT *pctinfo) { if (pctinfo == NULL) return E_INVALIDARG; *pctinfo = 0; return S_OK; } HRESULT mitk::USTelemedDevice::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { if (pptinfo == NULL) return E_INVALIDARG; *pptinfo = NULL; if(itinfo != 0) return DISP_E_BADINDEX; return S_OK; } HRESULT mitk::USTelemedDevice::GetIDsOfNames(const IID &riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) { // this is not used - must use the same fixed dispid's from Usgfw2 idl file return S_OK; } HRESULT mitk::USTelemedDevice::Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { if ( (dispIdMember >= 1) && (dispIdMember <= 6) ) { if (pDispParams->cArgs != 2) // we need 2 arguments return S_OK; IUnknown *unkn = NULL; ULONG *res = NULL; VARIANTARG* p1; VARIANTARG* p; p1 = pDispParams->rgvarg; p = p1; if (p->vt == (VT_BYREF|VT_UI4)) res = p->pulVal; p1++; p = p1; if (p->vt == VT_UNKNOWN) unkn = (IUnknown*)(p->punkVal); if (dispIdMember == 1) OnProbeArrive(unkn, res); else if (dispIdMember == 2) OnBeamformerArrive(unkn, res); else if (dispIdMember == 3) OnProbeRemove(unkn, res); else if (dispIdMember == 4) OnBeamformerRemove(unkn, res); else if (dispIdMember == 5) OnProbeStateChanged(unkn, res); else if (dispIdMember == 6) OnBeamformerStateChanged(unkn, res); } return S_OK; } \ No newline at end of file diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp index 324954e4c1..1d6c97c287 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp @@ -1,69 +1,85 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkUSTelemedImageSource.h" #include "mitkUSTelemedSDKHeader.h" #include "MITKUSTelemedScanConverterPlugin.h" #include "mitkImageReadAccessor.h" mitk::USTelemedImageSource::USTelemedImageSource( ) - : m_Image(mitk::Image::New()), m_Plugin(0), m_PluginCallback(0) + : m_Image(mitk::Image::New()), + m_ImageMutex(itk::FastMutexLock::New()), + m_Plugin(0), + m_PluginCallback(0) { } mitk::USTelemedImageSource::~USTelemedImageSource( ) { - SAFE_RELEASE(m_Plugin); SAFE_RELEASE(m_PluginCallback); + SAFE_RELEASE(m_Plugin); } void mitk::USTelemedImageSource::GetNextRawImage( mitk::Image::Pointer& image) { if ( image.IsNull() ) { image = mitk::Image::New(); } if ( m_Image->IsInitialized() ) { + m_ImageMutex->Lock(); + // copy contents of the given image into the member variable image->Initialize(m_Image->GetPixelType(), m_Image->GetDimension(), m_Image->GetDimensions()); mitk::ImageReadAccessor inputReadAccessor(m_Image, m_Image->GetSliceData(0,0,0)); image->SetSlice(inputReadAccessor.GetData()); + + m_ImageMutex->Unlock(); } } bool mitk::USTelemedImageSource::CreateAndConnectConverterPlugin(Usgfw2Lib::IUsgDataView* usgDataView, Usgfw2Lib::tagScanMode scanMode) { IUnknown* tmp_obj = NULL; // create control object from Telemed API mitk::telemed::CreateUsgControl( usgDataView, Usgfw2Lib::IID_IUsgScanConverterPlugin, scanMode, 0, (void**)&tmp_obj ); if ( ! tmp_obj ) { MITK_ERROR("USImageSource")("USTelemedImageSource") << "Could not create scan converter plugin."; return false; } - SAFE_RELEASE(m_Plugin); - m_Plugin = (Usgfw2Lib::IUsgScanConverterPlugin*)tmp_obj; + // create the callback object for the scan conversion + if ( ! m_PluginCallback ) + { + m_PluginCallback = new USTelemedScanConverterPlugin(); + + // current image buffer should be copied to m_Image at every callback + m_PluginCallback->SetOutputImage(m_Image.GetPointer(), m_ImageMutex); + } + else + { + // make sure that the scan converter plugin is not set + // to the plugin callback any longer + m_PluginCallback->SetScanConverterPlugin(0); + } // now the ScanConverterPlugin can be created and set as plugin - SAFE_RELEASE(m_PluginCallback); - m_PluginCallback = new USTelemedScanConverterPlugin(); + SAFE_RELEASE(m_Plugin); + m_Plugin = (Usgfw2Lib::IUsgScanConverterPlugin*)tmp_obj; m_PluginCallback->SetScanConverterPlugin(m_Plugin); - // current image buffer should be copied to m_Image at every callback - m_PluginCallback->SetOutputImage(m_Image.GetPointer()); - return true; } \ No newline at end of file diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h index a0d8c2f1a0..e6f9dde4f0 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h @@ -1,64 +1,67 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKUSTelemedImageSource_H_HEADER_INCLUDED_ #define MITKUSTelemedImageSource_H_HEADER_INCLUDED_ #include "mitkUSImageSource.h" #include "mitkUSTelemedSDKHeader.h" #include "mitkUSTelemedScanConverterPlugin.h" +#include "itkFastMutexLock.h" + namespace mitk { /** * \brief Implementation of mitk::USImageSource for Telemed API devices. * The method mitk::USImageSource::GetNextRawImage() is implemented for * getting images from the Telemed API. * * A method for connecting this ImageSource to the Telemed API is * implemented (mitk::USTelemedImageSource::CreateAndConnectConverterPlugin()). * This method is available for being used by mitk::USTelemedDevice. */ class USTelemedImageSource : public USImageSource { public: mitkClassMacro(USTelemedImageSource, USImageSource); itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** * Implementation of the superclass method. Returns the pointer * to the mitk::Image filled by Telemed API callback. */ virtual void GetNextRawImage( mitk::Image::Pointer& ); /** * \brief Connect this object to the Telemed API. * This method is for being used by mitk::USTelemedDevice. */ bool CreateAndConnectConverterPlugin( Usgfw2Lib::IUsgDataView*, Usgfw2Lib::tagScanMode ); protected: USTelemedImageSource( ); virtual ~USTelemedImageSource( ); Usgfw2Lib::IUsgScanConverterPlugin* m_Plugin; USTelemedScanConverterPlugin* m_PluginCallback; mitk::Image::Pointer m_Image; + itk::FastMutexLock::Pointer m_ImageMutex; }; } // namespace mitk #endif // MITKUSTelemedImageSource_H diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp index a3a3c67dda..cc18476cd7 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp @@ -1,148 +1,153 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkUSTelemedScanConverterPlugin.h" #include "mitkImageWriteAccessor.h" USTelemedScanConverterPlugin::USTelemedScanConverterPlugin( ) - : m_Plugin(NULL), m_OutputImage(NULL) + : m_Plugin(NULL), m_OutputImage(NULL), m_OutputImageMutex(NULL) { } USTelemedScanConverterPlugin::~USTelemedScanConverterPlugin( ) { ReleasePlugin(); } // -- internal Telemed API function HRESULT __stdcall USTelemedScanConverterPlugin::QueryInterface(const IID& iid, void** ppv) { reinterpret_cast(*ppv)->AddRef() ; return S_OK ; } // -- internal Telemed API function ULONG __stdcall USTelemedScanConverterPlugin::AddRef() { return InterlockedIncrement(&m_cRef) ; } // -- internal Telemed API function ULONG __stdcall USTelemedScanConverterPlugin::Release() { if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; } STDMETHODIMP USTelemedScanConverterPlugin::InterimOutBufferCB ( PBYTE pBufferInterim, int nInterimBufferLen, PBYTE pBufferOut, int nOutBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) { - if ( ! m_OutputImage ) { return S_FALSE; }; + if ( m_OutputImage.IsNull() ) { return S_FALSE; }; + + if ( m_OutputImageMutex.IsNotNull() ) { m_OutputImageMutex->Lock(); } // initialize mitk::Image with given image size on the first time if ( ! m_OutputImage->IsInitialized() ) { unsigned int dim[]={(nOutX2 - nOutX1), (nOutY2 - nOutY1)}; // image dimensions m_OutputImage->Initialize(mitk::MakeScalarPixelType(), 2, dim); } // lock the image for writing an copy the given buffer into the image then - mitk::ImageWriteAccessor imageWriteAccessor(m_OutputImage, m_OutputImage->GetSliceData(0,0,0)); m_OutputImage->SetSlice(pBufferOut); + if ( m_OutputImageMutex.IsNotNull() ) { m_OutputImageMutex->Unlock(); } + return S_OK; } void USTelemedScanConverterPlugin::ReleasePlugin() { if (m_Plugin != NULL) { // remove this callback from Telemed API plugin m_Plugin->SetCallback(NULL,USPC_BUFFER_INTERIM_OUTPUT); } - SAFE_RELEASE(m_Plugin); } -void USTelemedScanConverterPlugin::SetOutputImage(mitk::Image::Pointer outputImage) +void USTelemedScanConverterPlugin::SetOutputImage(mitk::Image::Pointer outputImage, itk::FastMutexLock::Pointer outputImageMutex) { m_OutputImage = outputImage; + m_OutputImageMutex = outputImageMutex; } STDMETHODIMP USTelemedScanConverterPlugin::SetScanConverterPlugin(IDispatch* plugin) { // make sure that there is no scan converter plugin registered already - ReleasePlugin(); + this->ReleasePlugin(); HRESULT hr; + // it is ok to call this method with a NULL plugin to remove + // a previous callback if (plugin == NULL) { - MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") - << "Plugin must not be NULL when calling SetScanConverterPlugin."; - return S_FALSE; + MITK_INFO("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") + << "NULL plugin set to the scan converter. The callback for the previous plugin is removed now."; + return S_OK; } // get Telemed API plugin from the COM library Usgfw2Lib::IUsgScanConverterPlugin* tmp_plugin; hr = plugin->QueryInterface(__uuidof(Usgfw2Lib::IUsgScanConverterPlugin), (void**)&tmp_plugin); if (FAILED(hr)) { MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "Could not query com interface for IUsgScanConverterPlugin (" << hr << ")."; return hr; } // get the converter for scan lines from the COM library and // save it as a member attribute hr = tmp_plugin->get_ScanConverter((IUnknown**)&m_Plugin); if (FAILED(hr)) { MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "Could not get ScanConverter from plugin (" << hr << ")."; return hr; } SAFE_RELEASE(tmp_plugin); // now the callback can be set -> interface functions of this // object will be called from now on when new image data is // available hr = m_Plugin->SetCallback(this,USPC_BUFFER_INTERIM_OUTPUT); if (FAILED(hr)) { MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "Could not set callback for plugin (" << hr << ")."; return hr; } return S_OK; } \ No newline at end of file diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.h b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.h index c30e86e54e..1bd71bcf06 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.h +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.h @@ -1,161 +1,170 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKUSTelemedScanConverterPlugin_H_HEADER_INCLUDED_ #define MITKUSTelemedScanConverterPlugin_H_HEADER_INCLUDED_ #include #include #include #include #include #include "mitkUSTelemedSDKHeader.h" - #include "mitkImage.h" +#include "itkFastMutexLock.h" + /** * \brief Telemed API plugin for getting images from scan lines. * Implements a COM interface whereat only the function InterimOutBufferCB * is used for copying given image buffer into a mitk::Image. * * A pointer to this mitk::Image must be set by calling * mitk::USTelemedScanConverterPlugin::SetOutputImage() first. * The image content is then updated every time the Telemed API calls * the implemented callback function of this class. * * For more infomration about the implemented COM interface refer to the * Telemed API documentation. */ class USTelemedScanConverterPlugin : public IUsgfwScanConverterPluginCB { public: USTelemedScanConverterPlugin( ); ~USTelemedScanConverterPlugin( ); // internal functions for Telemed API virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv); virtual ULONG __stdcall AddRef(); virtual ULONG __stdcall Release(); /** * Setter for a pointer to a mitk::Image in which the current * image buffer from the Telemed API will be stored at every * API callback. This function must be called before image data * can be got from this class. + * A pointer to a mutex can be set in addition. This mutex will + * be locked on every writing to the given image. */ - void SetOutputImage(mitk::Image::Pointer outputImage); + void SetOutputImage(mitk::Image::Pointer outputImage, itk::FastMutexLock::Pointer outputImageMutex = 0); // receives pointers to input and output media samples STDMETHOD(SampleCB) ( IMediaSample *pSampleIn, IMediaSample *pSampleOut, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receives pointers to input and output sample buffers STDMETHOD(BufferCB) ( PBYTE pBufferIn, int nInBufferLen, PBYTE pBufferOut, int nOutBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receives pointers to input and intermediate sample buffers STDMETHOD(InInterimBufferCB) ( PBYTE pBufferIn, int nInBufferLen, PBYTE pBufferInterim, int nInterimBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receves pointers to input media sample and intermediatesample buffer STDMETHOD(InInterimSampleCB) ( IMediaSample *pSampleIn, PBYTE pBufferInterim, int nInterimBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receives pointers to output and intermediate sample buffers STDMETHOD(InterimOutBufferCB) ( PBYTE pBufferInterim, int nInterimBufferLen, PBYTE pBufferOut, int nOutBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ); // receives pointers to output media sample and intermediate sample buffer STDMETHOD(InterimOutSampleCB) ( PBYTE pBufferInterim, int nInterimBufferLen, IMediaSample *pSampleIn, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receives conversion parameter change pin index // if parameter is negative parameter was changed by some filter interface STDMETHOD(ParameterCB) ( int nPin ) { return S_OK; } STDMETHOD(SetScanConverterPlugin)(IDispatch* plugin); //STDMETHOD(getSource)(LONG* plugin); protected: /** * Remove Telemed API callback and release and delete m_Plugin attribute. */ void ReleasePlugin( ); /** * Telemed API object for handling callbacks on new image data. */ IUsgfwScanConverterPlugin* m_Plugin; /** * Pointer to mitk::Image in which the current image buffer * from the Telemed API will be stored at every API callback. */ mitk::Image::Pointer m_OutputImage; + /** + * Mutex for the output image. Has to be set together with the + * output image via SetOutputImage(). + */ + itk::FastMutexLock::Pointer m_OutputImageMutex; + private: long m_cRef ; }; #endif // MITKUSTelemedScanConverterPlugin_H_HEADER_INCLUDED_ \ No newline at end of file