From 5c01b18c759435e90e92fc300e97dc01345a4f6f Mon Sep 17 00:00:00 2001 From: "wu@webrtc.org" Date: Thu, 13 Sep 2012 22:43:10 +0000 Subject: [PATCH] Remove DD renderer, which we no longer maintain. Review URL: https://webrtc-codereview.appspot.com/796005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2771 4adac7df-926f-26a2-2b94-8c16560cd09d --- src/engine_configurations.h | 1 - .../main/source/video_render.gypi | 4 - .../source/windows/video_render_directdraw.cc | 3950 ----------------- .../source/windows/video_render_directdraw.h | 399 -- .../windows/video_render_windows_impl.cc | 635 --- .../windows/video_render_windows_impl.h | 15 +- 6 files changed, 2 insertions(+), 5002 deletions(-) delete mode 100644 src/modules/video_render/main/source/windows/video_render_directdraw.cc delete mode 100644 src/modules/video_render/main/source/windows/video_render_directdraw.h diff --git a/src/engine_configurations.h b/src/engine_configurations.h index 691ccf43a3..35dec151f0 100644 --- a/src/engine_configurations.h +++ b/src/engine_configurations.h @@ -118,7 +118,6 @@ // ---------------------------------------------------------------------------- #if defined(_WIN32) -// #define DIRECTDRAW_RENDERING #define DIRECT3D9_RENDERING // Requires DirectX 9. #endif diff --git a/src/modules/video_render/main/source/video_render.gypi b/src/modules/video_render/main/source/video_render.gypi index 12e7b21f8c..fd1aae41b2 100644 --- a/src/modules/video_render/main/source/video_render.gypi +++ b/src/modules/video_render/main/source/video_render.gypi @@ -56,7 +56,6 @@ # Windows 'windows/i_video_render_win.h', 'windows/video_render_direct3d9.h', - 'windows/video_render_directdraw.h', 'windows/video_render_windows_impl.h', # External 'external/video_render_external_impl.h', @@ -84,7 +83,6 @@ 'mac/cocoa_full_screen_window.mm', # Windows 'windows/video_render_direct3d9.cc', - 'windows/video_render_directdraw.cc', 'windows/video_render_windows_impl.cc', # External 'external/video_render_external_impl.cc', @@ -147,10 +145,8 @@ 'sources!': [ 'windows/i_video_render_win.h', 'windows/video_render_direct3d9.h', - 'windows/video_render_directdraw.h', 'windows/video_render_windows_impl.h', 'windows/video_render_direct3d9.cc', - 'windows/video_render_directdraw.cc', 'windows/video_render_windows_impl.cc', ], }], diff --git a/src/modules/video_render/main/source/windows/video_render_directdraw.cc b/src/modules/video_render/main/source/windows/video_render_directdraw.cc deleted file mode 100644 index f597d0e4a6..0000000000 --- a/src/modules/video_render/main/source/windows/video_render_directdraw.cc +++ /dev/null @@ -1,3950 +0,0 @@ -/* - * 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 "video_render_directdraw.h" -#include "video_render_windows_impl.h" -#include "Windows.h" -#include -#include -#include -#include // timeGetTime -DEFINE_GUID( IID_IDirectDraw7,0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b ); - -#include "thread_wrapper.h" -#include "event_wrapper.h" -#include "trace.h" -#include "critical_section_wrapper.h" -//#include "VideoErrors.h" - -// Added -#include "module_common_types.h" - -#pragma warning(disable: 4355) // 'this' : used in base member initializer list -// picture in picture do we need overlay? answer no we can blit directly -// conference is easy since we can blt the quadrants seperatly - -// To determine if the driver supports DMA, retrieve the driver capabilities by calling the IDirectDraw::GetCaps method, -// then look for DDBLTCAPS_READSYSMEM and/or DDBLTCAPS_WRITESYSMEM. If either of these flags is set, the device supports DMA. -// Blt with SRCCOPY should do this can we use it? -// investigate DDLOCK_NOSYSLOCK - -namespace webrtc { - -#define EXTRACT_BITS_RL(the_val, bits_start, bits_len) ((the_val >> (bits_start - 1)) & ((1 << bits_len) - 1)) - -WindowsThreadCpuUsage::WindowsThreadCpuUsage() : - _lastGetCpuUsageTime(0), - _lastCpuUsageTime(0), - _hThread(::GetCurrentThread()), - _cores(0), - _lastCpuUsage(0) -{ - - DWORD_PTR pmask, smask; - DWORD access = PROCESS_QUERY_INFORMATION; - if (GetProcessAffinityMask( - OpenProcess(access, false, GetCurrentProcessId()), - &pmask, &smask) != 0) - { - - for (int i = 1; i < 33; i++) - { - if (EXTRACT_BITS_RL(pmask,i,1) == 0) - { - break; - } - _cores++; - } - //sanity - if (_cores > 32) - { - _cores = 32; - } - if (_cores < 1) - { - _cores = 1; - } - } - else - { - _cores = 1; - } - GetCpuUsage(); -} - -//in % since last call -int WindowsThreadCpuUsage::GetCpuUsage() -{ - DWORD now = timeGetTime(); - - _int64 newTime = 0; - FILETIME creationTime; - FILETIME exitTime; - _int64 kernelTime = 0; - _int64 userTime = 0; - if (GetThreadTimes(_hThread, (FILETIME*) &creationTime, &exitTime, - (FILETIME*) &kernelTime, (FILETIME*) &userTime) != 0) - { - newTime = (kernelTime + userTime); - } - if (newTime == 0) - { - _lastGetCpuUsageTime = now; - return _lastCpuUsage; - } - - // calculate the time difference since last call - const DWORD diffTime = (now - _lastGetCpuUsageTime); - _lastGetCpuUsageTime = now; - - if (newTime < _lastCpuUsageTime) - { - _lastCpuUsageTime = newTime; - return _lastCpuUsage; - } - const int cpuDiff = (int) (newTime - _lastCpuUsageTime) / 10000; - _lastCpuUsageTime = newTime; - - // calculate the CPU usage - - _lastCpuUsage = (int) (float((cpuDiff * 100)) / (diffTime * _cores) + 0.5f); - - if (_lastCpuUsage > 100) - { - _lastCpuUsage = 100; - } - return _lastCpuUsage; - -} - -DirectDrawStreamSettings::DirectDrawStreamSettings() : - _startWidth(0.0F), - _stopWidth(1.0F), - _startHeight(0.0F), - _stopHeight(1.0F), - _cropStartWidth(0.0F), - _cropStopWidth(1.0F), - _cropStartHeight(0.0F), - _cropStopHeight(1.0F) -{ -} -; - -DirectDrawBitmapSettings::DirectDrawBitmapSettings() : - _transparentBitMap(NULL), - _transparentBitmapLeft(0.0f), - _transparentBitmapRight(1.0f), - _transparentBitmapTop(0.0f), - _transparentBitmapBottom(1.0f), - _transparentBitmapWidth(0), - _transparentBitmapHeight(0), - _transparentBitmapColorKey(NULL), - _transparentBitmapSurface(NULL) -{ -} -; - -DirectDrawBitmapSettings::~DirectDrawBitmapSettings() -{ - if (_transparentBitmapColorKey) - { - delete _transparentBitmapColorKey; - } - if (_transparentBitmapSurface) - { - _transparentBitmapSurface->Release(); - } - _transparentBitmapColorKey = NULL; - _transparentBitmapSurface = NULL; -} -; - -int DirectDrawBitmapSettings::SetBitmap(Trace* _trace, - DirectDraw* directDraw) -{ - VideoFrame tempVideoBuffer; - HGDIOBJ oldhand; - BITMAPINFO pbi; - BITMAP bmap; - HDC hdcNew; - - hdcNew = CreateCompatibleDC(0); - - // Fill out the BITMAP structure. - GetObject(_transparentBitMap, sizeof(bmap), &bmap); - - //Select the bitmap handle into the new device context. - oldhand = SelectObject(hdcNew, (HGDIOBJ) _transparentBitMap); - - // we are done with this object - DeleteObject(oldhand); - - pbi.bmiHeader.biSize = 40; - pbi.bmiHeader.biWidth = bmap.bmWidth; - pbi.bmiHeader.biHeight = bmap.bmHeight; - pbi.bmiHeader.biPlanes = 1; - pbi.bmiHeader.biBitCount = bmap.bmBitsPixel; - pbi.bmiHeader.biCompression = BI_RGB; - pbi.bmiHeader.biSizeImage = bmap.bmWidth * bmap.bmHeight * 3; - - tempVideoBuffer.VerifyAndAllocate(bmap.bmWidth * bmap.bmHeight * 4); - - // the original un-stretched image in RGB24 - // todo is there another struct for pbi purify reports read of 24 bytes larger than size - int pixelHeight = GetDIBits(hdcNew, _transparentBitMap, 0, bmap.bmHeight, - tempVideoBuffer.Buffer(), &pbi, DIB_RGB_COLORS); - if (pixelHeight == 0) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to GetDIBits in SetBitmap."); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - - DeleteDC(hdcNew); - - if (pbi.bmiHeader.biBitCount != 24 && pbi.bmiHeader.biBitCount != 32) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to SetBitmap invalid bit depth"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - - DirectDrawSurfaceDesc ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; - ddsd.dwHeight = bmap.bmHeight; - ddsd.dwWidth = bmap.bmWidth; - - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; - - _transparentBitmapWidth = bmap.bmWidth; - _transparentBitmapHeight = bmap.bmHeight; - - ddsd.ddpfPixelFormat.dwRGBBitCount = 32; - ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000; - ddsd.ddpfPixelFormat.dwGBitMask = 0xff00; - ddsd.ddpfPixelFormat.dwBBitMask = 0xff; - ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0; - - if (_transparentBitmapSurface) - { - _transparentBitmapSurface->Release(); - _transparentBitmapSurface = NULL; - } - - HRESULT ddrval = - directDraw->CreateSurface(&ddsd, &_transparentBitmapSurface, NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _transparentBitmapSurface: 0x%x", - ddrval); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(DDSURFACEDESC); - ddrval = _transparentBitmapSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL); - if (ddrval == DDERR_SURFACELOST) - { - ddrval = _transparentBitmapSurface->Restore(); - if (ddrval != DD_OK) - { - WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, - "DirectDraw failed to restore lost _transparentBitmapSurface"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw restored lost _transparentBitmapSurface"); - - ddrval - = _transparentBitmapSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, - NULL); - if (ddrval != DD_OK) - { - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "DirectDraw lock error 0x%x _transparentBitmapSurface", - ddrval); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - } - unsigned char* dstPtr = (unsigned char*) ddsd.lpSurface; - unsigned char* srcPtr = (unsigned char*) tempVideoBuffer.Buffer(); - - int pitch = bmap.bmWidth * 4; - if (ddsd.dwFlags & DDSD_PITCH) - { - pitch = ddsd.lPitch; - } - - if (pbi.bmiHeader.biBitCount == 24) - { - ConvertRGB24ToARGB(srcPtr, dstPtr, bmap.bmWidth, bmap.bmHeight, - 0); - } - else - { - srcPtr += (bmap.bmWidth * 4) * (bmap.bmHeight - 1); - - for (int i = 0; i < bmap.bmHeight; ++i) - { - memcpy(dstPtr, srcPtr, bmap.bmWidth * 4); - srcPtr -= bmap.bmWidth * 4; - dstPtr += pitch; - } - } - - _transparentBitmapSurface->Unlock(NULL); - return 0; -} -/** - * - * DirectDrawTextSettings - * - */ -DirectDrawTextSettings::DirectDrawTextSettings() : - _ptrText(NULL), - _textLength(0), - _colorRefText(RGB(255, 255, 255)), // white - _colorRefBackground(RGB(0, 0, 0)), // black - _textLeft(0.0f), - _textRight(0.0f), - _textTop(0.0f), - _textBottom(0.0f), - _transparent(true) -{ -} - -DirectDrawTextSettings::~DirectDrawTextSettings() -{ - if (_ptrText) - { - delete[] _ptrText; - } -} - -int DirectDrawTextSettings::SetText(const char* text, int textLength, - COLORREF colorText, COLORREF colorBg, - float left, float top, float right, - float bottom) -{ - if (_ptrText) - { - delete[] _ptrText; - } - _ptrText = new char[textLength]; - memcpy(_ptrText, text, textLength); - _textLength = textLength; - _colorRefText = colorText; - _colorRefBackground = colorBg; - //_transparent = transparent; - _textLeft = left; - _textRight = right; - _textTop = top; - _textBottom = bottom; - return 0; -} - -/** - * - * DirectDrawChannel - * - * - */ - -// this need to have a refcount dueto multiple HWNDS demux -DirectDrawChannel::DirectDrawChannel(DirectDraw* directDraw, - VideoType blitVideoType, - VideoType incomingVideoType, - VideoType screenVideoType, - VideoRenderDirectDraw* owner) - : _critSect(CriticalSectionWrapper::CreateCriticalSection()), - _refCount(1), - _width(0), - _height(0), - _numberOfStreams(0), - _doubleBuffer(false), - _directDraw(directDraw), - _offScreenSurface(NULL), - _offScreenSurfaceNext(NULL), - _incomingVideoType(incomingVideoType), - _blitVideoType(blitVideoType), - _originalBlitVideoType(blitVideoType), - _screenVideoType(screenVideoType), - _deliverInScreenType(false), - _offScreenSurfaceUpdated(false), - _owner(owner) { - _directDraw->AddRef(); -} - -DirectDrawChannel::~DirectDrawChannel() -{ - if (_directDraw) - { - _directDraw->Release(); - } - if (_offScreenSurface) - { - _offScreenSurface->Release(); - } - if (_offScreenSurfaceNext) - { - _offScreenSurfaceNext->Release(); - } - std::map::iterator it = - _streamIdToSettings.begin(); - while (it != _streamIdToSettings.end()) - { - DirectDrawStreamSettings* streamSettings = it->second; - if (streamSettings) - { - delete streamSettings; - } - it = _streamIdToSettings.erase(it); - } - delete _critSect; -} - -void DirectDrawChannel::AddRef() -{ - CriticalSectionScoped cs(_critSect); - _refCount++; -} - -void DirectDrawChannel::Release() -{ - bool deleteObj = false; - _critSect->Enter(); - _refCount--; - if (_refCount == 0) - { - deleteObj = true; - } - _critSect->Leave(); - - if (deleteObj) - { - delete this; - } -} - -void DirectDrawChannel::SetStreamSettings(VideoRenderDirectDraw* DDobj, - short streamId, float startWidth, - float startHeight, - float stopWidth, float stopHeight) -{ - // we can save 5 bits due to 16 byte alignment of the pointer - unsigned long long lookupID = reinterpret_cast (DDobj); - lookupID &= 0xffffffffffffffe0; - lookupID <<= 11; - lookupID += streamId; - - CriticalSectionScoped cs(_critSect); - - DirectDrawStreamSettings* streamSettings = NULL; - - std::map::iterator it = - _streamIdToSettings.find(lookupID); - if (it == _streamIdToSettings.end()) - { - streamSettings = new DirectDrawStreamSettings(); - _streamIdToSettings[lookupID] = streamSettings; - } - else - { - streamSettings = it->second; - } - - streamSettings->_startHeight = startHeight; - streamSettings->_startWidth = startWidth; - streamSettings->_stopWidth = stopWidth; - streamSettings->_stopHeight = stopHeight; - - _offScreenSurfaceUpdated = false; -} - -void DirectDrawChannel::SetStreamCropSettings(VideoRenderDirectDraw* DDObj, - short streamId, - float startWidth, - float startHeight, - float stopWidth, - float stopHeight) -{ - unsigned long long lookupID = reinterpret_cast (DDObj); - lookupID &= 0xffffffffffffffe0; - lookupID <<= 11; - lookupID += streamId; - - CriticalSectionScoped cs(_critSect); - - DirectDrawStreamSettings* streamSettings = NULL; - std::map::iterator it = - _streamIdToSettings.find(lookupID); - if (it == _streamIdToSettings.end()) - { - streamSettings = new DirectDrawStreamSettings(); - _streamIdToSettings[streamId] = streamSettings; - } - else - { - streamSettings = it->second; - } - streamSettings->_cropStartWidth = startWidth; - streamSettings->_cropStopWidth = stopWidth; - streamSettings->_cropStartHeight = startHeight; - streamSettings->_cropStopHeight = stopHeight; -} - -int DirectDrawChannel::GetStreamSettings(VideoRenderDirectDraw* DDObj, - short streamId, float& startWidth, - float& startHeight, - float& stopWidth, - float& stopHeight) -{ - CriticalSectionScoped cs(_critSect); - - unsigned long long lookupID = reinterpret_cast (DDObj); - lookupID &= 0xffffffffffffffe0; - lookupID <<= 11; - lookupID += streamId; - - DirectDrawStreamSettings* streamSettings = NULL; - std::map::iterator it = - _streamIdToSettings.find(lookupID); - if (it == _streamIdToSettings.end()) - { - // Didn't find this stream... - return -1; - } - streamSettings = it->second; - startWidth = streamSettings->_startWidth; - startHeight = streamSettings->_startHeight; - stopWidth = streamSettings->_stopWidth; - stopHeight = streamSettings->_stopHeight; - - return 0; -} - -bool DirectDrawChannel::IsOffScreenSurfaceUpdated(VideoRenderDirectDraw* DDobj) -{ - CriticalSectionScoped cs(_critSect); - return _offScreenSurfaceUpdated; -} - -void DirectDrawChannel::GetLargestSize(RECT* mixingRect) -{ - CriticalSectionScoped cs(_critSect); - if (mixingRect) - { - if (mixingRect->bottom < _height) - { - mixingRect->bottom = _height; - } - if (mixingRect->right < _width) - { - mixingRect->right = _width; - } - } -} - -int DirectDrawChannel::ChangeDeliverColorFormat(bool useScreenType) -{ - _deliverInScreenType = useScreenType; - return FrameSizeChange(0, 0, 0); -} - -WebRtc_Word32 DirectDrawChannel::RenderFrame(const WebRtc_UWord32 streamId, - VideoFrame& videoFrame) -{ - CriticalSectionScoped cs(_critSect); - if (_width != videoFrame.Width() || _height != videoFrame.Height()) - { - if (FrameSizeChange(videoFrame.Width(), videoFrame.Height(), 1) == -1) - { - return -1; - } - } - return DeliverFrame(videoFrame.Buffer(), videoFrame.Length(), - videoFrame.TimeStamp()); -} - -int DirectDrawChannel::FrameSizeChange(int width, int height, - int numberOfStreams) -{ - CriticalSectionScoped cs(_critSect); - - if (_directDraw == NULL) - { - return -1; // signal that we are not ready for the change - } - if (_width == width && _height == height && _offScreenSurface - && _offScreenSurfaceNext) - { - _numberOfStreams = numberOfStreams; - return 0; - } - if (_offScreenSurface) - { - _offScreenSurface->Release(); - _offScreenSurface = NULL; - } - if (_offScreenSurfaceNext) - { - _offScreenSurfaceNext->Release(); - _offScreenSurfaceNext = NULL; - } - if (width && height) - { - _width = width; - _height = height; - _numberOfStreams = numberOfStreams; - } - - // create this channels offscreen buffer - DirectDrawSurfaceDesc ddsd; - HRESULT ddrval = DD_OK; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; - ddsd.dwHeight = _height; - ddsd.dwWidth = _width; - /* - char logStr[256]; - _snprintf(logStr,256, "offscreen H:%d W:%d \n",_height, _width); - OutputDebugString(logStr); - */ - //Fix for bad video driver on HP Mini. If it takes to long time to deliver a frame - try to blit using the same pixel format as used by the screen. - if (_deliverInScreenType && _screenVideoType != kUnknown) - { - //The HP mini netbook, which this fix for, uses the VIA processor. - //The measuring shows that this fix will impact systems with Intel processor, including Atom. - //So let's disable it here. If we really need this for VIA processor, we should have additional logic to detect - //the processor model. - //WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, "DirectDrawChannel changing to screen video type"); - //_blitVideoType=_screenVideoType; - } - else - { - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "DirectDrawChannel changing to originial blit video type %d", - _originalBlitVideoType); - _blitVideoType = _originalBlitVideoType; - } - - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "DirectDrawChannel::FrameSizeChange height %d, width %d, _blitVideoType %d", - ddsd.dwHeight, ddsd.dwWidth, _blitVideoType); - switch (_blitVideoType) - { - case kYV12: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; - ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y', 'V', '1', '2'); - } - break; - case kYUY2: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; - ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y', 'U', 'Y', '2'); - } - break; - case kUYVY: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; - ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('U', 'Y', 'V', 'Y'); - } - break; - case kIYUV: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; - ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('I', 'Y', 'U', 'V'); - } - break; - case kARGB: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; - ddsd.ddpfPixelFormat.dwRGBBitCount = 32; - ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000; - ddsd.ddpfPixelFormat.dwGBitMask = 0xff00; - ddsd.ddpfPixelFormat.dwBBitMask = 0xff; - ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0; - } - break; - case kRGB24: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; - ddsd.ddpfPixelFormat.dwRGBBitCount = 24; - ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000; - ddsd.ddpfPixelFormat.dwGBitMask = 0xff00; - ddsd.ddpfPixelFormat.dwBBitMask = 0xff; - ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0; - } - break; - case kRGB565: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; - ddsd.ddpfPixelFormat.dwRGBBitCount = 16; - ddsd.ddpfPixelFormat.dwRBitMask = 0x0000F800; - ddsd.ddpfPixelFormat.dwGBitMask = 0x000007e0; - ddsd.ddpfPixelFormat.dwBBitMask = 0x0000001F; - ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0; - } - break; - case kARGB4444: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; - ddsd.ddpfPixelFormat.dwRGBBitCount = 16; - ddsd.ddpfPixelFormat.dwRBitMask = 0x00000f00; - ddsd.ddpfPixelFormat.dwGBitMask = 0x000000f0; - ddsd.ddpfPixelFormat.dwBBitMask = 0x0000000f; - ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0; - break; - } - case kARGB1555: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; - ddsd.ddpfPixelFormat.dwRGBBitCount = 16; - ddsd.ddpfPixelFormat.dwRBitMask = 0x00007C00; - ddsd.ddpfPixelFormat.dwGBitMask = 0x3E0; - ddsd.ddpfPixelFormat.dwBBitMask = 0x1F; - ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0; - break; - } - case kI420: - { - ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; - ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('I', '4', '2', '0'); - } - break; - default: - ddrval = S_FALSE; - } - - if (ddrval == DD_OK) - { - if (!_owner->IsPrimaryOrMixingSurfaceOnSystem()) - { - ddrval - = _directDraw->CreateSurface(&ddsd, &_offScreenSurface, - NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "CreateSurface failed for _offScreenSurface on VideoMemory, trying on System Memory"); - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - - ddsd.dwHeight = _height; - ddsd.dwWidth = _width; - - ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; - _blitVideoType = kARGB; - - ddrval = _directDraw->CreateSurface(&ddsd, &_offScreenSurface, - NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _offScreenSurface using SystemMemory: 0x%x", - ddrval); - } - ddrval = _directDraw->CreateSurface(&ddsd, - &_offScreenSurfaceNext, - NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _offScreenSurfaceNext using SystemMemory: 0x%x", - ddrval); - } - } - else - { - ddrval = _directDraw->CreateSurface(&ddsd, - &_offScreenSurfaceNext, - NULL); - if (ddrval == DDERR_OUTOFVIDEOMEMORY) - { - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "CreateSurface failed for _offScreenSurfaceNext on VideoMemory, trying on System Memory"); - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - - ddsd.dwHeight = _height; - ddsd.dwWidth = _width; - - ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; - _blitVideoType = kARGB; - - ddrval = _directDraw->CreateSurface(&ddsd, - &_offScreenSurfaceNext, - NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _offScreenSurfaceNext using SystemMemory: 0x%x", - ddrval); - } - } - } - } - else - { - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - - ddsd.dwHeight = _height; - ddsd.dwWidth = _width; - - ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; - if (_owner->CanBltFourCC()) - { - _blitVideoType = kARGB; - } - else - { - _blitVideoType = _originalBlitVideoType; - } - - ddrval - = _directDraw->CreateSurface(&ddsd, &_offScreenSurface, - NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _offScreenSurface using SystemMemory: 0x%x", - ddrval); - } - - ddrval = _directDraw->CreateSurface(&ddsd, &_offScreenSurfaceNext, - NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _offScreenSurfaceNext using SystemMemory: 0x%x", - ddrval); - } - } - } - - if (FAILED(ddrval)) - { - // failed to change size - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to CreateSurface : 0x%x", ddrval); - return -1; - } - - return 0; -} - -int DirectDrawChannel::DeliverFrame(unsigned char* buffer, int bufferSize, - unsigned int /*timeStamp90KHz*/) -{ - CriticalSectionScoped cs(_critSect); - - if (CalcBufferSize(_incomingVideoType, _width, _height) - != bufferSize) - { - // sanity - return -1; - } - if (!_offScreenSurface || !_offScreenSurfaceNext) - { - if (_width && _height && _numberOfStreams) - { - // our surface was lost recreate it - FrameSizeChange(_width, _height, _numberOfStreams); - } - return -1; - } - if (_offScreenSurface->IsLost() == DDERR_SURFACELOST) - { - HRESULT ddrval = _offScreenSurface->Restore(); - if (ddrval != DD_OK) - { - // failed to restore our surface remove it and it will be re-created in next frame - _offScreenSurface->Release(); - _offScreenSurface = NULL; - _offScreenSurfaceNext->Release(); - _offScreenSurfaceNext = NULL; - return -1; - } - ddrval = _offScreenSurfaceNext->Restore(); - if (ddrval != DD_OK) - { - // failed to restore our surface remove it and it will be re-created in next frame - _offScreenSurface->Release(); - _offScreenSurface = NULL; - _offScreenSurfaceNext->Release(); - _offScreenSurfaceNext = NULL; - return -1; - } - } - _doubleBuffer = false; - - // check if _offScreenSurfaceUpdated is true - DirectDrawSurface* offScreenSurface = _offScreenSurface; - { - - if (_offScreenSurfaceUpdated) - { - // this frame is not yet rendered - offScreenSurface = _offScreenSurfaceNext; - _doubleBuffer = true; - } - } - - DirectDrawSurfaceDesc ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - HRESULT ddrval = offScreenSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL); - if (ddrval == DDERR_SURFACELOST) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDrawChannel::DeliverFrame offScreenSurface lost"); - ddrval = offScreenSurface->Restore(); - if (ddrval != DD_OK) - { - // failed to restore our surface remove it and it will be re-created in next frame - _offScreenSurface->Release(); - _offScreenSurface = NULL; - _offScreenSurfaceNext->Release(); - _offScreenSurfaceNext = NULL; - return -1; - } - return 0; - } - if (ddrval != DD_OK) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDrawChannel::DeliverFrame failed to lock"); - // failed to lock our surface remove it and it will be re-created in next frame - _offScreenSurface->Release(); - _offScreenSurface = NULL; - _offScreenSurfaceNext->Release(); - _offScreenSurfaceNext = NULL; - return -1; - } - - int ret = 0; - if (_incomingVideoType == kI420) { - unsigned char* ptr = static_cast(ddsd.lpSurface); - ret = ConvertFromI420(buffer, ddsd.lPitch, _blitVideoType, 0, - _width, _height, ptr); - } else { - assert(false && - "DirectDrawChannel::DeliverFrame wrong incoming video type"); - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "%s wrong incoming video type:%d", - __FUNCTION__, _incomingVideoType); - ret = -1; - } - _offScreenSurfaceUpdated = true; - offScreenSurface->Unlock(NULL); - return ret; -} - -int DirectDrawChannel::BlitFromOffscreenBufferToMixingBuffer( - VideoRenderDirectDraw* DDobj, - short streamID, - DirectDrawSurface* mixingSurface, - RECT &hwndRect, - bool demuxing) -{ - HRESULT ddrval; - RECT srcRect; - RECT dstRect; - DirectDrawStreamSettings* streamSettings = NULL; - unsigned long long lookupID = reinterpret_cast (DDobj); - lookupID &= 0xffffffffffffffe0; - lookupID <<= 11; - lookupID += streamID; - - CriticalSectionScoped cs(_critSect); - - if (_offScreenSurface == NULL) - { - // The offscreen surface has been deleted but not restored yet - return 0; - } - if (mixingSurface == NULL) - { - // Not a valid input argument - return 0; - } - - std::map::iterator it = - _streamIdToSettings.find(lookupID); - if (it == _streamIdToSettings.end()) - { - // ignore this stream id - return 0; - } - streamSettings = it->second; - - int numberOfStreams = _numberOfStreams; - if (!demuxing) - { - numberOfStreams = 1; // treat as one stream if we only have one config - } - - switch (numberOfStreams) - { - case 0: - return 0; - case 1: - { - // no demux - if (streamID > 0) - return 0; - - ::SetRect(&srcRect, int(_width * streamSettings->_cropStartWidth), - int(_height * streamSettings->_cropStartHeight), - int(_width * streamSettings->_cropStopWidth), int(_height - * streamSettings->_cropStopHeight)); - - ::SetRect(&dstRect, int(hwndRect.right - * streamSettings->_startWidth), int(hwndRect.bottom - * streamSettings->_startHeight), int(hwndRect.right - * streamSettings->_stopWidth), int(hwndRect.bottom - * streamSettings->_stopHeight)); - } - break; - case 2: - case 3: - case 4: - // classic quadrant demux - { - int width = _width >> 1; - int height = _height >> 1; - ::SetRect(&srcRect, int(width * streamSettings->_cropStartWidth), - int(height * streamSettings->_cropStartHeight), int(width - * streamSettings->_cropStopWidth), int(height - * streamSettings->_cropStopHeight)); - - ::SetRect(&dstRect, int(hwndRect.right - * streamSettings->_startWidth), int(hwndRect.bottom - * streamSettings->_startHeight), int(hwndRect.right - * streamSettings->_stopWidth), int(hwndRect.bottom - * streamSettings->_stopHeight)); - - // stream id to select quadrant - if (streamID == 1) - { - ::OffsetRect(&srcRect, width, 0); - } - if (streamID == 2) - { - ::OffsetRect(&srcRect, 0, height); - } - if (streamID == 3) - { - ::OffsetRect(&srcRect, width, height); - } - } - break; - case 5: - case 6: - { - const int width = (_width / (3 * 16)) * 16; - const int widthMidCol = width + ((_width % (16 * 3)) / 16) * 16; - const int height = _height / (2 * 16) * 16; - if (streamID == 1 || streamID == 4) - { - ::SetRect(&srcRect, int(widthMidCol - * streamSettings->_cropStartWidth), int(height - * streamSettings->_cropStartHeight), int(widthMidCol - * streamSettings->_cropStopWidth), int(height - * streamSettings->_cropStopHeight)); - } - else - { - ::SetRect(&srcRect, - int(width * streamSettings->_cropStartWidth), - int(height * streamSettings->_cropStartHeight), - int(width * streamSettings->_cropStopWidth), - int(height * streamSettings->_cropStopHeight)); - } - ::SetRect(&dstRect, int(hwndRect.right - * streamSettings->_startWidth), int(hwndRect.bottom - * streamSettings->_startHeight), int(hwndRect.right - * streamSettings->_stopWidth), int(hwndRect.bottom - * streamSettings->_stopHeight)); - - // stream id to select quadrant - switch (streamID) - { - case 1: - ::OffsetRect(&srcRect, width, 0); - break; - case 2: - ::OffsetRect(&srcRect, width + widthMidCol, 0); - break; - case 3: - ::OffsetRect(&srcRect, 0, height); - break; - case 4: - ::OffsetRect(&srcRect, width, height); - break; - case 5: - ::OffsetRect(&srcRect, width + widthMidCol, height); - break; - } - } - break; - case 7: - case 8: - case 9: - - { - const int width = (_width / (3 * 16)) * 16; - const int widthMidCol = width + ((_width % (16 * 3)) / 16) * 16; - const int height = _height / (3 * 16) * 16; - const int heightMidRow = height + ((_height % (16 * 3)) / 16) * 16; - - ::SetRect(&dstRect, int(hwndRect.right - * streamSettings->_startWidth), int(hwndRect.bottom - * streamSettings->_startHeight), int(hwndRect.right - * streamSettings->_stopWidth), int(hwndRect.bottom - * streamSettings->_stopHeight)); - - switch (streamID) - { - case 0: - //Size - ::SetRect(&srcRect, int(width - * streamSettings->_cropStartWidth), int(height - * streamSettings->_cropStartHeight), int(width - * streamSettings->_cropStopWidth), int(height - * streamSettings->_cropStopHeight)); - //Position - ::OffsetRect(&srcRect, 0, 0); - break; - case 1: - ::SetRect( - &srcRect, - int(widthMidCol * streamSettings->_cropStartWidth), - int(height * streamSettings->_cropStartHeight), - int(widthMidCol * streamSettings->_cropStopWidth), - int(height * streamSettings->_cropStopHeight)); - ::OffsetRect(&srcRect, width, 0); - break; - case 2: - ::SetRect(&srcRect, int(width - * streamSettings->_cropStartWidth), int(height - * streamSettings->_cropStartHeight), int(width - * streamSettings->_cropStopWidth), int(height - * streamSettings->_cropStopHeight)); - ::OffsetRect(&srcRect, width + widthMidCol, 0); - break; - case 3: - ::SetRect(&srcRect, int(width - * streamSettings->_cropStartWidth), - int(heightMidRow - * streamSettings->_cropStartHeight), - int(width * streamSettings->_cropStopWidth), - int(heightMidRow - * streamSettings->_cropStopHeight)); - ::OffsetRect(&srcRect, 0, height); - break; - case 4: - ::SetRect( - &srcRect, - int(widthMidCol * streamSettings->_cropStartWidth), - int(heightMidRow - * streamSettings->_cropStartHeight), - int(widthMidCol * streamSettings->_cropStopWidth), - int(heightMidRow - * streamSettings->_cropStopHeight)); - ::OffsetRect(&srcRect, width, height); - - break; - case 5: - ::SetRect(&srcRect, int(width - * streamSettings->_cropStartWidth), - int(heightMidRow - * streamSettings->_cropStartHeight), - int(width * streamSettings->_cropStopWidth), - int(heightMidRow - * streamSettings->_cropStopHeight)); - ::OffsetRect(&srcRect, width + widthMidCol, height); - break; - case 6: - ::SetRect(&srcRect, int(width - * streamSettings->_cropStartWidth), int(height - * streamSettings->_cropStartHeight), int(width - * streamSettings->_cropStopWidth), int(height - * streamSettings->_cropStopHeight)); - ::OffsetRect(&srcRect, 0, height + heightMidRow); - break; - case 7: - ::SetRect( - &srcRect, - int(widthMidCol * streamSettings->_cropStartWidth), - int(height * streamSettings->_cropStartHeight), - int(widthMidCol * streamSettings->_cropStopWidth), - int(height * streamSettings->_cropStopHeight)); - ::OffsetRect(&srcRect, width, height + heightMidRow); - break; - case 8: - ::SetRect(&srcRect, int(width - * streamSettings->_cropStartWidth), int(height - * streamSettings->_cropStartHeight), int(width - * streamSettings->_cropStopWidth), int(height - * streamSettings->_cropStopHeight)); - ::OffsetRect(&srcRect, width + widthMidCol, height - + heightMidRow); - break; - } - } - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - default: - { - ::SetRect(&srcRect, int(_width * streamSettings->_cropStartWidth), - int(_height * streamSettings->_cropStartHeight), - int(_width * streamSettings->_cropStopWidth), int(_height - * streamSettings->_cropStopHeight)); - - ::SetRect(&dstRect, int(hwndRect.right - * streamSettings->_startWidth), int(hwndRect.bottom - * streamSettings->_startHeight), int(hwndRect.right - * streamSettings->_stopWidth), int(hwndRect.bottom - * streamSettings->_stopHeight)); - } - } - - if (dstRect.right > hwndRect.right) - { - srcRect.right -= (int) ((float) (srcRect.right - srcRect.left) - * ((float) (dstRect.right - hwndRect.right) - / (float) (dstRect.right - dstRect.left))); - dstRect.right = hwndRect.right; - } - if (dstRect.left < hwndRect.left) - { - srcRect.left += (int) ((float) (srcRect.right - srcRect.left) - * ((float) (hwndRect.left - dstRect.left) - / (float) (dstRect.right - dstRect.left))); - dstRect.left = hwndRect.left; - } - if (dstRect.bottom > hwndRect.bottom) - { - srcRect.bottom -= (int) ((float) (srcRect.bottom - srcRect.top) - * ((float) (dstRect.bottom - hwndRect.bottom) - / (float) (dstRect.bottom - dstRect.top))); - dstRect.bottom = hwndRect.bottom; - } - if (dstRect.top < hwndRect.top) - { - srcRect.top += (int) ((float) (srcRect.bottom - srcRect.top) - * ((float) (hwndRect.top - dstRect.top) - / (float) (dstRect.bottom - dstRect.top))); - dstRect.top = hwndRect.top; - } - - DDBLTFX ddbltfx; - ZeroMemory(&ddbltfx, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - ddbltfx.dwDDFX = DDBLTFX_NOTEARING; - - // wait for the _mixingSurface to be available - ddrval = mixingSurface->Blt(&dstRect, _offScreenSurface, &srcRect, - DDBLT_WAIT | DDBLT_DDFX, &ddbltfx); - if (ddrval == DDERR_SURFACELOST) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "mixingSurface->Blt surface lost"); - ddrval = mixingSurface->Restore(); - if (ddrval != DD_OK) - { - // we dont own the surface just report the error - return -1; - } - } - else if (ddrval == DDERR_INVALIDRECT) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "mixingSurface->Blt DDERR_INVALIDRECT"); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "dstRect co-ordinates - top: %d left: %d bottom: %d right: %d", - dstRect.top, dstRect.left, dstRect.bottom, dstRect.right); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "srcRect co-ordinates - top: %d left: %d bottom: %d right: %d", - srcRect.top, srcRect.left, srcRect.bottom, srcRect.right); - - // ignore - } - else if (ddrval != DD_OK) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "mixingSurface->Blt !DD_OK"); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw blt mixingSurface BlitFromOffscreenBufferToMixingBuffer error 0x%x ", - ddrval); - - //logging the co-ordinates and hwnd - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "dstRect co-ordinates - top: %d left: %d bottom: %d right: %d", - dstRect.top, dstRect.left, dstRect.bottom, dstRect.right); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "srcRect co-ordinates - top: %d left: %d bottom: %d right: %d", - srcRect.top, srcRect.left, srcRect.bottom, srcRect.right); - - /* char logStr[256]; - _snprintf(logStr,256, "srcRect T:%d L:%d B:%d R:%d\n",srcRect.top, srcRect.left, srcRect.bottom, srcRect.right); - OutputDebugString(logStr); - char logStr1[256]; - _snprintf(logStr1,256, "dstRect T:%d L:%d B:%d R:%d\n",dstRect.top, dstRect.left, dstRect.bottom, dstRect.right); - OutputDebugString(logStr1); - char logStr2[256]; - _snprintf(logStr2,256, "error 0x:%x \n",ddrval); - OutputDebugString(logStr2); - */ - // we dont own the surface just report the error - return -1; - } - if (_doubleBuffer) - { - DirectDrawSurface* oldOffScreenSurface = _offScreenSurface; - _offScreenSurface = _offScreenSurfaceNext; - _offScreenSurfaceNext = oldOffScreenSurface; - _doubleBuffer = false; - } - else - { - _offScreenSurfaceUpdated = false; - } - return 0; -} - -/** - * - * VideoRenderDirectDraw - * - * - */ - -VideoRenderDirectDraw::VideoRenderDirectDraw(Trace* trace, - HWND hWnd, bool fullscreen) : - _trace(trace), - _confCritSect(CriticalSectionWrapper::CreateCriticalSection()), - _fullscreen(fullscreen), - _demuxing(false), - _transparentBackground(false), - _supportTransparency(false), - _canStretch(false), - _canMirrorLeftRight(false), - _clearMixingSurface(false), - _deliverInScreenType(false), - _renderModeWaitForCorrectScanLine(false), - _deliverInHalfFrameRate(false), - _deliverInQuarterFrameRate(false), - _bCanBltFourcc(true), - _frameChanged(false), - _processCount(0), - _hWnd(hWnd), - _screenRect(), - _mixingRect(), - - _incomingVideoType(kUnknown), - _blitVideoType(kUnknown), - _rgbVideoType(kUnknown), - - _directDraw(NULL), - _primarySurface(NULL), - _backSurface(NULL), - _mixingSurface(NULL), - _bitmapSettings(), - _textSettings(), - _directDrawChannels(), - _directDrawZorder(), - - _fullScreenWaitEvent(EventWrapper::Create()), - _screenEvent(EventWrapper::Create()), - _screenRenderThread( - ThreadWrapper::CreateThread( - RemoteRenderingThreadProc, - this, - kRealtimePriority, - "Video_directdraw_thread")), - _blit(true), _lastRenderModeCpuUsage(-1), _totalMemory(-1), - _availableMemory(-1), _systemCPUUsage(0), _maxAllowedRenderTime(0), - _nrOfTooLongRenderTimes(0), - _isPrimaryOrMixingSurfaceOnSystem(false) -{ - SetRect(&_screenRect, 0, 0, 0, 0); - SetRect(&_mixingRect, 0, 0, 0, 0); - SetRect(&_originalHwndRect, 0, 0, 0, 0); - ::GetClientRect(_hWnd, &_hwndRect); -} - -VideoRenderDirectDraw::~VideoRenderDirectDraw() -{ - ThreadWrapper* temp = _screenRenderThread; - _screenRenderThread = NULL; - if (temp) - { - temp->SetNotAlive(); - _screenEvent->Set(); - _screenEvent->StopTimer(); - _fullScreenWaitEvent->StopTimer(); - - if (temp->Stop()) - { - delete temp; - } - } - delete _screenEvent; - delete _fullScreenWaitEvent; - - std::map::iterator it; - it = _directDrawChannels.begin(); - while (it != _directDrawChannels.end()) - { - it->second->Release(); - it = _directDrawChannels.erase(it); - } - if (_primarySurface) - { - _primarySurface->Release(); - } - if (_mixingSurface) - { - _mixingSurface->Release(); - } - - std::map::iterator bitIt; - - bitIt = _bitmapSettings.begin(); - while (_bitmapSettings.end() != bitIt) - { - delete bitIt->second; - bitIt = _bitmapSettings.erase(bitIt); - } - - std::map::iterator textIt; - textIt = _textSettings.begin(); - while (_textSettings.end() != textIt) - { - delete textIt->second; - textIt = _textSettings.erase(textIt); - } - if (_directDraw) - { - _directDraw->Release(); - if (_fullscreen) - { - // restore hwnd to original size and position - ::SetWindowPos(_hWnd, HWND_NOTOPMOST, _originalHwndRect.left, - _originalHwndRect.top, _originalHwndRect.right - - _originalHwndRect.left, - _originalHwndRect.bottom - _originalHwndRect.top, - SWP_FRAMECHANGED); - ::RedrawWindow(_hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW - | RDW_ERASE); - ::RedrawWindow(NULL, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW - | RDW_ERASE); - } - } - delete _confCritSect; -} - -WebRtc_Word32 VideoRenderDirectDraw::Init() -{ - int retVal = 0; - HRESULT ddrval = DirectDrawCreateEx(NULL, (void**) &_directDraw, - IID_IDirectDraw7, NULL); - if (FAILED(ddrval) || NULL == _directDraw) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "Failed to created DirectDraw7 object"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - retVal = CheckCapabilities(); - if (retVal != 0) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw CheckCapabilities failed"); - return retVal; - } - if (_hWnd) - { - retVal = CreatePrimarySurface(); - if (retVal != 0) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to CreatePrimarySurface"); - return retVal; - } - retVal = CreateMixingSurface(); - if (retVal != 0) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to CreateMixingSurface"); - return retVal; - } - if (_screenRenderThread) - { - unsigned int tid; - _screenRenderThread->Start(tid); - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "Screen Render thread started, thread id: %d", tid); - } - DWORD freq = 0; - _directDraw->GetMonitorFrequency(&freq); - if (freq == 0) - { - freq = 60; - } - // Do this now to not do it in each render process loop - _maxAllowedRenderTime = (int) (1000 / freq * 0.8F); - _nrOfTooLongRenderTimes = 0; - - _screenEvent->StartTimer(true, 1000 / freq); - - _deliverInScreenType = false; - _renderModeWaitForCorrectScanLine = false; - _deliverInHalfFrameRate = false; - _deliverInQuarterFrameRate = false; - - _lastRenderModeCpuUsage = -1; - if (_fullscreen) - { - _fullScreenWaitEvent->StartTimer(true, 1); - } - - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "Screen freq %d", freq); - } - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "Created DirectDraw object"); - return 0; -} - -WebRtc_Word32 VideoRenderDirectDraw::GetGraphicsMemory( - WebRtc_UWord64& totalMemory, - WebRtc_UWord64& availableMemory) -{ - CriticalSectionScoped cs(_confCritSect); - - if (_totalMemory == -1 || _availableMemory == -1) - { - totalMemory = 0; - availableMemory = 0; - return -1; - } - totalMemory = _totalMemory; - availableMemory = _availableMemory; - return 0; -} - -int VideoRenderDirectDraw::GetScreenResolution(int& screenWidth, - int& screenHeight) -{ - CriticalSectionScoped cs(_confCritSect); - - screenWidth = _screenRect.right - _screenRect.left; - screenHeight = _screenRect.bottom - _screenRect.top; - return 0; -} - -int VideoRenderDirectDraw::UpdateSystemCPUUsage(int systemCPU) -{ - CriticalSectionScoped cs(_confCritSect); - if (systemCPU <= 100 && systemCPU >= 0) - { - _systemCPUUsage = systemCPU; - } - return 0; -} - -int VideoRenderDirectDraw::CheckCapabilities() -{ - HRESULT ddrval = DD_OK; - DDCAPS ddcaps; - DDCAPS ddcapsEmul; - memset(&ddcaps, 0, sizeof(ddcaps)); - memset(&ddcapsEmul, 0, sizeof(ddcapsEmul)); - ddcaps.dwSize = sizeof(ddcaps); - ddcapsEmul.dwSize = sizeof(ddcapsEmul); - if (_directDraw == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw object not created"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - if (IsRectEmpty(&_screenRect)) - { - ::GetWindowRect(GetDesktopWindow(), &_screenRect); - } - // Log Screen resolution - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "ScreenRect. Top: %d, left: %d, bottom: %d, right: %d", - _screenRect.top, _screenRect.left, _screenRect.bottom, - _screenRect.right); - - bool fullAccelerationEnabled = false; - bool badDriver = false; - VideoRenderWindowsImpl::CheckHWDriver(badDriver, fullAccelerationEnabled); - if (!fullAccelerationEnabled) - { - - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "Direct draw Hardware acceleration is not enabled."); - return -1; - //return VIDEO_DIRECT_DRAW_HWACC_NOT_ENABLED; - - } - - // ddcaps supported by the HW - // ddcapsEmul supported by the OS emulating the HW - ddrval = _directDraw->GetCaps(&ddcaps, &ddcapsEmul); - if (ddrval != DD_OK) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw HW: could not get capabilities: %x", ddrval); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - - unsigned int minVideoMemory = 3 * 4 * (_screenRect.right - * _screenRect.bottom); // assuming ARGB size (4 bytes) - - // Store the memory for possible calls to GetMemory() - _totalMemory = ddcaps.dwVidMemTotal; - _availableMemory = ddcaps.dwVidMemFree; - - if (ddcaps.dwVidMemFree < minVideoMemory) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw HW does not have enough memory, freeMem:%d, requiredMem:%d", - ddcaps.dwVidMemFree, minVideoMemory); - // If memory is not available on the Video Card...allocate it on RAM - } - else - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw video memory, freeMem:%d, totalMem:%d", - ddcaps.dwVidMemFree, ddcaps.dwVidMemTotal); - } - - /* - DirectDrawCaps ddsCaps ; - ZeroMemory(&ddsCaps, sizeof(ddsCaps)) ; - ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; - DWORD memTotal=0; - DWORD memFree=0; - ddrval = _directDraw->GetAvailableVidMem(&ddsCaps, &memTotal, &memFree); - if(ddrval == DD_OK) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, "DirectDraw video memory, freeMem:%d, totalMem:%d", memFree, memTotal); - } - */ - // Determine if the hardware supports overlay deinterlacing - // bCanDeinterlace = (ddcaps.dwCaps2 & DDCAPS2_CANFLIPODDEVEN) ? 1 : 0; - - // this fail since we check before we set the mode - // bool bCanFlip =(ddcaps.dwCaps & DDSCAPS_FLIP) ? 1 : 0; - - // Determine if the hardware supports colorkeying - _supportTransparency = (ddcaps.dwCaps & DDCAPS_COLORKEY) ? 1 : 0; - if (_supportTransparency) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw support colorkey"); - } - else - { - WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, - "DirectDraw don't support colorkey"); - } - - if (ddcaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED) - { - // required for _directDraw->FlipToGDISurface(); - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw support CANRENDERWINDOWED"); - } - else - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw don't support CANRENDERWINDOWED"); - } - - // Determine if the hardware supports scaling during a blit - _canStretch = (ddcaps.dwCaps & DDCAPS_BLTSTRETCH) ? 1 : 0; - if (_canStretch) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw blit can stretch"); - } - else - { - WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, - "DirectDraw blit can't stretch"); - } - - _canMirrorLeftRight = (ddcaps.dwFXAlphaCaps & DDBLTFX_MIRRORLEFTRIGHT) ? 1 - : 0; - if (_canMirrorLeftRight) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw mirroring is supported"); - } - else - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw mirroring is not supported"); - } - - // Determine if the hardware supports color conversion during a blit - _bCanBltFourcc = (ddcaps.dwCaps & DDCAPS_BLTFOURCC) ? 1 : 0; - if (_bCanBltFourcc) - _bCanBltFourcc = (ddcaps.dwCKeyCaps & DDCKEYCAPS_DESTBLT) ? 1 : 0; - - if (_bCanBltFourcc) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw can blit Fourcc"); - DWORD i_codes; - ddrval = _directDraw->GetFourCCCodes(&i_codes, NULL); - - if (i_codes > 0) - { - DWORD* pi_codes = new DWORD[i_codes]; - - ddrval = _directDraw->GetFourCCCodes(&i_codes, pi_codes); - for (unsigned int i = 0; i < i_codes && _blitVideoType - != kI420; i++) - { - DWORD w = pi_codes[i]; - switch (w) - { - case MAKEFOURCC('I', '4', '2', '0'): - // _blitVideoType = kI420; - // not enabled since its not tested - WEBRTC_TRACE(kTraceInfo, kTraceVideo, - -1, "DirectDraw support I420"); - break; - case MAKEFOURCC('I', 'Y', 'U', 'V'): // same as YV12 - // _blitVideoType = kIYUV; - // not enabled since its not tested - WEBRTC_TRACE(kTraceInfo, kTraceVideo, - -1, "DirectDraw support IYUV"); - break; - case MAKEFOURCC('U', 'Y', 'N', 'V'): // same shit different name - WEBRTC_TRACE(kTraceInfo, kTraceVideo, - -1, "DirectDraw support UYNV"); - // not enabled since its not tested - break; - case MAKEFOURCC('Y', '4', '2', '2'): // same shit different name - WEBRTC_TRACE(kTraceInfo, kTraceVideo, - -1, "DirectDraw support Y422"); - // not enabled since its not tested - break; - case MAKEFOURCC('Y', 'U', 'N', 'V'): // same shit different name - WEBRTC_TRACE(kTraceInfo, kTraceVideo, - -1, "DirectDraw support YUNV"); - // not enabled since its not tested - break; - case MAKEFOURCC('Y', 'V', '1', '2'): - _blitVideoType = kYV12; - WEBRTC_TRACE(kTraceInfo, kTraceVideo, - -1, "DirectDraw support YV12"); - break; - case MAKEFOURCC('Y', 'U', 'Y', '2'): - if (_blitVideoType != kYV12) - { - _blitVideoType = kYUY2; - } - WEBRTC_TRACE(kTraceInfo, kTraceVideo, - -1, "DirectDraw support YUY2"); - break; - case MAKEFOURCC('U', 'Y', 'V', 'Y'): - if (_blitVideoType != kYV12) - { - _blitVideoType = kUYVY; - } - WEBRTC_TRACE(kTraceInfo, kTraceVideo, - -1, "DirectDraw support UYVY"); - break; - default: - WEBRTC_TRACE(kTraceInfo, kTraceVideo, - -1, "DirectDraw unknown blit type %x", w); - break; - } - } - delete[] pi_codes; - } - } - return 0; -} - -int VideoRenderDirectDraw::Stop() -{ - _confCritSect->Enter(); - - _blit = false; - - _confCritSect->Leave(); - return 0; -} - -bool VideoRenderDirectDraw::IsPrimaryOrMixingSurfaceOnSystem() -{ - return _isPrimaryOrMixingSurfaceOnSystem; -} - -int VideoRenderDirectDraw::CreatePrimarySurface() -{ - // Create the primary surface - DirectDrawSurfaceDesc ddsd; - ZeroMemory(&ddsd, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - HRESULT ddrval = DD_OK; - - if (_directDraw == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw object not created"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - if (_primarySurface) - { - _primarySurface->Release(); - _primarySurface = NULL; - } - - if (!_fullscreen) - { - // create a normal window - ddrval = _directDraw->SetCooperativeLevel(_hWnd, DDSCL_NORMAL); - if (FAILED(ddrval)) - { - //******** Potential workaround for D#4608 *************** Ignore error. - WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, - "DirectDraw failed to set SetCooperativeLevel %x, ddrval"); - } - // we cant size the primary surface based on _hwndRect - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY; - -#ifndef NOGRAPHICSCARD_MEMORY - ddrval = _directDraw->CreateSurface(&ddsd, &_primarySurface, NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _primarySurface using VideoMemory: 0x%x", - ddrval); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "\t HWND: 0x%x, top: %d, left: %d, bottom: %d, right: %d, dwFlags: %d. Line : %d", - _hWnd, _hwndRect.top, _hwndRect.left, - _hwndRect.bottom, _hwndRect.right, ddsd.dwFlags, - __LINE__); - -#endif - //allocate using System memory - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY; - ddrval = _directDraw->CreateSurface(&ddsd, &_primarySurface, NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _primarySurface using SystemMemory: 0x%x", - ddrval); - if (ddrval != 0x887600E1) - { - _directDraw->Release(); - _directDraw = 0; - } - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - _isPrimaryOrMixingSurfaceOnSystem = true; - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw _primarySurface on SystemMemory"); - -#ifndef NOGRAPHICSCARD_MEMORY - } -#endif - - // Create a clipper to ensure that our drawing stays inside our window - LPDIRECTDRAWCLIPPER directDrawClipper; - ddrval = _directDraw->CreateClipper(0, &directDrawClipper, NULL ); - if (ddrval != DD_OK) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to CreateClipper"); - _primarySurface->Release(); - _directDraw->Release(); - _primarySurface = 0; - _directDraw = 0; - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - // setting it to our hwnd gives the clipper the coordinates from our window - // when using cliplist we run into problem with transparent HWNDs (such as REX) - ddrval = directDrawClipper->SetHWnd(0, _hWnd); - if (ddrval != DD_OK) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to SetHWnd"); - _primarySurface->Release(); - _directDraw->Release(); - _primarySurface = 0; - _directDraw = 0; - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - // attach the clipper to the primary surface - ddrval = _primarySurface->SetClipper(directDrawClipper); - directDrawClipper->Release(); // no need to keep the clipper around - if (ddrval != DD_OK) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to SetClipper"); - _primarySurface->Release(); - _directDraw->Release(); - _primarySurface = 0; - _directDraw = 0; - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - } - else - { - /* The cooperative level determines how much control we have over the - * screen. This must at least be either DDSCL_EXCLUSIVE or DDSCL_NORMAL - * - * DDSCL_EXCLUSIVE allows us to change video modes, and requires - * the DDSCL_FULLSCREEN flag, which will cause the window to take over - * the fullscreen. This is the preferred DirectDraw mode because it allows - * us to have control of the whole screen without regard for GDI. - * - * DDSCL_NORMAL is used to allow the DirectDraw app to run windowed. - */ - - // Note: debuging in fullscreen mode does not work, thanks MS... - ::GetWindowRect(_hWnd, &_originalHwndRect); - - // DDSCL_NOWINDOWCHANGES prevents DD to change the window but it give us trouble too, not using it - ddrval = _directDraw->SetCooperativeLevel(_hWnd, DDSCL_EXCLUSIVE - | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT); - - if (FAILED(ddrval)) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to SetCooperativeLevel DDSCL_EXCLUSIVE"); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "\t HWND: 0x%x, top: %d, left: %d, bottom: %d, right: %d, dwFlags: %d. Line : %d", - _hWnd, _hwndRect.top, _hwndRect.left, - _hwndRect.bottom, _hwndRect.right, ddsd.dwFlags, - __LINE__); - - _directDraw->Release(); - _directDraw = 0; - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP - | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY; - ddsd.dwBackBufferCount = 1; - - ddrval = _directDraw->CreateSurface(&ddsd, &_primarySurface, NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _primarySurface, fullscreen mode: 0x%x", - ddrval); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "\t HWND: 0x%x, top: %d, left: %d, bottom: %d, right: %d, dwFlags: %d. Line : %d", - _hWnd, _hwndRect.top, _hwndRect.left, - _hwndRect.bottom, _hwndRect.right, ddsd.dwFlags, - __LINE__); - - _directDraw->Release(); - _directDraw = 0; - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - // Get a pointer to the back buffer - DirectDrawCaps ddsCaps; - ZeroMemory(&ddsCaps, sizeof(ddsCaps)); - ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY; - - ddrval = _primarySurface->GetAttachedSurface(&ddsCaps, &_backSurface); - if (FAILED(ddrval)) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to GetAttachedSurface, fullscreen mode "); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "\t HWND: 0x%x, top: %d, left: %d, bottom: %d, right: %d, dwFlags: %d. Line : %d", - _hWnd, _hwndRect.top, _hwndRect.left, - _hwndRect.bottom, _hwndRect.right, ddsd.dwFlags, - __LINE__); - - _primarySurface->Release(); - _directDraw->Release(); - _primarySurface = 0; - _directDraw = 0; - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - // Get the screen size and save it as a rect - ZeroMemory(&ddsd, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - } - - ZeroMemory(&ddsd, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - // get our prinmary surface description - ddrval = _primarySurface->GetSurfaceDesc(&ddsd); - if (!(SUCCEEDED(ddrval) && (ddsd.dwFlags & DDSD_WIDTH) && (ddsd.dwFlags - & DDSD_HEIGHT))) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to GetSurfaceDesc _primarySurface"); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "\t HWND: 0x%x, top: %d, left: %d, bottom: %d, right: %d, dwFlags: %d. Line : %d", - _hWnd, _hwndRect.top, _hwndRect.left, _hwndRect.bottom, - _hwndRect.right, ddsd.dwFlags, __LINE__); - - _primarySurface->Release(); - _directDraw->Release(); - _primarySurface = 0; - _directDraw = 0; - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - // first we need to figure out the size of the primary surface - - // store screen size - ::SetRect(&_screenRect, 0, 0, ddsd.dwWidth, ddsd.dwHeight); - - // store RGB type - if (ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB) - { - // RGB surface - switch (ddsd.ddpfPixelFormat.dwRGBBitCount) - { - case 16: - switch (ddsd.ddpfPixelFormat.dwGBitMask) - { - case 0x00e0: - _rgbVideoType = kARGB4444; - break; - case 0x03e0: - _rgbVideoType = kARGB1555; - break; - case 0x07e0: - _rgbVideoType = kRGB565; - break; - } - break; - case 24: - _rgbVideoType = kRGB24; - break; - case 32: - _rgbVideoType = kARGB; - break; - } - } - switch (_blitVideoType) - { - case kI420: - case kIYUV: - case kYUY2: - case kYV12: - case kUYVY: - _incomingVideoType = kI420; - break; - case kUnknown: - _blitVideoType = _rgbVideoType; - _incomingVideoType = kI420; - break; - default: - _blitVideoType = _rgbVideoType; - _incomingVideoType = kI420; - break; - } - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "DirectDraw created _primarySurface, _blitVideoType %d, _rgbvideoType %d", - _blitVideoType, _rgbVideoType); - return 0; -} - -int VideoRenderDirectDraw::CreateMixingSurface() -{ - if (_directDraw == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw object not created"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - - if (_fullscreen) - { - ::CopyRect(&_hwndRect, &_screenRect); - } - else - { - // update our _hWnd size - ::GetClientRect(_hWnd, &_hwndRect); - } - - if (_mixingSurface) - { - _mixingSurface->Release(); - _mixingSurface = NULL; - } - // create mixing surface - DirectDrawSurfaceDesc ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; - ddsd.dwHeight = _hwndRect.bottom; - ddsd.dwWidth = _hwndRect.right; - - /* char logStr[256]; - _snprintf(logStr,256, "CreateMixingSurface H:%d W:%d \n",_hwndRect.bottom, _hwndRect.right); - OutputDebugString(logStr); - */ - -#ifndef NOGRAPHICSCARD_MEMORY - HRESULT ddrval = _directDraw->CreateSurface(&ddsd, &_mixingSurface, NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _mixingSurface using VideoMemory: 0x%x", - ddrval); - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "\t HWND: 0x%x, top: %d, left: %d, bottom: %d, right: %d, dwFlags: %d", - _hWnd, _hwndRect.top, _hwndRect.left, _hwndRect.bottom, - _hwndRect.right, ddsd.dwFlags); -#endif - - ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; - HRESULT ddrval = _directDraw->CreateSurface(&ddsd, &_mixingSurface, - NULL); - if (FAILED(ddrval)) - { - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to CreateSurface _mixingSurface on System Memory: 0x%x", - ddrval); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - _isPrimaryOrMixingSurfaceOnSystem = true; - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw CreateSurface _mixingSurface on SystemMemory"); - -#ifndef NOGRAPHICSCARD_MEMORY - } -#endif - - _clearMixingSurface = true; - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw _mixingSurface created"); - return 0; -} - -VideoRenderCallback* VideoRenderDirectDraw::CreateChannel(WebRtc_UWord32 channel, - WebRtc_UWord32 zOrder, - float startWidth, - float startHeight, - float stopWidth, - float stopHeight) -{ - if (!_canStretch) - { - if (startWidth != 0.0f || startHeight != 0.0f || stopWidth != 1.0f - || stopHeight != 1.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to CreateChannel HW don't support stretch"); - return NULL; - } - } - DirectDrawChannel* ddobj = - new DirectDrawChannel(_directDraw, _blitVideoType, - _incomingVideoType, _rgbVideoType, this); - ddobj->SetStreamSettings(this, 0, startWidth, startHeight, stopWidth, - stopHeight); - - // store channel - _directDrawChannels[channel & 0x0000ffff] = ddobj; - - // store Z order - // default streamID is 0 - _directDrawZorder.insert(ZorderPair(zOrder, channel & 0x0000ffff)); - return ddobj; -} - -int VideoRenderDirectDraw::AddDirectDrawChannel(int channel, - unsigned char streamID, - int zOrder, - DirectDrawChannel* ddObj) -{ - // Only allow one stream per channel, demuxing is done outside of DirectDraw... - streamID = 0; - unsigned int streamChannel = (streamID << 16) + (channel & 0x0000ffff); - - // store channel - _directDrawChannels[channel & 0x0000ffff] = ddObj; - - _demuxing = true; // with this function it's always demux - - // store Z order - _directDrawZorder.insert(ZorderPair(zOrder, streamChannel)); - return 0; -} - -DirectDrawChannel* VideoRenderDirectDraw::ShareDirectDrawChannel( - int channel) -{ - CriticalSectionScoped cs(_confCritSect); - - DirectDrawChannel* obj = NULL; - - std::map::iterator ddIt; - ddIt = _directDrawChannels.find(channel & 0x0000ffff); - if (ddIt != _directDrawChannels.end()) - { - obj = ddIt->second; - obj->AddRef(); - } - return obj; -} - -WebRtc_Word32 VideoRenderDirectDraw::DeleteChannel(const WebRtc_UWord32 channel) -{ - CriticalSectionScoped cs(_confCritSect); - - // Remove the old z order - - //unsigned int streamChannel = (streamID << 16) + (channel & 0x0000ffff); - std::multimap::iterator it; - it = _directDrawZorder.begin(); - while (it != _directDrawZorder.end()) - { - //if(streamChannel == it->second ) - if ((channel & 0x0000ffff) == (it->second & 0x0000ffff)) - { - it = _directDrawZorder.erase(it); - break; - } - it++; - } - - std::map::iterator ddIt; - ddIt = _directDrawChannels.find(channel & 0x0000ffff); - if (ddIt != _directDrawChannels.end()) - { - ddIt->second->Release(); - _directDrawChannels.erase(ddIt); - _clearMixingSurface = true; - } - - return 0; -} - -WebRtc_Word32 VideoRenderDirectDraw::GetStreamSettings(const WebRtc_UWord32 channel, - const WebRtc_UWord16 streamId, - WebRtc_UWord32& zOrder, - float& startWidth, - float& startHeight, - float& stopWidth, - float& stopHeight) -{ - CriticalSectionScoped cs(_confCritSect); - - std::map::iterator ddIt; - ddIt = _directDrawChannels.find(channel & 0x0000ffff); - if (ddIt == _directDrawChannels.end()) - { - // This channel doesn't exist. - return -1; - } - - DirectDrawChannel* ptrChannel = ddIt->second; - // Only support one stream per channel, is demuxing done outside if DD. - //if (ptrChannel->GetStreamSettings(this, streamId, startWidth, startHeight, stopWidth, stopHeight) == -1) - if (ptrChannel->GetStreamSettings(this, 0, startWidth, startHeight, - stopWidth, stopHeight) == -1) - { - // Error for this stream - return -1; - } - - // Get the zOrder - std::multimap::iterator it; - it = _directDrawZorder.begin(); - while (it != _directDrawZorder.end()) - { - if ((channel & 0x0000ffff) == (it->second & 0x0000ffff)) - { - // We found our channel zOrder - zOrder = (unsigned int) (it->first); - break; - } - it++; - } - - return 0; -} - -int VideoRenderDirectDraw::GetChannels(std::list& channelList) -{ - CriticalSectionScoped cs(_confCritSect); - - std::map::iterator ddIt; - ddIt = _directDrawChannels.begin(); - - while (ddIt != _directDrawChannels.end()) - { - int channel = ddIt->first; - if (channel == 0x0000ffff) - { - channel = -1; - } - channelList.push_back(channel); - ddIt++; - } - return 0; -} - -bool VideoRenderDirectDraw::HasChannel(int channel) -{ - CriticalSectionScoped cs(_confCritSect); - - std::map::iterator ddIt; - ddIt = _directDrawChannels.find(channel & 0x0000ffff); - if (ddIt != _directDrawChannels.end()) - { - return true; - } - return false; -} - -bool VideoRenderDirectDraw::HasChannels() -{ - CriticalSectionScoped cs(_confCritSect); - - if (_directDrawChannels.begin() != _directDrawChannels.end()) - { - return true; - } - return false; -} - -bool VideoRenderDirectDraw::IsFullScreen() -{ - return _fullscreen; -} - -VideoType VideoRenderDirectDraw::GetPerferedVideoFormat() -{ - return _incomingVideoType; -} - -// this can be called rutime from another thread -DirectDrawChannel* VideoRenderDirectDraw::ConfigureDirectDrawChannel(int channel, - unsigned char streamID, - int zOrder, - float left, - float top, - float right, - float bottom) -{ - // Only support one stream per channel, is demuxing done outside if DD. - streamID = 0; - - CriticalSectionScoped cs(_confCritSect); - - if (!_canStretch) - { - if (left != 0.0f || top != 0.0f || right != 1.0f || bottom != 1.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to ConfigureDirectDrawChannel HW don't support stretch"); - return NULL; - } - } - std::map::iterator ddIt; - ddIt = _directDrawChannels.find(channel & 0x0000ffff); - DirectDrawChannel* ddobj = NULL; - if (ddIt != _directDrawChannels.end()) - { - ddobj = ddIt->second; - } - if (ddobj == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, -1, - "DirectDraw failed to find channel"); - return NULL; - } - unsigned int streamChannel = (streamID << 16) + (channel & 0x0000ffff); - // remove the old z order - std::multimap::iterator it; - it = _directDrawZorder.begin(); - while (it != _directDrawZorder.end()) - { - if (streamChannel == it->second) - { - it = _directDrawZorder.erase(it); - break; - } - it++; - } - // if this channel already are in the zOrder map it's demux - it = _directDrawZorder.begin(); - while (it != _directDrawZorder.end()) - { - if (channel == (it->second & 0x0000ffff)) - { - _demuxing = true; - break; - } - it++; - } - if (it == _directDrawZorder.end()) - { - _demuxing = false; - } - - _clearMixingSurface = true; - - if (left == 0.0f && top == 0.0f && right == 0.0f && bottom == 0.0f) - { - // remove - _directDrawChannels.erase(ddIt); - ddobj->Release(); - return NULL; - } - ddobj->SetStreamSettings(this, streamID, left, top, right, bottom); - - _directDrawZorder.insert(ZorderPair(zOrder, streamChannel)); - return ddobj; -} - -WebRtc_Word32 VideoRenderDirectDraw::SetCropping(const WebRtc_UWord32 channel, - const WebRtc_UWord16 streamID, - float left, float top, - float right, float bottom) -{ - CriticalSectionScoped cs(_confCritSect); - if (!_canStretch) - { - if (left != 0.0f || top != 0.0f || right != 1.0f || bottom != 1.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, -1, - "DirectDraw failed to SetCropping HW don't support stretch"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - } - - std::map::iterator ddIt; - ddIt = _directDrawChannels.find(channel & 0x0000ffff); - if (ddIt != _directDrawChannels.end()) - { - DirectDrawChannel* ddobj = ddIt->second; - if (ddobj) - { - // Only support one stream per channel, is demuxing done outside if DD. - ddobj->SetStreamCropSettings(this, 0, left, top, right, bottom); - //ddobj->SetStreamCropSettings(this, streamID, left, top, right, bottom); - } - } - return 0; -} - -WebRtc_Word32 VideoRenderDirectDraw::ConfigureRenderer(const WebRtc_UWord32 channel, - const WebRtc_UWord16 streamId, - const unsigned int zOrder, - const float left, - const float top, - const float right, - const float bottom) -{ - if (ConfigureDirectDrawChannel(channel, (unsigned char) streamId, zOrder, - left, top, right, bottom) == NULL) - { - if (left == 0.0f && top == 0.0f && right == 0.0f && bottom == 0.0f) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, -1, - "ConfigureRender, removed channel:%d streamId:%d", - channel, streamId); - } - else - { - WEBRTC_TRACE( - kTraceError, - kTraceVideoRenderer, - -1, - "DirectDraw failed to ConfigureRenderer for channel: %d", - channel); - return -1; - } - } - return 0; -} - -// this can be called runtime from another thread -WebRtc_Word32 VideoRenderDirectDraw::SetText(const WebRtc_UWord8 textId, - const WebRtc_UWord8* text, - const WebRtc_Word32 textLength, - const WebRtc_UWord32 colorText, - const WebRtc_UWord32 colorBg, - const float left, - const float top, - const float right, - const float bottom) -{ - DirectDrawTextSettings* textSetting = NULL; - - CriticalSectionScoped cs(_confCritSect); - - _frameChanged = true; - - std::map::iterator it; - it = _textSettings.find(textId); - if (it != _textSettings.end()) - { - if (it->second) - { - textSetting = it->second; - } - } - _clearMixingSurface = true; - - if (text == NULL || textLength == 0) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw remove text textId:%d", textId); - if (textSetting) - { - delete textSetting; - _textSettings.erase(it); - } - return 0; - } - - // sanity - if (left > 1.0f || left < 0.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw SetText invalid parameter"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - if (top > 1.0f || top < 0.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw SetText invalid parameter"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - if (right > 1.0f || right < 0.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw SetText invalid parameter"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - if (bottom > 1.0f || bottom < 0.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw SetText invalid parameter"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - if (textSetting == NULL) - { - textSetting = new DirectDrawTextSettings(); - } - int retVal = textSetting->SetText((const char*) text, textLength, - (COLORREF) colorText, (COLORREF) colorBg, - left, top, right, bottom); - if (retVal != 0) - { - delete textSetting; - textSetting = NULL; - _textSettings.erase(textId); - return retVal; - } - if (textSetting) - { - _textSettings[textId] = textSetting; - } - return retVal; -} - -// this can be called runtime from another thread -WebRtc_Word32 VideoRenderDirectDraw::SetBitmap(const void* bitMap, - const WebRtc_UWord8 pictureId, - const void* colorKey, - const float left, - const float top, - const float right, - const float bottom) -{ - DirectDrawBitmapSettings* bitmapSetting = NULL; - - CriticalSectionScoped cs(_confCritSect); - - _frameChanged = true; - std::map::iterator it; - it = _bitmapSettings.find(pictureId); - if (it != _bitmapSettings.end()) - { - if (it->second) - { - bitmapSetting = it->second; - } - } - _clearMixingSurface = true; - - if (bitMap == NULL) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw remove bitmap pictureId:%d", pictureId); - if (bitmapSetting) - { - delete bitmapSetting; - _bitmapSettings.erase(it); - } - return 0; - } - - // sanity - if (left > 1.0f || left < 0.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw SetBitmap invalid parameter"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - if (top > 1.0f || top < 0.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw SetBitmap invalid parameter"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - if (right > 1.0f || right < 0.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw SetBitmap invalid parameter"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - if (bottom > 1.0f || bottom < 0.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw SetBitmap invalid parameter"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - if (!_canStretch) - { - if (left != 0.0f || top != 0.0f || right != 1.0f || bottom != 1.0f) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to SetBitmap HW don't support stretch"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - } - if (bitmapSetting == NULL) - { - bitmapSetting = new DirectDrawBitmapSettings(); - } - - bitmapSetting->_transparentBitMap = (HBITMAP) bitMap; - bitmapSetting->_transparentBitmapLeft = left; - bitmapSetting->_transparentBitmapRight = right; - bitmapSetting->_transparentBitmapTop = top; - bitmapSetting->_transparentBitmapBottom = bottom; - - // colorKey == NULL equals no transparency - if (colorKey) - { - // first remove constness - DDCOLORKEY* ddColorKey = - static_cast (const_cast (colorKey)); - if (!_supportTransparency) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to SetBitmap HW don't support transparency"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; - } - if (bitmapSetting->_transparentBitmapColorKey == NULL) - { - bitmapSetting->_transparentBitmapColorKey = new DDCOLORKEY(); - } - - if (ddColorKey) - { - bitmapSetting->_transparentBitmapColorKey->dwColorSpaceLowValue - = ddColorKey->dwColorSpaceLowValue; - bitmapSetting->_transparentBitmapColorKey->dwColorSpaceHighValue - = ddColorKey->dwColorSpaceHighValue; - } - } - int retval = bitmapSetting->SetBitmap(_trace, _directDraw); - if (retval != 0) - { - delete bitmapSetting; - bitmapSetting = NULL; - _bitmapSettings.erase(pictureId); - return retval; - } - if (bitmapSetting) - { - _bitmapSettings[pictureId] = bitmapSetting; - } - return retval; -} - -// this can be called rutime from another thread -WebRtc_Word32 VideoRenderDirectDraw::SetTransparentBackground( - const bool enable) -{ - CriticalSectionScoped cs(_confCritSect); - - if (_supportTransparency) - { - _transparentBackground = enable; - if (enable) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw enabled TransparentBackground"); - } - else - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw disabled TransparentBackground"); - } - return 0; - } - WEBRTC_TRACE( - kTraceError, - kTraceVideo, - -1, - "DirectDraw failed to EnableTransparentBackground HW don't support transparency"); - return -1; - //return VIDEO_DIRECT_DRAW_INVALID_ARG; -} - -int VideoRenderDirectDraw::FillSurface(DirectDrawSurface *pDDSurface, - RECT* rect) -{ - // sanity checks - if (NULL == pDDSurface) - { - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - if (NULL == rect) - { - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - - // Repaint the whole specified surface - HRESULT ddrval; - DDBLTFX ddFX; - - ZeroMemory(&ddFX, sizeof(ddFX)); - ddFX.dwSize = sizeof(ddFX); - ddFX.dwFillColor = RGB(0, 0, 0); - - // Draw color key on the video area of given surface - ddrval = pDDSurface->Blt(rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, - &ddFX); - if (FAILED(ddrval)) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw failed to fill surface"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - return 0; -} - -// the real rendering thread -bool VideoRenderDirectDraw::RemoteRenderingThreadProc(void *obj) -{ - return static_cast (obj)->RemoteRenderingProcess(); -} - -bool VideoRenderDirectDraw::RemoteRenderingProcess() -{ - bool hwndChanged = false; - int waitTime = 0; - - _screenEvent->Wait(100); - - _confCritSect->Enter(); - - if (_blit == false) - { - _confCritSect->Leave(); - return true; - } - - if (!::GetForegroundWindow()) - { - //no window, i.e the user have clicked CTRL+ALT+DEL, return true and wait - _confCritSect->Leave(); - return true; - } - - // Skip to blit if last render to primare surface took too long time. - _processCount++; - if (_deliverInQuarterFrameRate) - { - if (_processCount % 4 != 0) - { - _confCritSect->Leave(); - return true; - } - } - else if (_deliverInHalfFrameRate) - { - if (_processCount % 2 != 0) - { - _confCritSect->Leave(); - return true; - } - } - - // Calculate th erender process time - unsigned int startProcessTime = timeGetTime(); - - hwndChanged = HasHWNDChanged(); - if (hwndChanged) - { - _clearMixingSurface = true; - } - - std::map::iterator it; - it = _directDrawChannels.begin(); - while (it != _directDrawChannels.end() && !_frameChanged) - { - if (it->second) - { - _frameChanged = it->second->IsOffScreenSurfaceUpdated(this); - } - it++; - } - if (_backSurface) - { - if (hwndChanged || _frameChanged) - { - BlitFromOffscreenBuffersToMixingBuffer(); - BlitFromBitmapBuffersToMixingBuffer(); - BlitFromTextToMixingBuffer(); - } - BlitFromMixingBufferToBackBuffer(); - WaitAndFlip(waitTime); - } - else - { - if (hwndChanged || _frameChanged) - { - BlitFromOffscreenBuffersToMixingBuffer(); - BlitFromBitmapBuffersToMixingBuffer(); - BlitFromTextToMixingBuffer(); - } - BlitFromMixingBufferToFrontBuffer(hwndChanged, waitTime); - - } - // Check the total time it took processing all rendering. Don't consider waitTime. - //const int totalRenderTime=GET_TIME_IN_MS()- startProcessTime-waitTime; - const int totalRenderTime = ::timeGetTime() - startProcessTime - waitTime; - DecideBestRenderingMode(hwndChanged, totalRenderTime); - _frameChanged = false; - _confCritSect->Leave(); - - return true; -} -void VideoRenderDirectDraw::DecideBestRenderingMode(bool hwndChanged, - int totalRenderTime) -{ - /* Apply variuos fixes for bad graphic drivers. - 1. If cpu to high- test wait fix - 2. If cpu still too high render in 1/2 display update period. - 3. If RemoteRenderingProcess take to long time reduce the blit period to 1/2 display update period. - 4. If RemoteRenderingProcess still take to long time try color conversion fix. It do color conversion in VieoRenderDirectDrawChannel::DeliverFrame - 5. If RemoteRenderingProcess still take to long time reduce the blit period to 1/4 display update period and disable color conversion fix. - 6 if RemoteRenderingProcess still take to long time reduce the blit period to 1/4 display update period and enable color conversion fix again. - */ - - const int timesSinceLastCPUCheck = timeGetTime() - - _screenRenderCpuUsage.LastGetCpuTime(); - int cpu = 0; - - if (hwndChanged) // Render window changed. - { - cpu = _screenRenderCpuUsage.GetCpuUsage(); // Get CPU usage for this thread. (Called if hwndCanged just to reset the GET CPU Usage function) - _nrOfTooLongRenderTimes = 0; // Reset count of too long render times. - return; // Return - nothing more to do since the window has changed. - } - // Check total rendering times - if (_maxAllowedRenderTime > 0 && totalRenderTime > _maxAllowedRenderTime) - { - if (!_deliverInHalfFrameRate || totalRenderTime > 2 - * _maxAllowedRenderTime) - { - _nrOfTooLongRenderTimes += totalRenderTime / _maxAllowedRenderTime; //Weighted with the number of to long render times - } - } - - // If we are not using back surface (ie full screen rendering) we might try to switch BlitFromMixingBufferToFrontBuffer mode. - if (timesSinceLastCPUCheck > WindowsThreadCpuUsage::CPU_CHECK_INTERVAL) - { - cpu = _screenRenderCpuUsage.GetCpuUsage(); // Get CPU usage for this thread. (Called if hwndCanged just to reset the GET CPU Usage function) - WEBRTC_TRACE( - kTraceStream, - kTraceVideo, - -1, - "Screen render thread cpu usage. (Tid %d), cpu usage %d processTime %d, no of too long render times %d", - GetCurrentThreadId(), cpu, totalRenderTime, - _nrOfTooLongRenderTimes); - - // If this screen render thread uses more than 5% of the total CPU time and the - // 1. try waitFix - if (cpu >= 5 && _renderModeWaitForCorrectScanLine == false - && !_backSurface) - { - WEBRTC_TRACE( - kTraceWarning, - kTraceVideo, - -1, - "HIGH screen render thread cpu usage. (Tid %d), cpu usage %d, applying wait for scan line", - GetCurrentThreadId(), cpu); - _renderModeWaitForCorrectScanLine = true; - _fullScreenWaitEvent->StartTimer(true, 1); - } - else if (cpu >= 10 && _deliverInHalfFrameRate == false) - { - WEBRTC_TRACE( - kTraceWarning, - kTraceVideo, - -1, - "HIGH screen render thread cpu usage. (Tid %d), cpu usage %d, Render half rate", - GetCurrentThreadId(), cpu); - _deliverInHalfFrameRate = true; - } - else - { - // Check if rendering takes too long time - if (_nrOfTooLongRenderTimes > 15 || totalRenderTime - >= WindowsThreadCpuUsage::CPU_CHECK_INTERVAL) - { - - // The rendering is taking too long time - if (_deliverInHalfFrameRate == false) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "Render half rate, tid: %d", - GetCurrentThreadId()); - _deliverInHalfFrameRate = true; - } - else if (_deliverInScreenType == false - && !_deliverInQuarterFrameRate) - { - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "Applying deliver in screen type format, tid: %d", - GetCurrentThreadId()); - // 2. try RGB fix - std::map::iterator it; - it = _directDrawChannels.begin(); - while (it != _directDrawChannels.end()) - { - it->second->ChangeDeliverColorFormat(true); - it++; - } - _deliverInScreenType = true; - } - else if (_deliverInQuarterFrameRate == false) - { - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "Render quarter rate and disable deliver in screen type format, tid: %d", - GetCurrentThreadId()); - _deliverInQuarterFrameRate = true; - if (_deliverInScreenType) - { - //Disable RGB fix - std::map::iterator it; - it = _directDrawChannels.begin(); - while (it != _directDrawChannels.end()) - { - it->second->ChangeDeliverColorFormat(false); - it++; - } - _deliverInScreenType = false; - } - } - else if (_deliverInQuarterFrameRate == true - && !_deliverInScreenType) - { - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "Render quarter rate and enable RGB fix, tid: %d", - GetCurrentThreadId()); - _deliverInQuarterFrameRate = true; - - //Enabe RGB fix - std::map::iterator it; - it = _directDrawChannels.begin(); - while (it != _directDrawChannels.end()) - { - it->second->ChangeDeliverColorFormat(true); - it++; - } - _deliverInScreenType = true; - } - } - } - _nrOfTooLongRenderTimes = 0; // Reset count of too long render times. - } -} - -/* - * Internal help functions for blitting - */ - -bool VideoRenderDirectDraw::HasHWNDChanged() -{ - // we check if the HWND has changed - if (!_fullscreen) - { - RECT currentRect; - ::GetClientRect(_hWnd, ¤tRect); - if (!EqualRect(¤tRect, &_hwndRect)) - { - int retVal = CreateMixingSurface(); // this will delete the old mixing surface - if (retVal != 0) - { - return false; - } - return true; - } - } - return false; -} - -int VideoRenderDirectDraw::BlitFromOffscreenBuffersToMixingBuffer() -{ - bool updateAll = false; // used to minimize the number of blt - - DDBLTFX ddbltfx; - ZeroMemory(&ddbltfx, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - ddbltfx.dwDDFX = DDBLTFX_NOTEARING; - - if (_mixingSurface == NULL) - { - int retVal = CreateMixingSurface(); - if (retVal != 0) - { - // trace done - return retVal; - } - } - RECT mixingRect; - ::SetRectEmpty(&mixingRect); - - if (_fullscreen) - { - ::CopyRect(&mixingRect, &_screenRect); - } - else - { - ::CopyRect(&mixingRect, &_hwndRect); - // what if largest size is larger than screen - if (mixingRect.right > _screenRect.right) - { - mixingRect.right = _screenRect.right; - } - if (mixingRect.bottom > _screenRect.bottom) - { - mixingRect.bottom = _screenRect.bottom; - } - } - if (!EqualRect(&_mixingRect, &mixingRect)) - { - // size changed - CopyRect(&_mixingRect, &mixingRect); - FillSurface(_mixingSurface, &mixingRect); - updateAll = true; - } - - if (_clearMixingSurface) - { - FillSurface(_mixingSurface, &_mixingRect); - _clearMixingSurface = false; - updateAll = true; - } - - std::multimap::reverse_iterator it; - it = _directDrawZorder.rbegin(); - while (it != _directDrawZorder.rend()) - { - // loop through all channels and streams in Z order - short streamID = (it->second >> 16); - int channel = it->second & 0x0000ffff; - - std::map::iterator ddIt; - ddIt = _directDrawChannels.find(channel); - if (ddIt != _directDrawChannels.end()) - { - // found the channel - DirectDrawChannel* channelObj = ddIt->second; - if (channelObj && _mixingSurface) - { - if (updateAll || channelObj->IsOffScreenSurfaceUpdated(this)) - { - updateAll = true; - if (channelObj->BlitFromOffscreenBufferToMixingBuffer( - this, - streamID, - _mixingSurface, - _mixingRect, - _demuxing) - != 0) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, - -1, - "DirectDraw error BlitFromOffscreenBufferToMixingBuffer "); - _mixingSurface->Release(); - _mixingSurface = NULL; - } - } - } - } - it++; - } - return 0; -} - -int VideoRenderDirectDraw::BlitFromTextToMixingBuffer() -{ - if (_directDraw == NULL) - { - return -1; - } - if (!_mixingSurface) - { - return -1; - } - if (_textSettings.empty()) - { - return 0; - } - - HDC hdcDDSurface; - HRESULT res = _mixingSurface->GetDC(&hdcDDSurface); - if (res != S_OK) - { - return -1; - } - // - std::map::reverse_iterator it; - it = _textSettings.rbegin(); - - while (it != _textSettings.rend()) - { - DirectDrawTextSettings* settings = it->second; - it++; - if (settings == NULL) - { - continue; - } - SetTextColor(hdcDDSurface, settings->_colorRefText); - SetBkColor(hdcDDSurface, settings->_colorRefBackground); - - if (settings->_transparent) - { - SetBkMode(hdcDDSurface, TRANSPARENT); // do we need to call this all the time? - } - else - { - SetBkMode(hdcDDSurface, OPAQUE); // do we need to call this all the time? - } - RECT textRect; - textRect.left = int(_mixingRect.right * settings->_textLeft); - textRect.right = int(_mixingRect.right * settings->_textRight); - textRect.top = int(_mixingRect.bottom * settings->_textTop); - textRect.bottom = int(_mixingRect.bottom * settings->_textBottom); - - DrawTextA(hdcDDSurface, settings->_ptrText, settings->_textLength, - &textRect, DT_LEFT); - } - _mixingSurface->ReleaseDC(hdcDDSurface); - return 0; -} - -int VideoRenderDirectDraw::BlitFromBitmapBuffersToMixingBuffer() -{ - HRESULT ddrval; - DDBLTFX ddbltfx; - ZeroMemory(&ddbltfx, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - ddbltfx.dwDDFX = DDBLTFX_NOTEARING; - - if (_directDraw == NULL) - { - return -1; // signal that we are not ready for the change - } - - std::map::reverse_iterator it; - it = _bitmapSettings.rbegin(); - - while (it != _bitmapSettings.rend()) - { - DirectDrawBitmapSettings* settings = it->second; - it++; - if (settings == NULL) - { - continue; - } - - // Color keying lets you set colors on a surface to be completely transparent. - // always blit _transparentBitmapSurface last - if (_mixingSurface && settings->_transparentBitmapSurface - && settings->_transparentBitmapWidth - && settings->_transparentBitmapHeight) - { - DWORD signal = DDBLT_WAIT | DDBLT_DDFX; - // Set transparent color - if (settings->_transparentBitmapColorKey) - { - signal |= DDBLT_KEYSRC; - settings->_transparentBitmapSurface->SetColorKey( - DDCKEY_SRCBLT, - settings->_transparentBitmapColorKey); - } - - // Now we can blt the transparent surface to another surface - RECT srcRect; - SetRect(&srcRect, 0, 0, settings->_transparentBitmapWidth, - settings->_transparentBitmapHeight); - - RECT dstRect; - if (settings->_transparentBitmapLeft - != settings->_transparentBitmapRight - && settings->_transparentBitmapTop - != settings->_transparentBitmapBottom) - { - CopyRect(&dstRect, &_mixingRect); - dstRect.left = (int) (dstRect.right - * settings->_transparentBitmapLeft); - dstRect.right = (int) (dstRect.right - * settings->_transparentBitmapRight); - dstRect.top = (int) (dstRect.bottom - * settings->_transparentBitmapTop); - dstRect.bottom = (int) (dstRect.bottom - * settings->_transparentBitmapBottom); - } - else - { - - // if left, right, top and bottom are describing one point use the original size - CopyRect(&dstRect, &srcRect); - POINT startp; - startp.x = (int) (_mixingRect.right - * settings->_transparentBitmapLeft); - startp.y = (int) (_mixingRect.bottom - * settings->_transparentBitmapTop); - OffsetRect(&dstRect, startp.x, startp.y); - - // make sure that we blit inside our surface - if (dstRect.bottom > _mixingRect.bottom) - { - srcRect.bottom -= dstRect.bottom - _mixingRect.bottom; - // sanity - if (srcRect.bottom < 0) - { - srcRect.bottom = 0; - } - dstRect.bottom = _mixingRect.bottom; - } - if (dstRect.right > _mixingRect.right) - { - srcRect.right -= dstRect.right - _mixingRect.right; - // sanity - if (srcRect.right < 0) - { - srcRect.right = 0; - } - dstRect.right = _mixingRect.right; - } - } - // ddbltfx.dwDDFX |= DDBLTFX_MIRRORUPDOWN; //only for test requires hw support - - // wait for the _mixingSurface to be available - ddrval = _mixingSurface->Blt(&dstRect, - settings->_transparentBitmapSurface, - &srcRect, signal, &ddbltfx); - if (ddrval == DDERR_SURFACELOST) - { - if (!::GetForegroundWindow()) - { - // no window, i.e the user have clicked CTRL+ALT+DEL - return 0; - } - // always re-creted via the SetBitmap call - settings->_transparentBitmapSurface->Release(); - settings->_transparentBitmapSurface = NULL; - - _clearMixingSurface = true; - - if (settings->_transparentBitMap) - { - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw re-set transparent bitmap"); - settings->SetBitmap(_trace, _directDraw); - } - } - else if (ddrval != DD_OK) - { - settings->_transparentBitmapSurface->Release(); - settings->_transparentBitmapSurface = NULL; - WEBRTC_TRACE( - kTraceInfo, - kTraceVideo, - -1, - "DirectDraw blt error 0x%x _transparentBitmapSurface", - ddrval); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - } - } - return 0; -} - -/** - * normal blitting - */ -int VideoRenderDirectDraw::BlitFromMixingBufferToFrontBuffer( - bool hwndChanged, - int& waitTime) -{ - DDBLTFX ddbltfx; - ZeroMemory(&ddbltfx, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - ddbltfx.dwDDFX = DDBLTFX_NOTEARING; - RECT rcRectDest; - - // test for changing mode - /* for(int i= 0; i< 6000000; i ++) - { - rcRectDest.left = i; - } - */ - - if (IsRectEmpty(&_mixingRect)) - { - // no error just nothing to blit - return 0; - } - if (_mixingSurface == NULL) - { - // The mixing surface has probably been deleted - // and we haven't had time to restore it yet. Wait... - return 0; - } - if (_primarySurface == NULL) - { - int retVal = CreatePrimarySurface(); - if (retVal != 0) - { - // tracing done - return retVal; - } - } - - // first we need to figure out where on the primary surface our window lives - ::GetWindowRect(_hWnd, &rcRectDest); - - DWORD signal = DDBLT_WAIT | DDBLT_DDFX; - - // Set transparent color - if (_transparentBackground) - { - signal |= DDBLT_KEYSRC; - DDCOLORKEY ColorKey; - ColorKey.dwColorSpaceLowValue = RGB(0, 0, 0); - ColorKey.dwColorSpaceHighValue = RGB(0, 0, 0); - _mixingSurface->SetColorKey(DDCKEY_SRCBLT, &ColorKey); - } - - if (_renderModeWaitForCorrectScanLine) - { - // wait for previus draw to complete - DWORD scanLines = 0; - DWORD screenLines = _screenRect.bottom - 1; // scanlines start on 0 - DWORD screenLines90 = (screenLines * 9) / 10; // % of the screen is rendered - //waitTime=GET_TIME_IN_MS(); - waitTime = ::timeGetTime(); - HRESULT hr = _directDraw->GetScanLine(&scanLines); - while (screenLines90 > scanLines && hr == DD_OK) - { - _confCritSect->Leave(); - _fullScreenWaitEvent->Wait(3); - _confCritSect->Enter(); - if (_directDraw == NULL) - { - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - hr = _directDraw->GetScanLine(&scanLines); - } - //waitTime=GET_TIME_IN_MS()-waitTime; - waitTime = ::timeGetTime() - waitTime; - } - - HRESULT ddrval = _primarySurface->Blt(&rcRectDest, _mixingSurface, - &_mixingRect, signal, &ddbltfx); - if (ddrval == DDERR_SURFACELOST) - { - if (!::GetForegroundWindow()) - { - // no window, i.e the user have clicked CTRL+ALT+DEL - return 0; - } - ddrval = _primarySurface->Restore(); - if (ddrval == DD_OK) // Try again - { - ddrval = _primarySurface->Blt(&rcRectDest, _mixingSurface, - &_mixingRect, signal, &ddbltfx); - } - if (ddrval != DD_OK) // If restore failed or second time blt failed. Delete the surface. It will be recreated next time. - { - WEBRTC_TRACE( - kTraceWarning, - kTraceVideo, - -1, - "DirectDraw failed to restore lost _primarySurface 0x%x", - ddrval); - _primarySurface->Release(); - _primarySurface = NULL; - if (_mixingSurface) - { - _mixingSurface->Release(); - _mixingSurface = NULL; - } - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw restored lost _primarySurface"); - } - else if (ddrval == DDERR_EXCEPTION) - { - _primarySurface->Release(); - _primarySurface = NULL; - if (_mixingSurface) - { - _mixingSurface->Release(); - _mixingSurface = NULL; - } - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw exception in _primarySurface"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - if (ddrval != DD_OK) - { - if (ddrval != 0x80004005) // Undefined error. Ignore - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw blt error 0x%x _primarySurface", ddrval); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - } - return 0; -} - -/** - * fullscreen mode blitting - */ - -int VideoRenderDirectDraw::WaitAndFlip(int& waitTime) -{ - if (_primarySurface == NULL) - { - // no trace, too much in the file - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - if (_directDraw == NULL) - { - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - // wait for previus draw to complete - DWORD scanLines = 0; - DWORD screenLines = _screenRect.bottom - 1; // scanlines start on 0 - DWORD screenLines90 = (screenLines * 9) / 10; // % of the screen is rendered - - //waitTime=GET_TIME_IN_MS(); - waitTime = ::timeGetTime(); - HRESULT hr = _directDraw->GetScanLine(&scanLines); - while (screenLines90 > scanLines && hr == DD_OK) - { - _confCritSect->Leave(); - _fullScreenWaitEvent->Wait(3); - _confCritSect->Enter(); - if (_directDraw == NULL) - { - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - hr = _directDraw->GetScanLine(&scanLines); - } - //waitTime=GET_TIME_IN_MS()-waitTime; - waitTime = ::timeGetTime() - waitTime; - if (screenLines > scanLines) - { - // this function sucks a lot of the CPU... but it's worth it - _directDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL); - } - - // schedule a flip - HRESULT ddrval = _primarySurface->Flip(NULL, DDFLIP_WAIT); // schedule flip DDFLIP_WAIT - if (ddrval == DDERR_SURFACELOST) - { - if (!::GetForegroundWindow()) - { - // no window, i.e the user have clicked CTRL+ALT+DEL - return 0; - } - //if(::IsIconic(_hWnd)) - //{ - // need to do this before Restore - //WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, "DirectDraw our window is an icon maximize it "); - // When the full screen window is switched out by ALT-TAB or ALT-CTRL-DEL-TASKMANAGER, - // this call will hang the app. Remove it to fix the problem. - // FIXME: - // 1) Why we want to active and max the window when it was minimized? - // 2) Why this is needed before restore? We didn't do that in non full screen mode. - //::ShowWindow(_hWnd, SW_SHOWMAXIMIZED); - //} - ddrval = _primarySurface->Restore(); - if (ddrval != DD_OK) - { - WEBRTC_TRACE( - kTraceWarning, - kTraceVideo, - -1, - "DirectDraw failed to restore _primarySurface, in flip, 0x%x", - ddrval); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw restore _primarySurface in flip"); - - } - else if (ddrval != DD_OK) - { - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - return 0; -} - -int VideoRenderDirectDraw::BlitFromMixingBufferToBackBuffer() -{ - if (_backSurface == NULL) - { - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - if (IsRectEmpty(&_mixingRect)) - { - // nothing to blit - return 0; - } - DDBLTFX ddbltfx; - ZeroMemory(&ddbltfx, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - ddbltfx.dwDDFX = DDBLTFX_NOTEARING; - - // wait for the _backSurface to be available - HRESULT ddrval = _backSurface->Blt(&_screenRect, _mixingSurface, - &_mixingRect, DDBLT_WAIT | DDBLT_DDFX, - &ddbltfx); - if (ddrval == DDERR_SURFACELOST) - { - if (!::GetForegroundWindow()) - { - // no window, i.e the user have clicked CTRL+ALT+DEL - return 0; - } - //if(::IsIconic(_hWnd)) - //{ - // need to do this before Restore - //WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, "DirectDraw our window is an icon maximize it "); - //WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, "DirectDraw show our window is an icon maximize it "); - // When the full screen window is switch out by ALT-TAB or ALT-CTRL-DEL-TASKMANAGER, - // this call will hang the app. Remove it to fix the problem. - // FIXME: - // 1) Why we want to active and max the window when it was minimized? - // 2) Why this is needed before restore? We didn't do that in non full screen mode. - //::ShowWindow(_hWnd, SW_SHOWMAXIMIZED); - //} - ddrval = _primarySurface->Restore(); - if (ddrval != DD_OK) - { - WEBRTC_TRACE(kTraceWarning, kTraceVideo, -1, - "DirectDraw failed to restore _primarySurface"); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, - "DirectDraw restored _primarySurface"); - - _clearMixingSurface = true; - - } - else if (ddrval != DD_OK) - { - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, - "DirectDraw blt error 0x%x _backSurface", ddrval); - return -1; - //return VIDEO_DIRECT_DRAW_FAILURE; - } - return 0; -} - -/* - Saving the code for using a clip list instead of HWND, problem was that other transparent - HWNDs caused us not to update an area or that we painted in other HWNDs area. - - RECT hWndRect; - ::GetWindowRect(_hWnd, &hWndRect); - - LPRGNDATA lpClipList = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER) + sizeof(RECT)); - - // now fill out all the structure fields - memcpy(lpClipList->Buffer, &hWndRect, sizeof(RECT)); - - ::CopyRect(&(lpClipList->rdh.rcBound), &hWndRect); - lpClipList->rdh.dwSize = sizeof(RGNDATAHEADER); - lpClipList->rdh.iType = RDH_RECTANGLES; - lpClipList->rdh.nCount = 1; - lpClipList->rdh.nRgnSize = sizeof(RECT) * lpClipList->rdh.nCount; - ddrval= _directDrawClipper->SetClipList(lpClipList, 0); - - void Visible(HWND hwnd, HRGN &hRgn) - { - if (!IsWindowVisible(hwnd)) // If the window is visible - { - if(CombineRgn(hRgn, hRgn, hRgn, RGN_XOR) == NULLREGION) - { - return; - } - } - // Gets the topmost window - HWND hWnd=GetTopWindow(NULL); - while (hWnd != NULL && hWnd != hwnd) // If the window is above in Z-order - { - if (IsWindowVisible(hWnd)) // If the window is visible - { - RECT Rect; - // Gets window dimension - GetWindowRect(hWnd, &Rect); - // Creates a region corresponding to the window - if(Rect.left > 0) // test fo rnow - { - HRGN hrgnWnd = CreateRectRgn(Rect.left, Rect.top, Rect.right, Rect.bottom); - // int err = GetUpdateRgn(hWnd, hrgnWnd, FALSE); - // Creates a region corresponding to region not overlapped - if(CombineRgn(hRgn, hRgn, hrgnWnd, RGN_DIFF) == COMPLEXREGION) - { - int a = 0; - } - DeleteObject(hrgnWnd); - } - } - // Loops through all windows till the specified window - hWnd = GetWindow(hWnd, GW_HWNDNEXT); - } - - HRGN region; - region = CreateRectRgn(0, 0, 500, 500); - - // Get the affected region - // if (GetUpdateRgn(_hWnd, region, FALSE) != ERROR) - HDC dc = GetDC(_hWnd); - if(GetClipRgn(dc, region) > 0) - { - int buffsize; - UINT x; - RGNDATA *buff; - POINT TopLeft; - - // Get the top-left point of the client area - TopLeft.x = 0; - TopLeft.y = 0; - if (!ClientToScreen(_hWnd, &TopLeft)) - { - int a = 0; - } - - - // Get the size of buffer required - buffsize = GetRegionData(region, 0, 0); - if (buffsize != 0) - { - buff = (RGNDATA *) new BYTE [buffsize]; - if (buff == NULL) - { - int a = 0; - } - - // Now get the region data - if(GetRegionData(region, buffsize, buff)) - { - if(buff->rdh.nCount > 0) - { - ::OffsetRect(&(buff->rdh.rcBound), TopLeft.x, TopLeft.y); - for (x=0; x<(buff->rdh.nCount); x++) - { - RECT *urect = (RECT *) (((BYTE *) buff) + sizeof(RGNDATAHEADER) + (x * sizeof(RECT))); - ::OffsetRect(urect, TopLeft.x, TopLeft.y); - char logStr[256]; - _snprintf(logStr,256, "rect T:%d L:%d B:%d R:%d\n",urect->top, urect->left, urect->bottom, urect->right); - OutputDebugString(logStr); - - } - OutputDebugString("\n"); - _directDrawClipper->SetClipList(buff, 0); - } - LPRGNDATA lpClipList = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER) + sizeof(RECT) * buff->rdh.nCount); - if(buff->rdh.nCount > 0) - { - _directDrawClipper->SetClipList(lpClipList, 0); - - lpClipList-> - DWORD size = sizeof(RGNDATAHEADER) + sizeof(RECT)* buff->rdh.nCount; - lpClipList->rdh.dwSize = sizeof(RGNDATAHEADER); - lpClipList->rdh.iType = RDH_RECTANGLES; - lpClipList->rdh.nCount = 1; - - HRESULT ddrval1 = _directDrawClipper->GetClipList(NULL, lpClipList, &size); - memcpy(lpClipList->Buffer, &rcRectDest, sizeof(RECT)); - ::CopyRect(&(lpClipList->rdh.rcBound), &rcRectDest); - _directDrawClipper->SetClipList(lpClipList, 0); - } } - - for (x=0; x<(buff->rdh.nCount); x++) - { - // Obtain the rectangles from the list - RECT *urect = (RECT *) (((BYTE *) buff) + sizeof(RGNDATAHEADER) + (x * sizeof(RECT))); - int a = 0; - - } - delete lpClipList; - } - delete buff; - } - } - */ -/* - void VideoRenderDirectDraw::Wait() - { - // wait for previus draw to complete - int count = 0; - DWORD scanLines = 0; - DWORD screenLines = _screenRect.bottom -1; // scanlines start on 0 - DWORD screenLines75 = (screenLines*3)/4; // % of the screen is rendered - HRESULT hr = DD_OK; - if(_directDraw == NULL) - { - return; - } - hr =_directDraw->GetScanLine(&scanLines); - while ( screenLines75 > scanLines && hr == DD_OK) - { - // _confCritSect->Leave(); - _screenEvent->Wait(10); - // _confCritSect->Enter(); - if(_directDraw == NULL) - { - return; - } - hr = _directDraw->GetScanLine(&scanLines); - } - } - */ - -WebRtc_Word32 VideoRenderDirectDraw::StartRender() -{ - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported."); - return 0; -} - -WebRtc_Word32 VideoRenderDirectDraw::StopRender() -{ - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported."); - return 0; -} - -WebRtc_Word32 VideoRenderDirectDraw::ChangeWindow(void* window) -{ - WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported."); - return -1; -} - -} //namespace webrtc - diff --git a/src/modules/video_render/main/source/windows/video_render_directdraw.h b/src/modules/video_render/main/source/windows/video_render_directdraw.h deleted file mode 100644 index 19fc5c3eab..0000000000 --- a/src/modules/video_render/main/source/windows/video_render_directdraw.h +++ /dev/null @@ -1,399 +0,0 @@ -/* - * 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. - */ - -#ifndef WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_WINDOWS_VIDEO_RENDER_DIRECTDRAW_H_ -#define WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_WINDOWS_VIDEO_RENDER_DIRECTDRAW_H_ - -#include "typedefs.h" -#include "i_video_render_win.h" -#include "common_video/libyuv/include/webrtc_libyuv.h" - -#include "ddraw.h" -#include -#include - -// Added -#include "video_render_defines.h" - -#pragma comment(lib, "ddraw.lib") // located in DirectX SDK - -namespace webrtc { -class CriticalSectionWrapper; -class EventWrapper; -class ThreadWrapper; -class Trace; - -class VideoRenderDirectDraw; - -// some typedefs to make it easy to test different versions -typedef IDirectDraw7 DirectDraw; -typedef IDirectDrawSurface7 DirectDrawSurface; -typedef DDSURFACEDESC2 DirectDrawSurfaceDesc; -typedef DDSCAPS2 DirectDrawCaps; -typedef std::pair ZorderPair; - -class WindowsThreadCpuUsage -{ -public: - WindowsThreadCpuUsage(); - int GetCpuUsage(); //in % since last call - DWORD LastGetCpuTime() - { - return _lastGetCpuUsageTime; - } - const enum - { - CPU_CHECK_INTERVAL = 1000 - }; -private: - _int64 _lastCpuUsageTime; - DWORD _lastGetCpuUsageTime; - int _lastCpuUsage; - HANDLE _hThread; - int _cores; -}; - -class DirectDrawStreamSettings -{ -public: - DirectDrawStreamSettings(); - - float _startWidth; - float _stopWidth; - float _startHeight; - float _stopHeight; - - float _cropStartWidth; - float _cropStopWidth; - float _cropStartHeight; - float _cropStopHeight; -}; - -class DirectDrawBitmapSettings -{ -public: - DirectDrawBitmapSettings(); - ~DirectDrawBitmapSettings(); - - int SetBitmap(Trace* trace, DirectDraw* directDraw); - - HBITMAP _transparentBitMap; - float _transparentBitmapLeft; - float _transparentBitmapRight; - float _transparentBitmapTop; - float _transparentBitmapBottom; - int _transparentBitmapWidth; - int _transparentBitmapHeight; - DDCOLORKEY* _transparentBitmapColorKey; - DirectDrawSurface* _transparentBitmapSurface; // size of bitmap image -}; - -class DirectDrawTextSettings -{ -public: - DirectDrawTextSettings(); - ~DirectDrawTextSettings(); - - int SetText(const char* text, int textLength, COLORREF colorText, - COLORREF colorBg, float left, float top, float right, - float bottom); - - char* _ptrText; - WebRtc_UWord32 _textLength; - COLORREF _colorRefText; - COLORREF _colorRefBackground; - float _textLeft; - float _textRight; - float _textTop; - float _textBottom; - bool _transparent; -}; - -class DirectDrawChannel: public VideoRenderCallback -{ -public: - DirectDrawChannel(DirectDraw* directDraw, - VideoType blitVideoType, - VideoType incomingVideoType, - VideoType screenVideoType, - VideoRenderDirectDraw* owner); - - int FrameSizeChange(int width, int height, int numberOfStreams); - int DeliverFrame(unsigned char* buffer, int buffeSize, - unsigned int timeStamp90KHz); - virtual WebRtc_Word32 RenderFrame(const WebRtc_UWord32 streamId, - VideoFrame& videoFrame); - - int ChangeDeliverColorFormat(bool useScreenType); - - void AddRef(); - void Release(); - - void SetStreamSettings(VideoRenderDirectDraw* DDObj, short streamId, - float startWidth, float startHeight, - float stopWidth, float stopHeight); - void SetStreamCropSettings(VideoRenderDirectDraw* DDObj, - short streamId, float startWidth, - float startHeight, float stopWidth, - float stopHeight); - - int GetStreamSettings(VideoRenderDirectDraw* DDObj, short streamId, - float& startWidth, float& startHeight, - float& stopWidth, float& stopHeight); - - void GetLargestSize(RECT* mixingRect); - int - BlitFromOffscreenBufferToMixingBuffer( - VideoRenderDirectDraw* DDObj, - short streamID, - DirectDrawSurface* mixingSurface, - RECT &dstRect, bool demuxing); - bool IsOffScreenSurfaceUpdated(VideoRenderDirectDraw* DDobj); - -protected: - virtual ~DirectDrawChannel(); - -private: - CriticalSectionWrapper* _critSect; // protect members from change while using them - int _refCount; - int _width; - int _height; - int _numberOfStreams; - bool _deliverInScreenType; - bool _doubleBuffer; - DirectDraw* _directDraw; - DirectDrawSurface* _offScreenSurface; // size of incoming stream - DirectDrawSurface* _offScreenSurfaceNext; // size of incoming stream - VideoType _blitVideoType; - VideoType _originalBlitVideoType; - VideoType _incomingVideoType; - VideoType _screenVideoType; - enum - { - MAX_FRAMEDELIVER_TIME = 20 - }; //Maximum time it might take to deliver a frame (process time in DeliverFrame) - enum - { - MAX_NO_OF_LATE_FRAMEDELIVER_TIME = 10 - }; //No of times we allow DeliverFrame process time to exceed MAX_FRAMEDELIVER_TIME before we take action. - VideoFrame _tempRenderBuffer; - - std::map - _streamIdToSettings; - bool _offScreenSurfaceUpdated; - VideoRenderDirectDraw* _owner; -}; - -class VideoRenderDirectDraw: IVideoRenderWin -{ -public: - VideoRenderDirectDraw(Trace* trace, HWND hWnd, bool fullscreen); - ~VideoRenderDirectDraw(); -public: - //IVideoRenderWin - - /************************************************************************** - * - * Init - * - ***************************************************************************/ - virtual WebRtc_Word32 Init(); - - /************************************************************************** - * - * Incoming Streams - * - ***************************************************************************/ - virtual VideoRenderCallback - * CreateChannel(const WebRtc_UWord32 streamId, - const WebRtc_UWord32 zOrder, const float left, - const float top, const float right, - const float bottom); - - virtual WebRtc_Word32 DeleteChannel(const WebRtc_UWord32 streamId); - - virtual WebRtc_Word32 GetStreamSettings(const WebRtc_UWord32 channel, - const WebRtc_UWord16 streamId, - WebRtc_UWord32& zOrder, - float& left, float& top, - float& right, float& bottom); - - /************************************************************************** - * - * Start/Stop - * - ***************************************************************************/ - - virtual WebRtc_Word32 StartRender(); - virtual WebRtc_Word32 StopRender(); - - /************************************************************************** - * - * Properties - * - ***************************************************************************/ - - virtual bool IsFullScreen(); - - virtual WebRtc_Word32 SetCropping(const WebRtc_UWord32 channel, - const WebRtc_UWord16 streamId, - const float left, const float top, - const float right, const float bottom); - - virtual WebRtc_Word32 SetTransparentBackground(const bool enable); - - virtual WebRtc_Word32 ChangeWindow(void* window); - - virtual WebRtc_Word32 GetGraphicsMemory(WebRtc_UWord64& totalMemory, - WebRtc_UWord64& availableMemory); - - virtual WebRtc_Word32 SetText(const WebRtc_UWord8 textId, - const WebRtc_UWord8* text, - const WebRtc_Word32 textLength, - const WebRtc_UWord32 colorText, - const WebRtc_UWord32 colorBg, - const float left, const float top, - const float rigth, const float bottom); - - virtual WebRtc_Word32 SetBitmap(const void* bitMap, - const WebRtc_UWord8 pictureId, - const void* colorKey, const float left, - const float top, const float right, - const float bottom); - - virtual WebRtc_Word32 ConfigureRenderer(const WebRtc_UWord32 channel, - const WebRtc_UWord16 streamId, - const unsigned int zOrder, - const float left, const float top, - const float right, - const float bottom); -public: - - // Used for emergency stops... - int Stop(); - - DirectDrawChannel* ShareDirectDrawChannel(int channel); - DirectDrawChannel* ConfigureDirectDrawChannel(int channel, - unsigned char streamID, - int zOrder, float left, - float top, float right, - float bottom); - - int AddDirectDrawChannel(int channel, unsigned char streamID, int zOrder, - DirectDrawChannel*); - - VideoType GetPerferedVideoFormat(); - bool HasChannels(); - bool HasChannel(int channel); - bool DeliverInScreenType(); - int GetChannels(std::list& channelList); - - // code for getting graphics settings - int GetScreenResolution(int& screenWidth, int& screenHeight); - int UpdateSystemCPUUsage(int systemCPU); - - int SetBitmap(HBITMAP bitMap, unsigned char pictureId, - DDCOLORKEY* colorKey, float left, float top, float rigth, - float bottom); - - bool IsPrimaryOrMixingSurfaceOnSystem(); - bool CanBltFourCC() - { - return _bCanBltFourcc; - } - -protected: - static bool RemoteRenderingThreadProc(void* obj); - bool RemoteRenderingProcess(); - -private: - int CheckCapabilities(); - int CreateMixingSurface(); - int CreatePrimarySurface(); - - int FillSurface(DirectDrawSurface *pDDSurface, RECT* rect); - int DrawOnSurface(unsigned char* buffer, int buffeSize); - int BlitFromOffscreenBuffersToMixingBuffer(); - int BlitFromBitmapBuffersToMixingBuffer(); - int BlitFromTextToMixingBuffer(); - - bool HasHWNDChanged(); - void DecideBestRenderingMode(bool hwndChanged, int totalRenderTime); - - // in fullscreen flip mode - int WaitAndFlip(int& waitTime); - int BlitFromMixingBufferToBackBuffer(); - - // in normal window mode - int BlitFromMixingBufferToFrontBuffer(bool hwndChanged, int& waitTime); - - // private members - Trace* _trace; - CriticalSectionWrapper* _confCritSect; // protect members from change while using them - - bool _fullscreen; - bool _demuxing; - bool _transparentBackground; - bool _supportTransparency; - bool _canStretch; - bool _canMirrorLeftRight; - bool _clearMixingSurface; - bool _deliverInScreenType; - bool _renderModeWaitForCorrectScanLine; - bool _deliverInHalfFrameRate; - bool _deliverInQuarterFrameRate; - bool _bCanBltFourcc; - bool _frameChanged; // True if a frame has changed or bitmap or text has changed. - int _processCount; - HWND _hWnd; - RECT _screenRect; // whole screen as a rect - RECT _mixingRect; - RECT _originalHwndRect; - RECT _hwndRect; - - VideoType _incomingVideoType; - VideoType _blitVideoType; - VideoType _rgbVideoType; - - DirectDraw* _directDraw; - DirectDrawSurface* _primarySurface; // size of screen - DirectDrawSurface* _backSurface; // size of screen - DirectDrawSurface* _mixingSurface; // size of screen - - std::map _bitmapSettings; - std::map _textSettings; - std::map _directDrawChannels; - std::multimap _directDrawZorder; - - EventWrapper* _fullScreenWaitEvent; - EventWrapper* _screenEvent; - ThreadWrapper* _screenRenderThread; - WindowsThreadCpuUsage _screenRenderCpuUsage; - - int _lastRenderModeCpuUsage; - - // Used for emergency stop caused by OnDisplayChange - bool _blit; - - //code for providing graphics settings - DWORD _totalMemory; - DWORD _availableMemory; - int _systemCPUUsage; - - // Variables used for checking render time - int _maxAllowedRenderTime; - int _nrOfTooLongRenderTimes; - bool _isPrimaryOrMixingSurfaceOnSystem; -}; - -} //namespace webrtc - - -#endif // WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_WINDOWS_VIDEO_RENDER_DIRECTDRAW_H_ diff --git a/src/modules/video_render/main/source/windows/video_render_windows_impl.cc b/src/modules/video_render/main/source/windows/video_render_windows_impl.cc index d6161fa456..f42714f0c4 100644 --- a/src/modules/video_render/main/source/windows/video_render_windows_impl.cc +++ b/src/modules/video_render/main/source/windows/video_render_windows_impl.cc @@ -13,9 +13,6 @@ #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 @@ -46,27 +43,9 @@ VideoRenderWindowsImpl::~VideoRenderWindowsImpl() WebRtc_Word32 VideoRenderWindowsImpl::Init() { - //LogOSAndHardwareDetails(); - CheckHWAcceleration(); - // 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(ptrRenderer); -#else - return NULL; -#endif //DIRECTDRAW_RENDERING - } - break; case kVideoRenderWinD3D9: { #ifdef DIRECT3D9_RENDERING @@ -365,619 +344,5 @@ WebRtc_Word32 VideoRenderWindowsImpl::SetBitmap(const void* bitMap, 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; - - // 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)) || - !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_bDDAccelerationEnabled ? - "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; - - //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)); - - 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 diff --git a/src/modules/video_render/main/source/windows/video_render_windows_impl.h b/src/modules/video_render/main/source/windows/video_render_windows_impl.h index bdc0a0a406..ba438e35a4 100644 --- a/src/modules/video_render/main/source/windows/video_render_windows_impl.h +++ b/src/modules/video_render/main/source/windows/video_render_windows_impl.h @@ -24,9 +24,8 @@ class CriticalSectionWrapper; #pragma comment(lib, "dxguid.lib") -enum VideoRenderWinMethod -{ - kVideoRenderWinDd = 0, kVideoRenderWinD3D9 = 1 +enum VideoRenderWinMethod { + kVideoRenderWinD3D9 = 0, }; // Class definitions @@ -129,17 +128,7 @@ public: const float top, const float right, const float bottom); - static int CheckHWAcceleration(); - static void CheckHWDriver(bool& badDriver, bool& fullAccelerationEnabled); - private: - - void LogOSAndHardwareDetails(); - HRESULT GetBoolValue(IDxDiagContainer* pObject, WCHAR* wstrName, - BOOL* pbValue); - HRESULT GetStringValue(IDxDiagContainer* pObject, WCHAR* wstrName, - TCHAR* strValue, int nStrLen); - WebRtc_Word32 _id; CriticalSectionWrapper& _renderWindowsCritsect;