c++ - 向自定义 directshow 转换过滤器添加接口(interface)

标签 c++ directshow

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

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

添加接口(interface)后的代码如下所示:

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

.
.
}

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

  1. 构造器
  2. 添加引用
  3. 析构函数

调用析构函数后发生崩溃。相同的应用程序可以在没有界面的情况下工作。

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

最佳答案

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

关于c++ - 向自定义 directshow 转换过滤器添加接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35551492/

相关文章:

c++ - 如何在我的 C++ 程序中显示 Windows 的 "DLL not found"错误?

c# - 如何在 DirectShow.NET 中只播放特定的音频 channel 并将其余 channel 静音?

c++ - 播放前 SetPosition 后 EVR 在 Window 上显示少量黑框

c++ - 按整数对结构 vector 进行排序

c++ - 如何在我的程序中找到 "const char* + int"表达式

c++ - 静态数组声明

delphi - 如何使用 DSPack 和 Delphi 5 从网络摄像头捕获并保存到文件

c++ - 在 C++ 中使用 Windows API 播放音频流

c# - 如何知道相机预览成功或准备好使用 Directshow 进行快照

c++ - 了解 char 指针数组的大小