1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Own include file
127e5dc8741fbd5f07a709e6fd4d2cd8b08b7cee94pbos@webrtc.org#include "webrtc/modules/video_render/windows/video_render_direct3d9.h"
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// System include files
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <windows.h>
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// WebRtc include files
187e5dc8741fbd5f07a709e6fd4d2cd8b08b7cee94pbos@webrtc.org#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
197e5dc8741fbd5f07a709e6fd4d2cd8b08b7cee94pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
207e5dc8741fbd5f07a709e6fd4d2cd8b08b7cee94pbos@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h"
217e5dc8741fbd5f07a709e6fd4d2cd8b08b7cee94pbos@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h"
227e5dc8741fbd5f07a709e6fd4d2cd8b08b7cee94pbos@webrtc.org#include "webrtc/system_wrappers/interface/trace.h"
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// A structure for our custom vertex type
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstruct CUSTOMVERTEX
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    FLOAT x, y, z;
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DWORD color; // The vertex color
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    FLOAT u, v;
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Our custom FVF, which describes our custom vertex structure
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *    D3D9Channel
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgD3D9Channel::D3D9Channel(LPDIRECT3DDEVICE9 pd3DDevice,
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                 CriticalSectionWrapper* critSect,
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                 Trace* trace) :
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _width(0),
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _height(0),
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice(pd3DDevice),
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pTexture(NULL),
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _bufferIsUpdated(false),
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect(critSect),
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _streamId(0),
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _zOrder(0),
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _startWidth(0),
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _startHeight(0),
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _stopWidth(0),
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _stopHeight(0)
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgD3D9Channel::~D3D9Channel()
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //release the texture
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pTexture != NULL)
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture->Release();
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture = NULL;
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
71e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgvoid D3D9Channel::SetStreamSettings(uint16_t streamId,
72e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                        uint32_t zOrder,
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        float startWidth,
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        float startHeight,
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        float stopWidth,
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        float stopHeight)
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _streamId = streamId;
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _zOrder = zOrder;
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _startWidth = startWidth;
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _startHeight = startHeight;
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _stopWidth = stopWidth;
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _stopHeight = stopHeight;
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
86e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint D3D9Channel::GetStreamSettings(uint16_t streamId,
87e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                       uint32_t& zOrder,
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       float& startWidth,
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       float& startHeight,
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       float& stopWidth,
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       float& stopHeight)
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    streamId = _streamId;
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    zOrder = _zOrder;
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    startWidth = _startWidth;
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    startHeight = _startHeight;
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    stopWidth = _stopWidth;
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    stopHeight = _stopHeight;
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint D3D9Channel::GetTextureWidth()
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _width;
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint D3D9Channel::GetTextureHeight()
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _height;
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Called from video engine when a the frame size changed
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint D3D9Channel::FrameSizeChange(int width, int height, int numberOfStreams)
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1,
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "FrameSizeChange, wifth: %d, height: %d, streams: %d", width,
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 height, numberOfStreams);
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _width = width;
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _height = height;
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //clean the previous texture
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pTexture != NULL)
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture->Release();
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture = NULL;
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    HRESULT ret = E_POINTER;
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pd3dDevice)
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ret = _pd3dDevice->CreateTexture(_width, _height, 1, 0, D3DFMT_A8R8G8B8,
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       D3DPOOL_MANAGED, &_pTexture, NULL);
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (FAILED(ret))
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture = NULL;
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
145e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t D3D9Channel::RenderFrame(const uint32_t streamId,
146e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                 I420VideoFrame& videoFrame)
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
1493bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    if (_width != videoFrame.width() || _height != videoFrame.height())
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1513bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        if (FrameSizeChange(videoFrame.width(), videoFrame.height(), 1) == -1)
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return -1;
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return DeliverFrame(videoFrame);
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Called from video engine when a new frame should be rendered.
1603bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.orgint D3D9Channel::DeliverFrame(const I420VideoFrame& videoFrame) {
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  WEBRTC_TRACE(kTraceStream, kTraceVideo, -1,
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org               "DeliverFrame to D3D9Channel");
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  CriticalSectionScoped cs(_critSect);
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // FIXME if _bufferIsUpdated is still true (not be renderred), do we want to
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // update the texture? probably not
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (_bufferIsUpdated) {
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceStream, kTraceVideo, -1,
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "Last frame hasn't been rendered yet. Drop this frame.");
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!_pd3dDevice) {
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "D3D for rendering not initialized.");
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!_pTexture) {
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "Texture for rendering not initialized.");
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  D3DLOCKED_RECT lr;
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (FAILED(_pTexture->LockRect(0, &lr, NULL, 0))) {
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "Failed to lock a texture in D3D9 Channel.");
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  UCHAR* pRect = (UCHAR*) lr.pBits;
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1953bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  ConvertFromI420(videoFrame, kARGB, 0, pRect);
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (FAILED(_pTexture->UnlockRect(0))) {
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "Failed to unlock a texture in D3D9 Channel.");
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _bufferIsUpdated = true;
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Called by d3d channel owner to indicate the frame/texture has been rendered off
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint D3D9Channel::RenderOffFrame()
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceStream, kTraceVideo, -1,
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "Frame has been rendered to the screen.");
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _bufferIsUpdated = false;
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Called by d3d channel owner to check if the texture is updated
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint D3D9Channel::IsUpdated(bool& isUpdated)
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    isUpdated = _bufferIsUpdated;
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Called by d3d channel owner to get the texture
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgLPDIRECT3DTEXTURE9 D3D9Channel::GetTexture()
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _pTexture;
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint D3D9Channel::ReleaseTexture()
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //release the texture
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pTexture != NULL)
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture->Release();
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture = NULL;
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice = NULL;
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint D3D9Channel::RecreateTexture(LPDIRECT3DDEVICE9 pd3DDevice)
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice = pd3DDevice;
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pTexture != NULL)
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture->Release();
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture = NULL;
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    HRESULT ret;
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ret = _pd3dDevice->CreateTexture(_width, _height, 1, 0, D3DFMT_A8R8G8B8,
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     D3DPOOL_MANAGED, &_pTexture, NULL);
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (FAILED(ret))
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTexture = NULL;
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *    VideoRenderDirect3D9
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoRenderDirect3D9::VideoRenderDirect3D9(Trace* trace,
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                   HWND hWnd,
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                   bool fullScreen) :
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _refD3DCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _trace(trace),
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _hWnd(hWnd),
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _fullScreen(fullScreen),
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pTextureLogo(NULL),
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pVB(NULL),
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice(NULL),
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pD3D(NULL),
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _d3dChannels(),
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _d3dZorder(),
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateThread(NULL),
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateEvent(NULL),
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _logoLeft(0),
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _logoTop(0),
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _logoRight(0),
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _logoBottom(0),
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dSurface(NULL),
29722c283b04855b8775d323e8788a0438ce2d7c2b5henrike@webrtc.org    _totalMemory(0),
29822c283b04855b8775d323e8788a0438ce2d7c2b5henrike@webrtc.org    _availableMemory(0)
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateThread = ThreadWrapper::CreateThread(ScreenUpdateThreadProc,
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                      this, kRealtimePriority);
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateEvent = EventWrapper::Create();
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    SetRect(&_originalHwndRect, 0, 0, 0, 0);
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoRenderDirect3D9::~VideoRenderDirect3D9()
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //NOTE: we should not enter CriticalSection in here!
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Signal event to exit thread, then delete it
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ThreadWrapper* tmpPtr = _screenUpdateThread;
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateThread = NULL;
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (tmpPtr)
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        tmpPtr->SetNotAlive();
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _screenUpdateEvent->Set();
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _screenUpdateEvent->StopTimer();
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (tmpPtr->Stop())
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            delete tmpPtr;
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete _screenUpdateEvent;
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //close d3d device
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CloseDevice();
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Delete all channels
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, D3D9Channel*>::iterator it = _d3dChannels.begin();
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it != _d3dChannels.end())
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete it->second;
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it = _d3dChannels.erase(it);
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Clean the zOrder map
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _d3dZorder.clear();
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_fullScreen)
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // restore hwnd to original size and position
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ::SetWindowPos(_hWnd, HWND_NOTOPMOST, _originalHwndRect.left,
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                       _originalHwndRect.top, _originalHwndRect.right
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               - _originalHwndRect.left,
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                       _originalHwndRect.bottom - _originalHwndRect.top,
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                       SWP_FRAMECHANGED);
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ::RedrawWindow(_hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                | RDW_ERASE);
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ::RedrawWindow(NULL, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                | RDW_ERASE);
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete &_refD3DCritsect;
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgDWORD VideoRenderDirect3D9::GetVertexProcessingCaps()
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    D3DCAPS9 caps;
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DWORD dwVertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (SUCCEEDED(_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       &caps)))
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if ((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                == D3DDEVCAPS_HWTRANSFORMANDLIGHT)
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            dwVertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return dwVertexProcessing;
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderDirect3D9::InitializeD3D(HWND hWnd,
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                            D3DPRESENT_PARAMETERS* pd3dpp)
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // initialize Direct3D
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (NULL == (_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // determine what type of vertex processing to use based on the device capabilities
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DWORD dwVertexProcessing = GetVertexProcessingCaps();
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // get the display mode
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    D3DDISPLAYMODE d3ddm;
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pd3dpp->BackBufferFormat = d3ddm.Format;
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // create the D3D device
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (FAILED(_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                   dwVertexProcessing | D3DCREATE_MULTITHREADED
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                           | D3DCREATE_FPU_PRESERVE, pd3dpp,
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                   &_pd3dDevice)))
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //try the ref device
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (FAILED(_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF,
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       hWnd, dwVertexProcessing
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                               | D3DCREATE_MULTITHREADED
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                               | D3DCREATE_FPU_PRESERVE,
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       pd3dpp, &_pd3dDevice)))
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return -1;
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderDirect3D9::ResetDevice()
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1,
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "VideoRenderDirect3D9::ResetDevice");
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_refD3DCritsect);
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //release the channel texture
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, D3D9Channel*>::iterator it;
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    it = _d3dChannels.begin();
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it != _d3dChannels.end())
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (it->second)
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            it->second->ReleaseTexture();
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it++;
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //close d3d device
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (CloseDevice() != 0)
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "VideoRenderDirect3D9::ResetDevice failed to CloseDevice");
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //reinit d3d device
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (InitDevice() != 0)
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "VideoRenderDirect3D9::ResetDevice failed to InitDevice");
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //recreate channel texture
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    it = _d3dChannels.begin();
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it != _d3dChannels.end())
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (it->second)
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            it->second->RecreateTexture(_pd3dDevice);
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it++;
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderDirect3D9::InitDevice()
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Set up the structure used to create the D3DDevice
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ZeroMemory(&_d3dpp, sizeof(_d3dpp));
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (GetWindowRect(_hWnd, &_originalHwndRect) == 0)
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "VideoRenderDirect3D9::InitDevice Could not get window size");
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_fullScreen)
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _winWidth = _originalHwndRect.right - _originalHwndRect.left;
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _winHeight = _originalHwndRect.bottom - _originalHwndRect.top;
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _d3dpp.Windowed = TRUE;
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _d3dpp.BackBufferHeight = 0;
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _d3dpp.BackBufferWidth = 0;
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _winWidth = (LONG) ::GetSystemMetrics(SM_CXSCREEN);
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _winHeight = (LONG) ::GetSystemMetrics(SM_CYSCREEN);
482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _d3dpp.Windowed = FALSE;
483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _d3dpp.BackBufferWidth = _winWidth;
484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _d3dpp.BackBufferHeight = _winHeight;
485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (InitializeD3D(_hWnd, &_d3dpp) == -1)
489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "VideoRenderDirect3D9::InitDevice failed in InitializeD3D");
492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Turn off culling, so we see the front and back of the triangle
496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Turn off D3D lighting, since we are providing our own vertex colors
499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Settings for alpha blending
502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Initialize Vertices
511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CUSTOMVERTEX Vertices[] = {
512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //front
513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            { -1.0f, -1.0f, 0.0f, 0xffffffff, 0, 1 }, { -1.0f, 1.0f, 0.0f,
514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    0xffffffff, 0, 0 },
515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            { 1.0f, -1.0f, 0.0f, 0xffffffff, 1, 1 }, { 1.0f, 1.0f, 0.0f,
516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    0xffffffff, 1, 0 } };
517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Create the vertex buffer.
519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (FAILED(_pd3dDevice->CreateVertexBuffer(sizeof(Vertices), 0,
520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                               D3DFVF_CUSTOMVERTEX,
521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                               D3DPOOL_DEFAULT, &_pVB, NULL )))
522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Failed to create the vertex buffer.");
525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Now we fill the vertex buffer.
529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VOID* pVertices;
530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (FAILED(_pVB->Lock(0, sizeof(Vertices), (void**) &pVertices, 0)))
531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Failed to lock the vertex buffer.");
534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memcpy(pVertices, Vertices, sizeof(Vertices));
537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pVB->Unlock();
538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
542e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::Init()
543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1,
545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "VideoRenderDirect3D9::Init");
546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_refD3DCritsect);
548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Start rendering thread...
550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_screenUpdateThread)
551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Thread not created");
553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned int threadId;
556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateThread->Start(threadId);
557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Start the event triggering the render process
559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned int monitorFreq = 60;
560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DEVMODE dm;
561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // initialize the DEVMODE structure
562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ZeroMemory(&dm, sizeof(dm));
563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    dm.dmSize = sizeof(dm);
564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        monitorFreq = dm.dmDisplayFrequency;
567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateEvent->StartTimer(true, 1000 / monitorFreq);
569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return InitDevice();
571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
573e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::ChangeWindow(void* window)
574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderDirect3D9::UpdateRenderSurface()
580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_refD3DCritsect);
582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Check if there are any updated buffers
584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool updated = false;
585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, D3D9Channel*>::iterator it;
586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    it = _d3dChannels.begin();
587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it != _d3dChannels.end())
588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        D3D9Channel* channel = it->second;
591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        channel->IsUpdated(updated);
592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (updated)
593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it++;
597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //nothing is updated, continue
599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!updated)
600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Clear the backbuffer to a black color
603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f,
604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                       0);
605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Begin the scene
607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (SUCCEEDED(_pd3dDevice->BeginScene()))
608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pd3dDevice->SetStreamSource(0, _pVB, 0, sizeof(CUSTOMVERTEX));
610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        D3DXMATRIX matWorld;
613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        D3DXMATRIX matWorldTemp;
614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //draw all the channels
616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //get texture from the channels
617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        LPDIRECT3DTEXTURE9 textureFromChannel = NULL;
618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        DWORD textureWidth, textureHeight;
619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::multimap<int, unsigned int>::reverse_iterator it;
621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it = _d3dZorder.rbegin();
622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        while (it != _d3dZorder.rend())
623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // loop through all channels and streams in Z order
625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            int channel = it->second & 0x0000ffff;
626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            std::map<int, D3D9Channel*>::iterator ddIt;
628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            ddIt = _d3dChannels.find(channel);
629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (ddIt != _d3dChannels.end())
630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                // found the channel
632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                D3D9Channel* channelObj = ddIt->second;
633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                if (channelObj)
634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    textureFromChannel = channelObj->GetTexture();
636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    textureWidth = channelObj->GetTextureWidth();
637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    textureHeight = channelObj->GetTextureHeight();
638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
639e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                    uint32_t zOrder;
640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    float startWidth, startHeight, stopWidth, stopHeight;
641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    channelObj->GetStreamSettings(0, zOrder, startWidth,
642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  startHeight, stopWidth,
643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  stopHeight);
644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    //draw the video stream
646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    UpdateVerticeBuffer(_pVB, 0, startWidth, startHeight,
647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        stopWidth, stopHeight);
648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    _pd3dDevice->SetTexture(0, textureFromChannel);
649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    _pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    //Notice channel that this frame as been rendered
652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    channelObj->RenderOffFrame();
653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            it++;
656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //draw the logo
659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_pTextureLogo)
660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            UpdateVerticeBuffer(_pVB, 0, _logoLeft, _logoTop, _logoRight,
662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                _logoBottom);
663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _pd3dDevice->SetTexture(0, _pTextureLogo);
664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // End the scene
668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pd3dDevice->EndScene();
669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Present the backbuffer contents to the display
672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _pd3dDevice->Present(NULL, NULL, NULL, NULL );
673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//set the  alpha value of the pixal with a particular colorkey as 0
678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderDirect3D9::SetTransparentColor(LPDIRECT3DTEXTURE9 pTexture,
679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  DDCOLORKEY* transparentColorKey,
680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  DWORD width,
681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  DWORD height)
682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    D3DLOCKED_RECT lr;
684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!pTexture)
685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_refD3DCritsect);
688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (SUCCEEDED(pTexture->LockRect(0, &lr, NULL, D3DLOCK_DISCARD)))
689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        for (DWORD y = 0; y < height; y++)
691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            DWORD dwOffset = y * width;
693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            for (DWORD x = 0; x < width; x)
695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                DWORD temp = ((DWORD*) lr.pBits)[dwOffset + x];
697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                if ((temp & 0x00FFFFFF)
698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                        == transparentColorKey->dwColorSpaceLowValue)
699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    temp &= 0x00FFFFFF;
701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                else
703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    temp |= 0xFF000000;
705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                ((DWORD*) lr.pBits)[dwOffset + x] = temp;
707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                x++;
708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        pTexture->UnlockRect(0);
711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *    Rendering process
719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VideoRenderDirect3D9::ScreenUpdateThreadProc(void* obj)
722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return static_cast<VideoRenderDirect3D9*> (obj)->ScreenUpdateProcess();
724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VideoRenderDirect3D9::ScreenUpdateProcess()
727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateEvent->Wait(100);
729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_screenUpdateThread)
731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //stop the thread
733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return false;
734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_pd3dDevice)
736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "d3dDevice not created.");
739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return true;
740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    HRESULT hr = _pd3dDevice->TestCooperativeLevel();
743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (SUCCEEDED(hr))
745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UpdateRenderSurface();
747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (hr == D3DERR_DEVICELOST)
750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //Device is lost and cannot be reset yet
752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else if (hr == D3DERR_DEVICENOTRESET)
755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //Lost but we can reset it now
757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //Note: the standard way is to call Reset, however for some reason doesn't work here.
758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //so we will release the device and create it again.
759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ResetDevice();
760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return true;
763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderDirect3D9::CloseDevice()
766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_refD3DCritsect);
768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1,
769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "VideoRenderDirect3D9::CloseDevice");
770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pTextureLogo != NULL)
772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTextureLogo->Release();
774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTextureLogo = NULL;
775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pVB != NULL)
778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pVB->Release();
780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pVB = NULL;
781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pd3dDevice != NULL)
784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pd3dDevice->Release();
786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pd3dDevice = NULL;
787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pD3D != NULL)
790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pD3D->Release();
792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pD3D = NULL;
793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pd3dSurface != NULL)
796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pd3dSurface->Release();
797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgD3D9Channel* VideoRenderDirect3D9::GetD3DChannel(int channel)
801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, D3D9Channel*>::iterator ddIt;
803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ddIt = _d3dChannels.find(channel & 0x0000ffff);
804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    D3D9Channel* ddobj = NULL;
805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ddIt != _d3dChannels.end())
806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ddobj = ddIt->second;
808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ddobj == NULL)
810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Direct3D render failed to find channel");
813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return NULL;
814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return ddobj;
816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
818e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::DeleteChannel(const uint32_t streamId)
819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_refD3DCritsect);
821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::multimap<int, unsigned int>::iterator it;
824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    it = _d3dZorder.begin();
825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it != _d3dZorder.end())
826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if ((streamId & 0x0000ffff) == (it->second & 0x0000ffff))
828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            it = _d3dZorder.erase(it);
830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it++;
833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, D3D9Channel*>::iterator ddIt;
836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ddIt = _d3dChannels.find(streamId & 0x0000ffff);
837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ddIt != _d3dChannels.end())
838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete ddIt->second;
840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _d3dChannels.erase(ddIt);
841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
846e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgVideoRenderCallback* VideoRenderDirect3D9::CreateChannel(const uint32_t channel,
847e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                                 const uint32_t zOrder,
848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                                 const float left,
849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                                 const float top,
850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                                 const float right,
851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                                 const float bottom)
852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_refD3DCritsect);
854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //FIXME this should be done in VideoAPIWindows? stop the frame deliver first
856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //remove the old channel
857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DeleteChannel(channel);
858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    D3D9Channel* d3dChannel = new D3D9Channel(_pd3dDevice,
860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                      &_refD3DCritsect, _trace);
861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    d3dChannel->SetStreamSettings(0, zOrder, left, top, right, bottom);
862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // store channel
864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _d3dChannels[channel & 0x0000ffff] = d3dChannel;
865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // store Z order
867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // default streamID is 0
868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _d3dZorder.insert(
869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                      std::pair<int, unsigned int>(zOrder, channel & 0x0000ffff));
870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return d3dChannel;
872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
874e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::GetStreamSettings(const uint32_t channel,
875e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                const uint16_t streamId,
876e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                uint32_t& zOrder,
877e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                float& left, float& top,
878e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                float& right, float& bottom)
879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, D3D9Channel*>::iterator ddIt;
881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ddIt = _d3dChannels.find(channel & 0x0000ffff);
882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    D3D9Channel* ddobj = NULL;
883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ddIt != _d3dChannels.end())
884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ddobj = ddIt->second;
886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ddobj == NULL)
888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Direct3D render failed to find channel");
891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Only allow one stream per channel, demuxing is
894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return ddobj->GetStreamSettings(0, zOrder, left, top, right, bottom);
895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //return ddobj->GetStreamSettings(streamId, zOrder, left, top, right, bottom);
896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderDirect3D9::UpdateVerticeBuffer(LPDIRECT3DVERTEXBUFFER9 pVB,
899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  int offset,
900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  float startWidth,
901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  float startHeight,
902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  float stopWidth,
903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                  float stopHeight)
904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (pVB == NULL)
906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    float left, right, top, bottom;
909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //update the vertice buffer
911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //0,1 => -1,1
912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    left = startWidth * 2 - 1;
913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    right = stopWidth * 2 - 1;
914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //0,1 => 1,-1
916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    top = 1 - startHeight * 2;
917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bottom = 1 - stopHeight * 2;
918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CUSTOMVERTEX newVertices[] = {
920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //logo
921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            { left, bottom, 0.0f, 0xffffffff, 0, 1 }, { left, top, 0.0f,
922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    0xffffffff, 0, 0 },
923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            { right, bottom, 0.0f, 0xffffffff, 1, 1 }, { right, top, 0.0f,
924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    0xffffffff, 1, 0 }, };
925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Now we fill the vertex buffer.
926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VOID* pVertices;
927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (FAILED(pVB->Lock(sizeof(CUSTOMVERTEX) * offset, sizeof(newVertices),
928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                         (void**) &pVertices, 0)))
929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Failed to lock the vertex buffer.");
932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memcpy(pVertices, newVertices, sizeof(newVertices));
935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pVB->Unlock();
936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
940e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::StartRender()
941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
946e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::StopRender()
947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VideoRenderDirect3D9::IsFullScreen()
953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _fullScreen;
955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
957e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::SetCropping(const uint32_t channel,
958e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                          const uint16_t streamId,
959e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                          const float left, const float top,
960e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                          const float right, const float bottom)
961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
966e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::SetTransparentBackground(
967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                                 const bool enable)
968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
973e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::SetText(const uint8_t textId,
974e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                      const uint8_t* text,
975e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                      const int32_t textLength,
976e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                      const uint32_t colorText,
977e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                      const uint32_t colorBg,
978e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                      const float left, const float top,
979e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                      const float rigth, const float bottom)
980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Not supported.");
982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
985e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::SetBitmap(const void* bitMap,
986e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                        const uint8_t pictureId,
987e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                        const void* colorKey,
988e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                        const float left, const float top,
989e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                        const float right, const float bottom)
990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!bitMap)
992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_pTextureLogo != NULL)
994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _pTextureLogo->Release();
996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _pTextureLogo = NULL;
997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceInfo, kTraceVideo, -1, "Remove bitmap.");
999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // sanity
1003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (left > 1.0f || left < 0.0f ||
1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        top > 1.0f || top < 0.0f ||
1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        right > 1.0f || right < 0.0f ||
1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        bottom > 1.0f || bottom < 0.0f)
1007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Direct3D SetBitmap invalid parameter");
1010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ((bottom <= top) || (right <= left))
1014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Direct3D SetBitmap invalid parameter");
1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_refD3DCritsect);
1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned char* srcPtr;
1023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    HGDIOBJ oldhand;
1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    BITMAPINFO pbi;
1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    BITMAP bmap;
1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    HDC hdcNew;
1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    hdcNew = CreateCompatibleDC(0);
1028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Fill out the BITMAP structure.
1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GetObject((HBITMAP)bitMap, sizeof(bmap), &bmap);
1030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //Select the bitmap handle into the new device context.
1031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    oldhand = SelectObject(hdcNew, (HGDIOBJ) bitMap);
1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // we are done with this object
1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DeleteObject(oldhand);
1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pbi.bmiHeader.biSize = 40;
1035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pbi.bmiHeader.biWidth = bmap.bmWidth;
1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pbi.bmiHeader.biHeight = bmap.bmHeight;
1037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pbi.bmiHeader.biPlanes = 1;
1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pbi.bmiHeader.biBitCount = bmap.bmBitsPixel;
1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pbi.bmiHeader.biCompression = BI_RGB;
1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pbi.bmiHeader.biSizeImage = bmap.bmWidth * bmap.bmHeight * 3;
1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    srcPtr = new unsigned char[bmap.bmWidth * bmap.bmHeight * 4];
1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // the original un-stretched image in RGB24
1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int pixelHeight = GetDIBits(hdcNew, (HBITMAP)bitMap, 0, bmap.bmHeight, srcPtr, &pbi,
1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                DIB_RGB_COLORS);
1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (pixelHeight == 0)
1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
1048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Direct3D failed to GetDIBits in SetBitmap");
1049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete[] srcPtr;
1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DeleteDC(hdcNew);
1053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (pbi.bmiHeader.biBitCount != 24 && pbi.bmiHeader.biBitCount != 32)
1054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
1056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Direct3D failed to SetBitmap invalid bit depth");
1057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete[] srcPtr;
1058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1060b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    HRESULT ret;
1062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //release the previous logo texture
1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_pTextureLogo != NULL)
1064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTextureLogo->Release();
1066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTextureLogo = NULL;
1067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ret = _pd3dDevice->CreateTexture(bmap.bmWidth, bmap.bmHeight, 1, 0,
1069b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
1070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     &_pTextureLogo, NULL);
1071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (FAILED(ret))
1072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _pTextureLogo = NULL;
1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete[] srcPtr;
1075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_pTextureLogo)
1078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1079b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
1080b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Texture for rendering not initialized.");
1081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete[] srcPtr;
1082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    D3DLOCKED_RECT lr;
1086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (FAILED(_pTextureLogo->LockRect(0, &lr, NULL, 0)))
1087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1088b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete[] srcPtr;
1089b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1090b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned char* dstPtr = (UCHAR*) lr.pBits;
1092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int pitch = bmap.bmWidth * 4;
1093b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1094b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (pbi.bmiHeader.biBitCount == 24)
1095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ConvertRGB24ToARGB(srcPtr, dstPtr, bmap.bmWidth, bmap.bmHeight, 0);
1097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1098b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
1099b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        unsigned char* srcTmp = srcPtr + (bmap.bmWidth * 4) * (bmap.bmHeight - 1);
1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        for (int i = 0; i < bmap.bmHeight; ++i)
1102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
1103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            memcpy(dstPtr, srcTmp, bmap.bmWidth * 4);
1104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            srcTmp -= bmap.bmWidth * 4;
1105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            dstPtr += pitch;
1106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete[] srcPtr;
1110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (FAILED(_pTextureLogo->UnlockRect(0)))
1111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (colorKey)
1116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        DDCOLORKEY* ddColorKey =
1118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                static_cast<DDCOLORKEY*> (const_cast<void*> (colorKey));
1119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        SetTransparentColor(_pTextureLogo, ddColorKey, bmap.bmWidth,
1120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                            bmap.bmHeight);
1121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //update the vertice buffer
1124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //0,1 => -1,1
1125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _logoLeft = left;
1126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _logoRight = right;
1127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //0,1 => 1,-1
1129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _logoTop = top;
1130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _logoBottom = bottom;
1131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
1133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1136e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::GetGraphicsMemory(uint64_t& totalMemory,
1137e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                uint64_t& availableMemory)
1138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_totalMemory == -1 || _availableMemory == -1)
1140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        totalMemory = 0;
1142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        availableMemory = 0;
1143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    totalMemory = _totalMemory;
1146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    availableMemory = _availableMemory;
1147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
1148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1150e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderDirect3D9::ConfigureRenderer(const uint32_t channel,
1151e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                const uint16_t streamId,
1152e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                const unsigned int zOrder,
1153e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                const float left,
1154e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                const float top,
1155e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                const float right,
1156e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                const float bottom)
1157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, D3D9Channel*>::iterator ddIt;
1159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ddIt = _d3dChannels.find(channel & 0x0000ffff);
1160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    D3D9Channel* ddobj = NULL;
1161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ddIt != _d3dChannels.end())
1162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ddobj = ddIt->second;
1164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ddobj == NULL)
1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
1168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     "Direct3D render failed to find channel");
1169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Only allow one stream per channel, demuxing is
1172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ddobj->SetStreamSettings(0, zOrder, left, top, right, bottom);
1173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
1175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11773b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace webrtc
1178