ref: bc3c63c4319949a9da0257d4a195de43987a5db5
dir: /codec/console/dec/src/d3d9_utils.cpp/
/*! * \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 Dump2YUV(void *pDst[3], void *pSurface, int iWidth, int iHeight, int iStride[2]); 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 && pInfo->eBufferProperty == BUFFER_HOST); 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; EBufferProperty eBufferProperty = pInfo->eBufferProperty; if (eBufferProperty == BUFFER_HOST) { 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; EBufferProperty eBufferProperty = pInfo->eBufferProperty; 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); if (pInfo->eBufferProperty == BUFFER_HOST) { 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 && pInfo->eBufferProperty == BUFFER_HOST); 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; EBufferProperty eBufferProperty = pInfo->eBufferProperty; if (eBufferProperty == BUFFER_HOST) { hResult = InitResource(NULL, pInfo); if (SUCCEEDED(hResult)) hResult = Dump2Surface(pDst, m_lpD3D9RawSurfaceShare, pInfo->UsrData.sSystemBuffer.iWidth, pInfo->UsrData.sSystemBuffer.iHeight, pInfo->UsrData.sSystemBuffer.iStride); } else if (eBufferProperty == BUFFER_DEVICE) { VOID * pSharedHandle = pDst[0]; hResult = InitResource(pSharedHandle, pInfo); } 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; EBufferProperty eBufferProperty = pInfo->eBufferProperty; int iStride[2]; int iWidth; int iHeight; if (eBufferProperty != BUFFER_HOST) { iWidth = pInfo->UsrData.sVideoBuffer.iSurfaceWidth; iHeight = pInfo->UsrData.sVideoBuffer.iSurfaceHeight; iStride[0] = iWidth; iStride[1] = iWidth / 2; if (m_pDumpYUV == NULL) { m_pDumpYUV = (unsigned char *)malloc(iWidth * iHeight * 3 / 2 * sizeof(unsigned char)); } if (m_pDumpYUV) { void *pSurface = pDst[1]; pDst[0] = m_pDumpYUV; pDst[1] = m_pDumpYUV + iHeight * iStride[0] * sizeof(unsigned char); pDst[2] = m_pDumpYUV + iHeight * iStride[0] * 5 / 4 * sizeof(unsigned char); hResult = Dump2YUV(pDst, pSurface, iWidth, iHeight, iStride); } } else { 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); if (pInfo->eBufferProperty == BUFFER_HOST) { iWidth = pInfo->UsrData.sSystemBuffer.iWidth; iHeight = pInfo->UsrData.sSystemBuffer.iHeight; D3Dformat = (D3DFORMAT)NV12_FORMAT; D3Dpool = (D3DPOOL)D3DPOOL_DEFAULT; } else { iWidth = pInfo->UsrData.sVideoBuffer.iSurfaceWidth; iHeight = pInfo->UsrData.sVideoBuffer.iSurfaceHeight; D3Dformat = (D3DFORMAT)pInfo->UsrData.sVideoBuffer.D3Dformat; D3Dpool = (D3DPOOL)pInfo->UsrData.sVideoBuffer.D3DPool; } 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 Dump2YUV(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 *)sD3DLockedRect.pBits; unsigned char * pOutY = (unsigned char *)pDst[0]; int iInStride = sD3DLockedRect.Pitch; int iOutStride = iStride[0]; for (int j=0; j<iHeight; j++) memcpy(pOutY+j*iOutStride, pInY+j*iInStride, iWidth);//confirmed_safe_unsafe_usage unsigned char * pOutV = (unsigned char *)pDst[1]; unsigned char * pOutU = (unsigned char *)pDst[2]; unsigned char * pInC = pInY + iInStride * iHeight; iOutStride = iStride[1]; for (int i=0; i<iHeight/2; i++) { for (int j=0; j<iWidth; j+=2) { pOutV[i*iOutStride+j/2] = pInC[i*iInStride+j ]; pOutU[i*iOutStride+j/2] = pInC[i*iInStride+j+1]; } } pSurfaceData->UnlockRect(); 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 * pInV = (unsigned char *)pDst[1]; unsigned char * pInU = (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 ] = pInV[i*iStride[1]+j/2]; pOutC[i*iOutStride+j+1] = pInU[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]; } }