您的位置:首页 > 编程语言 > PHP开发

使用CBaseFilter, CBaseInputPin和CBaseOutputPin写一个简单的Filter

2013-11-08 19:32 351 查看
原文地址: http://blog.csdn.net/blackboyofsnp/article/details/4877305
原文作者 : blackboycpp(AT)gmail.com

类定义:



[cpp] view
plaincopyprint?

//=============================================================================

// 名 称 : zp_Gate.h

// 功 能 : Filter, 输入Pin, 输出Pin 3个类的类定义

//

// 这几个类主要示范了如何从CBaseFilter, CBaseInputPin, CBaseOutputPin这3个

// 类派生出自已需要的Filter及Pin类. 这3个类的实现已经几乎是最简单的了, 只实现了

// 必须实现的方法. 同样地, 这个Filter的功能也相当简单, 对于数据流相当于是透明的,

// 只是简单地转发一下sample, 不进行任何操作. 它有2个Pin, 一个输入Pin, 一输出Pin,

// 这两个Pin上的数据和媒体类型当然, 也是完全一样的.

//

// 开发者: blackboycpp@gmail.com

// 更新于: 2009-11-24 15:34:54

// 备 注 :

//=============================================================================

#pragma once



// the GUID of the filter

// {1B0FFB65-DB1A-494f-8748-046970465B86}

DEFINE_GUID(CLSID_Gate,

0x1b0ffb65, 0xdb1a, 0x494f, 0x87, 0x48, 0x4, 0x69, 0x70, 0x46, 0x5b, 0x86);



class CGate;

class CDataOut;

// 功 能 : 输入Pin类

// 更新于: 2009-11-24 15:36:13

// 备 注 :

class CDataIn : public CBaseInputPin

{

friend class CDataOut;

public:

CDataIn(TCHAR* pObjName,

CGate* pFilter,

HRESULT* phr,

LPCWSTR pPinName);

virtual ~CDataIn();

public:

// 连接时检查媒体类型

HRESULT CheckMediaType(const CMediaType *pmt);

STDMETHODIMP EndOfStream();

STDMETHODIMP BeginFlush();

STDMETHODIMP EndFlush();

// 从流中接收下一个Sample

STDMETHODIMP Receive(IMediaSample *pSample);

private:

CGate* m_pGate; // 所在的Filter

};



// 功 能 : 输出Pin类

// 更新于: 2009-11-24 15:37:55

// 备 注 :

class CDataOut : public CBaseOutputPin

{

friend class CDataIn;

public:

CDataOut(TCHAR* pObjName,

CGate* pFilter,

HRESULT* phr,

LPCWSTR pPinName);

virtual ~CDataOut();

public:

// 枚举首选的媒体类型

STDMETHODIMP EnumMediaTypes( IEnumMediaTypes **ppEnum);

HRESULT CheckMediaType(const CMediaType* pmt);

HRESULT DecideBufferSize( IMemAllocator * pAlloc,

ALLOCATOR_PROPERTIES * ppropInputRequest);

HRESULT Active();

HRESULT Inactive();

// 将Sample交到下级输入Pin

HRESULT Deliver(IMediaSample* pMediaSample);

HRESULT DeliverBeginFlush();

HRESULT DeliverEndFlush();

HRESULT DeliverEndOfStream();

private:

CGate* m_pGate; // 所在的Filter

COutputQueue* m_pOutQueue;

};



class CGate : public CCritSec, public CBaseFilter

{

friend class CDataIn;

friend class CDataOut;

public:

CGate(TCHAR* pName, LPUNKNOWN pUnk, HRESULT* hr);

public:

virtual ~CGate(void);

public:

static CUnknown* WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT* phr);



CBasePin* GetPin(int n); // 获得指定Pin

int GetPinCount(); // 获得Pin数量

private:

CDataIn* m_pInputPin; // 输入Pin

CDataOut* m_pOutputPin; // 输入Pin

};





-----------------------



实现:

[cpp] view
plaincopyprint?

//=============================================================================

// 名 称 : zp_Gate.cpp

// 功 能 : CGate, CDataIn, CDataOut 3个类的实现

