| /* |
| * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "engine_configurations.h" |
| #include "video_render_windows_impl.h" |
| |
| #include "critical_section_wrapper.h" |
| #include "trace.h" |
| #ifdef DIRECTDRAW_RENDERING |
| #include "video_render_directdraw.h" |
| #endif |
| #ifdef DIRECT3D9_RENDERING |
| #include "video_render_direct3d9.h" |
| #endif |
| |
| #include <tchar.h> |
| |
| namespace webrtc { |
| |
| VideoRenderWindowsImpl::VideoRenderWindowsImpl( |
| const WebRtc_Word32 id, |
| const VideoRenderType videoRenderType, |
| void* window, |
| const bool fullscreen) : |
| _id(id), |
| _renderWindowsCritsect( |
| *CriticalSectionWrapper::CreateCriticalSection()), |
| _prtWindow(window), _fullscreen(fullscreen), _ptrRendererWin(NULL) |
| { |
| } |
| |
| VideoRenderWindowsImpl::~VideoRenderWindowsImpl() |
| { |
| delete &_renderWindowsCritsect; |
| if (_ptrRendererWin) |
| { |
| delete _ptrRendererWin; |
| _ptrRendererWin = NULL; |
| } |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::Init() |
| { |
| //LogOSAndHardwareDetails(); |
| CheckHWAcceleration(); |
| |
| _renderMethod = kVideoRenderWinD3D9; |
| |
| // Create the win renderer |
| switch (_renderMethod) |
| { |
| case kVideoRenderWinDd: |
| { |
| #ifdef DIRECTDRAW_RENDERING |
| VideoRenderDirectDraw* ptrRenderer; |
| ptrRenderer = new VideoRenderDirectDraw(NULL, (HWND) _prtWindow, _fullscreen); |
| if (ptrRenderer == NULL) |
| { |
| break; |
| } |
| _ptrRendererWin = reinterpret_cast<IVideoRenderWin*>(ptrRenderer); |
| #else |
| return NULL; |
| #endif //DIRECTDRAW_RENDERING |
| } |
| break; |
| case kVideoRenderWinD3D9: |
| { |
| #ifdef DIRECT3D9_RENDERING |
| VideoRenderDirect3D9* ptrRenderer; |
| ptrRenderer = new VideoRenderDirect3D9(NULL, (HWND) _prtWindow, _fullscreen); |
| if (ptrRenderer == NULL) |
| { |
| break; |
| } |
| _ptrRendererWin = reinterpret_cast<IVideoRenderWin*>(ptrRenderer); |
| #else |
| return NULL; |
| #endif //DIRECT3D9_RENDERING |
| } |
| break; |
| default: |
| break; |
| } |
| |
| //Init renderer |
| if (_ptrRendererWin) |
| return _ptrRendererWin->Init(); |
| else |
| return -1; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::ChangeUniqueId(const WebRtc_Word32 id) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| _id = id; |
| return 0; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::ChangeWindow(void* window) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| return -1; |
| } |
| else |
| { |
| return _ptrRendererWin->ChangeWindow(window); |
| } |
| } |
| |
| VideoRenderCallback* |
| VideoRenderWindowsImpl::AddIncomingRenderStream(const WebRtc_UWord32 streamId, |
| const WebRtc_UWord32 zOrder, |
| const float left, |
| const float top, |
| const float right, |
| const float bottom) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| VideoRenderCallback* renderCallback = NULL; |
| |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| renderCallback = _ptrRendererWin->CreateChannel(streamId, zOrder, left, |
| top, right, bottom); |
| } |
| |
| return renderCallback; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::DeleteIncomingRenderStream( |
| const WebRtc_UWord32 streamId) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| WebRtc_Word32 error = -1; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| error = _ptrRendererWin->DeleteChannel(streamId); |
| } |
| return error; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::GetIncomingRenderStreamProperties( |
| const WebRtc_UWord32 streamId, |
| WebRtc_UWord32& zOrder, |
| float& left, |
| float& top, |
| float& right, |
| float& bottom) const |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| zOrder = 0; |
| left = 0; |
| top = 0; |
| right = 0; |
| bottom = 0; |
| |
| WebRtc_Word32 error = -1; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| error = _ptrRendererWin->GetStreamSettings(streamId, 0, zOrder, left, |
| top, right, bottom); |
| } |
| return error; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::StartRender() |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| WebRtc_Word32 error = -1; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| error = _ptrRendererWin->StartRender(); |
| } |
| return error; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::StopRender() |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| WebRtc_Word32 error = -1; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| error = _ptrRendererWin->StopRender(); |
| } |
| return error; |
| } |
| |
| VideoRenderType VideoRenderWindowsImpl::RenderType() |
| { |
| return kRenderWindows; |
| } |
| |
| RawVideoType VideoRenderWindowsImpl::PerferedVideoType() |
| { |
| return kVideoI420; |
| } |
| |
| bool VideoRenderWindowsImpl::FullScreen() |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| bool fullscreen = false; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| fullscreen = _ptrRendererWin->IsFullScreen(); |
| } |
| return fullscreen; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::GetGraphicsMemory( |
| WebRtc_UWord64& totalGraphicsMemory, |
| WebRtc_UWord64& availableGraphicsMemory) const |
| { |
| if (_ptrRendererWin) |
| { |
| return _ptrRendererWin->GetGraphicsMemory(totalGraphicsMemory, |
| availableGraphicsMemory); |
| } |
| |
| totalGraphicsMemory = 0; |
| availableGraphicsMemory = 0; |
| return -1; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::GetScreenResolution( |
| WebRtc_UWord32& screenWidth, |
| WebRtc_UWord32& screenHeight) const |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| screenWidth = 0; |
| screenHeight = 0; |
| return 0; |
| } |
| |
| WebRtc_UWord32 VideoRenderWindowsImpl::RenderFrameRate( |
| const WebRtc_UWord32 streamId) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| return 0; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::SetStreamCropping( |
| const WebRtc_UWord32 streamId, |
| const float left, |
| const float top, |
| const float right, |
| const float bottom) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| WebRtc_Word32 error = -1; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| error = _ptrRendererWin->SetCropping(streamId, 0, left, top, right, |
| bottom); |
| } |
| return error; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::ConfigureRenderer( |
| const WebRtc_UWord32 streamId, |
| const unsigned int zOrder, |
| const float left, |
| const float top, |
| const float right, |
| const float bottom) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| WebRtc_Word32 error = -1; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| error = _ptrRendererWin->ConfigureRenderer(streamId, 0, zOrder, left, |
| top, right, bottom); |
| } |
| |
| return error; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::SetTransparentBackground( |
| const bool enable) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| WebRtc_Word32 error = -1; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| error = _ptrRendererWin->SetTransparentBackground(enable); |
| } |
| return error; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::SetText( |
| const WebRtc_UWord8 textId, |
| const WebRtc_UWord8* text, |
| const WebRtc_Word32 textLength, |
| const WebRtc_UWord32 textColorRef, |
| const WebRtc_UWord32 backgroundColorRef, |
| const float left, |
| const float top, |
| const float right, |
| const float bottom) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| WebRtc_Word32 error = -1; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| error = _ptrRendererWin->SetText(textId, text, textLength, |
| textColorRef, backgroundColorRef, |
| left, top, right, bottom); |
| } |
| return error; |
| } |
| |
| WebRtc_Word32 VideoRenderWindowsImpl::SetBitmap(const void* bitMap, |
| const WebRtc_UWord8 pictureId, |
| const void* colorKey, |
| const float left, |
| const float top, |
| const float right, |
| const float bottom) |
| { |
| CriticalSectionScoped cs(_renderWindowsCritsect); |
| WebRtc_Word32 error = -1; |
| if (!_ptrRendererWin) |
| { |
| WEBRTC_TRACE(kTraceModuleCall, kTraceVideoRenderer, |
| _id, "%s, no renderer", __FUNCTION__); |
| } |
| else |
| { |
| error = _ptrRendererWin->SetBitmap(bitMap, pictureId, colorKey, left, |
| top, right, bottom); |
| } |
| return error; |
| } |
| |
| void VideoRenderWindowsImpl::LogOSAndHardwareDetails() |
| { |
| HRESULT hr; |
| IDxDiagProvider* m_pDxDiagProvider = NULL; |
| IDxDiagContainer* m_pDxDiagRoot = NULL; |
| |
| hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); |
| bool coUninitializeIsRequired = true; |
| if (FAILED(hr)) |
| { |
| // Avoid calling CoUninitialize() since CoInitializeEx() failed. |
| coUninitializeIsRequired = false; |
| if (hr == RPC_E_CHANGED_MODE) |
| { |
| // Calling thread has already initialized COM to be used in a single-threaded |
| // apartment (STA). We are then prevented from using STA. |
| // Details: hr = 0x80010106 <=> "Cannot change thread mode after it is set". |
| // |
| WEBRTC_TRACE( |
| kTraceWarning, |
| kTraceVideoRenderer, |
| _id, |
| "VideoRenderWindowsImpl::LogOSAndHardwareDetails() CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) => RPC_E_CHANGED_MODE, error 0x%x", |
| hr); |
| } |
| } |
| |
| hr = CoCreateInstance(CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, |
| IID_IDxDiagProvider, (LPVOID*) &m_pDxDiagProvider); |
| |
| if (FAILED(hr) || m_pDxDiagProvider == NULL) |
| { |
| if (coUninitializeIsRequired) |
| CoUninitialize(); |
| return; |
| } |
| |
| // Fill out a DXDIAG_INIT_PARAMS struct and pass it to IDxDiagContainer::Initialize |
| // Passing in TRUE for bAllowWHQLChecks, allows dxdiag to check if drivers are |
| // digital signed as logo'd by WHQL which may connect via internet to update |
| // WHQL certificates. |
| DXDIAG_INIT_PARAMS dxDiagInitParam; |
| ZeroMemory(&dxDiagInitParam, sizeof(DXDIAG_INIT_PARAMS)); |
| |
| dxDiagInitParam.dwSize = sizeof(DXDIAG_INIT_PARAMS); |
| dxDiagInitParam.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION; |
| dxDiagInitParam.bAllowWHQLChecks = TRUE; |
| dxDiagInitParam.pReserved = NULL; |
| |
| hr = m_pDxDiagProvider->Initialize(&dxDiagInitParam); |
| if (FAILED(hr)) |
| { |
| m_pDxDiagProvider->Release(); |
| if (coUninitializeIsRequired) |
| CoUninitialize(); |
| return; |
| } |
| |
| hr = m_pDxDiagProvider->GetRootContainer(&m_pDxDiagRoot); |
| if (FAILED(hr) || m_pDxDiagRoot == NULL) |
| { |
| m_pDxDiagProvider->Release(); |
| if (coUninitializeIsRequired) |
| CoUninitialize(); |
| return; |
| } |
| |
| IDxDiagContainer* pObject = NULL; |
| |
| hr = m_pDxDiagRoot->GetChildContainer(L"DxDiag_SystemInfo", &pObject); |
| if (FAILED(hr) || pObject == NULL) |
| { |
| m_pDxDiagRoot->Release(); |
| m_pDxDiagProvider->Release(); |
| if (coUninitializeIsRequired) |
| CoUninitialize(); |
| return; |
| } |
| |
| TCHAR m_szDirectXVersionLongEnglish[100]; |
| TCHAR m_szOSLocalized[100]; |
| TCHAR m_szProcessorEnglish[200]; |
| TCHAR m_szSystemManufacturerEnglish[200]; |
| |
| ZeroMemory(m_szDirectXVersionLongEnglish, sizeof(TCHAR) * 100); |
| ZeroMemory(m_szOSLocalized, sizeof(TCHAR) * 100); |
| ZeroMemory(m_szProcessorEnglish, sizeof(TCHAR) * 200); |
| ZeroMemory(m_szSystemManufacturerEnglish, sizeof(TCHAR) * 200); |
| |
| GetStringValue( pObject, L"szDirectXVersionLongEnglish", |
| EXPAND(m_szDirectXVersionLongEnglish) ); |
| GetStringValue(pObject, L"szOSLocalized", EXPAND(m_szOSLocalized) ); |
| GetStringValue(pObject, L"szProcessorEnglish", EXPAND(m_szProcessorEnglish) ); |
| GetStringValue( pObject, L"szSystemManufacturerEnglish", |
| EXPAND(m_szSystemManufacturerEnglish) ); |
| |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "System Manufacturer --- %s", |
| m_szSystemManufacturerEnglish); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "Processor --- %s", m_szProcessorEnglish); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "Operating System --- %s", m_szOSLocalized); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "DirectX Version --- %s", |
| m_szDirectXVersionLongEnglish); |
| |
| if (pObject) |
| pObject->Release(); |
| |
| struct DisplayInfo |
| { |
| TCHAR m_szDescription[200]; |
| TCHAR m_szManufacturer[200]; |
| TCHAR m_szChipType[100]; |
| TCHAR m_szDisplayMemoryEnglish[100]; |
| TCHAR m_szDisplayModeEnglish[100]; |
| TCHAR m_szDriverName[100]; |
| TCHAR m_szDriverVersion[100]; |
| TCHAR m_szDDStatusEnglish[100]; |
| TCHAR m_szD3DStatusEnglish[100]; |
| BOOL m_bDDAccelerationEnabled; |
| BOOL m_bNoHardware; |
| BOOL m_b3DAccelerationExists; |
| BOOL m_b3DAccelerationEnabled; |
| }; |
| |
| WCHAR wszContainer[256]; |
| IDxDiagContainer* pContainer = NULL; |
| |
| DWORD nInstanceCount = 0; |
| DWORD nItem = 0; |
| DWORD nCurCount = 0; |
| |
| // Get the IDxDiagContainer object called "DxDiag_DisplayDevices". |
| // This call may take some time while dxdiag gathers the info. |
| if (FAILED(hr = m_pDxDiagRoot->GetChildContainer(L"DxDiag_DisplayDevices", |
| &pContainer))) |
| { |
| m_pDxDiagRoot->Release(); |
| m_pDxDiagProvider->Release(); |
| if (coUninitializeIsRequired) |
| CoUninitialize(); |
| return; |
| } |
| |
| if (FAILED(hr = pContainer->GetNumberOfChildContainers(&nInstanceCount))) |
| { |
| pContainer->Release(); |
| m_pDxDiagRoot->Release(); |
| m_pDxDiagProvider->Release(); |
| if (coUninitializeIsRequired) |
| CoUninitialize(); |
| return; |
| } |
| |
| DisplayInfo *pDisplayInfo = new DisplayInfo; |
| if (pDisplayInfo == NULL) |
| return; |
| ZeroMemory(pDisplayInfo, sizeof(DisplayInfo)); |
| |
| hr = pContainer->EnumChildContainerNames(nItem, wszContainer, 256); |
| if (FAILED(hr)) |
| { |
| delete pDisplayInfo; |
| pContainer->Release(); |
| m_pDxDiagRoot->Release(); |
| m_pDxDiagProvider->Release(); |
| if (coUninitializeIsRequired) |
| CoUninitialize(); |
| return; |
| } |
| |
| hr = pContainer->GetChildContainer(wszContainer, &pObject); |
| if (FAILED(hr) || pObject == NULL) |
| { |
| delete pDisplayInfo; |
| pContainer->Release(); |
| m_pDxDiagRoot->Release(); |
| m_pDxDiagProvider->Release(); |
| if (coUninitializeIsRequired) |
| CoUninitialize(); |
| return; |
| } |
| |
| GetStringValue( pObject, L"szDescription", |
| EXPAND(pDisplayInfo->m_szDescription) ); |
| GetStringValue( pObject, L"szManufacturer", |
| EXPAND(pDisplayInfo->m_szManufacturer) ); |
| GetStringValue(pObject, L"szChipType", EXPAND(pDisplayInfo->m_szChipType) ); |
| GetStringValue( pObject, L"szDisplayMemoryEnglish", |
| EXPAND(pDisplayInfo->m_szDisplayMemoryEnglish) ); |
| GetStringValue( pObject, L"szDisplayModeEnglish", |
| EXPAND(pDisplayInfo->m_szDisplayModeEnglish) ); |
| GetStringValue( pObject, L"szDriverName", |
| EXPAND(pDisplayInfo->m_szDriverName) ); |
| GetStringValue( pObject, L"szDriverVersion", |
| EXPAND(pDisplayInfo->m_szDriverVersion) ); |
| GetBoolValue(pObject, L"bDDAccelerationEnabled", |
| &pDisplayInfo->m_bDDAccelerationEnabled); |
| GetBoolValue(pObject, L"bNoHardware", &pDisplayInfo->m_bNoHardware); |
| GetBoolValue(pObject, L"bDDAccelerationEnabled", |
| &pDisplayInfo->m_bDDAccelerationEnabled); |
| GetBoolValue(pObject, L"b3DAccelerationExists", |
| &pDisplayInfo->m_b3DAccelerationExists); |
| GetBoolValue(pObject, L"b3DAccelerationEnabled", |
| &pDisplayInfo->m_b3DAccelerationEnabled); |
| GetStringValue( pObject, L"szDDStatusEnglish", |
| EXPAND(pDisplayInfo->m_szDDStatusEnglish)); |
| GetStringValue( pObject, L"szD3DStatusEnglish", |
| EXPAND(pDisplayInfo->m_szD3DStatusEnglish)); |
| |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "Device Name --- %s", |
| pDisplayInfo->m_szDescription); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "Device Manufacturer --- %s", |
| pDisplayInfo->m_szManufacturer); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "Device ChipType --- %s", |
| pDisplayInfo->m_szChipType); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "Approx. Total Device Memory --- %s", |
| pDisplayInfo->m_szDisplayMemoryEnglish); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "Current Display Mode --- %s", |
| pDisplayInfo->m_szDisplayModeEnglish); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "Device Driver Name --- %s", |
| pDisplayInfo->m_szDriverName); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "Device Driver Version --- %s", |
| pDisplayInfo->m_szDriverVersion); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "DirectDraw Acceleration Enabled --- %s", |
| pDisplayInfo->m_szDescription ? "Enabled" : "Disabled"); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "bNoHardware --- %s", |
| pDisplayInfo->m_bNoHardware ? "Enabled" : "Disabled"); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "b3DAccelerationExists Enabled --- %s", |
| pDisplayInfo->m_b3DAccelerationExists ? "Enabled" : "Disabled"); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "b3DAccelerationEnabled Enabled --- %s", |
| pDisplayInfo->m_b3DAccelerationEnabled ? "Enabled" |
| : "Disabled"); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "DDraw Status --- %s", |
| pDisplayInfo->m_szDDStatusEnglish); |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, -1, |
| "D3D Status --- %s", |
| pDisplayInfo->m_szD3DStatusEnglish); |
| |
| // Get OS version |
| OSVERSIONINFOEX osvie; |
| osvie.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); |
| GetVersionEx((LPOSVERSIONINFO) & osvie); |
| /* |
| Operating system Version number dwMajorVersion dwMinorVersion |
| Windows 7 6.1 6 1 |
| Windows Server 2008 R2 6.1 6 1 |
| Windows Server 2008 6.0 6 0 |
| Windows Vista 6.0 6 0 |
| Windows Server 2003 R2 5.2 5 2 |
| Windows Server 2003 5.2 5 2 |
| Windows XP 5.1 5 1 |
| Windows 2000 5.0 5 0 |
| */ |
| //RDP problem exists only when XP is involved |
| if (osvie.dwMajorVersion < 6) |
| { |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideoRenderer, _id, |
| "Checking for RDP driver"); |
| if (_tcsncmp(pDisplayInfo->m_szDriverName, _T("RDPDD.dll"), 9) == 0) |
| { |
| // |
| } |
| } |
| |
| if (pObject) |
| { |
| pObject->Release(); |
| pObject = NULL; |
| } |
| |
| if (pContainer) |
| pContainer->Release(); |
| |
| if (m_pDxDiagProvider) |
| m_pDxDiagProvider->Release(); |
| |
| if (m_pDxDiagRoot) |
| m_pDxDiagRoot->Release(); |
| |
| if (pDisplayInfo) |
| delete pDisplayInfo; |
| |
| if (coUninitializeIsRequired) |
| CoUninitialize(); |
| |
| return; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Name: GetStringValue() |
| // Desc: Get a string value from a IDxDiagContainer object |
| //----------------------------------------------------------------------------- |
| HRESULT VideoRenderWindowsImpl::GetStringValue(IDxDiagContainer* pObject, |
| WCHAR* wstrName, |
| TCHAR* strValue, int nStrLen) |
| { |
| HRESULT hr; |
| VARIANT var; |
| VariantInit(&var); |
| |
| if (FAILED(hr = pObject->GetProp(wstrName, &var))) |
| return hr; |
| |
| if (var.vt != VT_BSTR) |
| return E_INVALIDARG; |
| |
| #ifdef _UNICODE |
| wcsncpy( strValue, var.bstrVal, nStrLen-1 ); |
| #else |
| wcstombs(strValue, var.bstrVal, nStrLen); |
| #endif |
| strValue[nStrLen - 1] = TEXT('\0'); |
| VariantClear(&var); |
| |
| return S_OK; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Name: GetBoolValue() |
| // Desc: Get a BOOL value from a IDxDiagContainer object |
| //----------------------------------------------------------------------------- |
| HRESULT VideoRenderWindowsImpl::GetBoolValue(IDxDiagContainer* pObject, |
| WCHAR* wstrName, BOOL* pbValue) |
| { |
| HRESULT hr; |
| VARIANT var; |
| VariantInit(&var); |
| |
| if (FAILED(hr = pObject->GetProp(wstrName, &var))) |
| return hr; |
| |
| if (var.vt != VT_BOOL) |
| return E_INVALIDARG; |
| |
| *pbValue = (var.boolVal != 0); |
| VariantClear(&var); |
| |
| return S_OK; |
| } |
| |
| int VideoRenderWindowsImpl::CheckHWAcceleration() |
| { |
| // Read the registry to check if HW acceleration is enabled or not. |
| HKEY regKey; |
| DWORD value = 0; |
| DWORD valueLength = 4; |
| |
| bool directDraw = true; |
| bool direct3D = true; |
| bool dci = true; |
| |
| // DirectDraw |
| if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\DirectDraw"), |
| 0, KEY_QUERY_VALUE, ®Key) == ERROR_SUCCESS) |
| { |
| // We have the registry key |
| value = 0; |
| if (RegQueryValueEx(regKey, _T("EmulationOnly"), NULL, NULL, |
| (BYTE*) &value, &valueLength) == ERROR_SUCCESS) |
| { |
| if (value == 1) |
| { |
| WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, |
| "DirectDraw acceleration is disabled"); |
| directDraw = false; |
| } |
| else |
| { |
| WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, |
| "DirectDraw acceleration is enabled"); |
| } |
| } |
| else |
| { |
| // Could not get the value for this one. |
| WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, |
| "Could not find EmulationOnly key, DirectDraw acceleration is probably enabled"); |
| } |
| RegCloseKey(regKey); |
| } |
| else |
| { |
| WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, |
| "Could not open DirectDraw settings"); |
| } |
| |
| // Direct3D |
| if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, |
| _T("SOFTWARE\\Microsoft\\Direct3D\\Drivers"), 0, |
| KEY_QUERY_VALUE, ®Key) == ERROR_SUCCESS) |
| { |
| // We have the registry key |
| value = 0; |
| if (RegQueryValueEx(regKey, _T("SoftwareOnly"), NULL, NULL, |
| (BYTE*) &value, &valueLength) == ERROR_SUCCESS) |
| { |
| if (value == 1) |
| { |
| WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, |
| "Direct3D acceleration is disabled"); |
| direct3D = false; |
| } |
| else |
| { |
| WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, |
| "Direct3D acceleration is enabled"); |
| } |
| } |
| else |
| { |
| // Could not get the value for this one. |
| WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, |
| "Could not find SoftwarOnly key, Direct3D acceleration is probably enabled"); |
| } |
| RegCloseKey(regKey); |
| } |
| else |
| { |
| WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, |
| "Could not open Direct3D settings"); |
| } |
| |
| // DCI |
| if (RegOpenKeyEx( |
| HKEY_LOCAL_MACHINE, |
| _T( |
| "SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\DCI"), |
| 0, KEY_QUERY_VALUE, ®Key) == ERROR_SUCCESS) |
| { |
| // We have found the registry key |
| value = 0; |
| if (RegQueryValueEx(regKey, _T("Timeout"), NULL, NULL, (BYTE*) &value, |
| &valueLength) == ERROR_SUCCESS) |
| { |
| if (value == 0) |
| { |
| WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, |
| "DCI - DirectDraw acceleration is disabled"); |
| dci = false; |
| } |
| else if (value == 7) |
| { |
| WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, |
| "DCI is fully enabled"); |
| } |
| else |
| { |
| WEBRTC_TRACE( |
| kTraceWarning, |
| kTraceVideo, |
| -1, |
| "DCI - DirectDraw acceleration is enabled, but short timeout: %d", |
| value); |
| } |
| } |
| else |
| { |
| // Could not get the value for this one. |
| WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, |
| "Could not find Timeout key"); |
| } |
| RegCloseKey(regKey); |
| } |
| else |
| { |
| WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, |
| "Could not open DCI settings"); |
| } |
| |
| // We don't care about Direct3D right now... |
| if (dci == false || directDraw == false) |
| { |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| void VideoRenderWindowsImpl::CheckHWDriver(bool& badDriver, |
| bool& fullAccelerationEnabled) |
| { |
| // Read the registry to check if HW acceleration is enabled or not. |
| HKEY regKey; |
| DWORD value = 0; |
| DWORD valueLength = 4; |
| |
| //Assume the best |
| badDriver = false; |
| fullAccelerationEnabled = true; |
| |
| // Check the path to the currently used driver |
| if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\VIDEO"), 0, |
| KEY_QUERY_VALUE, ®Key) == ERROR_SUCCESS) |
| { |
| // We have found the registry key containing the driver location |
| value = 0; |
| DWORD driverPathLen = 512; |
| TCHAR driverPath[512]; |
| memset(driverPath, 0, driverPathLen * sizeof(TCHAR)); |
| DWORD dwType = REG_SZ; |
| |
| long retVal = RegQueryValueEx(regKey, _T("\\Device\\Video0"), NULL, |
| NULL, (BYTE*) driverPath, &driverPathLen); |
| |
| // Close the key... |
| RegCloseKey(regKey); |
| |
| if (retVal == ERROR_SUCCESS) |
| { |
| // We have the path to the currently used video card |
| |
| // trueDriverPath = modified nameStr, from above, that works |
| // for RegOpenKeyEx |
| TCHAR trueDriverPath[512]; |
| memset(trueDriverPath, 0, 512 * sizeof(TCHAR)); |
| |
| // Convert the path to correct format. |
| // - Remove \Registry\Machine\ |
| // - Replace '\' with '\\' |
| // Should be something like this: System\\CurrentControlSet\\Control\\Video\\{F6987E15-F12C-4B15-8C84-0F635F3F09EA}\\0000" |
| int idx = 0; |
| for (DWORD i = 18; i < (driverPathLen / sizeof(TCHAR)); i++) |
| { |
| trueDriverPath[idx++] = driverPath[i]; |
| if (driverPath[i] == _T('\\')) |
| { |
| trueDriverPath[idx++] = driverPath[i]; |
| } |
| } |
| |
| // Open the driver key |
| if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, trueDriverPath, 0, |
| KEY_QUERY_VALUE, ®Key) == ERROR_SUCCESS) |
| { |
| TCHAR driverName[64]; |
| memset(driverName, 0, 64 * sizeof(TCHAR)); |
| DWORD driverNameLength = 64; |
| retVal = RegQueryValueEx(regKey, _T("drv"), NULL, NULL, |
| (BYTE*) driverName, &driverNameLength); |
| if (retVal == ERROR_SUCCESS) |
| { |
| WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, |
| "Graphics card driver name: %s", driverName); |
| } |
| DWORD accLevel = 0; |
| DWORD accLevelS = sizeof(accLevel); |
| |
| RegQueryValueEx(regKey, _T("Acceleration.Level"), NULL, NULL, |
| (LPBYTE) & accLevel, &accLevelS); |
| //Don't care if the key is not found. It probably means that acceleration is enabled |
| if (accLevel != 0) |
| { |
| // Close the key... |
| RegCloseKey(regKey); |
| |
| if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, trueDriverPath, 0, |
| KEY_SET_VALUE, ®Key) == ERROR_SUCCESS) |
| { |
| // try setting it to full |
| accLevel = 0; |
| LONG retVal; |
| retVal = RegSetValueEx(regKey, |
| _T("Acceleration.Level"), NULL, |
| REG_DWORD, (PBYTE) & accLevel, |
| sizeof(DWORD)); |
| if (retVal != ERROR_SUCCESS) |
| { |
| fullAccelerationEnabled = false; |
| } |
| else |
| { |
| RegQueryValueEx(regKey, _T("Acceleration.Level"), |
| NULL, NULL, (LPBYTE) & accLevel, |
| &accLevelS); |
| if (accLevel != 0) |
| { |
| fullAccelerationEnabled = false; |
| } |
| else |
| { |
| fullAccelerationEnabled = true; |
| } |
| } |
| } |
| else |
| { |
| fullAccelerationEnabled = false; |
| } |
| } |
| else |
| { |
| fullAccelerationEnabled = true; |
| } |
| |
| // Close the key... |
| RegCloseKey(regKey); |
| } |
| } |
| } |
| } |
| |
| } //namespace webrtc |
| |