/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "video_render_directdraw.h"
#include "video_render_windows_impl.h"
#include "Windows.h"
#include <ddraw.h>
#include <assert.h>
#include <initguid.h>
#include <MMSystem.h> // 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),
            _owner(owner)
{
    _directDraw->AddRef();
}

DirectDrawChannel::~DirectDrawChannel()
{
    if (_directDraw)
    {
        _directDraw->Release();
    }
    if (_offScreenSurface)
    {
        _offScreenSurface->Release();
    }
    if (_offScreenSurfaceNext)
    {
        _offScreenSurfaceNext->Release();
    }
    std::map<unsigned long long, DirectDrawStreamSettings*>::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<unsigned long long> (DDobj);
    lookupID &= 0xffffffffffffffe0;
    lookupID <<= 11;
    lookupID += streamId;

    CriticalSectionScoped cs(*_critSect);

    DirectDrawStreamSettings* streamSettings = NULL;

    std::map<unsigned long long, DirectDrawStreamSettings*>::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<unsigned long long> (DDObj);
    lookupID &= 0xffffffffffffffe0;
    lookupID <<= 11;
    lookupID += streamId;

    CriticalSectionScoped cs(*_critSect);

    DirectDrawStreamSettings* streamSettings = NULL;
    std::map<unsigned long long, DirectDrawStreamSettings*>::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<unsigned long long> (DDObj);
    lookupID &= 0xffffffffffffffe0;
    lookupID <<= 11;
    lookupID += streamId;

    DirectDrawStreamSettings* streamSettings = NULL;
    std::map<unsigned long long, DirectDrawStreamSettings*>::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;
    }

    unsigned char* ptr = (unsigned char*) ddsd.lpSurface;
    // ddsd.lPitch; distance in bytes


    switch (_incomingVideoType)
    {
        case kI420:
        {
            switch (_blitVideoType)
            {
                case kYUY2:
                case kUYVY:
                case kIYUV:  // same as kYV12
                case kYV12:
                    ConvertFromI420(buffer, _width,
                                    _blitVideoType, 0,
                                    _width, _height,
                                    ptr);
                    break;
                case kRGB24:
                {
                    _tempRenderBuffer.VerifyAndAllocate(_width * _height * 3);
                    unsigned char *ptrTempBuffer = _tempRenderBuffer.Buffer();
                    ConvertFromI420(buffer, _width, kRGB24, 0, _width, _height,
                                    ptrTempBuffer);
                    for (int i = 0; i < _height; i++)
                    {
                        memcpy(ptr, ptrTempBuffer, _width * 3);
                        ptrTempBuffer += _width * 3;
                        ptr += ddsd.lPitch;
                    }
                    break;
                }
                case kARGB:
                  ConvertFromI420(buffer, ddsd.lPitch, kARGB, 0,
                                  _width, _height, ptr);
                    break;
                case kARGB4444:
                    ConvertI420ToARGB4444(buffer, ptr, _width, _height,
                                          (ddsd.lPitch >> 1) - _width);
                    break;
                case kARGB1555:
                    ConvertI420ToARGB1555(buffer, ptr, _width, _height,
                                          (ddsd.lPitch >> 1) - _width);
                    break;
                case kRGB565:
                {
                    _tempRenderBuffer.VerifyAndAllocate(_width * _height * 2);
                    unsigned char *ptrTempBuffer = _tempRenderBuffer.Buffer();
                    ConvertI420ToRGB565(buffer, ptrTempBuffer, _width, _height);
                    ptr += ddsd.lPitch * (_height - 1);
                    for (int i = 0; i < _height; i++)
                    {
                        memcpy(ptr, ptrTempBuffer, _width * 2);
                        ptrTempBuffer += _width * 2;
                        ptr -= ddsd.lPitch;
                    }
                    break;
                }
                default:
                    assert(!"DirectDrawChannel::DeliverFrame unknown blitVideoType");
                    WEBRTC_TRACE(
                                 kTraceError,
                                 kTraceVideo,
                                 -1,
                                 "DirectDrawChannel::DeliverFrame unknown blitVideoType %d",
                                 _blitVideoType);
            }
            break;
        }
        default:
            assert(!"DirectDrawChannel::DeliverFrame wrong incomming video type");
            WEBRTC_TRACE(
                         kTraceError,
                         kTraceVideo,
                         -1,
                         "DirectDrawChannel::DeliverFrame wrong incomming %d",
                         _incomingVideoType);
    }

    _offScreenSurfaceUpdated = true;
    offScreenSurface->Unlock(NULL);
    return 0;
}

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<unsigned long long> (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<unsigned long long, DirectDrawStreamSettings*>::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<int, DirectDrawChannel*>::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<unsigned char, DirectDrawBitmapSettings*>::iterator bitIt;

    bitIt = _bitmapSettings.begin();
    while (_bitmapSettings.end() != bitIt)
    {
        delete bitIt->second;
        bitIt = _bitmapSettings.erase(bitIt);
    }

    std::map<unsigned char, DirectDrawTextSettings*>::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<int, DirectDrawChannel*>::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<int, unsigned int>::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<int, DirectDrawChannel*>::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<int, DirectDrawChannel*>::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<int, unsigned int>::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<int>& channelList)
{
    CriticalSectionScoped cs(*_confCritSect);

    std::map<int, DirectDrawChannel*>::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<int, DirectDrawChannel*>::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<int, DirectDrawChannel*>::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<int, unsigned int>::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<int, DirectDrawChannel*>::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<unsigned char, DirectDrawTextSettings*>::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<unsigned char, DirectDrawBitmapSettings*>::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<DDCOLORKEY*> (const_cast<void*> (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<VideoRenderDirectDraw*> (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<int, DirectDrawChannel*>::iterator it;
    it = _directDrawChannels.begin();
    while (it != _directDrawChannels.end() && !_frameChanged)
    {
        if (it->second)
        {
            int channel = it->first;
            _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<int, DirectDrawChannel*>::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<int, DirectDrawChannel*>::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<int, DirectDrawChannel*>::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, &currentRect);
        if (!EqualRect(&currentRect, &_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<int, unsigned int>::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<int, DirectDrawChannel*>::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<unsigned char, DirectDrawTextSettings*>::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<unsigned char, DirectDrawBitmapSettings*>::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

