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

// Own include file
#include "webrtc/modules/video_render/windows/video_render_direct3d9.h"

// System include files
#include <windows.h>

// WebRtc include files
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/system_wrappers/include/trace.h"

namespace webrtc {

// A structure for our custom vertex type
struct CUSTOMVERTEX
{
    FLOAT x, y, z;
    DWORD color; // The vertex color
    FLOAT u, v;
};

// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)

/*
 *
 *    D3D9Channel
 *
 */
D3D9Channel::D3D9Channel(LPDIRECT3DDEVICE9 pd3DDevice,
                                 CriticalSectionWrapper* critSect,
                                 Trace* trace) :
    _width(0),
    _height(0),
    _pd3dDevice(pd3DDevice),
    _pTexture(NULL),
    _bufferIsUpdated(false),
    _critSect(critSect),
    _streamId(0),
    _zOrder(0),
    _startWidth(0),
    _startHeight(0),
    _stopWidth(0),
    _stopHeight(0)
{

}

D3D9Channel::~D3D9Channel()
{
    //release the texture
    if (_pTexture != NULL)
    {
        _pTexture->Release();
        _pTexture = NULL;
    }
}

void D3D9Channel::SetStreamSettings(uint16_t streamId,
                                        uint32_t zOrder,
                                        float startWidth,
                                        float startHeight,
                                        float stopWidth,
                                        float stopHeight)
{
    _streamId = streamId;
    _zOrder = zOrder;
    _startWidth = startWidth;
    _startHeight = startHeight;
    _stopWidth = stopWidth;
    _stopHeight = stopHeight;
}

int D3D9Channel::GetStreamSettings(uint16_t streamId,
                                       uint32_t& zOrder,
                                       float& startWidth,
                                       float& startHeight,
                                       float& stopWidth,
                                       float& stopHeight)
{
    streamId = _streamId;
    zOrder = _zOrder;
    startWidth = _startWidth;
    startHeight = _startHeight;
    stopWidth = _stopWidth;
    stopHeight = _stopHeight;
    return 0;
}

int D3D9Channel::GetTextureWidth()
{
    return _width;
}

int D3D9Channel::GetTextureHeight()
{
    return _height;
}

// Called from video engine when a the frame size changed
int D3D9Channel::FrameSizeChange(int width, int height, int numberOfStreams)
{
    WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1,
                 "FrameSizeChange, wifth: %d, height: %d, streams: %d", width,
                 height, numberOfStreams);

    CriticalSectionScoped cs(_critSect);
    _width = width;
    _height = height;

    //clean the previous texture
    if (_pTexture != NULL)
    {
        _pTexture->Release();
        _pTexture = NULL;
    }

    HRESULT ret = E_POINTER;

    if (_pd3dDevice)
      ret = _pd3dDevice->CreateTexture(_width, _height, 1, 0, D3DFMT_A8R8G8B8,
                                       D3DPOOL_MANAGED, &_pTexture, NULL);

    if (FAILED(ret))
    {
        _pTexture = NULL;
        return -1;
    }

    return 0;
}

int32_t D3D9Channel::RenderFrame(const uint32_t streamId,
                                 const 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);
}

// Called from video engine when a new frame should be rendered.
int D3D9Channel::DeliverFrame(const VideoFrame& videoFrame) {
  WEBRTC_TRACE(kTraceStream, kTraceVideo, -1,
               "DeliverFrame to D3D9Channel");

  CriticalSectionScoped cs(_critSect);

  // FIXME if _bufferIsUpdated is still true (not be renderred), do we want to
  // update the texture? probably not
  if (_bufferIsUpdated) {
    WEBRTC_TRACE(kTraceStream, kTraceVideo, -1,
                 "Last frame hasn't been rendered yet. Drop this frame.");
    return -1;
  }

  if (!_pd3dDevice) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                 "D3D for rendering not initialized.");
    return -1;
  }

  if (!_pTexture) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                 "Texture for rendering not initialized.");
    return -1;
  }

  D3DLOCKED_RECT lr;

  if (FAILED(_pTexture->LockRect(0, &lr, NULL, 0))) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                 "Failed to lock a texture in D3D9 Channel.");
    return -1;
  }
  UCHAR* pRect = (UCHAR*) lr.pBits;

  ConvertFromI420(videoFrame, kARGB, 0, pRect);

  if (FAILED(_pTexture->UnlockRect(0))) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                 "Failed to unlock a texture in D3D9 Channel.");
    return -1;
  }

  _bufferIsUpdated = true;
  return 0;
}

// Called by d3d channel owner to indicate the frame/texture has been rendered off
int D3D9Channel::RenderOffFrame()
{
    WEBRTC_TRACE(kTraceStream, kTraceVideo, -1,
                 "Frame has been rendered to the screen.");
    CriticalSectionScoped cs(_critSect);
    _bufferIsUpdated = false;
    return 0;
}

// Called by d3d channel owner to check if the texture is updated
int D3D9Channel::IsUpdated(bool& isUpdated)
{
    CriticalSectionScoped cs(_critSect);
    isUpdated = _bufferIsUpdated;
    return 0;
}

// Called by d3d channel owner to get the texture
LPDIRECT3DTEXTURE9 D3D9Channel::GetTexture()
{
    CriticalSectionScoped cs(_critSect);
    return _pTexture;
}

int D3D9Channel::ReleaseTexture()
{
    CriticalSectionScoped cs(_critSect);

    //release the texture
    if (_pTexture != NULL)
    {
        _pTexture->Release();
        _pTexture = NULL;
    }
    _pd3dDevice = NULL;
    return 0;
}

int D3D9Channel::RecreateTexture(LPDIRECT3DDEVICE9 pd3DDevice)
{
    CriticalSectionScoped cs(_critSect);

    _pd3dDevice = pd3DDevice;

    if (_pTexture != NULL)
    {
        _pTexture->Release();
        _pTexture = NULL;
    }

    HRESULT ret;

    ret = _pd3dDevice->CreateTexture(_width, _height, 1, 0, D3DFMT_A8R8G8B8,
                                     D3DPOOL_MANAGED, &_pTexture, NULL);

    if (FAILED(ret))
    {
        _pTexture = NULL;
        return -1;
    }

    return 0;
}

/*
 *
 *    VideoRenderDirect3D9
 *
 */
VideoRenderDirect3D9::VideoRenderDirect3D9(Trace* trace,
                                                   HWND hWnd,
                                                   bool fullScreen) :
    _refD3DCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
    _trace(trace),
    _hWnd(hWnd),
    _fullScreen(fullScreen),
    _pTextureLogo(NULL),
    _pVB(NULL),
    _pd3dDevice(NULL),
    _pD3D(NULL),
    _d3dChannels(),
    _d3dZorder(),
    _screenUpdateEvent(NULL),
    _logoLeft(0),
    _logoTop(0),
    _logoRight(0),
    _logoBottom(0),
    _pd3dSurface(NULL),
    _totalMemory(0),
    _availableMemory(0)
{
    _screenUpdateThread = PlatformThread::CreateThread(
        ScreenUpdateThreadProc, this, "ScreenUpdateThread");
    _screenUpdateEvent = EventTimerWrapper::Create();
    SetRect(&_originalHwndRect, 0, 0, 0, 0);
}

VideoRenderDirect3D9::~VideoRenderDirect3D9()
{
    //NOTE: we should not enter CriticalSection in here!

    // Signal event to exit thread, then delete it
    PlatformThread* tmpPtr = _screenUpdateThread.release();
    if (tmpPtr)
    {
        _screenUpdateEvent->Set();
        _screenUpdateEvent->StopTimer();

        tmpPtr->Stop();
        delete tmpPtr;
    }
    delete _screenUpdateEvent;

    //close d3d device
    CloseDevice();

    // Delete all channels
    std::map<int, D3D9Channel*>::iterator it = _d3dChannels.begin();
    while (it != _d3dChannels.end())
    {
        delete it->second;
        it = _d3dChannels.erase(it);
    }
    // Clean the zOrder map
    _d3dZorder.clear();

    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 &_refD3DCritsect;
}

DWORD VideoRenderDirect3D9::GetVertexProcessingCaps()
{
    D3DCAPS9 caps;
    DWORD dwVertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    if (SUCCEEDED(_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
                                       &caps)))
    {
        if ((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
                == D3DDEVCAPS_HWTRANSFORMANDLIGHT)
        {
            dwVertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
        }
    }
    return dwVertexProcessing;
}

int VideoRenderDirect3D9::InitializeD3D(HWND hWnd,
                                            D3DPRESENT_PARAMETERS* pd3dpp)
{
    // initialize Direct3D
    if (NULL == (_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
    {
        return -1;
    }

    // determine what type of vertex processing to use based on the device capabilities
    DWORD dwVertexProcessing = GetVertexProcessingCaps();

    // get the display mode
    D3DDISPLAYMODE d3ddm;
    _pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
    pd3dpp->BackBufferFormat = d3ddm.Format;

    // create the D3D device
    if (FAILED(_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                   dwVertexProcessing | D3DCREATE_MULTITHREADED
                                           | D3DCREATE_FPU_PRESERVE, pd3dpp,
                                   &_pd3dDevice)))
    {
        //try the ref device
        if (FAILED(_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF,
                                       hWnd, dwVertexProcessing
                                               | D3DCREATE_MULTITHREADED
                                               | D3DCREATE_FPU_PRESERVE,
                                       pd3dpp, &_pd3dDevice)))
        {
            return -1;
        }
    }

    return 0;
}

int VideoRenderDirect3D9::ResetDevice()
{
    WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1,
                 "VideoRenderDirect3D9::ResetDevice");

    CriticalSectionScoped cs(&_refD3DCritsect);

    //release the channel texture
    std::map<int, D3D9Channel*>::iterator it;
    it = _d3dChannels.begin();
    while (it != _d3dChannels.end())
    {
        if (it->second)
        {
            it->second->ReleaseTexture();
        }
        it++;
    }

    //close d3d device
    if (CloseDevice() != 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "VideoRenderDirect3D9::ResetDevice failed to CloseDevice");
        return -1;
    }

    //reinit d3d device
    if (InitDevice() != 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "VideoRenderDirect3D9::ResetDevice failed to InitDevice");
        return -1;
    }

    //recreate channel texture
    it = _d3dChannels.begin();
    while (it != _d3dChannels.end())
    {
        if (it->second)
        {
            it->second->RecreateTexture(_pd3dDevice);
        }
        it++;
    }

    return 0;
}

int VideoRenderDirect3D9::InitDevice()
{
    // Set up the structure used to create the D3DDevice
    ZeroMemory(&_d3dpp, sizeof(_d3dpp));
    _d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    _d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
    if (GetWindowRect(_hWnd, &_originalHwndRect) == 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "VideoRenderDirect3D9::InitDevice Could not get window size");
        return -1;
    }
    if (!_fullScreen)
    {
        _winWidth = _originalHwndRect.right - _originalHwndRect.left;
        _winHeight = _originalHwndRect.bottom - _originalHwndRect.top;
        _d3dpp.Windowed = TRUE;
        _d3dpp.BackBufferHeight = 0;
        _d3dpp.BackBufferWidth = 0;
    }
    else
    {
        _winWidth = (LONG) ::GetSystemMetrics(SM_CXSCREEN);
        _winHeight = (LONG) ::GetSystemMetrics(SM_CYSCREEN);
        _d3dpp.Windowed = FALSE;
        _d3dpp.BackBufferWidth = _winWidth;
        _d3dpp.BackBufferHeight = _winHeight;
        _d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    }

    if (InitializeD3D(_hWnd, &_d3dpp) == -1)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "VideoRenderDirect3D9::InitDevice failed in InitializeD3D");
        return -1;
    }

    // Turn off culling, so we see the front and back of the triangle
    _pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    // Turn off D3D lighting, since we are providing our own vertex colors
    _pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

    // Settings for alpha blending
    _pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    _pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    _pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

    _pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    _pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
    _pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );

    // Initialize Vertices
    CUSTOMVERTEX Vertices[] = {
            //front
            { -1.0f, -1.0f, 0.0f, 0xffffffff, 0, 1 }, { -1.0f, 1.0f, 0.0f,
                    0xffffffff, 0, 0 },
            { 1.0f, -1.0f, 0.0f, 0xffffffff, 1, 1 }, { 1.0f, 1.0f, 0.0f,
                    0xffffffff, 1, 0 } };

    // Create the vertex buffer.
    if (FAILED(_pd3dDevice->CreateVertexBuffer(sizeof(Vertices), 0,
                                               D3DFVF_CUSTOMVERTEX,
                                               D3DPOOL_DEFAULT, &_pVB, NULL )))
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Failed to create the vertex buffer.");
        return -1;
    }

    // Now we fill the vertex buffer.
    VOID* pVertices;
    if (FAILED(_pVB->Lock(0, sizeof(Vertices), (void**) &pVertices, 0)))
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Failed to lock the vertex buffer.");
        return -1;
    }
    memcpy(pVertices, Vertices, sizeof(Vertices));
    _pVB->Unlock();

    return 0;
}

int32_t VideoRenderDirect3D9::Init()
{
    WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1,
                 "VideoRenderDirect3D9::Init");

    CriticalSectionScoped cs(&_refD3DCritsect);

    // Start rendering thread...
    if (!_screenUpdateThread)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Thread not created");
        return -1;
    }
    _screenUpdateThread->Start();
    _screenUpdateThread->SetPriority(kRealtimePriority);

    // Start the event triggering the render process
    unsigned int monitorFreq = 60;
    DEVMODE dm;
    // initialize the DEVMODE structure
    ZeroMemory(&dm, sizeof(dm));
    dm.dmSize = sizeof(dm);
    if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
    {
        monitorFreq = dm.dmDisplayFrequency;
    }
    _screenUpdateEvent->StartTimer(true, 1000 / monitorFreq);

    return InitDevice();
}

int32_t VideoRenderDirect3D9::ChangeWindow(void* window)
{
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
    return -1;
}

