www.pudn.com > SourceFilter.rar > fSnake_op.cpp


//------------------------------------------------------------------------------ 
// File: fSnake_op.cpp 
// 
// Desc: implement CSnakeStream class 
//  
// Author : Ashok Jaiswal 
// 
// Data/Time : September 2004 
//------------------------------------------------------------------------------ 
 
#include "stdafx.h" 
#include "fSnake.h" 
#include "fSnake_op.h" 
#include "stdio.h" 
#include  
 
 
// 
// Constructor 
// 
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; 
 
 
char *TimeToTimecode(LONGLONG llTime) 
{ 
	double		iFramesPerSecond	= 26; 
	double		iFRAMES_IN_SECOND	=	iFramesPerSecond; 
	double		iFRAMES_IN_MINUTE	=	(iFramesPerSecond*60); 
	double		iFRAMES_IN_HOUR		=	(iFramesPerSecond*60*60); 
 
	//Convert all the time into frames then calculate 
	LONGLONG llTotalFrames = llTime*iFramesPerSecond/10000000; 
	char szTime[MAX_PATH]; 
	//hours 
	int nHours = llTotalFrames/iFRAMES_IN_HOUR; 
	if( nHours > 0 ) 
		llTotalFrames =- nHours*iFRAMES_IN_HOUR; 
	//minutes 
	int nMinutes = llTotalFrames/iFRAMES_IN_MINUTE; 
	if( nMinutes > 0 ) 
		llTotalFrames = llTotalFrames - (nMinutes*iFRAMES_IN_MINUTE); 
	//seconds 
	int nSeconds = llTotalFrames/iFRAMES_IN_SECOND; 
	if( nSeconds > 0 ) 
		llTotalFrames = llTotalFrames - (nSeconds*iFRAMES_IN_SECOND); 
 
	sprintf(szTime,"%.2d:%.2d:%.2d:%.2d",nHours,nMinutes,nSeconds,llTotalFrames); 
 
	return szTime; 
} 
 
// 
// 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(); 
		if( nFrameRate++ > 150 ) 
		{ 
			PatBlt(m_dcPaint,0,0,m_bmpInfo.bmiHeader.biWidth,m_bmpInfo.bmiHeader.biHeight,BLACKNESS); 
			//PatBlt(m_dcPaint,0,m_bmpInfo.bmiHeader.biHeight-m_nScoreBoardHeight,m_bmpInfo.bmiHeader.biWidth,m_nScoreBoardHeight,WHITENESS); 
			RECT rcSnake; 
			for(int n=m_nNumberSnakeBlocks;n>=0;n--) 
			{ 
				rcSnake.left = m_nLastX + (m_bmpInfo.bmiHeader.biWidth/2) - (m_nSnakeBlockWidth)*n; 
				rcSnake.top = m_nLastY + (m_bmpInfo.bmiHeader.biHeight/2); 
				rcSnake.right = rcSnake.left + m_nSnakeBlockWidth; 
				rcSnake.bottom = rcSnake.top + m_nSnakeBlockHeight; 
				FillRect(m_dcPaint,&rcSnake,CreateSolidBrush(RGB(0,255,0))); 
				m_nLastX += m_nSnakeBlockWidth; 
 
				if( m_nLastX+(m_nSnakeBlockWidth+m_nSpaceBetweenBlock)*m_nNumberSnakeBlocks > m_bmpInfo.bmiHeader.biWidth ) 
				{ 
					m_nLastX = -m_bmpInfo.bmiHeader.biWidth/2; 
				} 
 
				TRACE("%d %d %d %d\n",rcSnake.left,rcSnake.top,rcSnake.right,rcSnake.bottom); 
			} 
			nFrameRate=0; 
		} 
 
		m_llFrameCount++; 
 
	    CRefTime		m_rtStart;			// source will start here 
	    CRefTime		m_rtStop;			// source will stop here 
 
		m_rtStart = m_llFrameCount*1000000/26; 
		m_rtStop = (m_llFrameCount+1)*1000000/26; 
 
 
		// Draw the current frame 
		TCHAR szText[256]; 
		wsprintf( szText, TEXT("%s\0"), TimeToTimecode(m_rtStart)); 
 
		PatBlt(m_dcPaint,0,m_bmpInfo.bmiHeader.biHeight-25,m_bmpInfo.bmiHeader.biWidth,m_bmpInfo.bmiHeader.biHeight,BLACKNESS); 
 
		SetBkMode(m_dcPaint,TRANSPARENT); 
		SetTextColor(m_dcPaint,RGB(255,255,255)); 
		if( !TextOut( m_dcPaint, m_bmpInfo.bmiHeader.biWidth/2-50, m_bmpInfo.bmiHeader.biHeight-20, szText,_tcslen( szText ) ) ) 
			return E_FAIL; 
 
		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(); 
}