DX9AllocatorPresenter.cpp
上传用户:tangyu_668
上传日期:2014-02-27
资源大小:678k
文件大小:12k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2006 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include "mplayerc.h"
  23. #include <atlbase.h>
  24. #include <atlcoll.h>
  25. #include "....DSUtilDSUtil.h"
  26. #include <Videoacc.h>
  27. #include <initguid.h>
  28. #include "DX9AllocatorPresenter.h"
  29. #include <d3d9.h>
  30. #include <d3dx9.h>
  31. #include <Vmr9.h>
  32. #include "....SubPicDX9SubPic.h"
  33. #include "......includeRealMediapntypes.h"
  34. #include "......includeRealMediapnwintyp.h"
  35. #include "......includeRealMediapncom.h"
  36. #include "......includeRealMediarmavsurf.h"
  37. #include "IQTVideoSurface.h"
  38. #include "......includemoreuuids.h"
  39. #include "MacrovisionKicker.h"
  40. #include "IPinHook.h"
  41. #include "PixelShaderCompiler.h"
  42. bool IsVMR9InGraph(IFilterGraph* pFG)
  43. {
  44. BeginEnumFilters(pFG, pEF, pBF)
  45. if(CComQIPtr<IVMRWindowlessControl9>(pBF)) return(true);
  46. EndEnumFilters
  47. return(false);
  48. }
  49. namespace DSObjects
  50. {
  51. class CDX9AllocatorPresenter
  52. : public ISubPicAllocatorPresenterImpl
  53. {
  54. protected:
  55. CSize m_ScreenSize;
  56. bool m_fVMRSyncFix;
  57. CComPtr<IDirect3D9> m_pD3D;
  58.     CComPtr<IDirect3DDevice9> m_pD3DDev;
  59. CComPtr<IDirect3DTexture9> m_pVideoTexture[3];
  60. CComPtr<IDirect3DSurface9> m_pVideoSurface[3];
  61. CInterfaceList<IDirect3DPixelShader9> m_pPixelShaders;
  62. CComPtr<IDirect3DPixelShader9> m_pResizerPixelShader[3]; // bl, bc1, bc2
  63. CComPtr<IDirect3DTexture9> m_pResizerBicubic1stPass;
  64. D3DTEXTUREFILTERTYPE m_filter;
  65. D3DCAPS9 m_caps;
  66. CAutoPtr<CPixelShaderCompiler> m_pPSC;
  67. virtual HRESULT CreateDevice();
  68. virtual HRESULT AllocSurfaces();
  69. virtual void DeleteSurfaces();
  70.     UINT GetAdapter(IDirect3D9 *pD3D);
  71. float m_bicubicA;
  72. HRESULT InitResizers(float bicubicA);
  73. HRESULT TextureCopy(CComPtr<IDirect3DTexture9> pTexture);
  74. HRESULT TextureResize(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4], D3DTEXTUREFILTERTYPE filter);
  75. HRESULT TextureResizeBilinear(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4]);
  76. HRESULT TextureResizeBicubic1pass(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4]);
  77. HRESULT TextureResizeBicubic2pass(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4]);
  78. public:
  79. CDX9AllocatorPresenter(HWND hWnd, HRESULT& hr);
  80. // ISubPicAllocatorPresenter
  81. STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
  82. STDMETHODIMP_(bool) Paint(bool fAll);
  83. STDMETHODIMP GetDIB(BYTE* lpDib, DWORD* size);
  84. STDMETHODIMP SetPixelShader(LPCSTR pSrcData, LPCSTR pTarget);
  85. };
  86. class CVMR9AllocatorPresenter
  87. : public CDX9AllocatorPresenter
  88. , public IVMRSurfaceAllocator9
  89. , public IVMRImagePresenter9
  90. , public IVMRWindowlessControl9
  91. {
  92. protected:
  93. CComPtr<IVMRSurfaceAllocatorNotify9> m_pIVMRSurfAllocNotify;
  94. CInterfaceArray<IDirect3DSurface9> m_pSurfaces;
  95. HRESULT CreateDevice();
  96. void DeleteSurfaces();
  97. bool m_fUseInternalTimer;
  98. REFERENCE_TIME m_rtPrevStart;
  99. public:
  100. CVMR9AllocatorPresenter(HWND hWnd, HRESULT& hr);
  101. DECLARE_IUNKNOWN
  102.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  103. // ISubPicAllocatorPresenter
  104. STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
  105. STDMETHODIMP_(void) SetTime(REFERENCE_TIME rtNow);
  106.     // IVMRSurfaceAllocator9
  107.     STDMETHODIMP InitializeDevice(DWORD_PTR dwUserID, VMR9AllocationInfo* lpAllocInfo, DWORD* lpNumBuffers);
  108.     STDMETHODIMP TerminateDevice(DWORD_PTR dwID);
  109.     STDMETHODIMP GetSurface(DWORD_PTR dwUserID, DWORD SurfaceIndex, DWORD SurfaceFlags, IDirect3DSurface9** lplpSurface);
  110.     STDMETHODIMP AdviseNotify(IVMRSurfaceAllocatorNotify9* lpIVMRSurfAllocNotify);
  111.     // IVMRImagePresenter9
  112.     STDMETHODIMP StartPresenting(DWORD_PTR dwUserID);
  113.     STDMETHODIMP StopPresenting(DWORD_PTR dwUserID);
  114.     STDMETHODIMP PresentImage(DWORD_PTR dwUserID, VMR9PresentationInfo* lpPresInfo);
  115. // IVMRWindowlessControl9
  116. STDMETHODIMP GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight);
  117. STDMETHODIMP GetMinIdealVideoSize(LONG* lpWidth, LONG* lpHeight);
  118. STDMETHODIMP GetMaxIdealVideoSize(LONG* lpWidth, LONG* lpHeight);
  119. STDMETHODIMP SetVideoPosition(const LPRECT lpSRCRect, const LPRECT lpDSTRect);
  120.     STDMETHODIMP GetVideoPosition(LPRECT lpSRCRect, LPRECT lpDSTRect);
  121. STDMETHODIMP GetAspectRatioMode(DWORD* lpAspectRatioMode);
  122. STDMETHODIMP SetAspectRatioMode(DWORD AspectRatioMode);
  123. STDMETHODIMP SetVideoClippingWindow(HWND hwnd);
  124. STDMETHODIMP RepaintVideo(HWND hwnd, HDC hdc);
  125. STDMETHODIMP DisplayModeChanged();
  126. STDMETHODIMP GetCurrentImage(BYTE** lpDib);
  127. STDMETHODIMP SetBorderColor(COLORREF Clr);
  128. STDMETHODIMP GetBorderColor(COLORREF* lpClr);
  129. };
  130. class CRM9AllocatorPresenter
  131. : public CDX9AllocatorPresenter
  132. , public IRMAVideoSurface
  133. {
  134. CComPtr<IDirect3DSurface9> m_pVideoSurfaceOff;
  135. CComPtr<IDirect3DSurface9> m_pVideoSurfaceYUY2;
  136.     RMABitmapInfoHeader m_bitmapInfo;
  137.     RMABitmapInfoHeader m_lastBitmapInfo;
  138. protected:
  139. HRESULT AllocSurfaces();
  140. void DeleteSurfaces();
  141. public:
  142. CRM9AllocatorPresenter(HWND hWnd, HRESULT& hr);
  143. DECLARE_IUNKNOWN
  144.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  145. // IRMAVideoSurface
  146.     STDMETHODIMP Blt(UCHAR* pImageData, RMABitmapInfoHeader* pBitmapInfo, REF(PNxRect) inDestRect, REF(PNxRect) inSrcRect);
  147. STDMETHODIMP BeginOptimizedBlt(RMABitmapInfoHeader* pBitmapInfo);
  148. STDMETHODIMP OptimizedBlt(UCHAR* pImageBits, REF(PNxRect) rDestRect, REF(PNxRect) rSrcRect);
  149. STDMETHODIMP EndOptimizedBlt();
  150. STDMETHODIMP GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) ulType);
  151.     STDMETHODIMP GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) ulType);
  152. };
  153. class CQT9AllocatorPresenter
  154. : public CDX9AllocatorPresenter
  155. , public IQTVideoSurface
  156. {
  157. CComPtr<IDirect3DSurface9> m_pVideoSurfaceOff;
  158. protected:
  159.  HRESULT AllocSurfaces();
  160.  void DeleteSurfaces();
  161. public:
  162. CQT9AllocatorPresenter(HWND hWnd, HRESULT& hr);
  163. DECLARE_IUNKNOWN
  164.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  165. // IQTVideoSurface
  166. STDMETHODIMP BeginBlt(const BITMAP& bm);
  167. STDMETHODIMP DoBlt(const BITMAP& bm);
  168. };
  169. class CDXRAllocatorPresenter
  170. : public ISubPicAllocatorPresenterImpl
  171. {
  172. class CSubRenderCallback : public CUnknown, public ISubRenderCallback, public CCritSec
  173. {
  174. CDXRAllocatorPresenter* m_pDXRAP;
  175. public:
  176. CSubRenderCallback(CDXRAllocatorPresenter* pDXRAP)
  177. : CUnknown(_T("CSubRender"), NULL)
  178. , m_pDXRAP(pDXRAP)
  179. {
  180. }
  181. DECLARE_IUNKNOWN
  182. STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
  183. {
  184. return 
  185. QI(ISubRenderCallback)
  186. __super::NonDelegatingQueryInterface(riid, ppv);
  187. }
  188. void SetDXRAP(CDXRAllocatorPresenter* pDXRAP)
  189. {
  190. CAutoLock cAutoLock(this);
  191. m_pDXRAP = pDXRAP;
  192. }
  193. // ISubRenderCallback
  194. STDMETHODIMP SetDevice(IDirect3DDevice9* pD3DDev)
  195. {
  196. CAutoLock cAutoLock(this);
  197. return m_pDXRAP ? m_pDXRAP->SetDevice(pD3DDev) : E_UNEXPECTED;
  198. }
  199. STDMETHODIMP Render(REFERENCE_TIME rtStart, int left, int top, int right, int bottom, int width, int height)
  200. {
  201. CAutoLock cAutoLock(this);
  202. return m_pDXRAP ? m_pDXRAP->Render(rtStart, 0, 0, left, top, right, bottom, width, height) : E_UNEXPECTED;
  203. }
  204. // ISubRendererCallback2
  205. STDMETHODIMP RenderEx(REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, REFERENCE_TIME AvgTimePerFrame, int left, int top, int right, int bottom, int width, int height)
  206. {
  207. CAutoLock cAutoLock(this);
  208. return m_pDXRAP ? m_pDXRAP->Render(rtStart, rtStop, AvgTimePerFrame, left, top, right, bottom, width, height) : E_UNEXPECTED;
  209. }
  210. };
  211. CComPtr<IUnknown> m_pDXR;
  212. CComPtr<ISubRenderCallback> m_pSRCB;
  213. public:
  214. CDXRAllocatorPresenter(HWND hWnd, HRESULT& hr);
  215. virtual ~CDXRAllocatorPresenter();
  216. DECLARE_IUNKNOWN
  217.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  218. HRESULT SetDevice(IDirect3DDevice9* pD3DDev);
  219. HRESULT Render(
  220. REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, REFERENCE_TIME atpf,
  221. int left, int top, int bottom, int right, int width, int height);
  222. // ISubPicAllocatorPresenter
  223. STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
  224. STDMETHODIMP_(void) SetPosition(RECT w, RECT v);
  225. STDMETHODIMP_(SIZE) GetVideoSize(bool fCorrectAR);
  226. STDMETHODIMP_(bool) Paint(bool fAll);
  227. STDMETHODIMP GetDIB(BYTE* lpDib, DWORD* size);
  228. STDMETHODIMP SetPixelShader(LPCSTR pSrcData, LPCSTR pTarget);
  229. };
  230. }
  231. using namespace DSObjects;
  232. //
  233. HRESULT CreateAP9(const CLSID& clsid, HWND hWnd, ISubPicAllocatorPresenter** ppAP)
  234. {
  235. CheckPointer(ppAP, E_POINTER);
  236. *ppAP = NULL;
  237. HRESULT hr = E_FAIL;
  238. if(clsid == CLSID_VMR9AllocatorPresenter && !(*ppAP = new CVMR9AllocatorPresenter(hWnd, hr))
  239. || clsid == CLSID_RM9AllocatorPresenter && !(*ppAP = new CRM9AllocatorPresenter(hWnd, hr))
  240. || clsid == CLSID_QT9AllocatorPresenter && !(*ppAP = new CQT9AllocatorPresenter(hWnd, hr))
  241. || clsid == CLSID_DXRAllocatorPresenter && !(*ppAP = new CDXRAllocatorPresenter(hWnd, hr)))
  242. return E_OUTOFMEMORY;
  243. if(*ppAP == NULL)
  244. return E_FAIL;
  245. (*ppAP)->AddRef();
  246. if(FAILED(hr))
  247. {
  248. (*ppAP)->Release();
  249. *ppAP = NULL;
  250. }
  251. return hr;
  252. }
  253. //
  254. #pragma pack(push, 1)
  255. template<int texcoords>
  256. struct MYD3DVERTEX {float x, y, z, rhw; struct {float u, v;} t[texcoords];};
  257. #pragma pack(pop)
  258. template<int texcoords>
  259. static void AdjustQuad(MYD3DVERTEX<texcoords>* v, float dx, float dy)
  260. {
  261. float offset = 0.5f;
  262. for(int i = 0; i < 4; i++)
  263. {
  264. v[i].x -= offset;
  265. v[i].y -= offset;
  266. for(int j = 0; j < texcoords-1; j++)
  267. {
  268. v[i].t[j].u -= offset*dx;
  269. v[i].t[j].v -= offset*dy;
  270. }
  271. if(texcoords > 1)
  272. {
  273. v[i].t[texcoords-1].u -= offset;
  274. v[i].t[texcoords-1].v -= offset;
  275. }
  276. }
  277. }
  278. template<int texcoords>
  279. static HRESULT TextureBlt(CComPtr<IDirect3DDevice9> pD3DDev, MYD3DVERTEX<texcoords> v[4], D3DTEXTUREFILTERTYPE filter = D3DTEXF_LINEAR)
  280. {
  281. if(!pD3DDev)
  282. return E_POINTER;
  283. DWORD FVF = 0;
  284. switch(texcoords)
  285. {
  286. case 1: FVF = D3DFVF_TEX1; break;
  287. case 2: FVF = D3DFVF_TEX2; break;
  288. case 3: FVF = D3DFVF_TEX3; break;
  289. case 4: FVF = D3DFVF_TEX4; break;
  290. case 5: FVF = D3DFVF_TEX5; break;
  291. case 6: FVF = D3DFVF_TEX6; break;
  292. case 7: FVF = D3DFVF_TEX7; break;
  293. case 8: FVF = D3DFVF_TEX8; break;
  294. default: return E_FAIL;
  295. }
  296. HRESULT hr;
  297.     do
  298. {
  299.         hr = pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  300.         hr = pD3DDev->SetRenderState(D3DRS_LIGHTING, FALSE);
  301. hr = pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
  302. hr = pD3DDev->SetRenderState(D3DRS_STENCILENABLE, FALSE);
  303.      hr = pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
  304. hr = pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 
  305. hr = pD3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); 
  306. hr = pD3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED); 
  307. for(int i = 0; i < texcoords; i++)
  308. {
  309. hr = pD3DDev->SetSamplerState(i, D3DSAMP_MAGFILTER, filter);
  310. hr = pD3DDev->SetSamplerState(i, D3DSAMP_MINFILTER, filter);
  311. hr = pD3DDev->SetSamplerState(i, D3DSAMP_MIPFILTER, filter);
  312. hr = pD3DDev->SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  313. hr = pD3DDev->SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
  314. }
  315. //
  316. if(FAILED(hr = pD3DDev->BeginScene()))
  317. break;
  318.         hr = pD3DDev->SetFVF(D3DFVF_XYZRHW | FVF);
  319. // hr = pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(v[0]));
  320. MYD3DVERTEX<texcoords> tmp = v[2]; v[2] = v[3]; v[3] = tmp;
  321. hr = pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, v, sizeof(v[0]));
  322. hr = pD3DDev->EndScene();
  323.         //
  324. for(int i = 0; i < texcoords; i++)
  325. {
  326. pD3DDev->SetTexture(i, NULL);
  327. }
  328. return S_OK;
  329.     }
  330. while(0);
  331.     return E_FAIL;
  332. }
  333. // CDX9AllocatorPresenter
  334. CDX9AllocatorPresenter::CDX9AllocatorPresenter(HWND hWnd, HRESULT& hr) 
  335. : ISubPicAllocatorPresenterImpl(hWnd, hr)
  336. , m_ScreenSize(0, 0)
  337. , m_bicubicA(0)
  338. {
  339. if(FAILED(hr)) return;
  340. m_pD3D.Attach(Direct3DCreate9(D3D_SDK_VERSION));
  341. if(!m_pD3D) m_pD3D.Attach(Direct3DCreate9(D3D9b_SDK_VERSION));
  342. if(!m_pD3D) {hr = E_FAIL; return;}
  343. hr = CreateDevice();
  344. }
  345. HRESULT CDX9AllocatorPresenter::CreateDevice()
  346. {
  347. m_pPSC.Free();
  348.     m_pD3DDev = NULL;
  349. D3DDISPLAYMODE d3dd