int VideoRenderDirect3D9::UpdateRenderSurface()
{
    CriticalSectionScoped cs(&_refD3DCritsect);

    // Check if there are any updated buffers
    bool updated = false;
    std::map<int, D3D9Channel*>::iterator it;
    it = _d3dChannels.begin();
    while (it != _d3dChannels.end())
    {

        D3D9Channel* channel = it->second;
        channel->IsUpdated(updated);
        if (updated)
        {
            break;
        }
        it++;
    }
    //nothing is updated, continue
    if (!updated)
        return -1;

    // Clear the backbuffer to a black color
    _pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f,
                       0);

    // Begin the scene
    if (SUCCEEDED(_pd3dDevice->BeginScene()))
    {
        _pd3dDevice->SetStreamSource(0, _pVB, 0, sizeof(CUSTOMVERTEX));
        _pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);

        //draw all the channels
        //get texture from the channels
        LPDIRECT3DTEXTURE9 textureFromChannel = NULL;
        DWORD textureWidth, textureHeight;

        std::multimap<int, unsigned int>::reverse_iterator it;
        it = _d3dZorder.rbegin();
        while (it != _d3dZorder.rend())
        {
            // loop through all channels and streams in Z order
            int channel = it->second & 0x0000ffff;

            std::map<int, D3D9Channel*>::iterator ddIt;
            ddIt = _d3dChannels.find(channel);
            if (ddIt != _d3dChannels.end())
            {
                // found the channel
                D3D9Channel* channelObj = ddIt->second;
                if (channelObj)
                {
                    textureFromChannel = channelObj->GetTexture();
                    textureWidth = channelObj->GetTextureWidth();
                    textureHeight = channelObj->GetTextureHeight();

                    uint32_t zOrder;
                    float startWidth, startHeight, stopWidth, stopHeight;
                    channelObj->GetStreamSettings(0, zOrder, startWidth,
                                                  startHeight, stopWidth,
                                                  stopHeight);

                    //draw the video stream
                    UpdateVerticeBuffer(_pVB, 0, startWidth, startHeight,
                                        stopWidth, stopHeight);
                    _pd3dDevice->SetTexture(0, textureFromChannel);
                    _pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

                    //Notice channel that this frame as been rendered
                    channelObj->RenderOffFrame();
                }
            }
            it++;
        }

        //draw the logo
        if (_pTextureLogo)
        {
            UpdateVerticeBuffer(_pVB, 0, _logoLeft, _logoTop, _logoRight,
                                _logoBottom);
            _pd3dDevice->SetTexture(0, _pTextureLogo);
            _pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
        }

        // End the scene
        _pd3dDevice->EndScene();
    }

    // Present the backbuffer contents to the display
    _pd3dDevice->Present(NULL, NULL, NULL, NULL );

    return 0;
}

//set the  alpha value of the pixal with a particular colorkey as 0
int VideoRenderDirect3D9::SetTransparentColor(LPDIRECT3DTEXTURE9 pTexture,
                                                  DDCOLORKEY* transparentColorKey,
                                                  DWORD width,
                                                  DWORD height)
{
    D3DLOCKED_RECT lr;
    if (!pTexture)
        return -1;

    CriticalSectionScoped cs(&_refD3DCritsect);
    if (SUCCEEDED(pTexture->LockRect(0, &lr, NULL, D3DLOCK_DISCARD)))
    {
        for (DWORD y = 0; y < height; y++)
        {
            DWORD dwOffset = y * width;

            for (DWORD x = 0; x < width; x)
            {
                DWORD temp = ((DWORD*) lr.pBits)[dwOffset + x];
                if ((temp & 0x00FFFFFF)
                        == transparentColorKey->dwColorSpaceLowValue)
                {
                    temp &= 0x00FFFFFF;
                }
                else
                {
                    temp |= 0xFF000000;
                }
                ((DWORD*) lr.pBits)[dwOffset + x] = temp;
                x++;
            }
        }
        pTexture->UnlockRect(0);
        return 0;
    }
    return -1;
}

/*
 *
 *    Rendering process
 *
 */
bool VideoRenderDirect3D9::ScreenUpdateThreadProc(void* obj)
{
    return static_cast<VideoRenderDirect3D9*> (obj)->ScreenUpdateProcess();
}

bool VideoRenderDirect3D9::ScreenUpdateProcess()
{
    _screenUpdateEvent->Wait(100);

    if (!_screenUpdateThread)
    {
        //stop the thread
        return false;
    }
    if (!_pd3dDevice)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "d3dDevice not created.");
        return true;
    }

    HRESULT hr = _pd3dDevice->TestCooperativeLevel();

    if (SUCCEEDED(hr))
    {
        UpdateRenderSurface();
    }

    if (hr == D3DERR_DEVICELOST)
    {
        //Device is lost and cannot be reset yet

    }
    else if (hr == D3DERR_DEVICENOTRESET)
    {
        //Lost but we can reset it now
        //Note: the standard way is to call Reset, however for some reason doesn't work here.
        //so we will release the device and create it again.
        ResetDevice();
    }

    return true;
}