// 开发者: blackboycpp@gmail.com

// 更新于: 2009-11-24 16:02:17

// 备 注 :

//

//=============================================================================

#include "stdafx.h"

#include "zp_Gate.h"

//#include "zp_utl.h"

#ifdef _MANAGED

#pragma managed(push, off)

#endif



#pragma warning(disable:4355 4127)

const AMOVIESETUP_MEDIATYPE sudPinTypes =

{

&MEDIATYPE_NULL, // Major type

&MEDIASUBTYPE_NULL // Minor type

};

const AMOVIESETUP_PIN psudPins[] =

{

{

L"Input", // Pin名字字符串

FALSE, // 是否被render

FALSE, // 是否输出

FALSE, // 允许为空

FALSE, // 允许多个

&CLSID_NULL, // 连接到Filter

L"Output", // 连接到Pin

1, // 媒体类型数量

&sudPinTypes // Pin信息

},

{

L"Output",

FALSE,

TRUE,

FALSE,

FALSE,

&CLSID_NULL,

L"Input",

1,

&sudPinTypes

}

};

const AMOVIESETUP_FILTER sudGate =

{

&CLSID_Gate, // Filetr的CLSID

L"Gate", // Filter的名字

MERIT_DO_NOT_USE, // Filter的Merit

2, // Pin数量

psudPins // Pin信息

};

CFactoryTemplate g_Templates [1] =

{

{

L"Gate",

&CLSID_Gate,

CGate::CreateInstance,

NULL,

&sudGate

}

};

int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);

STDAPI DllRegisterServer()

{

return AMovieDllRegisterServer2(TRUE);

}

STDAPI DllUnregisterServer()

{

return AMovieDllRegisterServer2(FALSE);

}

extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);

BOOL APIENTRY DllMain( HMODULE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

return DllEntryPoint((HINSTANCE)(hModule), ul_reason_for_call, lpReserved);

}



//////////////////////////////////////////////////////////////////////////

CDataIn::CDataIn(TCHAR* pObjName,

CGate* pFilter,

HRESULT* phr,

LPCWSTR pPinName)

: CBaseInputPin(pObjName, pFilter, pFilter, phr, pPinName),

m_pGate(pFilter)

{

ASSERT(pFilter);

}



CDataIn::~CDataIn()

{



}

HRESULT CDataIn::CheckMediaType(const CMediaType *pmt)

{

CAutoLock lockit(m_pLock);

// TODO:

return NOERROR;

}



STDMETHODIMP CDataIn::EndOfStream()

{

CAutoLock lockit(m_pLock);

HRESULT hr = NOERROR;

CDataOut* pOutPin = m_pGate->m_pOutputPin;

if(pOutPin != NULL)

{

hr = pOutPin->DeliverEndOfStream();

if(FAILED(hr)) return hr;

}

return NOERROR;

}



HRESULT CDataIn::BeginFlush()

{

CAutoLock lockit(m_pLock);

// TODO:

HRESULT hr = m_pGate->m_pOutputPin->DeliverBeginFlush();

if(FAILED(hr)) return hr;

return CBaseInputPin::BeginFlush();

}



HRESULT CDataIn::EndFlush()

{

CAutoLock lockit(m_pLock);

// TODO:

HRESULT hr = m_pGate->m_pOutputPin->DeliverEndFlush();

if(FAILED(hr)) return hr;

return CBaseInputPin::EndFlush();

}



HRESULT CDataIn::Receive(IMediaSample *pSample)

{

ASSERT(pSample);

CAutoLock lockit(m_pLock);

HRESULT hr = NOERROR;

hr = CBaseInputPin::Receive(pSample);

if(FAILED(hr)) return hr;

// TODO:

hr = m_pGate->m_pOutputPin->Deliver(pSample);

if(FAILED(hr)) return hr;

return NOERROR;

}

//////////////////////////////////////////////////////////////////////////

CDataOut::CDataOut(TCHAR* pObjName,

CGate* pFilter,

HRESULT* phr,

LPCWSTR pPinName)

: CBaseOutputPin(pObjName, pFilter, pFilter, phr, pPinName),

