/*
 *  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.
 */

// Own include file
#include "video_render_direct3d9.h"

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

// WebRtc include files
#include "critical_section_wrapper.h"
#include "event_wrapper.h"
#include "trace.h"
#include "thread_wrapper.h"
#include "common_video/libyuv/include/libyuv.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(WebRtc_UWord16 streamId,
                                        WebRtc_UWord32 zOrder,
                                        float startWidth,
                                        float startHeight,
                                        float stopWidth,
                                        float stopHeight)
{
    _streamId = streamId;
    _zOrder = zOrder;
    _startWidth = startWidth;
    _startHeight = startHeight;
    _stopWidth = stopWidth;
    _stopHeight = stopHeight;
}

int D3D9Channel::GetStreamSettings(WebRtc_UWord16 streamId,
                                       WebRtc_UWord32& 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;
}

WebRtc_Word32 D3D9Channel::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());
}

// Called from video engine when a new frame should be rendered.
int D3D9Channel::DeliverFrame(unsigned char* buffer,
                                  int bufferSize,
                                  unsigned int timeStamp90kHz)
{
    WEBRTC_TRACE(kTraceStream, kTraceVideo, -1,
                 "DeliverFrame to D3D9Channel");

    CriticalSectionScoped cs(*_critSect);

    //FIXME if _bufferIsUpdated is still true (not be renderred), do we what 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(buffer, _width, kARGB, 0, _width, _height, 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(),
    _screenUpdateThread(NULL),
    _screenUpdateEvent(NULL),
    _logoLeft(0),
    _logoTop(0),
    _logoRight(0),
    _logoBottom(0),
    _pd3dSurface(NULL),
    _totalMemory(-1),
    _availableMemory(-1)
{
    _screenUpdateThread = ThreadWrapper::CreateThread(ScreenUpdateThreadProc,
                                                      this, kRealtimePriority);
    _screenUpdateEvent = EventWrapper::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
    ThreadWrapper* tmpPtr = _screenUpdateThread;
    _screenUpdateThread = NULL;
    if (tmpPtr)
    {
        tmpPtr->SetNotAlive();
        _screenUpdateEvent->Set();
        _screenUpdateEvent->StopTimer();

        if (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->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
    //_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);

    // 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;
}

WebRtc_Word32 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;
    }
    unsigned int threadId;
    _screenUpdateThread->Start(threadId);

    // 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();
}

WebRtc_Word32 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);

        D3DXMATRIX matWorld;
        D3DXMATRIX matWorldTemp;

        //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();

                    WebRtc_UWord32 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 a = (DWORD) 0;

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

WebRtc_Word32 VideoRenderDirect3D9::DeleteChannel(const WebRtc_UWord32 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);
    D3D9Channel* ddobj = NULL;
    if (ddIt != _d3dChannels.end())
    {
        delete ddIt->second;
        _d3dChannels.erase(ddIt);        
        return 0;
    }
    return -1;
}

VideoRenderCallback* VideoRenderDirect3D9::CreateChannel(const WebRtc_UWord32 channel,
                                                                 const WebRtc_UWord32 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;
}

WebRtc_Word32 VideoRenderDirect3D9::GetStreamSettings(const WebRtc_UWord32 channel,
                                                          const WebRtc_UWord16 streamId,
                                                          WebRtc_UWord32& 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);
    //return ddobj->GetStreamSettings(streamId, 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;
}

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

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

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

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

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

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

WebRtc_Word32 VideoRenderDirect3D9::SetBitmap(const void* bitMap,
                                                  const WebRtc_UWord8 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");
        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");
        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;
        return -1;
    }
    if (!_pTextureLogo)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
                     "Texture for rendering not initialized.");
        return -1;
    }

    D3DLOCKED_RECT lr;
    if (FAILED(_pTextureLogo->LockRect(0, &lr, NULL, 0)))
    {
        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;

}

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

WebRtc_Word32 VideoRenderDirect3D9::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)
{
    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