int VideoRenderDirect3D9::CloseDevice()
{
    CriticalSectionScoped cs(&_refD3DCritsect);
    WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1,
                 "VideoRenderDirect3D9::CloseDevice");

    if (_pTextureLogo != NULL)
    {
        _pTextureLogo->Release();
        _pTextureLogo = NULL;
    }

    if (_pVB != NULL)
    {
        _pVB->Release();
        _pVB = NULL;
    }

    if (_pd3dDevice != NULL)
    {
        _pd3dDevice->Release();
        _pd3dDevice = NULL;
    }

    if (_pD3D != NULL)
    {
        _pD3D->Release();
        _pD3D = NULL;
    }

    if (_pd3dSurface != NULL)
        _pd3dSurface->Release();
    return 0;
}

D3D9Channel* VideoRenderDirect3D9::GetD3DChannel(int channel)
{
    std::map<int, D3D9Channel*>::iterator ddIt;
    ddIt = _d3dChannels.find(channel & 0x0000ffff);
    D3D9Channel* ddobj = NULL;
    if (ddIt != _d3dChannels.end())
    {
        ddobj = ddIt->second;
    }
    if (ddobj == NULL)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Direct3D render failed to find channel");
        return NULL;
    }
    return ddobj;
}

int32_t VideoRenderDirect3D9::DeleteChannel(const uint32_t streamId)
{
    CriticalSectionScoped cs(&_refD3DCritsect);


    std::multimap<int, unsigned int>::iterator it;
    it = _d3dZorder.begin();
    while (it != _d3dZorder.end())
    {
        if ((streamId & 0x0000ffff) == (it->second & 0x0000ffff))
        {
            it = _d3dZorder.erase(it);
            break;
        }
        it++;
    }

    std::map<int, D3D9Channel*>::iterator ddIt;
    ddIt = _d3dChannels.find(streamId & 0x0000ffff);
    if (ddIt != _d3dChannels.end())
    {
        delete ddIt->second;
        _d3dChannels.erase(ddIt);
        return 0;
    }
    return -1;
}

VideoRenderCallback* VideoRenderDirect3D9::CreateChannel(const uint32_t channel,
                                                                 const uint32_t zOrder,
                                                                 const float left,
                                                                 const float top,
                                                                 const float right,
                                                                 const float bottom)
{
    CriticalSectionScoped cs(&_refD3DCritsect);

    //FIXME this should be done in VideoAPIWindows? stop the frame deliver first
    //remove the old channel
    DeleteChannel(channel);

    D3D9Channel* d3dChannel = new D3D9Channel(_pd3dDevice,
                                                      &_refD3DCritsect, _trace);
    d3dChannel->SetStreamSettings(0, zOrder, left, top, right, bottom);

    // store channel
    _d3dChannels[channel & 0x0000ffff] = d3dChannel;

    // store Z order
    // default streamID is 0
    _d3dZorder.insert(
                      std::pair<int, unsigned int>(zOrder, channel & 0x0000ffff));

    return d3dChannel;
}

int32_t VideoRenderDirect3D9::GetStreamSettings(const uint32_t channel,
                                                const uint16_t streamId,
                                                uint32_t& zOrder,
                                                float& left, float& top,
                                                float& right, float& bottom)
{
    std::map<int, D3D9Channel*>::iterator ddIt;
    ddIt = _d3dChannels.find(channel & 0x0000ffff);
    D3D9Channel* ddobj = NULL;
    if (ddIt != _d3dChannels.end())
    {
        ddobj = ddIt->second;
    }
    if (ddobj == NULL)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Direct3D render failed to find channel");
        return -1;
    }
    // Only allow one stream per channel, demuxing is
    return ddobj->GetStreamSettings(0, zOrder, left, top, right, bottom);
}

