device_directx9.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*********************************************************************************
  2. INTEL CORPORATION PROPRIETARY INFORMATION
  3. This software is supplied under the terms of a license agreement or nondisclosure
  4. agreement with Intel Corporation and may not be copied or disclosed except in
  5. accordance with the terms of that agreement
  6. Copyright(c) 2011-2015 Intel Corporation. All Rights Reserved.
  7. **********************************************************************************/
  8. // #include "mfx_samples_config.h"
  9. #if defined(WIN32) || defined(WIN64)
  10. //prefast signature used in combaseapi.h
  11. #ifndef _PREFAST_
  12. #pragma warning(disable : 4068)
  13. #endif
  14. #include "device_directx9.h"
  15. // #include "igfx_s3dcontrol.h"
  16. #include "atlbase.h"
  17. // Macros
  18. #define MSDK_ZERO_MEMORY(VAR) \
  19. { \
  20. memset(&VAR, 0, sizeof(VAR)); \
  21. }
  22. #define MSDK_MEMCPY_VAR(dstVarName, src, count) \
  23. memcpy_s(&(dstVarName), sizeof(dstVarName), (src), (count))
  24. CD3D9Device::CD3D9Device()
  25. {
  26. m_pD3D9 = NULL;
  27. m_pD3DD9 = NULL;
  28. m_pDeviceManager9 = NULL;
  29. MSDK_ZERO_MEMORY(m_D3DPP);
  30. m_resetToken = 0;
  31. m_nViews = 0;
  32. m_pS3DControl = NULL;
  33. MSDK_ZERO_MEMORY(m_backBufferDesc);
  34. m_pDXVAVPS = NULL;
  35. m_pDXVAVP_Left = NULL;
  36. m_pDXVAVP_Right = NULL;
  37. MSDK_ZERO_MEMORY(m_targetRect);
  38. MSDK_ZERO_MEMORY(m_VideoDesc);
  39. MSDK_ZERO_MEMORY(m_BltParams);
  40. MSDK_ZERO_MEMORY(m_Sample);
  41. // Initialize DXVA structures
  42. DXVA2_AYUVSample16 color = {
  43. 0x8000, // Cr
  44. 0x8000, // Cb
  45. 0x1000, // Y
  46. 0xffff // Alpha
  47. };
  48. DXVA2_ExtendedFormat format = {
  49. // DestFormat
  50. DXVA2_SampleProgressiveFrame, // SampleFormat
  51. DXVA2_VideoChromaSubsampling_MPEG2, // VideoChromaSubsampling
  52. DXVA_NominalRange_0_255, // NominalRange
  53. DXVA2_VideoTransferMatrix_BT709, // VideoTransferMatrix
  54. DXVA2_VideoLighting_bright, // VideoLighting
  55. DXVA2_VideoPrimaries_BT709, // VideoPrimaries
  56. DXVA2_VideoTransFunc_709 // VideoTransferFunction
  57. };
  58. // init m_VideoDesc structure
  59. MSDK_MEMCPY_VAR(m_VideoDesc.SampleFormat, &format,
  60. sizeof(DXVA2_ExtendedFormat));
  61. m_VideoDesc.SampleWidth = 0;
  62. m_VideoDesc.SampleHeight = 0;
  63. m_VideoDesc.InputSampleFreq.Numerator = 60;
  64. m_VideoDesc.InputSampleFreq.Denominator = 1;
  65. m_VideoDesc.OutputFrameFreq.Numerator = 60;
  66. m_VideoDesc.OutputFrameFreq.Denominator = 1;
  67. // init m_BltParams structure
  68. MSDK_MEMCPY_VAR(m_BltParams.DestFormat, &format,
  69. sizeof(DXVA2_ExtendedFormat));
  70. MSDK_MEMCPY_VAR(m_BltParams.BackgroundColor, &color,
  71. sizeof(DXVA2_AYUVSample16));
  72. // init m_Sample structure
  73. m_Sample.Start = 0;
  74. m_Sample.End = 1;
  75. m_Sample.SampleFormat = format;
  76. m_Sample.PlanarAlpha.Fraction = 0;
  77. m_Sample.PlanarAlpha.Value = 1;
  78. m_bIsA2rgb10 = FALSE;
  79. }
  80. bool CD3D9Device::CheckOverlaySupport()
  81. {
  82. D3DCAPS9 d3d9caps;
  83. D3DOVERLAYCAPS d3doverlaycaps = {0};
  84. IDirect3D9ExOverlayExtension *d3d9overlay = NULL;
  85. bool overlaySupported = false;
  86. memset(&d3d9caps, 0, sizeof(d3d9caps));
  87. HRESULT hr = m_pD3D9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
  88. &d3d9caps);
  89. if (FAILED(hr) || !(d3d9caps.Caps & D3DCAPS_OVERLAY)) {
  90. overlaySupported = false;
  91. } else {
  92. hr = m_pD3D9->QueryInterface(IID_PPV_ARGS(&d3d9overlay));
  93. if (FAILED(hr) || (d3d9overlay == NULL)) {
  94. overlaySupported = false;
  95. } else {
  96. hr = d3d9overlay->CheckDeviceOverlayType(
  97. D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
  98. m_D3DPP.BackBufferWidth,
  99. m_D3DPP.BackBufferHeight,
  100. m_D3DPP.BackBufferFormat, NULL,
  101. D3DDISPLAYROTATION_IDENTITY, &d3doverlaycaps);
  102. MSDK_SAFE_RELEASE(d3d9overlay);
  103. if (FAILED(hr)) {
  104. overlaySupported = false;
  105. } else {
  106. overlaySupported = true;
  107. }
  108. }
  109. }
  110. return overlaySupported;
  111. }
  112. mfxStatus CD3D9Device::FillD3DPP(mfxHDL hWindow, mfxU16 nViews,
  113. D3DPRESENT_PARAMETERS &D3DPP)
  114. {
  115. mfxStatus sts = MFX_ERR_NONE;
  116. D3DPP.Windowed = true;
  117. D3DPP.hDeviceWindow = (HWND)hWindow;
  118. D3DPP.Flags = D3DPRESENTFLAG_VIDEO;
  119. D3DPP.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  120. D3DPP.PresentationInterval =
  121. D3DPRESENT_INTERVAL_ONE; // note that this setting leads to an implicit timeBeginPeriod call
  122. D3DPP.BackBufferCount = 1;
  123. D3DPP.BackBufferFormat = (m_bIsA2rgb10) ? D3DFMT_A2R10G10B10
  124. : D3DFMT_X8R8G8B8;
  125. if (hWindow) {
  126. RECT r;
  127. GetClientRect((HWND)hWindow, &r);
  128. int x = GetSystemMetrics(SM_CXSCREEN);
  129. int y = GetSystemMetrics(SM_CYSCREEN);
  130. D3DPP.BackBufferWidth = min(r.right - r.left, x);
  131. D3DPP.BackBufferHeight = min(r.bottom - r.top, y);
  132. } else {
  133. D3DPP.BackBufferWidth = GetSystemMetrics(SM_CYSCREEN);
  134. D3DPP.BackBufferHeight = GetSystemMetrics(SM_CYSCREEN);
  135. }
  136. //
  137. // Mark the back buffer lockable if software DXVA2 could be used.
  138. // This is because software DXVA2 device requires a lockable render target
  139. // for the optimal performance.
  140. //
  141. {
  142. D3DPP.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
  143. }
  144. bool isOverlaySupported = CheckOverlaySupport();
  145. if (2 == nViews && !isOverlaySupported)
  146. return MFX_ERR_UNSUPPORTED;
  147. bool needOverlay = (2 == nViews) ? true : false;
  148. D3DPP.SwapEffect = needOverlay ? D3DSWAPEFFECT_OVERLAY
  149. : D3DSWAPEFFECT_DISCARD;
  150. return sts;
  151. }
  152. mfxStatus CD3D9Device::Init(mfxHDL hWindow, mfxU16 nViews, mfxU32 nAdapterNum)
  153. {
  154. mfxStatus sts = MFX_ERR_NONE;
  155. if (2 < nViews)
  156. return MFX_ERR_UNSUPPORTED;
  157. m_nViews = nViews;
  158. HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_pD3D9);
  159. if (!m_pD3D9 || FAILED(hr))
  160. return MFX_ERR_DEVICE_FAILED;
  161. ZeroMemory(&m_D3DPP, sizeof(m_D3DPP));
  162. sts = FillD3DPP(hWindow, nViews, m_D3DPP);
  163. MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
  164. hr = m_pD3D9->CreateDeviceEx(nAdapterNum, D3DDEVTYPE_HAL, (HWND)hWindow,
  165. D3DCREATE_SOFTWARE_VERTEXPROCESSING |
  166. D3DCREATE_MULTITHREADED |
  167. D3DCREATE_FPU_PRESERVE,
  168. &m_D3DPP, NULL, &m_pD3DD9);
  169. if (FAILED(hr))
  170. return MFX_ERR_NULL_PTR;
  171. if (hWindow) {
  172. hr = m_pD3DD9->ResetEx(&m_D3DPP, NULL);
  173. if (FAILED(hr))
  174. return MFX_ERR_UNDEFINED_BEHAVIOR;
  175. hr = m_pD3DD9->Clear(0, NULL, D3DCLEAR_TARGET,
  176. D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
  177. if (FAILED(hr))
  178. return MFX_ERR_UNDEFINED_BEHAVIOR;
  179. }
  180. UINT resetToken = 0;
  181. hr = DXVA2CreateDirect3DDeviceManager9(&resetToken, &m_pDeviceManager9);
  182. if (FAILED(hr))
  183. return MFX_ERR_NULL_PTR;
  184. hr = m_pDeviceManager9->ResetDevice(m_pD3DD9, resetToken);
  185. if (FAILED(hr))
  186. return MFX_ERR_UNDEFINED_BEHAVIOR;
  187. m_resetToken = resetToken;
  188. return sts;
  189. }
  190. mfxStatus CD3D9Device::Reset()
  191. {
  192. HRESULT hr = NO_ERROR;
  193. MSDK_CHECK_POINTER(m_pD3DD9, MFX_ERR_NULL_PTR);
  194. if (m_D3DPP.Windowed) {
  195. RECT r;
  196. GetClientRect((HWND)m_D3DPP.hDeviceWindow, &r);
  197. int x = GetSystemMetrics(SM_CXSCREEN);
  198. int y = GetSystemMetrics(SM_CYSCREEN);
  199. m_D3DPP.BackBufferWidth = min(r.right - r.left, x);
  200. m_D3DPP.BackBufferHeight = min(r.bottom - r.top, y);
  201. } else {
  202. m_D3DPP.BackBufferWidth = GetSystemMetrics(SM_CXSCREEN);
  203. m_D3DPP.BackBufferHeight = GetSystemMetrics(SM_CYSCREEN);
  204. }
  205. // Reset will change the parameters, so use a copy instead.
  206. D3DPRESENT_PARAMETERS d3dpp = m_D3DPP;
  207. hr = m_pD3DD9->ResetEx(&d3dpp, NULL);
  208. if (FAILED(hr))
  209. return MFX_ERR_UNDEFINED_BEHAVIOR;
  210. hr = m_pDeviceManager9->ResetDevice(m_pD3DD9, m_resetToken);
  211. if (FAILED(hr))
  212. return MFX_ERR_UNDEFINED_BEHAVIOR;
  213. return MFX_ERR_NONE;
  214. }
  215. void CD3D9Device::Close()
  216. {
  217. MSDK_SAFE_RELEASE(m_pDXVAVP_Left);
  218. MSDK_SAFE_RELEASE(m_pDXVAVP_Right);
  219. MSDK_SAFE_RELEASE(m_pDXVAVPS);
  220. MSDK_SAFE_RELEASE(m_pDeviceManager9);
  221. MSDK_SAFE_RELEASE(m_pD3DD9);
  222. MSDK_SAFE_RELEASE(m_pD3D9);
  223. m_pS3DControl = NULL;
  224. }
  225. CD3D9Device::~CD3D9Device()
  226. {
  227. Close();
  228. }
  229. mfxStatus CD3D9Device::GetHandle(mfxHandleType type, mfxHDL *pHdl)
  230. {
  231. if (MFX_HANDLE_DIRECT3D_DEVICE_MANAGER9 == type && pHdl != NULL) {
  232. *pHdl = m_pDeviceManager9;
  233. return MFX_ERR_NONE;
  234. } else if (MFX_HANDLE_GFXS3DCONTROL == type && pHdl != NULL) {
  235. *pHdl = m_pS3DControl;
  236. return MFX_ERR_NONE;
  237. }
  238. return MFX_ERR_UNSUPPORTED;
  239. }
  240. mfxStatus CD3D9Device::SetHandle(mfxHandleType type, mfxHDL hdl)
  241. {
  242. if (MFX_HANDLE_GFXS3DCONTROL == type && hdl != NULL) {
  243. m_pS3DControl = (IGFXS3DControl *)hdl;
  244. return MFX_ERR_NONE;
  245. } else if (MFX_HANDLE_DEVICEWINDOW == type &&
  246. hdl != NULL) //for render window handle
  247. {
  248. m_D3DPP.hDeviceWindow = (HWND)hdl;
  249. return MFX_ERR_NONE;
  250. }
  251. return MFX_ERR_UNSUPPORTED;
  252. }
  253. mfxStatus CD3D9Device::RenderFrame(mfxFrameSurface1 *pSurface,
  254. mfxFrameAllocator *pmfxAlloc)
  255. {
  256. HRESULT hr = S_OK;
  257. if (!(1 == m_nViews || (2 == m_nViews && NULL != m_pS3DControl)))
  258. return MFX_ERR_UNDEFINED_BEHAVIOR;
  259. MSDK_CHECK_POINTER(pSurface, MFX_ERR_NULL_PTR);
  260. MSDK_CHECK_POINTER(m_pDeviceManager9, MFX_ERR_NOT_INITIALIZED);
  261. MSDK_CHECK_POINTER(pmfxAlloc, MFX_ERR_NULL_PTR);
  262. // don't try to render second view if output rect changed since first view
  263. if (2 == m_nViews && (0 != pSurface->Info.FrameId.ViewId))
  264. return MFX_ERR_NONE;
  265. hr = m_pD3DD9->TestCooperativeLevel();
  266. switch (hr) {
  267. case D3D_OK:
  268. break;
  269. case D3DERR_DEVICELOST: {
  270. return MFX_ERR_DEVICE_LOST;
  271. }
  272. case D3DERR_DEVICENOTRESET: {
  273. return MFX_ERR_UNKNOWN;
  274. }
  275. default: {
  276. return MFX_ERR_UNKNOWN;
  277. }
  278. }
  279. CComPtr<IDirect3DSurface9> pBackBuffer;
  280. hr = m_pD3DD9->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
  281. &pBackBuffer);
  282. mfxHDLPair *dxMemId = (mfxHDLPair *)pSurface->Data.MemId;
  283. hr = m_pD3DD9->StretchRect((IDirect3DSurface9 *)dxMemId->first, NULL,
  284. pBackBuffer, NULL, D3DTEXF_LINEAR);
  285. if (FAILED(hr)) {
  286. return MFX_ERR_UNKNOWN;
  287. }
  288. if (SUCCEEDED(hr) &&
  289. (1 == m_nViews || pSurface->Info.FrameId.ViewId == 1)) {
  290. hr = m_pD3DD9->Present(NULL, NULL, NULL, NULL);
  291. }
  292. return SUCCEEDED(hr) ? MFX_ERR_NONE : MFX_ERR_DEVICE_FAILED;
  293. }
  294. /*
  295. mfxStatus CD3D9Device::CreateVideoProcessors()
  296. {
  297. if (!(1 == m_nViews || (2 == m_nViews && NULL != m_pS3DControl)))
  298. return MFX_ERR_UNDEFINED_BEHAVIOR;
  299. MSDK_SAFE_RELEASE(m_pDXVAVP_Left);
  300. MSDK_SAFE_RELEASE(m_pDXVAVP_Right);
  301. HRESULT hr ;
  302. if (2 == m_nViews && NULL != m_pS3DControl)
  303. {
  304. hr = m_pS3DControl->SetDevice(m_pDeviceManager9);
  305. if (FAILED(hr))
  306. {
  307. return MFX_ERR_DEVICE_FAILED;
  308. }
  309. }
  310. ZeroMemory(&m_backBufferDesc, sizeof(m_backBufferDesc));
  311. IDirect3DSurface9 *backBufferTmp = NULL;
  312. hr = m_pD3DD9->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBufferTmp);
  313. if (NULL != backBufferTmp)
  314. backBufferTmp->GetDesc(&m_backBufferDesc);
  315. MSDK_SAFE_RELEASE(backBufferTmp);
  316. if (SUCCEEDED(hr))
  317. {
  318. // Create DXVA2 Video Processor Service.
  319. hr = DXVA2CreateVideoService(m_pD3DD9,
  320. IID_IDirectXVideoProcessorService,
  321. (void**)&m_pDXVAVPS);
  322. }
  323. if (2 == m_nViews)
  324. {
  325. // Activate L channel
  326. if (SUCCEEDED(hr))
  327. {
  328. hr = m_pS3DControl->SelectLeftView();
  329. }
  330. if (SUCCEEDED(hr))
  331. {
  332. // Create VPP device for the L channel
  333. hr = m_pDXVAVPS->CreateVideoProcessor(DXVA2_VideoProcProgressiveDevice,
  334. &m_VideoDesc,
  335. m_D3DPP.BackBufferFormat,
  336. 1,
  337. &m_pDXVAVP_Left);
  338. }
  339. // Activate R channel
  340. if (SUCCEEDED(hr))
  341. {
  342. hr = m_pS3DControl->SelectRightView();
  343. }
  344. }
  345. if (SUCCEEDED(hr))
  346. {
  347. hr = m_pDXVAVPS->CreateVideoProcessor(DXVA2_VideoProcProgressiveDevice,
  348. &m_VideoDesc,
  349. m_D3DPP.BackBufferFormat,
  350. 1,
  351. &m_pDXVAVP_Right);
  352. }
  353. return SUCCEEDED(hr) ? MFX_ERR_NONE : MFX_ERR_DEVICE_FAILED;
  354. }
  355. */
  356. #endif // #if defined(WIN32) || defined(WIN64)