blob: 6f2237fd3f62262e96662b8a6d3a34ea97222a46 [file] [log] [blame]
/*
* Copyright (c) 2012 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)
{
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)
{
}
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)
{
}
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)
{
}
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)
{
}
else
{
error = _ptrRendererWin->StartRender();
}
return error;
}
WebRtc_Word32 VideoRenderWindowsImpl::StopRender()
{
CriticalSectionScoped cs(_renderWindowsCritsect);
WebRtc_Word32 error = -1;
if (!_ptrRendererWin)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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, &regKey) == 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, &regKey) == 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, &regKey) == 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, &regKey) == 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, &regKey) == 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, &regKey) == 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