www.gusucode.com > VC++远程视频监控系统源代码-源码程序 > VC++远程视频监控系统源代码-源码程序/code/AV8SDK/AV8SDK/Demo/PlayWnd.cpp
// PlayWnd.cpp : implementation file // #include "stdafx.h" #include "MAV8.h" #include "PlayWnd.h" #include ".\av8inc\av8api.h" #include ".\av8inc\define.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define WM_DATABLOCK_UPDATE WM_USER+20 #define CHECK_ERROR(x, idFailMsg) if (FAILED(hr = (x))) { if (idFailMsg) MessageBox(idFailMsg); return;} #define HELPER_RELEASE(x) {if(x) x -> Release(); x = NULL;} // 控件释放 BOOL Rendered; PBYTE pbMem[100]; int rIndex = 0; extern BOOL Ready; extern PBYTE Ptr[]; BOOL PeekAndPump() { static MSG msg; while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) { ::PostQuitMessage(0); return FALSE; } } return TRUE; } ///////////////////////////////////////////////////////////////////////////// class CMemStream : public CAsyncStream { public: CMemStream( LPBYTE pbData, LONGLONG llLength, DWORD dwKBPerSec = INFINITE) : m_pbData(pbData), m_llLength(llLength), m_llPosition(0), m_dwKBPerSec(dwKBPerSec) { m_dwTimeStart = timeGetTime(); } HRESULT SetPointer(LONGLONG llPos) { if (llPos < 0 || llPos > m_llLength) { return S_FALSE; } else { m_llPosition = llPos; return S_OK; } } HRESULT Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, LPDWORD pdwBytesRead) { CAutoLock lck(&m_csLock); DWORD dwReadLength; ///* Wait until the bytes are here! DWORD dwTime = timeGetTime(); if (m_llPosition + dwBytesToRead > m_llLength) { dwReadLength = (DWORD)(m_llLength - m_llPosition); } else { dwReadLength = dwBytesToRead; } DWORD dwTimeToArrive = ((DWORD)m_llPosition + dwReadLength) / m_dwKBPerSec; if (dwTime - m_dwTimeStart < dwTimeToArrive) { Sleep(dwTimeToArrive - dwTime + m_dwTimeStart); } while (!Ready) { PeekAndPump(); } CopyMemory((PVOID)pbBuffer, (PVOID)(Ptr[rIndex]), dwReadLength); TRACE1 ("Read Addr = %lX\n",(DWORD)(Ptr[rIndex])); rIndex = (rIndex + 1) % 100; Ready = false; m_llPosition += dwReadLength; *pdwBytesRead = dwReadLength; return S_OK; } LONGLONG Size(LONGLONG *pSizeAvailable) { LONGLONG llCurrentAvailable = Int32x32To64((timeGetTime() - m_dwTimeStart),m_dwKBPerSec); *pSizeAvailable = min(m_llLength, llCurrentAvailable); return m_llLength; } DWORD Alignment() { return 1; } void Lock() { m_csLock.Lock(); } void Unlock() { m_csLock.Unlock(); } private: CCritSec m_csLock; const PBYTE m_pbData; const LONGLONG m_llLength; LONGLONG m_llPosition; DWORD m_dwKBPerSec; DWORD m_dwTimeStart; }; class CMemReader : public CAsyncReader { public: // We're not going to be CoCreate'd so we don't need registration // stuff etc STDMETHODIMP Register() { return S_OK; } STDMETHODIMP Unregister() { return S_OK; } CMemReader(CMemStream *pStream, CMediaType *pmt, HRESULT *phr) : CAsyncReader(NAME("Mem Reader"), NULL, pStream, phr) { m_mt = *pmt; } }; ///////////////////////////////////////////////////////////////////////////// // CPlayWnd IMPLEMENT_DYNCREATE(CPlayWnd, CFrameWnd) CPlayWnd::CPlayWnd() { m_pStream = NULL; m_rdr = NULL; m_pivw = NULL; m_pifg = NULL; m_pigb = NULL; m_pimc = NULL; CRect rect; rect.left = 0; rect.top = 0; rect.right = 352+GetSystemMetrics(SM_CXFRAME) + 5; rect.bottom = 288+GetSystemMetrics(SM_CYFRAME)+ //GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYMENU); GetSystemMetrics(SM_CYCAPTION) + 10; CFrameWnd::Create(NULL, "Playback Window",WS_OVERLAPPEDWINDOW, rect); } CPlayWnd::~CPlayWnd() { } BEGIN_MESSAGE_MAP(CPlayWnd, CFrameWnd) //{{AFX_MSG_MAP(CPlayWnd) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_SIZE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPlayWnd message handlers int CPlayWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; CoInitialize(NULL); for (int i = 0; i< 100; i++ ) pbMem[i] = new BYTE [0x8000]; m_pStream = new CMemStream(NULL, 0x80000000, INFINITE); mt.majortype = MEDIATYPE_Stream; mt.subtype = MEDIASUBTYPE_MPEG1System; hr = S_OK; m_rdr = new CMemReader(m_pStream, &mt, &hr); if(FAILED(hr) || m_rdr == NULL) { MessageBox("CMemReader Error"); return 0; } InitFilter (); Ready = false; Rendered = false; return 0; } void CPlayWnd::InitFilter () { CHECK_ERROR(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IFilterGraph, (void**)&m_pifg),"CoCreateInstance Error") ; CHECK_ERROR(m_pifg -> AddFilter(m_rdr, NULL), "AddFilter Error"); CHECK_ERROR(m_pifg -> QueryInterface(IID_IGraphBuilder, (void **)&m_pigb),"QueryInterface(IGraphBuilder) Error"); CHECK_ERROR(m_pigb -> QueryInterface(IID_IMediaControl, (void **)&m_pimc),"QueryInterface(IMediaControl) Error"); CHECK_ERROR(m_pigb -> QueryInterface(IID_IVideoWindow, (void **)&m_pivw),"QueryInterface(IVideoWindow) Error"); } void CPlayWnd::OnDestroy() { CFrameWnd::OnDestroy(); if(m_pivw) { m_pivw -> put_Visible(OAFALSE); m_pivw -> put_Owner(NULL); HELPER_RELEASE(m_pivw); } HELPER_RELEASE(m_pifg); HELPER_RELEASE(m_pigb); HELPER_RELEASE(m_pimc); for (int i = 0; i< 100; i++) { if (pbMem[i]) { delete pbMem[i]; pbMem[i] = NULL; } } if(m_pStream) { delete m_pStream; m_pStream = NULL; } if(m_rdr) { delete m_rdr; m_rdr = NULL; } CoUninitialize(); } BOOL CPlayWnd::PreCreateWindow(CREATESTRUCT& cs) { HBRUSH hBrushMagenta=::CreateSolidBrush(RGB(255, 0, 255)); HCURSOR hCursor=::LoadCursor(NULL, IDC_ARROW); HICON hIcon = ::LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_TSTLOGO)); cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, hCursor, hBrushMagenta, hIcon); DeleteObject(hBrushMagenta); nScreenX=GetSystemMetrics(SM_CXSCREEN); nScreenY=GetSystemMetrics(SM_CYSCREEN); return CFrameWnd::PreCreateWindow(cs); } void CPlayWnd::OnSize(UINT nType, int cx, int cy) { #define DIVIDEVALUE 40 // TODO: Add your message handler code here if(cx+(cx/DIVIDEVALUE) > nScreenX || cy+(cy/DIVIDEVALUE) > nScreenY){ // make the window size smaller to avoid the 352 and 360 problem CRect rect; rect.left=0; rect.top=0; rect.right= nScreenX - (nScreenX/DIVIDEVALUE) ; rect.bottom= nScreenY- (nScreenY/DIVIDEVALUE) ; SetWindowPos(&wndTop, rect.left, rect.top, rect.right, rect.bottom+12, SWP_SHOWWINDOW); } else { // make the destination lager than window size, because 360 and 352 problem CFrameWnd::OnSize(nType, cx, cy); } } void CPlayWnd::Render () { if (m_pigb) { rIndex = 0; CHECK_ERROR(m_pigb -> Render(m_rdr -> GetPin(0)), "render Error"); Rendered = true; m_pivw -> put_Owner((OAHWND)m_hWnd); m_pivw -> put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); RECT m_rc; GetClientRect(&m_rc); m_pivw -> SetWindowPosition(m_rc.left, m_rc.top, m_rc.right, m_rc.bottom); m_pimc -> Run(); } }