|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article explains how to write your custom BackgroundIn a recent project of mine, I needed to do some real-time video analysis in .NET CF. However the .NET API only allows for taking still images or recording videos, but it offers no way to access the video frame buffer so that I could parse the frames from the camera on the fly. So I decided to use the You could use the sample code as a starting point to write your own filter or take the ready Setting Up Your Visual Studio ProjectBefore your set up your Visual Studio project, you will need to install Windows Mobile SDK, Windows CE 5.0 and Windows CE 5.0 Platform builder which contains the First create a Smart Devices DLL project with ATL support. You also need to add the header files from the Windows Mobile SDK and Platform Builder to your include path. Writing the FilterIn this example, we will use a // define the filter class
class CSampleGrabber :
public CTransInPlaceFilter, public ISampleGrabber
{
private:
MANAGEDCALLBACKPROC callback;
long m_Width;
long m_Height;
long m_SampleSize;
long m_Stride;
public:
// instantiation
CSampleGrabber( IUnknown * pOuter, HRESULT * phr, BOOL ModifiesData );
~CSampleGrabber();
static CUnknown *WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);
// IUnknown
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
// CTransInPlaceFilter
HRESULT CheckInputType(const CMediaType *pmt);
HRESULT SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt);
HRESULT Transform(IMediaSample *pMediaSample);
HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties);
HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);
HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut) {
return NOERROR;
}
// ISampleGrabber
STDMETHODIMP RegisterCallback(MANAGEDCALLBACKPROC mdelegate);
};
You could implement all interfaces like any other filter. The interesting parts are the // Set the client callback
STDMETHODIMP
CSampleGrabber::RegisterCallback( MANAGEDCALLBACKPROC mdelegate )
{
// Set pointer to managed delegate
callback = mdelegate;
return S_OK;
}
// Get the pointer to the raw data and pass it to the applications
HRESULT
CSampleGrabber::Transform(IMediaSample *pMediaSample)
{
long Size = 0;
BYTE *pData;
if ( !pMediaSample )
return E_FAIL;
// Get pointer to the video buffer data
if( FAILED(pMediaSample->GetPointer(&pData)) )
return E_FAIL;
Size = pMediaSample->GetSize();
// invoke managed delegate
if ( callback )
callback(pData,Size);
return S_OK;
}
Using the CodeYou can use the // Create and initialize the SampleGrabber filter
CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC,
IID_IBaseFilter, (void**)&pSampleGrabber );
m_pFilterGraph->AddFilter( pSampleGrabber, FILTERNAME );
// Get a pointer to the ISampleGrabber interface
pSampleGrabber->QueryInterface( IID_ISampleGrabber, (void**)&m_pISampleGrabber );
// Register the client callback
if ( m_pISampleGrabber )
m_pISampleGrabber->RegisterCallback( &CGraphBuilder::OnSampleProcessed );
When the client receives the frame sample, it should copy it to local buffer as soon as possible and return. This allows the filter to carry on and not wait for the client to process the data, which will considerably slow down the whole graph. You could also make a C++ DLL which creates the filter graph and manages it and calls it through P/Invoke from your .NET CF applications. Creating filter graphs in .NET CF directly should be a bit trickier, as the .NET CF lacks C++. NET support, but maybe possible. Online References
History
|
||||||||||||||||||||||