使用CBaseFilter, CBaseInputPin和CBaseOutputPin写一个简单的Filter 收藏
类定义:
- //=============================================================================
- // 名 称 : 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
- };
-----------------------
实现:
- //=============================================================================
- // 名 称 : 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里测试: