6
6
#include < array>
7
7
#include < cstdio>
8
8
#include " rtc_base/logging.h"
9
+ #include < system_error>
9
10
#include " talk/owt/sdk/base/nativehandlebuffer.h"
10
11
#include " talk/owt/sdk/base/win/d3dnativeframe.h"
11
12
#include " talk/owt/sdk/include/cpp/owt/base/videorendererinterface.h"
@@ -32,6 +33,14 @@ void WebrtcVideoRendererD3D11Impl::OnFrame(
32
33
return ;
33
34
}
34
35
36
+ if (!wnd_ || !IsWindow (wnd_) || !IsWindowVisible (wnd_))
37
+ return ;
38
+
39
+ RECT rect;
40
+ GetClientRect (wnd_, &rect);
41
+ int window_width_ = rect.right - rect.left ;
42
+ int window_height_ = rect.bottom - rect.top ;
43
+
35
44
if (video_frame.video_frame_buffer ()->type () ==
36
45
webrtc::VideoFrameBuffer::Type::kNative ) {
37
46
D3D11ImageHandle* native_handle = reinterpret_cast <D3D11ImageHandle*>(
@@ -67,29 +76,13 @@ void WebrtcVideoRendererD3D11Impl::OnFrame(
67
76
RenderNativeHandleFrame (video_frame);
68
77
} else { // I420 frame passed.
69
78
// First scale down to target window size.
70
- RECT rect;
71
- GetClientRect (wnd_, &rect);
72
- int window_width_ = rect.right - rect.left ;
73
- int window_height_ = rect.bottom - rect.top ;
74
-
75
79
webrtc::VideoFrame new_frame (video_frame);
76
-
77
- {
78
- rtc::CritScope lock (&d3d11_texture_lock_);
79
- if (window_width != window_width_ || window_height != window_height_) {
80
- if (swap_chain_for_hwnd_) {
81
- swap_chain_for_hwnd_.Release ();
82
- swap_chain_for_hwnd_ = nullptr ;
83
- }
84
- window_width = window_width_;
85
- window_height = window_height_;
86
- }
87
- }
88
80
rtc::scoped_refptr<webrtc::I420Buffer> scaled_buffer =
89
81
I420Buffer::Create (window_width_, window_height_);
90
82
auto i420_buffer = video_frame.video_frame_buffer ()->ToI420 ();
91
83
scaled_buffer->ScaleFrom (*i420_buffer);
92
84
new_frame.set_video_frame_buffer (scaled_buffer);
85
+
93
86
RenderI420Frame_DX11 (new_frame);
94
87
}
95
88
return ;
@@ -141,8 +134,8 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
141
134
HRESULT hr = S_OK;
142
135
RECT rect;
143
136
GetClientRect (wnd_, &rect);
144
- int window_width_ = rect.right - rect.left ;
145
- int window_height_ = rect.bottom - rect.top ;
137
+ window_width = rect.right - rect.left ;
138
+ window_height = rect.bottom - rect.top ;
146
139
147
140
rtc::CritScope lock (&d3d11_texture_lock_);
148
141
if (swap_chain_for_hwnd_) {
@@ -154,9 +147,11 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
154
147
return false ;
155
148
}
156
149
157
- if (desc.BufferDesc .Width != (unsigned int )window_width_ ||
158
- desc.BufferDesc .Height != (unsigned int )window_height_) {
159
- hr = swap_chain_for_hwnd_->ResizeBuffers (0 , window_width_, window_height_,
150
+ if (desc.BufferDesc .Width != (unsigned int )window_width ||
151
+ desc.BufferDesc .Height != (unsigned int )window_height) {
152
+ d3d11_device_context_->ClearState ();
153
+ d3d11_device_context_->Flush ();
154
+ hr = swap_chain_for_hwnd_->ResizeBuffers (0 , window_width, window_height,
160
155
DXGI_FORMAT_UNKNOWN, desc.Flags );
161
156
if (FAILED (hr)) {
162
157
RTC_LOG (LS_ERROR) << " failed to resize buffer for swapchain." ;
@@ -171,8 +166,8 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
171
166
ZeroMemory (&desc, sizeof (DXGI_SWAP_CHAIN_DESC1));
172
167
desc.BufferCount = 2 ;
173
168
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
174
- desc.Height = window_height_ ;
175
- desc.Width = window_width_ ;
169
+ desc.Height = window_height ;
170
+ desc.Width = window_width ;
176
171
desc.Scaling = DXGI_SCALING_STRETCH;
177
172
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
178
173
desc.SampleDesc .Count = 1 ;
@@ -184,23 +179,38 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
184
179
CComPtr<IDXGIDevice2> dxgi_device;
185
180
hr = d3d11_device_->QueryInterface (__uuidof (IDXGIDevice1),
186
181
(void **)&dxgi_device);
187
- if (FAILED (hr))
182
+ if (FAILED (hr)) {
183
+ RTC_LOG (LS_ERROR) << " Failed to query dxgi device." ;
188
184
return false ;
185
+ }
189
186
190
187
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter = nullptr ;
191
188
Microsoft::WRL::ComPtr<IDXGIFactory2> factory = nullptr ;
192
189
193
190
hr = dxgi_device->GetAdapter (&adapter);
194
- if (FAILED (hr))
191
+ if (FAILED (hr)) {
192
+ RTC_LOG (LS_ERROR) << " Failed to get the adatper." ;
195
193
return false ;
194
+ }
196
195
197
196
hr = adapter->GetParent (IID_PPV_ARGS (&factory));
198
- if (FAILED (hr))
197
+ if (FAILED (hr)) {
198
+ RTC_LOG (LS_ERROR) << " Failed to get dxgi factory." ;
199
199
return false ;
200
+ }
201
+
202
+ d3d11_device_context_->ClearState ();
203
+ d3d11_device_context_->Flush ();
204
+
205
+ if (swap_chain_for_hwnd_)
206
+ swap_chain_for_hwnd_.Release ();
200
207
201
208
hr = factory->CreateSwapChainForHwnd (d3d11_device_, wnd_, &desc, nullptr , nullptr , &swap_chain_for_hwnd_);
202
- if (FAILED (hr))
209
+ if (FAILED (hr)) {
210
+ std::string message = std::system_category ().message (hr);
211
+ RTC_LOG (LS_ERROR) << " Failed to create swapchain for hwnd." << message;
203
212
return false ;
213
+ }
204
214
205
215
return true ;
206
216
}
@@ -243,8 +253,15 @@ void WebrtcVideoRendererD3D11Impl::RenderNV12DXGIMPO(int width, int height) {
243
253
244
254
RECT rect;
245
255
GetClientRect (wnd_, &rect);
246
- int window_width = rect.right - rect.left ;
247
- int window_height = rect.bottom - rect.top ;
256
+ window_width = rect.right - rect.left ;
257
+ window_height = rect.bottom - rect.top ;
258
+
259
+ if (!d3d11_video_device_) {
260
+ hr = d3d11_device_->QueryInterface (__uuidof (ID3D11VideoDevice),
261
+ (void **)&d3d11_video_device_);
262
+ if (FAILED (hr))
263
+ return ;
264
+ }
248
265
249
266
if (swap_chain_for_hwnd_) {
250
267
DXGI_SWAP_CHAIN_DESC desc;
@@ -254,6 +271,10 @@ void WebrtcVideoRendererD3D11Impl::RenderNV12DXGIMPO(int width, int height) {
254
271
255
272
if (desc.BufferDesc .Width != (unsigned int )window_width ||
256
273
desc.BufferDesc .Height != (unsigned int )window_height) {
274
+ // Hold the lock to avoid rendering when resizing buffer.
275
+ rtc::CritScope lock (&d3d11_texture_lock_);
276
+ d3d11_device_context_->ClearState ();
277
+
257
278
hr = swap_chain_for_hwnd_->ResizeBuffers (0 , window_width, window_height,
258
279
DXGI_FORMAT_UNKNOWN, desc.Flags );
259
280
if (FAILED (hr))
@@ -262,12 +283,6 @@ void WebrtcVideoRendererD3D11Impl::RenderNV12DXGIMPO(int width, int height) {
262
283
}
263
284
264
285
bool reset = false ;
265
- if (!d3d11_video_device_) {
266
- hr = d3d11_device_->QueryInterface (__uuidof (ID3D11VideoDevice),
267
- (void **)&d3d11_video_device_);
268
- if (FAILED (hr))
269
- return ;
270
- }
271
286
272
287
if (!d3d11_video_context_) {
273
288
hr = d3d11_device_context_->QueryInterface (__uuidof (ID3D11VideoContext),
@@ -345,6 +360,9 @@ bool WebrtcVideoRendererD3D11Impl::InitMPO(int width, int height) {
345
360
int rect_width = rect.right - rect.left ;
346
361
int rect_height = rect.bottom - rect.top ;
347
362
363
+ window_width = rect_width;
364
+ window_height = rect_height;
365
+
348
366
swapChainDesc.Width = (rect_width%2 ) ? (rect_width + 1 ) : rect_width;
349
367
swapChainDesc.Height = (rect_height%2 ) ? (rect_height + 1 ) : rect_height;
350
368
swapChainDesc.Format = DXGI_FORMAT_NV12;
@@ -396,7 +414,7 @@ bool WebrtcVideoRendererD3D11Impl::CreateVideoProcessor(int width,
396
414
int window_height = rect.bottom - rect.top ;
397
415
D3D11_VIDEO_PROCESSOR_CONTENT_DESC content_desc;
398
416
ZeroMemory (&content_desc, sizeof (content_desc));
399
- // Check input size to decide if
417
+
400
418
if (video_processor_.p && video_processor_enum_.p ) {
401
419
hr = video_processor_enum_->GetVideoProcessorContentDesc (&content_desc);
402
420
if (FAILED (hr))
0 commit comments