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(); }