{
friend class CSnakeStream;
public:
CSnakeFilter(LPUNKNOWN pUnk, HRESULT *phr);
virtual ~CSnakeFilter(void);
// static
public:
static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
// Attributes
public:
// Operations
public:
// Overrides
protected:
// Implementations
protected:
// IUnknown interface
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
return CSource::NonDelegatingQueryInterface(riid, ppv);
}
// member variables
private:
};
CSnakeFilter::CSnakeFilter(LPUNKNOWN pUnk, HRESULT *phr)
: CSource(NAME("CSnakeFilter"), pUnk, CLSID_Snake)
{
CAutoLock cAutoLock(&m_cStateLock);
//
// CSource::AddPin() is automatically called
// by creating a source stream (CSourceStream)
//
// Add one source stream (output pin)!
new CSnakeStream(phr, this, L"Out");
// TODO: add source stream here
}
//
// Destructor
//
CSnakeFilter::~CSnakeFilter()
{
}
// CSourceStream derived class....
class CSnakeStream : public CSourceStream
{
public:
CSnakeStream(HRESULT *phr, CSnakeFilter *pParent, LPCWSTR pPinName);
virtual ~CSnakeStream(void);
// Attributes
public:
// Operations
public:
LONGLONG m_llFrameCount;
BITMAPINFO m_bmpInfo;
void *m_pPaintBuffer;
HDC m_dcPaint;
int m_nLastX;
int m_nLastY;
int m_nScoreBoardHeight;
int m_nSnakeBlockHeight;
int m_nSnakeBlockWidth;
int m_nNumberSnakeBlocks;
int m_nSpaceBetweenBlock;
// Overrides
protected:
///////////////////////////
// Media Type support
// media types filter have
virtual HRESULT GetMediaType(CMediaType *pMediaType);
///////////////////////////
// Buffer Negotiation support
// buffer size
virtual HRESULT DecideBufferSize(IMemAllocator *pMemAlloc, ALLOCATOR_PROPERTIES *pProperties);
///////////////////////////
// Data Source support
// media sample
virtual HRESULT FillBuffer(IMediaSample *pSample);
// signal
virtual HRESULT OnThreadCreate(void);
virtual HRESULT OnThreadDestroy(void);
virtual HRESULT OnThreadStartPlay(void);
// Overrides
protected:
// Implementations
protected:
// member variables
private:
};
CSnakeStream::CSnakeStream(HRESULT *phr, CSnakeFilter *pParent, LPCWSTR pPinName)
: CSourceStream(NAME("CSnakeStream"), phr, pParent, pPinName)
, m_llFrameCount(0)
{
CAutoLock cAutoLock(m_pFilter->pStateLock());
}
//
// Destructor
//
CSnakeStream::~CSnakeStream()
{
}
//
// GetMediaType
//
HRESULT CSnakeStream::GetMediaType(CMediaType *pMediaType)
{
CAutoLock lock(m_pFilter->pStateLock());
ZeroMemory(pMediaType, sizeof(CMediaType));
// TODO: modify this option
{
VIDEOINFO *pvi = (VIDEOINFO *)pMediaType->AllocFormatBuffer(sizeof(VIDEOINFO));
if (NULL == pvi)
return E_OUTOFMEMORY;
ZeroMemory(pvi, sizeof(VIDEOINFO));
pvi->bmiHeader.biCompression = BI_RGB;
pvi->bmiHeader.biBitCount = 24;
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth = 320;
pvi->bmiHeader.biHeight = 240;
pvi->bmiHeader.biPlanes = 1;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
pvi->bmiHeader.biClrImportant = 0;
SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered.
SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle
pMediaType->SetType(&MEDIATYPE_Video);
pMediaType->SetFormatType(&FORMAT_VideoInfo);
pMediaType->SetTemporalCompression(FALSE);
const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
pMediaType->SetSubtype(&SubTypeGUID);
pMediaType->SetSampleSize(pvi->bmiHeader.biSizeImage);
m_bmpInfo.bmiHeader = pvi->bmiHeader;
}
return S_OK;
}
//
// DecideBufferSize
//
HRESULT CSnakeStream::DecideBufferSize(IMemAllocator *pMemAlloc, ALLOCATOR_PROPERTIES *pProperties)
{
CAutoLock cAutoLock(m_pFilter->pStateLock());
ASSERT(pMemAlloc);
ASSERT(pProperties);
HRESULT hr;
// TODO: set the properties
{
VIDEOINFO *pvi = (VIDEOINFO *)m_mt.Format();
pProperties->cBuffers = 3;
pProperties->cbBuffer = pvi->bmiHeader.biSizeImage;
}
// Ask the allocator to reserve us some sample memory, NOTE the function
// can succeed (that is return NOERROR) but still not have allocated the
// memory that we requested, so we must check we got whatever we wanted
ALLOCATOR_PROPERTIES Actual;
hr = pMemAlloc->SetProperties(pProperties, &Actual);
if (FAILED(hr))
{
return hr;
}
// Is this allocator unsuitable
if (Actual.cbBuffer < pProperties->cbBuffer)
{
return E_FAIL;
}
return S_OK;
}
int nFrameRate = 0;
// FillBuffer
//
HRESULT CSnakeStream::FillBuffer(IMediaSample *pSample)
{
CAutoLock lock(m_pFilter->pStateLock());
HRESULT hr;
BYTE *pBuffer;
long lSize;
hr = pSample->GetPointer(&pBuffer);
if (SUCCEEDED(hr))
{
lSize = pSample->GetSize();
//write the TExt to BackDC or MemDc
sprintf(str,"%ld",count++ );
DrawText(hMemDC,str,strlen(str),DT_CENTER);
CopyMemory(pBuffer,m_pPaintBuffer,lSize);
}
return S_OK;
}
//
// OnThreadCreate
//
HRESULT CSnakeStream::OnThreadCreate(void)
{
HBITMAP hDibSection = CreateDIBSection(NULL, (BITMAPINFO *) &m_bmpInfo, DIB_RGB_COLORS,&m_pPaintBuffer, NULL, 0);
HDC hDC = GetDC(NULL);
m_dcPaint = CreateCompatibleDC(hDC);
SetMapMode(m_dcPaint, GetMapMode(hDC));
HGDIOBJ OldObject = SelectObject(m_dcPaint,hDibSection);
m_nScoreBoardHeight = m_bmpInfo.bmiHeader.biHeight/8;
m_nSnakeBlockHeight = 4, m_nSnakeBlockWidth = 6;
m_nNumberSnakeBlocks = 6;
m_nSpaceBetweenBlock = 1;
m_nLastX = 0;//(m_bmpInfo.bmiHeader.biWidth/2) - (m_nSnakeBlockWidth+m_nSpaceBetweenBlock)*m_nNumberSnakeBlocks;
m_nLastY = 0;//(m_bmpInfo.bmiHeader.biHeight/2);
return CSourceStream::OnThreadCreate();
}
//
// OnThreadDestroy
//
HRESULT CSnakeStream::OnThreadDestroy(void)
{
return CSourceStream::OnThreadDestroy();
}
//
// OnThreadStartPlay
//
HRESULT CSnakeStream::OnThreadStartPlay(void)
{
return CSourceStream::OnThreadStartPlay();
}
/// Another file
// {92E9BF2A-4385-4a08-8236-397478EB34B8}
DEFINE_GUID(CLSID_Snake,
0x92e9bf2a, 0x4385, 0x4a08, 0x82, 0x36, 0x39, 0x74, 0x78, 0xeb, 0x34, 0xb8);
#include
#include "Snake.h"
//
// Setup data for filter registration
//
const AMOVIESETUP_MEDIATYPE sudPinTypes =
{ &MEDIATYPE_NULL, // Major CLSID
&MEDIASUBTYPE_NULL // Minor type
};
const AMOVIESETUP_PIN psudPins[] =
{
{
L"Output", // Pin's string name
FALSE, // Is it rendered
TRUE, // Is it an output
FALSE, // Allowed none
FALSE, // Allowed many
&CLSID_NULL, // Connects to filter
L"Input", // Connects to pin
1, // Number of types
&sudPinTypes // Pin type information
},
};
const AMOVIESETUP_FILTER sudSnake =
{
&CLSID_Snake, // CLSID of filter
L"Snake Filter", // Filter's name
MERIT_DO_NOT_USE, // Filter merit
1, // Number of pins
psudPins // Pin information
};
//
// Object creation template
//
CFactoryTemplate g_Templates[] =
{
{
L"Snake Filter",
&CLSID_Snake,
CSnakeFilter::CreateInstance,
NULL,
&sudSnake
},
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
//
// Filter registration functions
//
HRESULT DllRegisterServer()
{
return AMovieDllRegisterServer2(TRUE);
}
HRESULT DllUnregisterServer()
{
return AMovieDllRegisterServer2(FALSE);
}
//
// Create a new instance of this class
//
CUnknown *CSnakeFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
{
// DLLEntry does the right thing with the return code and
// returned value on failure
CUnknown *pUnknown = new CSnakeFilter(pUnk, phr);
if (pUnknown == NULL)
{
*phr = E_OUTOFMEMORY;
}
return pUnknown;
}
No comments:
Post a Comment