1 /*!
2 * \copy
3 * Copyright (c) 2013, Cisco Systems
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33 #include "d3d9_utils.h"
34
35 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36 void Write2File (FILE* pFp, unsigned char* pData[3], int iStride[2], int iWidth, int iHeight);
37 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
38
39 #ifdef ENABLE_DISPLAY_MODULE
40
41 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
42 #define IDM_ABOUT 104
43 #define IDM_EXIT 105
44 #define IDI_TESTSHARESURFACE 107
45 #define IDI_SMALL 108
46 #define IDC_TESTSHARESURFACE 109
47
48 #define NV12_FORMAT MAKEFOURCC('N','V','1','2')
49
50 typedef struct {
51 UINT uiWidth;
52 UINT uiHeight;
53 D3DFORMAT D3Dformat;
54 D3DPOOL D3DPool;
55 } SHandleInfo;
56
57 #define SAFE_RELEASE(p) if(p) { (p)->Release(); (p) = NULL; }
58 #define SAFE_FREE(p) if(p) { free (p); (p) = NULL; }
59
60 HRESULT Dump2Surface (void* pDst[3], void* pSurface, int iWidth, int iHeight, int iStride[2]);
61 HRESULT InitWindow (HWND* hWnd);
62 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
63
64 typedef HRESULT (WINAPI* pFnCreateD3D9Ex) (UINT SDKVersion, IDirect3D9Ex**);
65 typedef LPDIRECT3D9 (WINAPI* pFnCreateD3D9) (UINT SDKVersion);
66 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
67
CD3D9Utils()68 CD3D9Utils::CD3D9Utils() {
69 m_hDll = NULL;
70 m_hWnd = NULL;
71 m_pDumpYUV = NULL;
72
73 m_bInitDone = FALSE;
74
75 m_lpD3D9 = NULL;
76 m_lpD3D9Device = NULL;
77 m_lpD3D9RawSurfaceShare = NULL;
78 m_nWidth = 0;
79 m_nHeight = 0;
80 // coverity scan uninitial
81 ZeroMemory (&m_d3dpp, sizeof (m_d3dpp));
82 }
83
~CD3D9Utils()84 CD3D9Utils::~CD3D9Utils() {
85 Uninit();
86 }
87
Init(BOOL bWindowed)88 HRESULT CD3D9Utils::Init (BOOL bWindowed) {
89 if (m_bInitDone)
90 return S_OK;
91
92 m_hDll = LoadLibrary (TEXT ("d3d9.dll"));
93 pFnCreateD3D9 pCreateD3D9 = NULL;
94 if (m_hDll)
95 pCreateD3D9 = (pFnCreateD3D9) GetProcAddress (m_hDll, TEXT ("Direct3DCreate9"));
96 else
97 return E_FAIL;
98
99 m_lpD3D9 = pCreateD3D9 (D3D_SDK_VERSION);
100
101 return bWindowed ? InitWindow (&m_hWnd) : S_OK;
102 }
103
Uninit()104 HRESULT CD3D9Utils::Uninit() {
105 SAFE_RELEASE (m_lpD3D9RawSurfaceShare);
106 SAFE_RELEASE (m_lpD3D9Device);
107 SAFE_RELEASE (m_lpD3D9);
108 SAFE_FREE (m_pDumpYUV);
109
110 if (m_hDll) {
111 FreeLibrary (m_hDll);
112 m_hDll = NULL;
113 }
114
115 return S_OK;
116 }
117
Process(void * pDst[3],SBufferInfo * pInfo,FILE * pFp)118 HRESULT CD3D9Utils::Process (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
119 HRESULT hResult = E_FAIL;
120
121 if (pDst == NULL || pInfo == NULL)
122 return hResult;
123
124 BOOL bWindowed = pFp ? FALSE : TRUE;
125 BOOL bNeedD3D9 = ! (!bWindowed);
126 if (!m_bInitDone)
127 m_bInitDone = !bNeedD3D9;
128
129 if (!m_bInitDone) {
130 hResult = Init (bWindowed);
131 if (SUCCEEDED (hResult))
132 m_bInitDone = TRUE;
133 }
134
135 if (m_bInitDone) {
136 if (bWindowed) {
137 hResult = Render (pDst, pInfo);
138 Sleep (30);
139 } else if (pFp) {
140 hResult = Dump (pDst, pInfo, pFp);
141 Sleep (0);
142 }
143 }
144
145 return hResult;
146 }
147
Render(void * pDst[3],SBufferInfo * pInfo)148 HRESULT CD3D9Utils::Render (void* pDst[3], SBufferInfo* pInfo) {
149 HRESULT hResult = E_FAIL;
150
151 if (!pInfo)
152 return E_FAIL;
153
154 if (m_nWidth != pInfo->UsrData.sSystemBuffer.iWidth
155 || m_nHeight != pInfo->UsrData.sSystemBuffer.iHeight) {
156 m_nWidth = pInfo->UsrData.sSystemBuffer.iWidth;
157 m_nHeight = pInfo->UsrData.sSystemBuffer.iHeight;
158 SAFE_RELEASE (m_lpD3D9RawSurfaceShare);
159 SAFE_RELEASE (m_lpD3D9Device);
160 }
161 hResult = InitResource (NULL, pInfo);
162 if (SUCCEEDED (hResult))
163 hResult = Dump2Surface (pDst, m_lpD3D9RawSurfaceShare, pInfo->UsrData.sSystemBuffer.iWidth,
164 pInfo->UsrData.sSystemBuffer.iHeight, pInfo->UsrData.sSystemBuffer.iStride);
165
166 if (SUCCEEDED (hResult)) {
167 IDirect3DSurface9* pBackBuffer = NULL;
168 hResult = m_lpD3D9Device->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
169 hResult = m_lpD3D9Device->StretchRect (m_lpD3D9RawSurfaceShare, NULL, pBackBuffer, NULL, D3DTEXF_NONE);
170 hResult = m_lpD3D9Device->Present (0, 0, NULL, NULL);
171 }
172
173 return hResult;
174 }
175
Dump(void * pDst[3],SBufferInfo * pInfo,FILE * pFp)176 HRESULT CD3D9Utils::Dump (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
177 HRESULT hResult = E_FAIL;
178 int iStride[2];
179 int iWidth;
180 int iHeight;
181
182 iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
183 iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
184 iStride[0] = pInfo->UsrData.sSystemBuffer.iStride[0];
185 iStride[1] = pInfo->UsrData.sSystemBuffer.iStride[1];
186
187 if (pDst[0] && pDst[1] && pDst[2])
188 Write2File (pFp, (unsigned char**)pDst, iStride, iWidth, iHeight);
189
190 return hResult;
191 }
192
InitResource(void * pSharedHandle,SBufferInfo * pInfo)193 HRESULT CD3D9Utils::InitResource (void* pSharedHandle, SBufferInfo* pInfo) {
194 HRESULT hResult = S_OK;
195
196 // coverity scan uninitial
197 int iWidth = 0;
198 int iHeight = 0;
199 D3DFORMAT D3Dformat = (D3DFORMAT)D3DFMT_UNKNOWN;
200 D3DPOOL D3Dpool = (D3DPOOL)D3DPOOL_DEFAULT;
201
202 if (pInfo == NULL)
203 return E_FAIL;
204
205 if (m_lpD3D9Device == NULL && m_lpD3D9RawSurfaceShare == NULL) {
206 HMONITOR hMonitorWnd = MonitorFromWindow (m_hWnd, MONITOR_DEFAULTTONULL);
207
208 UINT uiAdapter = D3DADAPTER_DEFAULT;
209 UINT uiCnt = m_lpD3D9->GetAdapterCount();
210 for (UINT i = 0; i < uiCnt; i++) {
211 HMONITOR hMonitor = m_lpD3D9->GetAdapterMonitor (i);
212 if (hMonitor == hMonitorWnd) {
213 uiAdapter = i;
214 break;
215 }
216 }
217
218 D3DDISPLAYMODE D3DDisplayMode;
219 hResult = m_lpD3D9->GetAdapterDisplayMode (uiAdapter, &D3DDisplayMode);
220
221 D3DDEVTYPE D3DDevType = D3DDEVTYPE_HAL;
222 DWORD dwBehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED;
223
224 ZeroMemory (&m_d3dpp, sizeof (m_d3dpp));
225 m_d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
226 m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
227 m_d3dpp.BackBufferFormat = D3DDisplayMode.Format;
228 m_d3dpp.Windowed = TRUE;
229 m_d3dpp.hDeviceWindow = m_hWnd;
230 m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
231 hResult = m_lpD3D9->CreateDevice (uiAdapter, D3DDevType, NULL, dwBehaviorFlags, &m_d3dpp, &m_lpD3D9Device);
232 iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
233 iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
234 D3Dformat = (D3DFORMAT)NV12_FORMAT;
235 D3Dpool = (D3DPOOL)D3DPOOL_DEFAULT;
236
237 hResult = m_lpD3D9Device->CreateOffscreenPlainSurface (iWidth, iHeight, (D3DFORMAT)D3Dformat, (D3DPOOL)D3Dpool,
238 &m_lpD3D9RawSurfaceShare, NULL);
239
240 }
241
242 if (m_lpD3D9Device == NULL || m_lpD3D9RawSurfaceShare == NULL)
243 hResult = E_FAIL;
244
245 return hResult;
246 }
247
CD3D9ExUtils()248 CD3D9ExUtils::CD3D9ExUtils() {
249 m_hDll = NULL;
250 m_hWnd = NULL;
251 m_pDumpYUV = NULL;
252
253 m_bInitDone = FALSE;
254
255 m_lpD3D9 = NULL;
256 m_lpD3D9Device = NULL;
257 m_lpD3D9RawSurfaceShare = NULL;
258
259 m_nWidth = 0;
260 m_nHeight = 0;
261 // coverity scan uninitial
262 ZeroMemory (&m_d3dpp, sizeof (m_d3dpp));
263 }
264
~CD3D9ExUtils()265 CD3D9ExUtils::~CD3D9ExUtils() {
266 Uninit();
267 }
268
Init(BOOL bWindowed)269 HRESULT CD3D9ExUtils::Init (BOOL bWindowed) {
270 if (m_bInitDone)
271 return S_OK;
272
273 m_hDll = LoadLibrary (TEXT ("d3d9.dll"));
274 pFnCreateD3D9Ex pCreateD3D9Ex = NULL;
275 if (m_hDll)
276 pCreateD3D9Ex = (pFnCreateD3D9Ex) GetProcAddress (m_hDll, TEXT ("Direct3DCreate9Ex"));
277 else
278 return E_FAIL;
279
280 pCreateD3D9Ex (D3D_SDK_VERSION, &m_lpD3D9);
281
282 return bWindowed ? InitWindow (&m_hWnd) : S_OK;
283 }
284
Uninit()285 HRESULT CD3D9ExUtils::Uninit() {
286 SAFE_RELEASE (m_lpD3D9RawSurfaceShare);
287 SAFE_RELEASE (m_lpD3D9Device);
288 SAFE_RELEASE (m_lpD3D9);
289 SAFE_FREE (m_pDumpYUV);
290
291 if (m_hDll) {
292 FreeLibrary (m_hDll);
293 m_hDll = NULL;
294 }
295
296 return S_OK;
297 }
298
Process(void * pDst[3],SBufferInfo * pInfo,FILE * pFp)299 HRESULT CD3D9ExUtils::Process (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
300 HRESULT hResult = E_FAIL;
301
302 if (pDst == NULL || pInfo == NULL)
303 return hResult;
304
305 BOOL bWindowed = pFp ? FALSE : TRUE;
306 BOOL bNeedD3D9 = ! (!bWindowed);
307 if (!m_bInitDone)
308 m_bInitDone = !bNeedD3D9;
309
310 if (!m_bInitDone) {
311 hResult = Init (bWindowed);
312 if (SUCCEEDED (hResult))
313 m_bInitDone = TRUE;
314 }
315
316 if (m_bInitDone) {
317 if (bWindowed) {
318 hResult = Render (pDst, pInfo);
319 Sleep (30); // set a simple time controlling with default of 30fps
320 } else if (pFp) {
321 hResult = Dump (pDst, pInfo, pFp);
322 Sleep (0);
323 }
324 }
325
326 return hResult;
327 }
328
Render(void * pDst[3],SBufferInfo * pInfo)329 HRESULT CD3D9ExUtils::Render (void* pDst[3], SBufferInfo* pInfo) {
330 HRESULT hResult = E_FAIL;
331
332 if (!pInfo)
333 return E_FAIL;
334
335 if (m_nWidth != pInfo->UsrData.sSystemBuffer.iWidth
336 || m_nHeight != pInfo->UsrData.sSystemBuffer.iHeight) {
337 m_nWidth = pInfo->UsrData.sSystemBuffer.iWidth;
338 m_nHeight = pInfo->UsrData.sSystemBuffer.iHeight;
339 MoveWindow (m_hWnd, 0, 0, pInfo->UsrData.sSystemBuffer.iWidth, pInfo->UsrData.sSystemBuffer.iHeight, true);
340 SAFE_RELEASE (m_lpD3D9RawSurfaceShare);
341 SAFE_RELEASE (m_lpD3D9Device);
342 }
343 hResult = InitResource (NULL, pInfo);
344 if (SUCCEEDED (hResult))
345 hResult = Dump2Surface (pDst, m_lpD3D9RawSurfaceShare, pInfo->UsrData.sSystemBuffer.iWidth,
346 pInfo->UsrData.sSystemBuffer.iHeight, pInfo->UsrData.sSystemBuffer.iStride);
347
348 if (SUCCEEDED (hResult)) {
349 IDirect3DSurface9* pBackBuffer = NULL;
350 hResult = m_lpD3D9Device->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
351 hResult = m_lpD3D9Device->StretchRect (m_lpD3D9RawSurfaceShare, NULL, pBackBuffer, NULL, D3DTEXF_NONE);
352 hResult = m_lpD3D9Device->PresentEx (0, 0, NULL, NULL, 0);
353 }
354
355 return hResult;
356 }
357
Dump(void * pDst[3],SBufferInfo * pInfo,FILE * pFp)358 HRESULT CD3D9ExUtils::Dump (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
359 HRESULT hResult = E_FAIL;
360 int iStride[2];
361 int iWidth;
362 int iHeight;
363
364 iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
365 iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
366 iStride[0] = pInfo->UsrData.sSystemBuffer.iStride[0];
367 iStride[1] = pInfo->UsrData.sSystemBuffer.iStride[1];
368
369 if (pDst[0] && pDst[1] && pDst[2])
370 Write2File (pFp, (unsigned char**)pDst, iStride, iWidth, iHeight);
371
372 return hResult;
373 }
374
InitResource(void * pSharedHandle,SBufferInfo * pInfo)375 HRESULT CD3D9ExUtils::InitResource (void* pSharedHandle, SBufferInfo* pInfo) {
376 HRESULT hResult = S_OK;
377 int iWidth;
378 int iHeight;
379 D3DFORMAT D3Dformat;
380 D3DPOOL D3Dpool;
381
382 if (pInfo == NULL)
383 return E_FAIL;
384
385 if (m_lpD3D9Device == NULL && m_lpD3D9RawSurfaceShare == NULL) {
386 HMONITOR hMonitorWnd = MonitorFromWindow (m_hWnd, MONITOR_DEFAULTTONULL);
387
388 UINT uiAdapter = D3DADAPTER_DEFAULT;
389 UINT uiCnt = m_lpD3D9->GetAdapterCount();
390 for (UINT i = 0; i < uiCnt; i++) {
391 HMONITOR hMonitor = m_lpD3D9->GetAdapterMonitor (i);
392 if (hMonitor == hMonitorWnd) {
393 uiAdapter = i;
394 break;
395 }
396 }
397
398 D3DDISPLAYMODEEX D3DDisplayMode;
399 D3DDisplayMode.Size = sizeof (D3DDISPLAYMODEEX);
400 hResult = m_lpD3D9->GetAdapterDisplayModeEx (uiAdapter, &D3DDisplayMode, NULL);
401
402 D3DDEVTYPE D3DDevType = D3DDEVTYPE_HAL;
403 DWORD dwBehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED;
404
405 ZeroMemory (&m_d3dpp, sizeof (m_d3dpp));
406 m_d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
407 m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
408 m_d3dpp.BackBufferFormat = D3DDisplayMode.Format;
409 m_d3dpp.Windowed = TRUE;
410 m_d3dpp.hDeviceWindow = m_hWnd;
411 m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
412 hResult = m_lpD3D9->CreateDeviceEx (uiAdapter, D3DDevType, NULL, dwBehaviorFlags, &m_d3dpp, NULL, &m_lpD3D9Device);
413 if (FAILED (hResult)) {
414 return hResult;
415 }
416 iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
417 iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
418 D3Dformat = (D3DFORMAT)NV12_FORMAT;
419 D3Dpool = (D3DPOOL)D3DPOOL_DEFAULT;
420 hResult = m_lpD3D9Device->CreateOffscreenPlainSurface (iWidth, iHeight, (D3DFORMAT)D3Dformat, (D3DPOOL)D3Dpool,
421 &m_lpD3D9RawSurfaceShare, &pSharedHandle);
422 }
423
424 if (m_lpD3D9Device == NULL || m_lpD3D9RawSurfaceShare == NULL)
425 hResult = E_FAIL;
426
427 return hResult;
428 }
429
430
Dump2Surface(void * pDst[3],void * pSurface,int iWidth,int iHeight,int iStride[2])431 HRESULT Dump2Surface (void* pDst[3], void* pSurface, int iWidth, int iHeight, int iStride[2]) {
432 HRESULT hResult = E_FAIL;
433
434 if (!pDst[0] || !pDst[1] || !pDst[2] || !pSurface)
435 return hResult;
436
437 IDirect3DSurface9* pSurfaceData = (IDirect3DSurface9*)pSurface;
438 D3DLOCKED_RECT sD3DLockedRect = {0};
439 hResult = pSurfaceData->LockRect (&sD3DLockedRect, NULL, 0);
440
441 unsigned char* pInY = (unsigned char*)pDst[0];
442 unsigned char* pOutY = (unsigned char*)sD3DLockedRect.pBits;
443 int iOutStride = sD3DLockedRect.Pitch;
444
445 for (int j = 0; j < iHeight; j++)
446 memcpy (pOutY + j * iOutStride, pInY + j * iStride[0], iWidth); //confirmed_safe_unsafe_usage
447
448 unsigned char* pInU = (unsigned char*)pDst[1];
449 unsigned char* pInV = (unsigned char*)pDst[2];
450 unsigned char* pOutC = pOutY + iOutStride * iHeight;
451 for (int i = 0; i < iHeight / 2; i++) {
452 for (int j = 0; j < iWidth; j += 2) {
453 pOutC[i * iOutStride + j ] = pInU[i * iStride[1] + j / 2];
454 pOutC[i * iOutStride + j + 1] = pInV[i * iStride[1] + j / 2];
455 }
456 }
457
458 pSurfaceData->UnlockRect();
459
460 return hResult;
461 }
462
InitWindow(HWND * hWnd)463 HRESULT InitWindow (HWND* hWnd) {
464 const TCHAR kszWindowTitle[] = TEXT ("Wels Decoder Application");
465 const TCHAR kszWindowClass[] = TEXT ("Wels Decoder Class");
466
467 WNDCLASSEX sWndClassEx = {0};
468 sWndClassEx.cbSize = sizeof (WNDCLASSEX);
469 sWndClassEx.style = CS_HREDRAW | CS_VREDRAW;
470 sWndClassEx.lpfnWndProc = (WNDPROC)WndProc;
471 sWndClassEx.cbClsExtra = 0;
472 sWndClassEx.cbWndExtra = 0;
473 sWndClassEx.hInstance = GetModuleHandle (NULL);
474 sWndClassEx.hIcon = LoadIcon (sWndClassEx.hInstance, (LPCTSTR)IDI_TESTSHARESURFACE);
475 sWndClassEx.hCursor = LoadCursor (NULL, IDC_ARROW);
476 sWndClassEx.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
477 sWndClassEx.lpszMenuName = (LPCSTR)IDC_TESTSHARESURFACE;
478 sWndClassEx.lpszClassName = kszWindowClass;
479 sWndClassEx.hIconSm = LoadIcon (sWndClassEx.hInstance, (LPCTSTR)IDI_SMALL);
480
481 if (!RegisterClassEx (&sWndClassEx))
482 return E_FAIL;
483
484 HWND hTmpWnd = CreateWindow (kszWindowClass, kszWindowTitle, WS_OVERLAPPEDWINDOW,
485 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, sWndClassEx.hInstance, NULL);
486
487 *hWnd = hTmpWnd;
488 if (!hTmpWnd)
489 return E_FAIL;
490
491 ShowWindow (hTmpWnd, SW_SHOWDEFAULT);
492 UpdateWindow (hTmpWnd);
493
494 return S_OK;
495 }
496
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)497 LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
498 INT wmId, wmEvent;
499
500 switch (message) {
501 case WM_COMMAND:
502 wmId = LOWORD (wParam);
503 wmEvent = HIWORD (wParam);
504 switch (wmId) {
505 case IDM_ABOUT:
506 break;
507 case IDM_EXIT:
508 DestroyWindow (hWnd);
509 break;
510 default:
511 return DefWindowProc (hWnd, message, wParam, lParam);
512 }
513 break;
514 case WM_PAINT:
515 ValidateRect (hWnd , NULL);
516 break;
517 case WM_DESTROY:
518 PostQuitMessage (0);
519 break;
520 default:
521 return DefWindowProc (hWnd, message, wParam, lParam);
522 }
523 return 0;
524 }
525
526 #endif
527
CUtils()528 CUtils::CUtils() {
529 hHandle = NULL;
530 iOSType = CheckOS();
531
532 #ifdef ENABLE_DISPLAY_MODULE
533 if (iOSType == OS_XP)
534 hHandle = (void*) new CD3D9Utils;
535
536 else if (iOSType == OS_VISTA_UPPER)
537 hHandle = (void*) new CD3D9ExUtils;
538 #endif
539
540 if (hHandle == NULL)
541 iOSType = OS_UNSUPPORTED;
542 }
543
~CUtils()544 CUtils::~CUtils() {
545 #ifdef ENABLE_DISPLAY_MODULE
546 if (hHandle) {
547 if (iOSType == OS_XP) {
548 CD3D9Utils* hTmp = (CD3D9Utils*) hHandle;
549 delete hTmp;
550 } else if (iOSType == OS_VISTA_UPPER) {
551 CD3D9ExUtils* hTmp = (CD3D9ExUtils*) hHandle;
552 delete hTmp;
553 }
554 hHandle = NULL;
555 }
556 #endif
557 }
558
Process(void * pDst[3],SBufferInfo * pInfo,FILE * pFp)559 int CUtils::Process (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
560
561 int iRet = 0;
562
563 if (iOSType == OS_UNSUPPORTED) {
564 if (pFp && pDst[0] && pDst[1] && pDst[2] && pInfo) {
565 int iStride[2];
566 int iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
567 int iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
568 iStride[0] = pInfo->UsrData.sSystemBuffer.iStride[0];
569 iStride[1] = pInfo->UsrData.sSystemBuffer.iStride[1];
570
571 Write2File (pFp, (unsigned char**)pDst, iStride, iWidth, iHeight);
572 }
573 }
574
575 #ifdef ENABLE_DISPLAY_MODULE
576 else {
577 MSG msg;
578 ZeroMemory (&msg, sizeof (msg));
579 while (msg.message != WM_QUIT) {
580 if (PeekMessage (&msg, NULL, 0U, 0U, PM_REMOVE)) {
581 TranslateMessage (&msg);
582 DispatchMessage (&msg);
583 } else {
584 HRESULT hResult = S_OK;
585 if (iOSType == OS_XP)
586 hResult = ((CD3D9Utils*)hHandle)->Process (pDst, pInfo, pFp);
587
588 else if (iOSType == OS_VISTA_UPPER)
589 hResult = ((CD3D9ExUtils*)hHandle)->Process (pDst, pInfo, pFp);
590
591 iRet = !SUCCEEDED (hResult);
592 break;
593 }
594 }
595 }
596 #endif
597
598 return iRet;
599 }
600
CheckOS()601 int CUtils::CheckOS() {
602 int iType = OS_UNSUPPORTED;
603
604 #ifdef ENABLE_DISPLAY_MODULE
605 OSVERSIONINFOEX osvi;
606 ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
607 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
608 osvi.dwPlatformId = VER_PLATFORM_WIN32_NT;
609 osvi.dwMajorVersion = 6; // Vista
610 DWORDLONG condmask = VerSetConditionMask (VerSetConditionMask (0, VER_MAJORVERSION, VER_GREATER_EQUAL),
611 VER_PLATFORMID, VER_EQUAL);
612
613 if (VerifyVersionInfo (&osvi, VER_MAJORVERSION | VER_PLATFORMID, condmask)) {
614 iType = OS_VISTA_UPPER;
615 } else {
616 osvi.dwMajorVersion = 5; // XP/2000
617 if (VerifyVersionInfo (&osvi, VER_MAJORVERSION | VER_PLATFORMID, condmask))
618 iType = OS_XP;
619 }
620 #endif
621
622 return iType;
623 }
624
Write2File(FILE * pFp,unsigned char * pData[3],int iStride[2],int iWidth,int iHeight)625 void Write2File (FILE* pFp, unsigned char* pData[3], int iStride[2], int iWidth, int iHeight) {
626 int i;
627 unsigned char* pPtr = NULL;
628
629 pPtr = pData[0];
630 for (i = 0; i < iHeight; i++) {
631 fwrite (pPtr, 1, iWidth, pFp);
632 pPtr += iStride[0];
633 }
634
635 iHeight = iHeight / 2;
636 iWidth = iWidth / 2;
637 pPtr = pData[1];
638 for (i = 0; i < iHeight; i++) {
639 fwrite (pPtr, 1, iWidth, pFp);
640 pPtr += iStride[1];
641 }
642
643 pPtr = pData[2];
644 for (i = 0; i < iHeight; i++) {
645 fwrite (pPtr, 1, iWidth, pFp);
646 pPtr += iStride[1];
647 }
648 }
649