int VideoRenderDirect3D9::UpdateVerticeBuffer(LPDIRECT3DVERTEXBUFFER9 pVB,
                                                  int offset,
                                                  float startWidth,
                                                  float startHeight,
                                                  float stopWidth,
                                                  float stopHeight)
{
    if (pVB == NULL)
        return -1;

    float left, right, top, bottom;

    //update the vertice buffer
    //0,1 => -1,1
    left = startWidth * 2 - 1;
    right = stopWidth * 2 - 1;

    //0,1 => 1,-1
    top = 1 - startHeight * 2;
    bottom = 1 - stopHeight * 2;

    CUSTOMVERTEX newVertices[] = {
            //logo
            { left, bottom, 0.0f, 0xffffffff, 0, 1 }, { left, top, 0.0f,
                    0xffffffff, 0, 0 },
            { right, bottom, 0.0f, 0xffffffff, 1, 1 }, { right, top, 0.0f,
                    0xffffffff, 1, 0 }, };
    // Now we fill the vertex buffer.
    VOID* pVertices;
    if (FAILED(pVB->Lock(sizeof(CUSTOMVERTEX) * offset, sizeof(newVertices),
                         (void**) &pVertices, 0)))
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Failed to lock the vertex buffer.");
        return -1;
    }
    memcpy(pVertices, newVertices, sizeof(newVertices));
    pVB->Unlock();

    return 0;
}

int32_t VideoRenderDirect3D9::StartRender()
{
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
    return 0;
}

int32_t VideoRenderDirect3D9::StopRender()
{
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
    return 0;
}

bool VideoRenderDirect3D9::IsFullScreen()
{
    return _fullScreen;
}

int32_t VideoRenderDirect3D9::SetCropping(const uint32_t channel,
                                          const uint16_t streamId,
                                          const float left, const float top,
                                          const float right, const float bottom)
{
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
    return 0;
}

int32_t VideoRenderDirect3D9::SetTransparentBackground(
                                                                 const bool enable)
{
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
    return 0;
}

int32_t VideoRenderDirect3D9::SetText(const uint8_t textId,
                                      const uint8_t* text,
                                      const int32_t textLength,
                                      const uint32_t colorText,
                                      const uint32_t colorBg,
                                      const float left, const float top,
                                      const float rigth, const float bottom)
{
    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
    return 0;
}

int32_t VideoRenderDirect3D9::SetBitmap(const void* bitMap,
                                        const uint8_t pictureId,
                                        const void* colorKey,
                                        const float left, const float top,
                                        const float right, const float bottom)
{
    if (!bitMap)
    {
        if (_pTextureLogo != NULL)
        {
            _pTextureLogo->Release();
            _pTextureLogo = NULL;
        }
        WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, "Remove bitmap.");
        return 0;
    }

    // sanity
    if (left > 1.0f || left < 0.0f ||
        top > 1.0f || top < 0.0f ||
        right > 1.0f || right < 0.0f ||
        bottom > 1.0f || bottom < 0.0f)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Direct3D SetBitmap invalid parameter");
        return -1;
    }

    if ((bottom <= top) || (right <= left))
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Direct3D SetBitmap invalid parameter");
        return -1;
    }

    CriticalSectionScoped cs(&_refD3DCritsect);

    unsigned char* srcPtr;
    HGDIOBJ oldhand;
    BITMAPINFO pbi;
    BITMAP bmap;
    HDC hdcNew;
    hdcNew = CreateCompatibleDC(0);
    // Fill out the BITMAP structure.
    GetObject((HBITMAP)bitMap, sizeof(bmap), &bmap);
    //Select the bitmap handle into the new device context.
    oldhand = SelectObject(hdcNew, (HGDIOBJ) bitMap);
    // 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;
    srcPtr = new unsigned char[bmap.bmWidth * bmap.bmHeight * 4];
    // the original un-stretched image in RGB24
    int pixelHeight = GetDIBits(hdcNew, (HBITMAP)bitMap, 0, bmap.bmHeight, srcPtr, &pbi,
                                DIB_RGB_COLORS);
    if (pixelHeight == 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Direct3D failed to GetDIBits in SetBitmap");
        delete[] srcPtr;
        return -1;
    }
    DeleteDC(hdcNew);
    if (pbi.bmiHeader.biBitCount != 24 && pbi.bmiHeader.biBitCount != 32)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Direct3D failed to SetBitmap invalid bit depth");
        delete[] srcPtr;
        return -1;
    }

    HRESULT ret;
    //release the previous logo texture
    if (_pTextureLogo != NULL)
    {
        _pTextureLogo->Release();
        _pTextureLogo = NULL;
    }
    ret = _pd3dDevice->CreateTexture(bmap.bmWidth, bmap.bmHeight, 1, 0,
                                     D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
                                     &_pTextureLogo, NULL);
    if (FAILED(ret))
    {
        _pTextureLogo = NULL;
        delete[] srcPtr;
        return -1;
    }
    if (!_pTextureLogo)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Texture for rendering not initialized.");
        delete[] srcPtr;
        return -1;
    }

    D3DLOCKED_RECT lr;
    if (FAILED(_pTextureLogo->LockRect(0, &lr, NULL, 0)))
    {
        delete[] srcPtr;
        return -1;
    }
    unsigned char* dstPtr = (UCHAR*) lr.pBits;
    int pitch = bmap.bmWidth * 4;

    if (pbi.bmiHeader.biBitCount == 24)
    {
        ConvertRGB24ToARGB(srcPtr, dstPtr, bmap.bmWidth, bmap.bmHeight, 0);
    }
    else
    {
        unsigned char* srcTmp = srcPtr + (bmap.bmWidth * 4) * (bmap.bmHeight - 1);
        for (int i = 0; i < bmap.bmHeight; ++i)
        {
            memcpy(dstPtr, srcTmp, bmap.bmWidth * 4);
            srcTmp -= bmap.bmWidth * 4;
            dstPtr += pitch;
        }
    }

    delete[] srcPtr;
    if (FAILED(_pTextureLogo->UnlockRect(0)))
    {
        return -1;
    }

    if (colorKey)
    {
        DDCOLORKEY* ddColorKey =
                static_cast<DDCOLORKEY*> (const_cast<void*> (colorKey));
        SetTransparentColor(_pTextureLogo, ddColorKey, bmap.bmWidth,
                            bmap.bmHeight);
    }

    //update the vertice buffer
    //0,1 => -1,1
    _logoLeft = left;
    _logoRight = right;

    //0,1 => 1,-1
    _logoTop = top;
    _logoBottom = bottom;

    return 0;

}

int32_t VideoRenderDirect3D9::GetGraphicsMemory(uint64_t& totalMemory,
                                                uint64_t& availableMemory)
{
    if (_totalMemory == -1 || _availableMemory == -1)
    {
        totalMemory = 0;
        availableMemory = 0;
        return -1;
    }
    totalMemory = _totalMemory;
    availableMemory = _availableMemory;
    return 0;
}

int32_t VideoRenderDirect3D9::ConfigureRenderer(const uint32_t channel,
                                                const uint16_t streamId,
                                                const unsigned int zOrder,
                                                const float left,
                                                const float top,
                                                const float right,
                                                const float bottom)
{
    std::map<int, D3D9Channel*>::iterator ddIt;
    ddIt = _d3dChannels.find(channel & 0x0000ffff);
    D3D9Channel* ddobj = NULL;
    if (ddIt != _d3dChannels.end())
    {
        ddobj = ddIt->second;
    }
    if (ddobj == NULL)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Direct3D render failed to find channel");
        return -1;
    }
    // Only allow one stream per channel, demuxing is
    ddobj->SetStreamSettings(0, zOrder, left, top, right, bottom);

    return 0;
}

}  // namespace webrtc
