55d7491f3d
There is no implementation available for actually doing decoding in HW.
628 lines
18 KiB
C++
628 lines
18 KiB
C++
/*!
|
|
* \copy
|
|
* Copyright (c) 2013, Cisco Systems
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include "d3d9_utils.h"
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void Write2File (FILE* pFp, unsigned char* pData[3], int iStride[2], int iWidth, int iHeight);
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef ENABLE_DISPLAY_MODULE
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#define IDM_ABOUT 104
|
|
#define IDM_EXIT 105
|
|
#define IDI_TESTSHARESURFACE 107
|
|
#define IDI_SMALL 108
|
|
#define IDC_TESTSHARESURFACE 109
|
|
|
|
#define NV12_FORMAT MAKEFOURCC('N','V','1','2')
|
|
|
|
typedef struct {
|
|
UINT uiWidth;
|
|
UINT uiHeight;
|
|
D3DFORMAT D3Dformat;
|
|
D3DPOOL D3DPool;
|
|
} SHandleInfo;
|
|
|
|
#define SAFE_RELEASE(p) if(p) { (p)->Release(); (p) = NULL; }
|
|
#define SAFE_FREE(p) if(p) { free (p); (p) = NULL; }
|
|
|
|
HRESULT Dump2Surface (void* pDst[3], void* pSurface, int iWidth, int iHeight, int iStride[2]);
|
|
HRESULT InitWindow (HWND* hWnd);
|
|
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
|
|
|
|
typedef HRESULT (WINAPI* pFnCreateD3D9Ex) (UINT SDKVersion, IDirect3D9Ex**);
|
|
typedef LPDIRECT3D9 (WINAPI* pFnCreateD3D9) (UINT SDKVersion);
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CD3D9Utils::CD3D9Utils() {
|
|
m_hDll = NULL;
|
|
m_hWnd = NULL;
|
|
m_pDumpYUV = NULL;
|
|
|
|
m_bInitDone = FALSE;
|
|
|
|
m_lpD3D9 = NULL;
|
|
m_lpD3D9Device = NULL;
|
|
m_lpD3D9RawSurfaceShare = NULL;
|
|
|
|
// coverity scan uninitial
|
|
ZeroMemory (&m_d3dpp, sizeof (m_d3dpp));
|
|
}
|
|
|
|
CD3D9Utils::~CD3D9Utils() {
|
|
Uninit();
|
|
}
|
|
|
|
HRESULT CD3D9Utils::Init (BOOL bWindowed) {
|
|
if (m_bInitDone)
|
|
return S_OK;
|
|
|
|
m_hDll = LoadLibrary (TEXT ("d3d9.dll"));
|
|
pFnCreateD3D9 pCreateD3D9 = NULL;
|
|
if (m_hDll)
|
|
pCreateD3D9 = (pFnCreateD3D9) GetProcAddress (m_hDll, TEXT ("Direct3DCreate9"));
|
|
else
|
|
return E_FAIL;
|
|
|
|
m_lpD3D9 = pCreateD3D9 (D3D_SDK_VERSION);
|
|
|
|
return bWindowed ? InitWindow (&m_hWnd) : S_OK;
|
|
}
|
|
|
|
HRESULT CD3D9Utils::Uninit() {
|
|
SAFE_RELEASE (m_lpD3D9RawSurfaceShare);
|
|
SAFE_RELEASE (m_lpD3D9Device);
|
|
SAFE_RELEASE (m_lpD3D9);
|
|
SAFE_FREE (m_pDumpYUV);
|
|
|
|
if (m_hDll) {
|
|
FreeLibrary (m_hDll);
|
|
m_hDll = NULL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CD3D9Utils::Process (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
|
|
HRESULT hResult = E_FAIL;
|
|
|
|
if (pDst == NULL || pInfo == NULL)
|
|
return hResult;
|
|
|
|
BOOL bWindowed = pFp ? FALSE : TRUE;
|
|
BOOL bNeedD3D9 = ! (!bWindowed);
|
|
if (!m_bInitDone)
|
|
m_bInitDone = !bNeedD3D9;
|
|
|
|
if (!m_bInitDone) {
|
|
hResult = Init (bWindowed);
|
|
if (SUCCEEDED (hResult))
|
|
m_bInitDone = TRUE;
|
|
}
|
|
|
|
if (m_bInitDone) {
|
|
if (bWindowed) {
|
|
hResult = Render (pDst, pInfo);
|
|
Sleep (30);
|
|
} else if (pFp) {
|
|
hResult = Dump (pDst, pInfo, pFp);
|
|
Sleep (0);
|
|
}
|
|
}
|
|
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT CD3D9Utils::Render (void* pDst[3], SBufferInfo* pInfo) {
|
|
HRESULT hResult = E_FAIL;
|
|
|
|
hResult = InitResource (NULL, pInfo);
|
|
if (SUCCEEDED (hResult))
|
|
hResult = Dump2Surface (pDst, m_lpD3D9RawSurfaceShare, pInfo->UsrData.sSystemBuffer.iWidth,
|
|
pInfo->UsrData.sSystemBuffer.iHeight, pInfo->UsrData.sSystemBuffer.iStride);
|
|
|
|
if (SUCCEEDED (hResult)) {
|
|
IDirect3DSurface9* pBackBuffer = NULL;
|
|
hResult = m_lpD3D9Device->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
|
|
hResult = m_lpD3D9Device->StretchRect (m_lpD3D9RawSurfaceShare, NULL, pBackBuffer, NULL, D3DTEXF_NONE);
|
|
hResult = m_lpD3D9Device->Present (0, 0, NULL, NULL);
|
|
}
|
|
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT CD3D9Utils::Dump (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
|
|
HRESULT hResult = E_FAIL;
|
|
int iStride[2];
|
|
int iWidth;
|
|
int iHeight;
|
|
|
|
iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
|
|
iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
|
|
iStride[0] = pInfo->UsrData.sSystemBuffer.iStride[0];
|
|
iStride[1] = pInfo->UsrData.sSystemBuffer.iStride[1];
|
|
|
|
if (pDst[0] && pDst[1] && pDst[2])
|
|
Write2File (pFp, (unsigned char**)pDst, iStride, iWidth, iHeight);
|
|
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT CD3D9Utils::InitResource (void* pSharedHandle, SBufferInfo* pInfo) {
|
|
HRESULT hResult = S_OK;
|
|
|
|
// coverity scan uninitial
|
|
int iWidth = 0;
|
|
int iHeight = 0;
|
|
D3DFORMAT D3Dformat = (D3DFORMAT)D3DFMT_UNKNOWN;
|
|
D3DPOOL D3Dpool = (D3DPOOL)D3DPOOL_DEFAULT;
|
|
|
|
if (pInfo == NULL)
|
|
return E_FAIL;
|
|
|
|
if (m_lpD3D9Device == NULL && m_lpD3D9RawSurfaceShare == NULL) {
|
|
HMONITOR hMonitorWnd = MonitorFromWindow (m_hWnd, MONITOR_DEFAULTTONULL);
|
|
|
|
UINT uiAdapter = D3DADAPTER_DEFAULT;
|
|
UINT uiCnt = m_lpD3D9->GetAdapterCount();
|
|
for (UINT i = 0; i < uiCnt; i++) {
|
|
HMONITOR hMonitor = m_lpD3D9->GetAdapterMonitor (i);
|
|
if (hMonitor == hMonitorWnd) {
|
|
uiAdapter = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
D3DDISPLAYMODE D3DDisplayMode;
|
|
hResult = m_lpD3D9->GetAdapterDisplayMode (uiAdapter, &D3DDisplayMode);
|
|
|
|
D3DDEVTYPE D3DDevType = D3DDEVTYPE_HAL;
|
|
DWORD dwBehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED;
|
|
|
|
ZeroMemory (&m_d3dpp, sizeof (m_d3dpp));
|
|
m_d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
|
|
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
m_d3dpp.BackBufferFormat = D3DDisplayMode.Format;
|
|
m_d3dpp.Windowed = TRUE;
|
|
m_d3dpp.hDeviceWindow = m_hWnd;
|
|
m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
|
hResult = m_lpD3D9->CreateDevice (uiAdapter, D3DDevType, NULL, dwBehaviorFlags, &m_d3dpp, &m_lpD3D9Device);
|
|
iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
|
|
iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
|
|
D3Dformat = (D3DFORMAT)NV12_FORMAT;
|
|
D3Dpool = (D3DPOOL)D3DPOOL_DEFAULT;
|
|
|
|
hResult = m_lpD3D9Device->CreateOffscreenPlainSurface (iWidth, iHeight, (D3DFORMAT)D3Dformat, (D3DPOOL)D3Dpool,
|
|
&m_lpD3D9RawSurfaceShare, NULL);
|
|
|
|
}
|
|
|
|
if (m_lpD3D9Device == NULL || m_lpD3D9RawSurfaceShare == NULL)
|
|
hResult = E_FAIL;
|
|
|
|
return hResult;
|
|
}
|
|
|
|
CD3D9ExUtils::CD3D9ExUtils() {
|
|
m_hDll = NULL;
|
|
m_hWnd = NULL;
|
|
m_pDumpYUV = NULL;
|
|
|
|
m_bInitDone = FALSE;
|
|
|
|
m_lpD3D9 = NULL;
|
|
m_lpD3D9Device = NULL;
|
|
m_lpD3D9RawSurfaceShare = NULL;
|
|
|
|
// coverity scan uninitial
|
|
ZeroMemory (&m_d3dpp, sizeof (m_d3dpp));
|
|
}
|
|
|
|
CD3D9ExUtils::~CD3D9ExUtils() {
|
|
Uninit();
|
|
}
|
|
|
|
HRESULT CD3D9ExUtils::Init (BOOL bWindowed) {
|
|
if (m_bInitDone)
|
|
return S_OK;
|
|
|
|
m_hDll = LoadLibrary (TEXT ("d3d9.dll"));
|
|
pFnCreateD3D9Ex pCreateD3D9Ex = NULL;
|
|
if (m_hDll)
|
|
pCreateD3D9Ex = (pFnCreateD3D9Ex) GetProcAddress (m_hDll, TEXT ("Direct3DCreate9Ex"));
|
|
else
|
|
return E_FAIL;
|
|
|
|
pCreateD3D9Ex (D3D_SDK_VERSION, &m_lpD3D9);
|
|
|
|
return bWindowed ? InitWindow (&m_hWnd) : S_OK;
|
|
}
|
|
|
|
HRESULT CD3D9ExUtils::Uninit() {
|
|
SAFE_RELEASE (m_lpD3D9RawSurfaceShare);
|
|
SAFE_RELEASE (m_lpD3D9Device);
|
|
SAFE_RELEASE (m_lpD3D9);
|
|
SAFE_FREE (m_pDumpYUV);
|
|
|
|
if (m_hDll) {
|
|
FreeLibrary (m_hDll);
|
|
m_hDll = NULL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CD3D9ExUtils::Process (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
|
|
HRESULT hResult = E_FAIL;
|
|
|
|
if (pDst == NULL || pInfo == NULL)
|
|
return hResult;
|
|
|
|
BOOL bWindowed = pFp ? FALSE : TRUE;
|
|
BOOL bNeedD3D9 = ! (!bWindowed);
|
|
if (!m_bInitDone)
|
|
m_bInitDone = !bNeedD3D9;
|
|
|
|
if (!m_bInitDone) {
|
|
hResult = Init (bWindowed);
|
|
if (SUCCEEDED (hResult))
|
|
m_bInitDone = TRUE;
|
|
}
|
|
|
|
if (m_bInitDone) {
|
|
if (bWindowed) {
|
|
hResult = Render (pDst, pInfo);
|
|
Sleep (30); // set a simple time controlling with default of 30fps
|
|
} else if (pFp) {
|
|
hResult = Dump (pDst, pInfo, pFp);
|
|
Sleep (0);
|
|
}
|
|
}
|
|
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT CD3D9ExUtils::Render (void* pDst[3], SBufferInfo* pInfo) {
|
|
HRESULT hResult = E_FAIL;
|
|
|
|
hResult = InitResource (NULL, pInfo);
|
|
if (SUCCEEDED (hResult))
|
|
hResult = Dump2Surface (pDst, m_lpD3D9RawSurfaceShare, pInfo->UsrData.sSystemBuffer.iWidth,
|
|
pInfo->UsrData.sSystemBuffer.iHeight, pInfo->UsrData.sSystemBuffer.iStride);
|
|
|
|
if (SUCCEEDED (hResult)) {
|
|
IDirect3DSurface9* pBackBuffer = NULL;
|
|
hResult = m_lpD3D9Device->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
|
|
hResult = m_lpD3D9Device->StretchRect (m_lpD3D9RawSurfaceShare, NULL, pBackBuffer, NULL, D3DTEXF_NONE);
|
|
hResult = m_lpD3D9Device->PresentEx (0, 0, NULL, NULL, 0);
|
|
}
|
|
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT CD3D9ExUtils::Dump (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
|
|
HRESULT hResult = E_FAIL;
|
|
int iStride[2];
|
|
int iWidth;
|
|
int iHeight;
|
|
|
|
iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
|
|
iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
|
|
iStride[0] = pInfo->UsrData.sSystemBuffer.iStride[0];
|
|
iStride[1] = pInfo->UsrData.sSystemBuffer.iStride[1];
|
|
|
|
if (pDst[0] && pDst[1] && pDst[2])
|
|
Write2File (pFp, (unsigned char**)pDst, iStride, iWidth, iHeight);
|
|
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT CD3D9ExUtils::InitResource (void* pSharedHandle, SBufferInfo* pInfo) {
|
|
HRESULT hResult = S_OK;
|
|
int iWidth;
|
|
int iHeight;
|
|
D3DFORMAT D3Dformat;
|
|
D3DPOOL D3Dpool;
|
|
|
|
if (pInfo == NULL)
|
|
return E_FAIL;
|
|
|
|
if (m_lpD3D9Device == NULL && m_lpD3D9RawSurfaceShare == NULL) {
|
|
HMONITOR hMonitorWnd = MonitorFromWindow (m_hWnd, MONITOR_DEFAULTTONULL);
|
|
|
|
UINT uiAdapter = D3DADAPTER_DEFAULT;
|
|
UINT uiCnt = m_lpD3D9->GetAdapterCount();
|
|
for (UINT i = 0; i < uiCnt; i++) {
|
|
HMONITOR hMonitor = m_lpD3D9->GetAdapterMonitor (i);
|
|
if (hMonitor == hMonitorWnd) {
|
|
uiAdapter = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
D3DDISPLAYMODEEX D3DDisplayMode;
|
|
D3DDisplayMode.Size = sizeof (D3DDISPLAYMODEEX);
|
|
hResult = m_lpD3D9->GetAdapterDisplayModeEx (uiAdapter, &D3DDisplayMode, NULL);
|
|
|
|
D3DDEVTYPE D3DDevType = D3DDEVTYPE_HAL;
|
|
DWORD dwBehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED;
|
|
|
|
ZeroMemory (&m_d3dpp, sizeof (m_d3dpp));
|
|
m_d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
|
|
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
m_d3dpp.BackBufferFormat = D3DDisplayMode.Format;
|
|
m_d3dpp.Windowed = TRUE;
|
|
m_d3dpp.hDeviceWindow = m_hWnd;
|
|
m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
|
hResult = m_lpD3D9->CreateDeviceEx (uiAdapter, D3DDevType, NULL, dwBehaviorFlags, &m_d3dpp, NULL, &m_lpD3D9Device);
|
|
iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
|
|
iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
|
|
D3Dformat = (D3DFORMAT)NV12_FORMAT;
|
|
D3Dpool = (D3DPOOL)D3DPOOL_DEFAULT;
|
|
hResult = m_lpD3D9Device->CreateOffscreenPlainSurface (iWidth, iHeight, (D3DFORMAT)D3Dformat, (D3DPOOL)D3Dpool,
|
|
&m_lpD3D9RawSurfaceShare, &pSharedHandle);
|
|
}
|
|
|
|
if (m_lpD3D9Device == NULL || m_lpD3D9RawSurfaceShare == NULL)
|
|
hResult = E_FAIL;
|
|
|
|
return hResult;
|
|
}
|
|
|
|
|
|
HRESULT Dump2Surface (void* pDst[3], void* pSurface, int iWidth, int iHeight, int iStride[2]) {
|
|
HRESULT hResult = E_FAIL;
|
|
|
|
if (!pDst[0] || !pDst[1] || !pDst[2] || !pSurface)
|
|
return hResult;
|
|
|
|
IDirect3DSurface9* pSurfaceData = (IDirect3DSurface9*)pSurface;
|
|
D3DLOCKED_RECT sD3DLockedRect = {0};
|
|
hResult = pSurfaceData->LockRect (&sD3DLockedRect, NULL, 0);
|
|
|
|
unsigned char* pInY = (unsigned char*)pDst[0];
|
|
unsigned char* pOutY = (unsigned char*)sD3DLockedRect.pBits;
|
|
int iOutStride = sD3DLockedRect.Pitch;
|
|
|
|
for (int j = 0; j < iHeight; j++)
|
|
memcpy (pOutY + j * iOutStride, pInY + j * iStride[0], iWidth); //confirmed_safe_unsafe_usage
|
|
|
|
unsigned char* pInU = (unsigned char*)pDst[1];
|
|
unsigned char* pInV = (unsigned char*)pDst[2];
|
|
unsigned char* pOutC = pOutY + iOutStride * iHeight;
|
|
for (int i = 0; i < iHeight / 2; i++) {
|
|
for (int j = 0; j < iWidth; j += 2) {
|
|
pOutC[i * iOutStride + j ] = pInU[i * iStride[1] + j / 2];
|
|
pOutC[i * iOutStride + j + 1] = pInV[i * iStride[1] + j / 2];
|
|
}
|
|
}
|
|
|
|
pSurfaceData->UnlockRect();
|
|
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT InitWindow (HWND* hWnd) {
|
|
const TCHAR kszWindowTitle[] = TEXT ("Wels Decoder Application");
|
|
const TCHAR kszWindowClass[] = TEXT ("Wels Decoder Class");
|
|
|
|
WNDCLASSEX sWndClassEx = {0};
|
|
sWndClassEx.cbSize = sizeof (WNDCLASSEX);
|
|
sWndClassEx.style = CS_HREDRAW | CS_VREDRAW;
|
|
sWndClassEx.lpfnWndProc = (WNDPROC)WndProc;
|
|
sWndClassEx.cbClsExtra = 0;
|
|
sWndClassEx.cbWndExtra = 0;
|
|
sWndClassEx.hInstance = GetModuleHandle (NULL);
|
|
sWndClassEx.hIcon = LoadIcon (sWndClassEx.hInstance, (LPCTSTR)IDI_TESTSHARESURFACE);
|
|
sWndClassEx.hCursor = LoadCursor (NULL, IDC_ARROW);
|
|
sWndClassEx.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
|
|
sWndClassEx.lpszMenuName = (LPCSTR)IDC_TESTSHARESURFACE;
|
|
sWndClassEx.lpszClassName = kszWindowClass;
|
|
sWndClassEx.hIconSm = LoadIcon (sWndClassEx.hInstance, (LPCTSTR)IDI_SMALL);
|
|
|
|
if (!RegisterClassEx (&sWndClassEx))
|
|
return E_FAIL;
|
|
|
|
HWND hTmpWnd = CreateWindow (kszWindowClass, kszWindowTitle, WS_OVERLAPPEDWINDOW,
|
|
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, sWndClassEx.hInstance, NULL);
|
|
|
|
*hWnd = hTmpWnd;
|
|
if (!hTmpWnd)
|
|
return E_FAIL;
|
|
|
|
ShowWindow (hTmpWnd, SW_SHOWDEFAULT);
|
|
UpdateWindow (hTmpWnd);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
|
INT wmId, wmEvent;
|
|
|
|
switch (message) {
|
|
case WM_COMMAND:
|
|
wmId = LOWORD (wParam);
|
|
wmEvent = HIWORD (wParam);
|
|
switch (wmId) {
|
|
case IDM_ABOUT:
|
|
break;
|
|
case IDM_EXIT:
|
|
DestroyWindow (hWnd);
|
|
break;
|
|
default:
|
|
return DefWindowProc (hWnd, message, wParam, lParam);
|
|
}
|
|
break;
|
|
case WM_PAINT:
|
|
ValidateRect (hWnd , NULL);
|
|
break;
|
|
case WM_DESTROY:
|
|
PostQuitMessage (0);
|
|
break;
|
|
default:
|
|
return DefWindowProc (hWnd, message, wParam, lParam);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
CUtils::CUtils() {
|
|
hHandle = NULL;
|
|
iOSType = CheckOS();
|
|
|
|
#ifdef ENABLE_DISPLAY_MODULE
|
|
if (iOSType == OS_XP)
|
|
hHandle = (void*) new CD3D9Utils;
|
|
|
|
else if (iOSType == OS_VISTA_UPPER)
|
|
hHandle = (void*) new CD3D9ExUtils;
|
|
#endif
|
|
|
|
if (hHandle == NULL)
|
|
iOSType = OS_UNSUPPORTED;
|
|
}
|
|
|
|
CUtils::~CUtils() {
|
|
#ifdef ENABLE_DISPLAY_MODULE
|
|
if (hHandle) {
|
|
if (iOSType == OS_XP) {
|
|
CD3D9Utils* hTmp = (CD3D9Utils*) hHandle;
|
|
delete hTmp;
|
|
} else if (iOSType == OS_VISTA_UPPER) {
|
|
CD3D9ExUtils* hTmp = (CD3D9ExUtils*) hHandle;
|
|
delete hTmp;
|
|
}
|
|
hHandle = NULL;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
int CUtils::Process (void* pDst[3], SBufferInfo* pInfo, FILE* pFp) {
|
|
|
|
int iRet = 0;
|
|
|
|
if (iOSType == OS_UNSUPPORTED) {
|
|
if (pFp && pDst[0] && pDst[1] && pDst[2] && pInfo) {
|
|
int iStride[2];
|
|
int iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
|
|
int iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
|
|
iStride[0] = pInfo->UsrData.sSystemBuffer.iStride[0];
|
|
iStride[1] = pInfo->UsrData.sSystemBuffer.iStride[1];
|
|
|
|
Write2File (pFp, (unsigned char**)pDst, iStride, iWidth, iHeight);
|
|
}
|
|
}
|
|
|
|
#ifdef ENABLE_DISPLAY_MODULE
|
|
else {
|
|
MSG msg;
|
|
ZeroMemory (&msg, sizeof (msg));
|
|
while (msg.message != WM_QUIT) {
|
|
if (PeekMessage (&msg, NULL, 0U, 0U, PM_REMOVE)) {
|
|
TranslateMessage (&msg);
|
|
DispatchMessage (&msg);
|
|
} else {
|
|
HRESULT hResult = S_OK;
|
|
if (iOSType == OS_XP)
|
|
hResult = ((CD3D9Utils*)hHandle)->Process (pDst, pInfo, pFp);
|
|
|
|
else if (iOSType == OS_VISTA_UPPER)
|
|
hResult = ((CD3D9ExUtils*)hHandle)->Process (pDst, pInfo, pFp);
|
|
|
|
iRet = !SUCCEEDED (hResult);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int CUtils::CheckOS() {
|
|
int iType = OS_UNSUPPORTED;
|
|
|
|
#ifdef ENABLE_DISPLAY_MODULE
|
|
OSVERSIONINFOEX osvi;
|
|
ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
|
|
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
|
|
|
|
if (!GetVersionEx ((OSVERSIONINFO*) &osvi)) {
|
|
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
|
|
if (! GetVersionEx ((OSVERSIONINFO*) &osvi))
|
|
return iType;
|
|
}
|
|
|
|
switch (osvi.dwPlatformId) {
|
|
case VER_PLATFORM_WIN32_NT:
|
|
if (osvi.dwMajorVersion >= 6)
|
|
iType = OS_VISTA_UPPER;
|
|
else if (osvi.dwMajorVersion == 5)
|
|
iType = OS_XP;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
return iType;
|
|
}
|
|
|
|
void Write2File (FILE* pFp, unsigned char* pData[3], int iStride[2], int iWidth, int iHeight) {
|
|
int i;
|
|
unsigned char* pPtr = NULL;
|
|
|
|
pPtr = pData[0];
|
|
for (i = 0; i < iHeight; i++) {
|
|
fwrite (pPtr, 1, iWidth, pFp);
|
|
pPtr += iStride[0];
|
|
}
|
|
|
|
iHeight = iHeight / 2;
|
|
iWidth = iWidth / 2;
|
|
pPtr = pData[1];
|
|
for (i = 0; i < iHeight; i++) {
|
|
fwrite (pPtr, 1, iWidth, pFp);
|
|
pPtr += iStride[1];
|
|
}
|
|
|
|
pPtr = pData[2];
|
|
for (i = 0; i < iHeight; i++) {
|
|
fwrite (pPtr, 1, iWidth, pFp);
|
|
pPtr += iStride[1];
|
|
}
|
|
}
|