将接口添加到自定义directshow转换过滤器

时间:2016-02-22 10:40:12

标签: c++ directshow

我正在为CTransformFilter编写自定义DirectShow过滤器。 基本过滤器工作正常。当我向过滤器添加接口时,我遇到了问题。工作正常的过滤器代码如下:

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:
}

添加界面后的代码如下所示:

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);

.
.
}

我已经实现了接口函数(QueryInterfaceAddRefRelease)。接口和过滤器类都在同一个头文件中。问题是在添加接口部件后,实例创建本身失败。将过滤器添加到应用程序时所做的调用序列是

  1. 构造
  2. AddRef
  3. 析构
  4. 在调用析构函数后,发生了崩溃。相同的应用程序在没有界面的情况下工作。

    有关过滤器和界面有什么问题的建议吗?如果我应该分享更多信息,请告诉我。

1 个答案:

答案 0 :(得分:1)

感谢Roman R提出建议。事情现在开始奏效。以下是界面的变化。



    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);




NonDelegatingQueryInterface的实施方式如下。



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);
    }
}