2,542
社区成员
发帖
与我相关
我的任务
分享
#include <streams.h> // DirectShow (includes windows.h)
#include <initguid.h> // declares DEFINE_GUID to declare an EXTERN_C const.
#include <stdio.h>
#include <DvdMedia.h>
// The CLSID used by the minimal, in-place, null filter
// DO NOT REUSE IT. Run uuidgen.exe to create a new one.
// {08af6540-4f21-11cf-aacb-0020af0b99a3}
DEFINE_GUID(CLSID_NullNull,
0x08af6540, 0x4f21, 0x11cf, 0xaa, 0xcb, 0x00, 0x20, 0xaf, 0x0b, 0x99, 0xa3);
// setup data - allows the self-registration to work.
const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_NULL // clsMajorType
, &MEDIASUBTYPE_NULL // clsMinorType
};
const AMOVIESETUP_PIN psudPins[] =
{ { L"Input" // strName
, FALSE // bRendered
, FALSE // bOutput
, FALSE // bZero
, FALSE // bMany
, &CLSID_NULL // clsConnectsToFilter
, L"" // strConnectsToPin
, 1 // nTypes
, &sudPinTypes // lpTypes
}
, { L"Output" // strName
, FALSE // bRendered
, TRUE // bOutput
, FALSE // bZero
, FALSE // bMany
, &CLSID_NULL // clsConnectsToFilter
, L"" // strConnectsToPin
, 1 // nTypes
, &sudPinTypes // lpTypes
}
};
const AMOVIESETUP_FILTER sudNullNull =
{
&CLSID_NullNull // clsID
, L"Minimal Null" // strName
, MERIT_DO_NOT_USE // dwMerit
, 2 // nPins
, psudPins // lpPin
};
class CMyInputPin : public CTransInPlaceInputPin
{
public:
CMyInputPin::CMyInputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName);
~CMyInputPin() { };
STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt);
STDMETHODIMP ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt);
BOOL mReConnet;
};
CMyInputPin::CMyInputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName) : CTransInPlaceInputPin(pObjectName,pFilter,phr,pName)
,mReConnet(FALSE)
{ };
class CMyOutputPin : public CTransInPlaceOutputPin
{
public:
CMyOutputPin::CMyOutputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,LPCWSTR pName);
~CMyOutputPin() { };
STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt);
STDMETHODIMP ChangeMediaType(const AM_MEDIA_TYPE *pmt);
};
CMyOutputPin::CMyOutputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName) : CTransInPlaceOutputPin(pObjectName,pFilter,phr,pName)
{ };
STDMETHODIMP CMyOutputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
return CTransInPlaceOutputPin::QueryAccept(pmt);
}
// CNullNull
//
class CNullNull
: public CTransInPlaceFilter
{
public:
static CUnknown *WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);
STDMETHODIMP ChangeMediaType(const AM_MEDIA_TYPE *pmt);
DECLARE_IUNKNOWN;
private:
// Constructor - just calls the base class constructor
CNullNull(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr)
: CTransInPlaceFilter (tszName, punk, CLSID_NullNull, phr)
{ }
// Overrides the PURE virtual Transform of CTransInPlaceFilter base class.
// This is where the "real work" is done by altering *pSample.
// We do the Null transform by leaving it alone.
HRESULT Transform(IMediaSample *pSample);//{ return NOERROR; }
CBasePin * GetPin(int n);
// We accept any input type. We'd return S_FALSE for any we didn't like.
HRESULT CheckInputType(const CMediaType* mtIn) { return S_OK; }
};
STDMETHODIMP CMyInputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::QueryAccept(pmt);
if (hr == S_OK)
{
mReConnet = TRUE;
}
char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::QueryAccept = %08x\n",hr);
OutputDebugStringA(buffer);
return hr;
}
STDMETHODIMP CMyInputPin::ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::ReceiveConnection(pConnector,pmt);
if (hr == S_OK && mReConnet)
{
hr = ((CNullNull*)m_pTIPFilter)->ChangeMediaType(pmt);
}
char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::ReceiveConnection = %08x\n",hr);
OutputDebugStringA(buffer);
return hr;
}
CBasePin * CNullNull::GetPin(int n)
{
HRESULT hr = S_OK;
if(m_pInput == NULL)
{
//CBasePin *pPin = NULL;
m_pInput = new CMyInputPin(("CMyInputPin"),this,&hr,L"Input");
ASSERT(SUCCEEDED(hr));
}
if (m_pOutput == NULL) {
m_pOutput = new CMyOutputPin(("CMyOutputPin"), this, &hr, L"Output");
ASSERT(SUCCEEDED(hr));
}
// Return the appropriate pin
ASSERT (n>=0 && n<=1);
if (n == 0) {
return m_pInput;
} else if (n==1) {
return m_pOutput;
} else {
return NULL;
}
}
STDMETHODIMP CMyOutputPin::ChangeMediaType(const AM_MEDIA_TYPE *pmt)
{
CheckPointer(m_Connected, E_POINTER);
CheckPointer(pmt, E_POINTER);
HRESULT hr = m_Connected->QueryAccept(pmt);
if(FAILED(hr))
{
return hr;
}
hr = m_Connected->ReceiveConnection(this, pmt);
if(FAILED(hr))
{
return hr;
}
CMediaType mt = *pmt;
hr = SetMediaType(&mt);
hr = m_pAllocator->Decommit();
if(FAILED(hr))
{
return hr;
}
//0x80040227
hr = CompleteConnect(m_Connected);
if(FAILED(hr))
{
return hr;
}
hr = m_pAllocator->Commit();
if(FAILED(hr))
{
return hr;
}
return S_OK;
}
STDMETHODIMP CNullNull::ChangeMediaType(const AM_MEDIA_TYPE *pmt)
{
return ((CMyOutputPin*) m_pOutput)->ChangeMediaType(pmt);
}
HRESULT CNullNull::Transform(IMediaSample *pSample)
{
AM_MEDIA_TYPE *pNewMediaType = NULL;
HRESULT hr_sample = NULL;
AM_MEDIA_TYPE mt = {0};
BITMAPINFOHEADER *pbmi = NULL, *pbmiNew = NULL;
hr_sample = pSample->GetMediaType(&pNewMediaType);
if (hr_sample == S_OK && pNewMediaType && pNewMediaType->formattype == FORMAT_VideoInfo2)
{
((CMyOutputPin*) m_pOutput)->ChangeMediaType(pNewMediaType);
}
return NOERROR;
}
// Class factory template - needed for the CreateInstance mechanism
CFactoryTemplate g_Templates[]=
{ { L"Minimal Null"
, &CLSID_NullNull
, CNullNull::CreateInstance
, NULL
, &sudNullNull }
};
int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);
//
// CreateInstance
//
// Provide the way for COM to create a CNullNull object
CUnknown * WINAPI CNullNull::CreateInstance(LPUNKNOWN punk, HRESULT *phr) {
CheckPointer(phr,NULL);
CNullNull *pNewObject =
new CNullNull(NAME("Minimal, in-place, null filter"), punk, phr );
if (pNewObject == NULL) {
*phr = E_OUTOFMEMORY;
}
return pNewObject;
} // CreateInstance
////////////////////////////////////////////////////////////////////////
//
// 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);
}
// Microsoft C Compiler will give hundreds of warnings about
// unused inline functions in header files. Try to disable them.
#pragma warning( disable:4514)
#include <streams.h> // DirectShow (includes windows.h)
#include <initguid.h> // declares DEFINE_GUID to declare an EXTERN_C const.
#include <stdio.h>
#include <DvdMedia.h>
// The CLSID used by the minimal, in-place, null filter
// DO NOT REUSE IT. Run uuidgen.exe to create a new one.
// {08af6540-4f21-11cf-aacb-0020af0b99a3}
DEFINE_GUID(CLSID_NullNull,
0x08af6540, 0x4f21, 0x11cf, 0xaa, 0xcb, 0x00, 0x20, 0xaf, 0x0b, 0x99, 0xa3);
// setup data - allows the self-registration to work.
const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_NULL // clsMajorType
, &MEDIASUBTYPE_NULL // clsMinorType
};
const AMOVIESETUP_PIN psudPins[] =
{ { L"Input" // strName
, FALSE // bRendered
, FALSE // bOutput
, FALSE // bZero
, FALSE // bMany
, &CLSID_NULL // clsConnectsToFilter
, L"" // strConnectsToPin
, 1 // nTypes
, &sudPinTypes // lpTypes
}
, { L"Output" // strName
, FALSE // bRendered
, TRUE // bOutput
, FALSE // bZero
, FALSE // bMany
, &CLSID_NULL // clsConnectsToFilter
, L"" // strConnectsToPin
, 1 // nTypes
, &sudPinTypes // lpTypes
}
};
const AMOVIESETUP_FILTER sudNullNull =
{
&CLSID_NullNull // clsID
, L"Minimal Null" // strName
, MERIT_DO_NOT_USE // dwMerit
, 2 // nPins
, psudPins // lpPin
};
class CMyInputPin : public CTransInPlaceInputPin
{
public:
CMyInputPin::CMyInputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName);
~CMyInputPin() { };
STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt);
STDMETHODIMP ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt);
};
CMyInputPin::CMyInputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName) : CTransInPlaceInputPin(pObjectName,pFilter,phr,pName)
{ };
class CMyOutputPin : public CTransInPlaceOutputPin
{
public:
CMyOutputPin::CMyOutputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,LPCWSTR pName);
~CMyOutputPin() { };
STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt);
STDMETHODIMP ChangeMediaType(const AM_MEDIA_TYPE *pmt);
};
CMyOutputPin::CMyOutputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName) : CTransInPlaceOutputPin(pObjectName,pFilter,phr,pName)
{ };
STDMETHODIMP CMyOutputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
return CTransInPlaceOutputPin::QueryAccept(pmt);
}
// CNullNull
//
class CNullNull
: public CTransInPlaceFilter
{
public:
static CUnknown *WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);
STDMETHODIMP ChangeMediaType(const AM_MEDIA_TYPE *pmt);
DECLARE_IUNKNOWN;
private:
// Constructor - just calls the base class constructor
CNullNull(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr)
: CTransInPlaceFilter (tszName, punk, CLSID_NullNull, phr)
{ }
// Overrides the PURE virtual Transform of CTransInPlaceFilter base class.
// This is where the "real work" is done by altering *pSample.
// We do the Null transform by leaving it alone.
HRESULT Transform(IMediaSample *pSample);//{ return NOERROR; }
CBasePin * GetPin(int n);
// We accept any input type. We'd return S_FALSE for any we didn't like.
HRESULT CheckInputType(const CMediaType* mtIn) { return S_OK; }
};
STDMETHODIMP CMyInputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::QueryAccept(pmt);
CMediaType mt = *pmt;
SetMediaType(&mt);
hr = ((CNullNull*)m_pTIPFilter)->ChangeMediaType(pmt);
char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::QueryAccept = %08x\n",hr);
OutputDebugStringA(buffer);
return hr;
}
STDMETHODIMP CMyInputPin::ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::ReceiveConnection(pConnector,pmt);
if (pmt->formattype == FORMAT_VideoInfo2)
{
VIDEOINFOHEADER2 * pHeader = (VIDEOINFOHEADER2 *) pmt->pbFormat;
int mWidth = pHeader->bmiHeader.biWidth;
int mHeight = pHeader->bmiHeader.biHeight;
}
char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::ReceiveConnection = %08x\n",hr);
OutputDebugStringA(buffer);
return hr;
}
CBasePin * CNullNull::GetPin(int n)
{
HRESULT hr = S_OK;
if(m_pInput == NULL)
{
//CBasePin *pPin = NULL;
m_pInput = new CMyInputPin(("CMyInputPin"),this,&hr,L"Input");
ASSERT(SUCCEEDED(hr));
}
if (m_pOutput == NULL) {
m_pOutput = new CMyOutputPin(("CMyOutputPin"), this, &hr, L"Output");
ASSERT(SUCCEEDED(hr));
}
// Return the appropriate pin
ASSERT (n>=0 && n<=1);
if (n == 0) {
return m_pInput;
} else if (n==1) {
return m_pOutput;
} else {
return NULL;
}
}
STDMETHODIMP CMyOutputPin::ChangeMediaType(const AM_MEDIA_TYPE *pmt)
{
CheckPointer(m_Connected, E_POINTER);
CheckPointer(pmt, E_POINTER);
HRESULT hr = m_Connected->QueryAccept(pmt);
if(FAILED(hr))
{
return hr;
}
hr = m_Connected->ReceiveConnection(this, pmt);
if(FAILED(hr))
{
return hr;
}
CMediaType mt = *pmt;
hr = SetMediaType(&mt);
hr = m_pAllocator->Decommit();
if(FAILED(hr))
{
return hr;
}
//0x80040227
hr = CompleteConnect(m_Connected);
if(FAILED(hr))
{
return hr;
}
hr = m_pAllocator->Commit();
if(FAILED(hr))
{
return hr;
}
return S_OK;
}
STDMETHODIMP CNullNull::ChangeMediaType(const AM_MEDIA_TYPE *pmt)
{
return ((CMyOutputPin*) m_pOutput)->ChangeMediaType(pmt);
}
HRESULT CNullNull::Transform(IMediaSample *pSample)
{
AM_MEDIA_TYPE *pNewMediaType = NULL;
HRESULT hr_sample = NULL;
AM_MEDIA_TYPE mt = {0};
BITMAPINFOHEADER *pbmi = NULL, *pbmiNew = NULL;
hr_sample = pSample->GetMediaType(&pNewMediaType);
if (hr_sample == S_OK && pNewMediaType && pNewMediaType->formattype == FORMAT_VideoInfo2)
{
((CMyOutputPin*) m_pOutput)->ChangeMediaType(pNewMediaType);
}
return NOERROR;
}
// Class factory template - needed for the CreateInstance mechanism
CFactoryTemplate g_Templates[]=
{ { L"Minimal Null"
, &CLSID_NullNull
, CNullNull::CreateInstance
, NULL
, &sudNullNull }
};
int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);
//
// CreateInstance
//
// Provide the way for COM to create a CNullNull object
CUnknown * WINAPI CNullNull::CreateInstance(LPUNKNOWN punk, HRESULT *phr) {
CheckPointer(phr,NULL);
CNullNull *pNewObject =
new CNullNull(NAME("Minimal, in-place, null filter"), punk, phr );
if (pNewObject == NULL) {
*phr = E_OUTOFMEMORY;
}
return pNewObject;
} // CreateInstance
////////////////////////////////////////////////////////////////////////
//
// 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);
}
// Microsoft C Compiler will give hundreds of warnings about
// unused inline functions in header files. Try to disable them.
#pragma warning( disable:4514)