Reputation: 115
I am working on writing custom DirectShow filter for CTransformFilter
.
The basic filter is working fine. I am facing issues when I add interface to the filter. The filter code that is working fine is written below:
interface CVideoDecoder : public CTransformFilter, public IVideoDecoderProp
{
public:
static CUnknown* WINAPI
CreateInstance(LPUNKNOWN pUnknown, HRESULT* pHresult);
public:
// Constructor
CVideoDecoder(TCHAR* FilterName, LPUNKNOWN pUnknown, HRESULT *pHr);
//Destructor
~CVideoDecoder(void);
/* CTransformFilter's methods overidden by this class */
HRESULT Transform(IMediaSample* pSourceMediaSample, IMediaSample* pDestMediaSample);
HRESULT CheckInputType(const CMediaType* pInMediaType);
HRESULT CheckTransform(const CMediaType* pInMediaType, const CMediaType* pOutMediaType);
HRESULT GetMediaType(int Position, CMediaType* pMediaType);
HRESULT DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties);
HRESULT BreakConnect(PIN_DIRECTION PinDirection);
HRESULT SetMediaType(PIN_DIRECTION direction,
const CMediaType *pmt);
HRESULT allocBuffer(UWORD32 bufferSize, void** buffer);
HRESULT freeBuffer(UWORD32 bufferSize, void* buffer);
HRESULT CacheInvalidateBuffer(void* buffer, UWORD32 bufferSize);
HRESULT CheckMediaType(const CMediaType *pmt);
#if SUPPORT_BEGIN_FLUSH
/* Overriding the CTransform Filter's Begin Flush */
HRESULT BeginFlush();
#endif
#if SUPPORT_EOS
HRESULT EndOfStream(void);
#endif
//HRESULT StopStreaming();
#if QUALITY_CONTROL
HRESULT AlterQuality(Quality q);
#endif
protected:
private:
}
The code after adding the interface looks like this:
EXTERN_C const IID IID_IVideoDecoderProp;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("11c4bb72-1df3-4bf3-a158-f23aa886e53b")
IVideoDecoderProp : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, __deref_out void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
virtual HRESULT STDMETHODCALLTYPE PrintSomething() = 0;
};
#endif
interface CVideoDecoder : public CTransformFilter, public IVideoDecoderProp
{
public:
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, __deref_out void **ppv);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
// function for testing interface implementation
HRESULT STDMETHODCALLTYPE PrintSomething();
static CUnknown* WINAPI
CreateInstance(LPUNKNOWN pUnknown, HRESULT* pHresult);
public:
// moved to videodecoder.cpp
// Constructor
CVideoDecoder(TCHAR* FilterName, LPUNKNOWN pUnknown, HRESULT *pHr);
//Destructor
~CVideoDecoder(void);
/* CTransformFilter's methods overidden by this class */
HRESULT Transform(IMediaSample* pSourceMediaSample, IMediaSample* pDestMediaSample);
.
.
}
I have implemented the interface functions (QueryInterface
, AddRef
and Release
). Both, the interface and the filter class are in same header file. The problem is that after adding the interface part, the instance creation itself fails. The sequence of calls that is made when adding the filter to application is
After calling the destructor, there is a crash. The same application works without the interface.
Any suggestion on what is wrong with the filter and interface? Please let me know if I should share any more information.
Upvotes: 0
Views: 538
Reputation: 115
Thanks to Roman R for the suggestion. Things start working now. Below is the interface changes.
DEFINE_GUID(IID_IVideoDecoderProperty,
0x11c4bb72, 0x1df3, 0x4bf3, 0xa1, 0x58, 0xf2, 0x3a, 0xa8, 0x86, 0xe5, 0x3b);
DECLARE_INTERFACE_(IVideoDecoderProperty, IUnknown)
{
STDMETHOD(MyFilterSetting1) (THIS_ unsigned int) PURE;
STDMETHOD(MyFilterSetting2) (THIS_ unsigned int) PURE;
};
class CVideoDecoder : public CTransformFilter, public IVideoDecoderProperty
{
public:
DECLARE_IUNKNOWN;
static CUnknown* WINAPI
CreateInstance(LPUNKNOWN pUnknown, HRESULT* pHresult);
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
public:
// moved to videodecoder.cpp
// Constructor
CVideoDecoder(TCHAR* FilterName,
LPUNKNOWN pUnknown,
HRESULT *pHr);
//Destructor
~CVideoDecoder(void);
/* CTransformFilter's methods overidden by this class */
HRESULT Transform(IMediaSample* pSourceMediaSample, IMediaSample* pDestMediaSample);
HRESULT CheckInputType(const CMediaType* pInMediaType);
HRESULT CheckTransform(const CMediaType* pInMediaType, const CMediaType* pOutMediaType);
HRESULT GetMediaType(int Position, CMediaType* pMediaType);
HRESULT DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties);
HRESULT BreakConnect(PIN_DIRECTION PinDirection);
HRESULT SetMediaType(PIN_DIRECTION direction,
const CMediaType *pmt);
// filter property
STDMETHODIMP MyFilterSetting1(unsigned int);
STDMETHODIMP MyFilterSetting2(unsigned int);
The NonDelegatingQueryInterface
is implemented as follows.
STDMETHODIMP CVideoDecoder::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
CheckPointer(ppv,E_POINTER);
if (riid == IID_IVideoDecoderProperty)
{
return GetInterface((IVideoDecoderProperty *) this, ppv);
}
else if (riid == IID_ISpecifyPropertyPages)
{
return GetInterface((ISpecifyPropertyPages *) this, ppv);
}
else
{
return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
}
}
Upvotes: 1