PlayWnd.cpp
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:8k
源码类别:

VC书籍

开发平台:

Visual C++

  1. // PlayWnd.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "MAV8.h"
  5. #include "PlayWnd.h"
  6. #include ".av8incav8api.h"
  7. #include ".av8incdefine.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. #define WM_DATABLOCK_UPDATE WM_USER+20
  14. #define CHECK_ERROR(x, idFailMsg) if (FAILED(hr = (x))) { if (idFailMsg) MessageBox(idFailMsg); return;}
  15. #define HELPER_RELEASE(x) {if(x) x -> Release(); x = NULL;} // 控件释放
  16. BOOL Rendered;
  17. PBYTE pbMem[100];
  18. int rIndex = 0;
  19. extern BOOL Ready;
  20. extern PBYTE Ptr[];
  21. BOOL PeekAndPump()
  22. {
  23. static MSG msg;
  24. while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {
  25. if (!AfxGetApp()->PumpMessage()) {
  26. ::PostQuitMessage(0);
  27. return FALSE;
  28. }
  29. }
  30. return TRUE;
  31. }
  32. /////////////////////////////////////////////////////////////////////////////
  33. class CMemStream : public CAsyncStream
  34. {
  35. public:
  36.     CMemStream( LPBYTE pbData, LONGLONG llLength, DWORD dwKBPerSec = INFINITE) :
  37. m_pbData(pbData),
  38.         m_llLength(llLength),
  39.         m_llPosition(0),
  40.         m_dwKBPerSec(dwKBPerSec)
  41.     {
  42.         m_dwTimeStart = timeGetTime();
  43.     }
  44.     HRESULT SetPointer(LONGLONG llPos)
  45.     {
  46.         if (llPos < 0 || llPos > m_llLength) {
  47.             return S_FALSE;
  48.         } else {
  49.             m_llPosition = llPos;
  50.             return S_OK;
  51.         }
  52.     }
  53.     HRESULT Read(PBYTE pbBuffer,
  54.                  DWORD dwBytesToRead,
  55.                  BOOL bAlign,
  56.                  LPDWORD pdwBytesRead)
  57.     {
  58.         CAutoLock lck(&m_csLock);
  59.         DWORD dwReadLength;
  60.         ///*  Wait until the bytes are here! 
  61.         DWORD dwTime = timeGetTime();
  62.         if (m_llPosition + dwBytesToRead > m_llLength) {
  63.             dwReadLength = (DWORD)(m_llLength - m_llPosition);
  64.         } else {
  65.             dwReadLength = dwBytesToRead;
  66.         }
  67.         DWORD dwTimeToArrive =
  68.             ((DWORD)m_llPosition + dwReadLength) / m_dwKBPerSec;
  69.         if (dwTime - m_dwTimeStart < dwTimeToArrive) {
  70.             Sleep(dwTimeToArrive - dwTime + m_dwTimeStart);
  71.         }
  72. while (!Ready) {
  73. PeekAndPump();
  74. }
  75.         CopyMemory((PVOID)pbBuffer, (PVOID)(Ptr[rIndex]), dwReadLength);
  76. TRACE1 ("Read Addr = %lXn",(DWORD)(Ptr[rIndex]));
  77. rIndex = (rIndex + 1) % 100;
  78. Ready = false;
  79.         m_llPosition += dwReadLength;
  80.         *pdwBytesRead = dwReadLength;
  81.         return S_OK;
  82.     }
  83.     LONGLONG Size(LONGLONG *pSizeAvailable)
  84.     {
  85.         LONGLONG llCurrentAvailable =
  86.             Int32x32To64((timeGetTime() - m_dwTimeStart),m_dwKBPerSec);
  87.         *pSizeAvailable = min(m_llLength, llCurrentAvailable);
  88.         return m_llLength;
  89.     }
  90.     DWORD Alignment()
  91.     {
  92.         return 1;
  93.     }
  94.     void Lock()
  95.     {
  96.         m_csLock.Lock();
  97.     }
  98.     void Unlock()
  99.     {
  100.         m_csLock.Unlock();
  101.     }
  102. private:
  103.     CCritSec       m_csLock;
  104.     const PBYTE    m_pbData;
  105.     const LONGLONG m_llLength;
  106.     LONGLONG       m_llPosition;
  107.     DWORD          m_dwKBPerSec;
  108.     DWORD          m_dwTimeStart;
  109. };
  110. class CMemReader : public CAsyncReader
  111. {
  112. public:
  113.     //  We're not going to be CoCreate'd so we don't need registration
  114.     //  stuff etc
  115.     STDMETHODIMP Register()
  116.     {
  117.         return S_OK;
  118.     }
  119.     STDMETHODIMP Unregister()
  120.     {
  121.         return S_OK;
  122.     }
  123.     CMemReader(CMemStream *pStream, CMediaType *pmt, HRESULT *phr) :
  124.         CAsyncReader(NAME("Mem Reader"), NULL, pStream, phr)
  125.     {
  126.         m_mt = *pmt;
  127.     }
  128. };
  129. /////////////////////////////////////////////////////////////////////////////
  130. // CPlayWnd 
  131. IMPLEMENT_DYNCREATE(CPlayWnd, CFrameWnd)
  132. CPlayWnd::CPlayWnd()
  133. {
  134. m_pStream = NULL;
  135. m_rdr = NULL;
  136. m_pivw = NULL; 
  137. m_pifg = NULL;
  138. m_pigb = NULL;
  139. m_pimc = NULL;
  140. CRect rect;
  141. rect.left = 0;
  142. rect.top = 0;
  143. rect.right = 352+GetSystemMetrics(SM_CXFRAME) + 5;
  144. rect.bottom = 288+GetSystemMetrics(SM_CYFRAME)+ 
  145. //GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYMENU);
  146. GetSystemMetrics(SM_CYCAPTION) + 10;
  147. CFrameWnd::Create(NULL, "Playback Window",WS_OVERLAPPEDWINDOW, rect);
  148. }
  149. CPlayWnd::~CPlayWnd()
  150. {
  151. }
  152. BEGIN_MESSAGE_MAP(CPlayWnd, CFrameWnd)
  153. //{{AFX_MSG_MAP(CPlayWnd)
  154. ON_WM_CREATE()
  155. ON_WM_DESTROY()
  156. ON_WM_SIZE()
  157. //}}AFX_MSG_MAP
  158. END_MESSAGE_MAP()
  159. /////////////////////////////////////////////////////////////////////////////
  160. // CPlayWnd message handlers
  161. int CPlayWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  162. {
  163. if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  164. return -1;
  165.     CoInitialize(NULL);
  166. for (int i = 0; i< 100; i++ )
  167. pbMem[i] = new BYTE [0x8000];
  168. m_pStream = new CMemStream(NULL, 0x80000000, INFINITE);
  169. mt.majortype = MEDIATYPE_Stream;
  170.     mt.subtype = MEDIASUBTYPE_MPEG1System;
  171. hr = S_OK;
  172.     m_rdr = new CMemReader(m_pStream, &mt, &hr);
  173.     if(FAILED(hr) || m_rdr == NULL)
  174. {
  175. MessageBox("CMemReader Error");
  176. return 0;
  177. }
  178. InitFilter ();
  179. Ready = false;
  180. Rendered = false;
  181. return 0;
  182. }
  183. void CPlayWnd::InitFilter ()
  184. {
  185. CHECK_ERROR(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IFilterGraph, (void**)&m_pifg),"CoCreateInstance Error") ;
  186.     
  187. CHECK_ERROR(m_pifg -> AddFilter(m_rdr, NULL), "AddFilter Error");
  188.     
  189. CHECK_ERROR(m_pifg -> QueryInterface(IID_IGraphBuilder, (void **)&m_pigb),"QueryInterface(IGraphBuilder) Error");
  190.     
  191. CHECK_ERROR(m_pigb -> QueryInterface(IID_IMediaControl, (void **)&m_pimc),"QueryInterface(IMediaControl) Error");
  192.     CHECK_ERROR(m_pigb -> QueryInterface(IID_IVideoWindow, (void **)&m_pivw),"QueryInterface(IVideoWindow) Error");
  193. }
  194. void CPlayWnd::OnDestroy() 
  195. {
  196. CFrameWnd::OnDestroy();
  197. if(m_pivw) {
  198. m_pivw -> put_Visible(OAFALSE);
  199. m_pivw -> put_Owner(NULL);
  200. HELPER_RELEASE(m_pivw);
  201. }
  202. HELPER_RELEASE(m_pifg);
  203. HELPER_RELEASE(m_pigb);
  204. HELPER_RELEASE(m_pimc);
  205. for (int i = 0; i< 100; i++) {
  206. if (pbMem[i]) {
  207. delete pbMem[i];
  208. pbMem[i] = NULL;
  209. }
  210. }
  211. if(m_pStream) {
  212. delete m_pStream;
  213. m_pStream = NULL;
  214. }
  215. if(m_rdr) {
  216. delete m_rdr;
  217. m_rdr = NULL;
  218. }
  219.     CoUninitialize();
  220. }
  221. BOOL CPlayWnd::PreCreateWindow(CREATESTRUCT& cs) 
  222. {
  223. HBRUSH hBrushMagenta=::CreateSolidBrush(RGB(255, 0, 255));
  224. HCURSOR hCursor=::LoadCursor(NULL, IDC_ARROW);
  225. HICON hIcon = ::LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_TSTLOGO));
  226. cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
  227. hCursor, hBrushMagenta, hIcon);
  228. DeleteObject(hBrushMagenta);
  229. nScreenX=GetSystemMetrics(SM_CXSCREEN);
  230. nScreenY=GetSystemMetrics(SM_CYSCREEN);
  231. return CFrameWnd::PreCreateWindow(cs);
  232. }
  233. void CPlayWnd::OnSize(UINT nType, int cx, int cy) 
  234. {
  235. #define DIVIDEVALUE 40
  236. // TODO: Add your message handler code here
  237. if(cx+(cx/DIVIDEVALUE) > nScreenX || 
  238.    cy+(cy/DIVIDEVALUE) > nScreenY){
  239.   // make the window size smaller to avoid the 352 and 360 problem
  240. CRect rect;
  241. rect.left=0;
  242. rect.top=0;
  243. rect.right= nScreenX - (nScreenX/DIVIDEVALUE) ;
  244. rect.bottom= nScreenY- (nScreenY/DIVIDEVALUE) ;
  245. SetWindowPos(&wndTop, rect.left, rect.top, 
  246. rect.right, rect.bottom+12, SWP_SHOWWINDOW);
  247. } else {
  248. // make the destination lager than window size, because 360 and 352 problem
  249. CFrameWnd::OnSize(nType, cx, cy);
  250. }
  251. }
  252. void CPlayWnd::Render ()
  253. {
  254. if (m_pigb) {
  255. rIndex = 0;
  256. CHECK_ERROR(m_pigb -> Render(m_rdr -> GetPin(0)), "render Error");
  257. Rendered = true;
  258. m_pivw -> put_Owner((OAHWND)m_hWnd);    
  259. m_pivw -> put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
  260. RECT m_rc;
  261. GetClientRect(&m_rc);
  262. m_pivw -> SetWindowPosition(m_rc.left, m_rc.top, m_rc.right, m_rc.bottom);
  263. m_pimc -> Run();
  264. }
  265. }