📄 dxfilter.cpp
字号:
/*mediastreamer2 library - modular sound and video processing and streamingCopyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/#if !defined(_WIN32_WCE) //Allready defined for wince#define UNICODE#endif#include <streams.h>#include <initguid.h>#if !defined(_WIN32_WCE)#include "qedit.h"#endif#include "dxfilter.h"#pragma warning(disable: 4800)const AMOVIESETUP_PIN psudDXFilterPins[] ={ { L"Input" // strName , FALSE // bRendered , FALSE // bOutput , FALSE // bZero , FALSE // bMany , &CLSID_NULL // clsConnectsToFilter , L"" // strConnectsToPin , 0 // nTypes , NULL // lpTypes }, { L"Output" // strName , FALSE // bRendered , TRUE // bOutput , FALSE // bZero , FALSE // bMany , &CLSID_NULL // clsConnectsToFilter , L"" // strConnectsToPin , 0 // nTypes , NULL // lpTypes }};const AMOVIESETUP_FILTER sudDXFilter ={ &CLSID_DXFilter // clsID, L"DXFilter for mediastreamer2" // strName, MERIT_DO_NOT_USE // dwMerit, 2 // nPins, psudDXFilterPins }; // lpPin// Needed for the CreateInstance mechanismCFactoryTemplate g_Templates[]={ { L"DirectX Filter for mediastreamer2" , &CLSID_DXFilter , CDXFilter::CreateInstance , NULL , &sudDXFilter }};int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);//////////////////////////////////////////////////////////////////////////// Exported entry points for registration and unregistration // (in this case they only call through to default implementations).//////////////////////////////////////////////////////////////////////////STDAPI DllRegisterServer() { return AMovieDllRegisterServer2(TRUE);}STDAPI DllUnregisterServer() { return AMovieDllRegisterServer2(FALSE);}//// DllEntryPoint//extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved){ return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);}//// CreateInstance//// Provide the way for COM to create a CDXFilter object//CUnknown * WINAPI CDXFilter::CreateInstance(LPUNKNOWN punk, HRESULT *phr) { /* ASSERT(phr); */ // assuming we don't want to modify the data CDXFilter *pNewObject = new CDXFilter(punk, phr, FALSE); if(pNewObject == NULL) { if (phr) *phr = E_OUTOFMEMORY; } return pNewObject; } // CreateInstance//----------------------------------------------------------------------------////----------------------------------------------------------------------------CDXFilter::CDXFilter( IUnknown * pOuter, HRESULT * phr, BOOL ModifiesData ) : CTransInPlaceFilter( TEXT("DXFilter"), (IUnknown*) pOuter, CLSID_DXFilter, phr#if !defined(_WIN32_WCE) ,(BOOL)ModifiesData#endif ) , m_callback( NULL ){ // this is used to override the input pin with our own m_pInput = (CTransInPlaceInputPin*) new CDXFilterInPin( this, phr ); if( !m_pInput ) { if (phr) *phr = E_OUTOFMEMORY; } // Ensure that the output pin gets created. This is necessary because our // SetDeliveryBuffer() method assumes that the input/output pins are created, but // the output pin isn't created until GetPin() is called. The // CTransInPlaceFilter::GetPin() method will create the output pin, since we // have not already created one. IPin *pOutput = GetPin(1); // The pointer is not AddRef'ed by GetPin(), so don't release it}STDMETHODIMP CDXFilter::NonDelegatingQueryInterface( REFIID riid, void ** ppv) { CheckPointer(ppv,E_POINTER); if(riid == IID_IDXFilter) { return GetInterface((IDXFilter *) this, ppv); } else { return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv); }}//----------------------------------------------------------------------------// This is where you force the sample grabber to connect with one type// or the other. What you do here is crucial to what type of data your// app will be dealing with in the sample grabber's callback. For instance,// if you don't enforce right-side-up video in this call, you may not get// right-side-up video in your callback. It all depends on what you do here.//----------------------------------------------------------------------------HRESULT CDXFilter::CheckInputType( const CMediaType * pmt ){ CheckPointer(pmt,E_POINTER); CAutoLock lock( &m_Lock ); // if the major type is not set, then accept anything GUID g = *m_mtAccept.Type( ); if( g == GUID_NULL ) { return NOERROR; } // if the major type is set, don't accept anything else if( g != *pmt->Type( ) ) { return VFW_E_INVALID_MEDIA_TYPE; } // subtypes must match, if set. if not set, accept anything VIDEOINFO *pvi = (VIDEOINFO *)pmt->Format(); g = *m_mtAccept.Subtype( ); if( g == GUID_NULL ) { return NOERROR; }#if 0 if( MEDIASUBTYPE_RGB24 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_YVU9 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_Y411 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_Y41P == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_YUY2 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_YVYU == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_UYVY == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_Y211 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_YV12 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_CLJR == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_IF09 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_CPLA == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_MJPG == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_TVMJ == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_WAKE == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_CFCC == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_IJPG == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_Plum == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_RGB1 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_RGB1 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_RGB1 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_RGB4 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_RGB8 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_RGB565 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_RGB555 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_RGB24 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_RGB32 == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_Overlay == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_MPEG1Packet == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_MPEG1Payload == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_MPEG1AudioPayload == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIATYPE_MPEG1SystemStream == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_MPEG1System == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_MPEG1VideoCD == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_MPEG1Video == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_Avi == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_Asf == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_QTMovie == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_QTRpza == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_QTSmc == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_QTRle == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_QTJpeg == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_PCM == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_WAVE == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_AU == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_AIFF == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_DssVideo == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_VPVBI == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE; if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) return VFW_E_INVALID_MEDIA_TYPE;#endif if( g != *pmt->Subtype( ) ) { return VFW_E_INVALID_MEDIA_TYPE; } // format types must match, if one is set g = *m_mtAccept.FormatType( ); if( g == GUID_NULL ) { return NOERROR; } if( g != *pmt->FormatType( ) ) { return VFW_E_INVALID_MEDIA_TYPE; } // at this point, for this sample code, this is good enough, // but you may want to make it more strict //compare sizes //VIDEOINFO *pvi = (VIDEOINFO *)pmt->Format(); VIDEOINFO *pvi2 = (VIDEOINFO *)m_mtAccept.Format(); if (pvi2==NULL) return NOERROR; if (pvi==NULL) return VFW_E_INVALID_MEDIA_TYPE;#if !defined(_WIN32_WCE) if (pvi->bmiHeader.biCompression!=pvi2->bmiHeader.biCompression) return VFW_E_INVALID_MEDIA_TYPE;#endif if (pvi->bmiHeader.biBitCount!=pvi2->bmiHeader.biBitCount) return VFW_E_INVALID_MEDIA_TYPE; if (pvi->bmiHeader.biWidth!=pvi2->bmiHeader.biWidth) return VFW_E_INVALID_MEDIA_TYPE; if (pvi->bmiHeader.biHeight!=pvi2->bmiHeader.biHeight) return VFW_E_INVALID_MEDIA_TYPE; if (pvi->bmiHeader.biSizeImage!=pvi2->bmiHeader.biSizeImage) return VFW_E_INVALID_MEDIA_TYPE; return NOERROR;}//----------------------------------------------------------------------------// This bit is almost straight out of the base classes.// We override this so we can handle Transform( )'s error// result differently.//----------------------------------------------------------------------------HRESULT CDXFilter::Receive( IMediaSample * pms ){ CheckPointer(pms,E_POINTER); HRESULT hr; AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps(); if (pProps->dwStreamId != AM_STREAM_MEDIA) { if( m_pOutput->IsConnected() ) return m_pOutput->Deliver(pms); else return NOERROR; }#if !defined(_WIN32_WCE) if (UsingDifferentAllocators()) { // We have to copy the data. pms = Copy(pms); if (pms == NULL) { return E_UNEXPECTED; } }#endif // have the derived class transform the data hr = Transform(pms); if (FAILED(hr)) { //DbgLog((LOG_TRACE, 1, TEXT("Error from TransInPlace")));#if !defined(_WIN32_WCE) if (UsingDifferentAllocators()) { pms->Release(); }#endif return hr; } if (hr == NOERROR) { hr = m_pOutput->Deliver(pms); } // release the output buffer. If the connected pin still needs it, // it will have addrefed it itself.#if !defined(_WIN32_WCE) if (UsingDifferentAllocators()) { pms->Release(); }#endif return hr;}//----------------------------------------------------------------------------// Transform//----------------------------------------------------------------------------HRESULT CDXFilter::Transform ( IMediaSample * pms ){ CheckPointer(pms,E_POINTER); CAutoLock lock( &m_Lock );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -