www.pudn.com > IPcaptu.rar > 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(); 
	} 
 
}