m_pGate(pFilter)

{

ASSERT(pFilter);

m_pOutQueue = NULL;

}

CDataOut::~CDataOut()

{

}



HRESULT CDataOut::CheckMediaType(const CMediaType* pmt)

{

CAutoLock lockit(m_pLock);

// TODO:

HRESULT hr = NOERROR;

if(m_pGate->m_pInputPin->m_Connected == NULL) return VFW_E_NOT_CONNECTED;

hr = m_pGate->m_pInputPin->m_Connected->QueryAccept(pmt);

if(hr != NOERROR) return VFW_E_TYPE_NOT_ACCEPTED;

return NOERROR;

}



STDMETHODIMP CDataOut::EnumMediaTypes(IEnumMediaTypes **ppEnum)

{

CAutoLock lockit(m_pLock);

ASSERT(ppEnum);

if(m_pGate->m_pInputPin->m_Connected == NULL) return VFW_E_NOT_CONNECTED;

return m_pGate->m_pInputPin->m_Connected->EnumMediaTypes(ppEnum);

}



HRESULT CDataOut::DecideBufferSize(IMemAllocator * pAlloc,

ALLOCATOR_PROPERTIES * ppropInputRequest)

{

return NOERROR;

}



HRESULT CDataOut::Deliver(IMediaSample* pMediaSample)

{

CheckPointer(pMediaSample, E_POINTER);

// TODO:

if(m_pOutQueue == NULL) return NOERROR;

pMediaSample->AddRef();

// TODO:

return m_pOutQueue->Receive(pMediaSample);

}



HRESULT CDataOut::Active()

{

CAutoLock lockit(m_pLock);

HRESULT hr = NOERROR;

if(m_Connected == NULL) return NOERROR;

if(m_pOutQueue == NULL)

{

m_pOutQueue = new COutputQueue(m_Connected, &hr, TRUE, FALSE);

if(m_pOutQueue == NULL) return E_OUTOFMEMORY;

if(FAILED(hr))

{

delete m_pOutQueue;

m_pOutQueue = NULL;

return hr;

}

}

CBaseOutputPin::Active();

return NOERROR;

}



HRESULT CDataOut::Inactive()

{

CAutoLock lockit(m_pLock);

if(m_pOutQueue)

{

delete m_pOutQueue;

m_pOutQueue = NULL;

}

CBaseOutputPin::Inactive();

return NOERROR;

}

HRESULT CDataOut::DeliverEndOfStream()

{

if(m_pOutQueue == NULL) return NOERROR;

m_pOutQueue->EOS();

return NOERROR;

}

HRESULT CDataOut::DeliverBeginFlush()

{

if(m_pOutQueue == NULL) return NOERROR;

m_pOutQueue->BeginFlush();

return NOERROR;

}

HRESULT CDataOut::DeliverEndFlush()

{

if(m_pOutQueue == NULL) return NOERROR;

m_pOutQueue->EndFlush();

return NOERROR;

}



//////////////////////////////////////////////////////////////////////////



CUnknown* WINAPI CGate::CreateInstance(LPUNKNOWN pUnk, HRESULT* phr)

{

return new CGate(NAME("Gate"), pUnk, phr);

}

CGate::CGate(TCHAR* pName, LPUNKNOWN pUnk, HRESULT* phr) :

CBaseFilter(NAME("Gate"), pUnk, this, CLSID_Gate)

{

m_pInputPin = new CDataIn(NAME("Input Pin"), this, phr, L"Input");

m_pOutputPin = new CDataOut(NAME("Output Pin"), this, phr, L"Output");

}

CGate::~CGate()

{

if(m_pInputPin != NULL)

{

delete m_pInputPin;

}

if(m_pOutputPin != NULL)

{

delete m_pOutputPin;

}

}



CBasePin* CGate::GetPin(int n)

{

if(n < 0) return NULL;

else if(n == 0) return m_pInputPin;

else if(n == 1) return m_pOutputPin;

else return NULL;

}

int CGate::GetPinCount()

{

return 2;

}



#ifdef _MANAGED

#pragma managed(pop)

#endif







FilterGraph里测试:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